diff --git a/go.mod b/go.mod
index b8ec5e8e6..914b66c97 100644
--- a/go.mod
+++ b/go.mod
@@ -9,6 +9,8 @@ require (
code.gitea.io/sdk/gitea v0.18.0
github.com/AlecAivazis/survey/v2 v2.3.7
github.com/bradleyfalzon/ghinstallation/v2 v2.10.0
+ github.com/cli/cli/v2 v2.46.0
+ github.com/cli/oauth v1.0.1
github.com/cloudevents/sdk-go/v2 v2.15.2
github.com/fvbommel/sortorder v1.1.0
github.com/gfleury/go-bitbucket-v1 v0.0.0-20240131155556-0b41d7863037
@@ -18,6 +20,7 @@ require (
github.com/google/go-github/scrape v0.0.0-20240403195118-24209f034709
github.com/google/go-github/v60 v60.0.0
github.com/google/go-github/v61 v61.0.0
+ github.com/h2non/gock v1.2.0
github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b
github.com/jonboulle/clockwork v0.4.0
github.com/juju/ansiterm v1.0.0
@@ -27,10 +30,11 @@ require (
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d
github.com/mitchellh/mapstructure v1.5.0
github.com/pkg/errors v0.9.1
- github.com/spf13/cobra v1.8.0
+ github.com/spf13/cobra v1.8.1
github.com/stretchr/testify v1.9.0
github.com/tektoncd/pipeline v0.62.1
github.com/xanzy/go-gitlab v0.101.0
+ github.com/zalando/go-keyring v0.2.5
go.opencensus.io v0.24.0
go.uber.org/zap v1.27.0
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8
@@ -48,7 +52,36 @@ require (
sigs.k8s.io/yaml v1.4.0
)
-require github.com/coreos/go-oidc/v3 v3.9.0 // indirect
+require (
+ github.com/MakeNowJust/heredoc v1.0.0 // indirect
+ github.com/alessio/shellescape v1.4.2 // indirect
+ github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
+ github.com/briandowns/spinner v1.18.1 // indirect
+ github.com/charmbracelet/lipgloss v0.10.1-0.20240413172830-d0be07ea6b9c // indirect
+ github.com/charmbracelet/x/exp/term v0.0.0-20240425164147-ba2a9512b05f // indirect
+ github.com/cli/browser v1.3.0 // indirect
+ github.com/cli/go-gh/v2 v2.9.0 // indirect
+ github.com/cli/safeexec v1.0.1 // indirect
+ github.com/cli/shurcooL-graphql v0.0.4 // indirect
+ github.com/coreos/go-oidc/v3 v3.9.0 // indirect
+ github.com/danieljoos/wincred v1.2.1 // indirect
+ github.com/fatih/color v1.16.0 // indirect
+ github.com/go-jose/go-jose/v3 v3.0.3 // indirect
+ github.com/godbus/dbus/v5 v5.1.0 // indirect
+ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
+ github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect
+ github.com/henvic/httpretty v0.1.3 // indirect
+ github.com/itchyny/gojq v0.12.15 // indirect
+ github.com/itchyny/timefmt-go v0.1.5 // indirect
+ github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
+ github.com/mattn/go-runewidth v0.0.15 // indirect
+ github.com/muesli/reflow v0.3.0 // indirect
+ github.com/muesli/termenv v0.15.2 // indirect
+ github.com/rivo/uniseg v0.4.7 // indirect
+ github.com/shurcooL/githubv4 v0.0.0-20230704064427-599ae7bbf278 // indirect
+ github.com/shurcooL/graphql v0.0.0-20230722043721-ed46e5a46466 // indirect
+ github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e // indirect
+)
replace (
k8s.io/kube-openapi => k8s.io/kube-openapi v0.0.0-20230515203736-54b630e78af5
@@ -86,6 +119,7 @@ require (
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/gnostic v0.7.0 // indirect
github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect
+ github.com/google/go-containerregistry v0.19.2 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.6.0 // indirect
diff --git a/go.sum b/go.sum
index 3c90d485d..a20f1e771 100644
--- a/go.sum
+++ b/go.sum
@@ -612,6 +612,8 @@ github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1r
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk=
+github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
+github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
@@ -629,6 +631,8 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
+github.com/alessio/shellescape v1.4.2 h1:MHPfaU+ddJ0/bYWpgIeUnQUqKrlJ1S7BfEYPM4uEoM0=
+github.com/alessio/shellescape v1.4.2/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30=
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss=
github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
@@ -640,6 +644,8 @@ github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9
github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0=
github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI=
github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU=
+github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
+github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@@ -652,6 +658,8 @@ github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/bradleyfalzon/ghinstallation/v2 v2.10.0 h1:XWuWBRFEpqVrHepQob9yPS3Xg4K3Wr9QCx4fu8HbUNg=
github.com/bradleyfalzon/ghinstallation/v2 v2.10.0/go.mod h1:qoGA4DxWPaYTgVCrmEspVSjlTu4WYAiSxMIhorMRXXc=
+github.com/briandowns/spinner v1.18.1 h1:yhQmQtM1zsqFsouh09Bk/jCjd50pC3EOGsh28gLVvwY=
+github.com/briandowns/spinner v1.18.1/go.mod h1:mQak9GHqbspjC/5iUx3qMlIho8xBS/ppAL/hX5SmPJU=
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
@@ -662,9 +670,27 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/charmbracelet/lipgloss v0.10.1-0.20240413172830-d0be07ea6b9c h1:0FwZb0wTiyalb8QQlILWyIuh3nF5wok6j9D9oUQwfQY=
+github.com/charmbracelet/lipgloss v0.10.1-0.20240413172830-d0be07ea6b9c/go.mod h1:EPP2QJ0ectp3zo6gx9f8oJGq8keirqPJ3XpYEI8wrrs=
+github.com/charmbracelet/x/exp/term v0.0.0-20240425164147-ba2a9512b05f h1:1BXkZqDueTOBECyDoFGRi0xMYgjJ6vvoPIkWyKOwzTc=
+github.com/charmbracelet/x/exp/term v0.0.0-20240425164147-ba2a9512b05f/go.mod h1:yQqGHmheaQfkqiJWjklPHVAq1dKbk8uGbcoS/lcKCJ0=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
+github.com/cli/browser v1.0.0/go.mod h1:IEWkHYbLjkhtjwwWlwTHW2lGxeS5gezEQBMLTwDHf5Q=
+github.com/cli/browser v1.3.0 h1:LejqCrpWr+1pRqmEPDGnTZOjsMe7sehifLynZJuqJpo=
+github.com/cli/browser v1.3.0/go.mod h1:HH8s+fOAxjhQoBUAsKuPCbqUuxZDhQ2/aD+SzsEfBTk=
+github.com/cli/cli/v2 v2.46.0 h1:NwMeyiYuVxrrHnCqrs9ZRUJu9UY1JzgW2BCr3ETNB+0=
+github.com/cli/cli/v2 v2.46.0/go.mod h1:fT+63cxZjrBUnYauUq9xMBEPL913JMk/ZxHtuH57CfU=
+github.com/cli/go-gh/v2 v2.9.0 h1:D3lTjEneMYl54M+WjZ+kRPrR5CEJ5BHS05isBPOV3LI=
+github.com/cli/go-gh/v2 v2.9.0/go.mod h1:MeRoKzXff3ygHu7zP+NVTT+imcHW6p3tpuxHAzRM2xE=
+github.com/cli/oauth v1.0.1 h1:pXnTFl/qUegXHK531Dv0LNjW4mLx626eS42gnzfXJPA=
+github.com/cli/oauth v1.0.1/go.mod h1:qd/FX8ZBD6n1sVNQO3aIdRxeu5LGw9WhKnYhIIoC2A4=
+github.com/cli/safeexec v1.0.0/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q=
+github.com/cli/safeexec v1.0.1 h1:e/C79PbXF4yYTN/wauC4tviMxEV13BwljGj0N9j+N00=
+github.com/cli/safeexec v1.0.1/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q=
+github.com/cli/shurcooL-graphql v0.0.4 h1:6MogPnQJLjKkaXPyGqPRXOI2qCsQdqNfUY1QSJu2GuY=
+github.com/cli/shurcooL-graphql v0.0.4/go.mod h1:3waN4u02FiZivIV+p1y4d0Jo1jc6BViMA73C+sZo2fk=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudevents/sdk-go/observability/opencensus/v2 v2.15.2 h1:AbtPqiUDzKup5JpTZzO297/QXgL/TAdpdXQCNwLzlaM=
github.com/cloudevents/sdk-go/observability/opencensus/v2 v2.15.2/go.mod h1:ZbYLE+yaEQ2j4vbRc9qzvGmg30A9LhwFt/1bSebNnbU=
@@ -687,10 +713,13 @@ github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWH
github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/coreos/go-oidc/v3 v3.9.0 h1:0J/ogVOd4y8P0f0xUh8l9t07xRP/d8tccvjHl2dcsSo=
github.com/coreos/go-oidc/v3 v3.9.0/go.mod h1:rTKz2PYwftcrtoCzV5g5kvfJoWcm0Mk8AF8y1iAQro4=
-github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
-github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI=
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
+github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0=
+github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
+github.com/danieljoos/wincred v1.2.1 h1:dl9cBrupW8+r5250DYkYxocLeZ1Y4vB1kxgtjxw8GQs=
+github.com/danieljoos/wincred v1.2.1/go.mod h1:uGaFL9fDn3OLTvzCGulzE+SzjEe5NGlh5FdCcyfPwps=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
@@ -724,6 +753,7 @@ github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lSh
github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg=
github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ=
+github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0=
@@ -779,6 +809,8 @@ github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
+github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
+github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@@ -853,6 +885,8 @@ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-containerregistry v0.19.2 h1:TannFKE1QSajsP6hPWb5oJNgKe1IKjHukIKDUmvsV6w=
+github.com/google/go-containerregistry v0.19.2/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI=
github.com/google/go-github/scrape v0.0.0-20240403195118-24209f034709 h1:VRG+f7JgOukeWfJbgBLjkAkvvgQE97WPJYw199WfGL8=
github.com/google/go-github/scrape v0.0.0-20240403195118-24209f034709/go.mod h1:8gdN46n0rSW2jEvBD7hp2YL1IkJRewL4wAFVNA7FjLE=
github.com/google/go-github/v60 v60.0.0 h1:oLG98PsLauFvvu4D/YPxq374jhSxFYdzQGNCyONLfn8=
@@ -890,6 +924,8 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
github.com/google/s2a-go v0.1.0/go.mod h1:OJpEgntRZo8ugHpF9hkoLJbS5dSI20XZeXJ9JVywLlM=
github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
+github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
+github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
@@ -926,6 +962,10 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4Zs
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k=
+github.com/h2non/gock v1.2.0 h1:K6ol8rfrRkUOefooBC8elXoaNGYkpp7y2qcxGG6BzUE=
+github.com/h2non/gock v1.2.0/go.mod h1:tNhoxHYW2W42cYkYb1WqzdbYIieALC99kpYr7rH/BQk=
+github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
+github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b h1:wDUNC2eKiL35DbLvsDhiblTUXHxcOPwQSCzi7xpQUN4=
github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b/go.mod h1:VzxiSdG6j1pi7rwGm/xYI5RbtpBgM8sARDXlvEvxlu0=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@@ -945,6 +985,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
+github.com/henvic/httpretty v0.1.3 h1:4A6vigjz6Q/+yAfTD4wqipCv+Px69C7Th/NhT0ApuU8=
+github.com/henvic/httpretty v0.1.3/go.mod h1:UUEv7c2kHZ5SPQ51uS3wBpzPDibg2U3Y+IaXyHy5GBg=
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
@@ -955,6 +997,10 @@ github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
+github.com/itchyny/gojq v0.12.15 h1:WC1Nxbx4Ifw5U2oQWACYz32JK8G9qxNtHzrvW4KEcqI=
+github.com/itchyny/gojq v0.12.15/go.mod h1:uWAHCbCIla1jiNxmeT5/B5mOjSdfkCq6p8vxWg+BM10=
+github.com/itchyny/timefmt-go v0.1.5 h1:G0INE2la8S6ru/ZI5JecgyzbbJNs5lG1RcBqa7Jm6GE=
+github.com/itchyny/timefmt-go v0.1.5/go.mod h1:nEP7L+2YmAbT2kZ2HfSs1d8Xtw9LY8D2stDBckWakZ8=
github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4=
github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
@@ -1001,6 +1047,8 @@ github.com/ktrysmt/go-bitbucket v0.9.77 h1:D/xyUFLDaxI9USElXzjQr+s4hYR22vcsIl8+d
github.com/ktrysmt/go-bitbucket v0.9.77/go.mod h1:7dN/AHXCCG9TW2KzXdJJy2J2uvcvZCLJR4uXYr1Gx/A=
github.com/lightstep/tracecontext.go v0.0.0-20181129014701-1757c391b1ac h1:+2b6iGRJe3hvV/yVXrd41yVEjxuFHxasJqDhkIjS4gk=
github.com/lightstep/tracecontext.go v0.0.0-20181129014701-1757c391b1ac/go.mod h1:Frd2bnT3w5FB5q49ENTfVlztJES+1k/7lyWX2+9gq/M=
+github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
+github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/lunixbochs/vtclean v1.0.0 h1:xu2sLAri4lGiovBDQKxl5mrXyESr3gUr5m5SM5+LVb8=
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA=
@@ -1020,6 +1068,9 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
+github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
+github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
@@ -1037,10 +1088,16 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
+github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
+github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
+github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
+github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4=
+github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
@@ -1111,6 +1168,10 @@ github.com/rickb777/date v1.20.2 h1:CUpAaa4ksqvcRaidSgwzK7zeO2wUG5/VGy6Zlfcu/d4=
github.com/rickb777/date v1.20.2/go.mod h1:PVaM/Zn0IOzjm1uj84Eh9NJ/imtQSm1SVKtOvIunaYw=
github.com/rickb777/plural v1.4.1 h1:5MMLcbIaapLFmvDGRT5iPk8877hpTPt8Y9cdSKRw9sU=
github.com/rickb777/plural v1.4.1/go.mod h1:kdmXUpmKBJTS0FtG/TFumd//VBWsNTD7zOw7x4umxNw=
+github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
+github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
@@ -1122,6 +1183,10 @@ github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w=
github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk=
+github.com/shurcooL/githubv4 v0.0.0-20230704064427-599ae7bbf278 h1:kdEGVAV4sO46DPtb8k793jiecUEhaX9ixoIBt41HEGU=
+github.com/shurcooL/githubv4 v0.0.0-20230704064427-599ae7bbf278/go.mod h1:zqMwyHmnN/eDOZOdiTohqIUKUrTFX62PNlu7IJdu0q8=
+github.com/shurcooL/graphql v0.0.0-20230722043721-ed46e5a46466 h1:17JxqqJY66GmZVHkmAsGEkcIu0oCe3AM420QDgGwZx0=
+github.com/shurcooL/graphql v0.0.0-20230722043721-ed46e5a46466/go.mod h1:9dIRpgIY7hVhoqfe0/FcYp0bpInZaT7dc3BYOprrIUE=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
@@ -1129,8 +1194,8 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO
github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
-github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
-github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
+github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
+github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
@@ -1141,6 +1206,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
@@ -1157,6 +1223,8 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8
github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc=
github.com/tektoncd/pipeline v0.62.1 h1:l+EvRCrLqTHuHwas+C4bRP6jzln8E1J9I7tnfwmWfJQ=
github.com/tektoncd/pipeline v0.62.1/go.mod h1:cYPH4n3X8t39arNMhgyU7swyv3hVeWToz1yYDRzTLT8=
+github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e h1:BuzhfgfWQbX0dWzYzT1zsORLnHRv3bcRcsaUk0VmXA8=
+github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e/go.mod h1:/Tnicc6m/lsJE0irFMA0LfIwTBo4QP7A8IfyIv4zZKI=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/xanzy/go-gitlab v0.101.0 h1:qRgvX8DNE19zRugB6rnnZMZ5ubhITSKPLNWEyc6UIPg=
@@ -1173,6 +1241,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+github.com/zalando/go-keyring v0.2.5 h1:Bc2HHpjALryKD62ppdEzaFG6VxL6Bc+5v0LYpN8Lba8=
+github.com/zalando/go-keyring v0.2.5/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk=
github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
@@ -1462,6 +1532,7 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -1918,6 +1989,8 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY=
+gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
diff --git a/pkg/cmd/tknpac/auth/keyring.go b/pkg/cmd/tknpac/auth/keyring.go
new file mode 100644
index 000000000..2f736ae66
--- /dev/null
+++ b/pkg/cmd/tknpac/auth/keyring.go
@@ -0,0 +1,86 @@
+package auth
+
+import (
+ "errors"
+ "strings"
+ "time"
+
+ "github.com/zalando/go-keyring"
+)
+
+var ErrNotFound = errors.New("secret not found in keyring")
+
+type TimeoutError struct {
+ message string
+}
+
+func (e *TimeoutError) Error() string {
+ return e.message
+}
+
+// Set secret in keyring for user.
+func SetCred(service, user, secret string) error {
+ ch := make(chan error, 1)
+ go func() {
+ defer close(ch)
+ ch <- keyring.Set(keyringServiceName(service), user, secret)
+ }()
+ select {
+ case err := <-ch:
+ return err
+ case <-time.After(3 * time.Second):
+ return &TimeoutError{"timeout while trying to set secret in keyring"}
+ }
+}
+
+// Get secret from keyring given service and user name.
+func GetCred(service, user string) (string, error) {
+ ch := make(chan struct {
+ val string
+ err error
+ }, 1)
+ go func() {
+ defer close(ch)
+ val, err := keyring.Get(keyringServiceName(service), user)
+ ch <- struct {
+ val string
+ err error
+ }{val, err}
+ }()
+ select {
+ case res := <-ch:
+ if errors.Is(res.err, keyring.ErrNotFound) {
+ return "", ErrNotFound
+ }
+ return res.val, res.err
+ case <-time.After(3 * time.Second):
+ return "", &TimeoutError{"timeout while trying to get secret from keyring"}
+ }
+}
+
+// Delete secret from keyring.
+func Delete(service, user string) error {
+ ch := make(chan error, 1)
+ go func() {
+ defer close(ch)
+ ch <- keyring.Delete(service, user)
+ }()
+ select {
+ case err := <-ch:
+ return err
+ case <-time.After(3 * time.Second):
+ return &TimeoutError{"timeout while trying to delete secret from keyring"}
+ }
+}
+
+func keyringServiceName(hostname string) string {
+ switch {
+ case strings.Contains(hostname, "github"):
+ return "gh:" + hostname
+ case strings.Contains(hostname, "gitlab"):
+ return "gl:" + hostname
+ case strings.Contains(hostname, "bitbucket"):
+ return "bb:" + hostname
+ }
+ return hostname
+}
diff --git a/pkg/cmd/tknpac/auth/login.go b/pkg/cmd/tknpac/auth/login.go
new file mode 100644
index 000000000..ddb37336d
--- /dev/null
+++ b/pkg/cmd/tknpac/auth/login.go
@@ -0,0 +1,188 @@
+package auth
+
+import (
+ "fmt"
+ "net/http"
+ "strings"
+
+ "github.com/AlecAivazis/survey/v2"
+ "github.com/cli/cli/v2/pkg/cmd/auth/shared"
+ "github.com/openshift-pipelines/pipelines-as-code/pkg/cli"
+ "github.com/openshift-pipelines/pipelines-as-code/pkg/params"
+ "github.com/spf13/cobra"
+)
+
+var (
+ provider string
+ authToken string
+ hostname string
+ authMode string
+)
+
+func loginCommand(_ *params.Run, ioStreams *cli.IOStreams) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "login",
+ Short: "login user with provider",
+ RunE: func(_ *cobra.Command, _ []string) error {
+ var username string
+ var err error
+ cs := ioStreams.ColorScheme()
+
+ if provider != "github" && provider != "gitlab" && provider != "bitbucket" {
+ return fmt.Errorf("provide is invalid must be amongst these three [github, gitlab, bitbucket]")
+ }
+
+ if provider != "github" {
+ return fmt.Errorf("feature is in under development, at the moment only github is supported")
+ }
+
+ hosts := []string{"Github.com", "Github Enterprise Server"}
+ authModes := []string{"Login with web browser", "Paste an authentication token"}
+
+ // if user hasn't specified `--hostname` flag
+ if hostname == "" {
+ err = askForHostname(hosts)
+ if err != nil {
+ return err
+ }
+ }
+
+ // if user hasn't specified token, it is needed to ask user for auth methods
+ if authToken == "" {
+ err = askForAuthMode(authModes)
+ if err != nil {
+ return err
+ }
+ } else {
+ // if user specifies `--token`, no need to ask for auth methods
+ authMode = authModes[1]
+ }
+
+ if strings.EqualFold(hostname, hosts[0]) {
+ hostname = defaultGithubHostname
+ } else {
+ hostname, err = askForEnterpriseHostName()
+ if err != nil {
+ return err
+ }
+ }
+
+ if authMode == authModes[0] {
+ authToken, err = RunAuthFlow(hostname, ioStreams, "", []string{}, true, true)
+ if err != nil {
+ return fmt.Errorf("failed to authenticate via web browser: %w", err)
+ }
+
+ username, err = GetViewer(hostname, authToken, ioStreams.ErrOut)
+ if err != nil {
+ return fmt.Errorf("failed to get user name from github: %w", err)
+ }
+
+ fmt.Fprintf(ioStreams.ErrOut, "%s Authentication complete for user %s.\n", cs.SuccessIcon(), cs.GreenBold(username))
+ } else {
+ minimumScopes := []string{"repo", "read:org"}
+ fmt.Fprintf(ioStreams.ErrOut, "Tip: you can generate a Personal Access Token here https://%s/settings/tokens, The minimum required scopes are %s.\n", hostname, scopesSentence(minimumScopes))
+
+ if authToken == "" {
+ err = askForAuthToken()
+ if err != nil {
+ return err
+ }
+ }
+
+ // checking github permission scopes for authToken
+ if err = shared.HasMinimumScopes(http.DefaultClient, hostname, authToken); err != nil {
+ return fmt.Errorf("error validating token: %w", err)
+ }
+ }
+
+ err = SetCred(hostname, username, authToken)
+ if err != nil {
+ return fmt.Errorf("error saving token in keyring: %w", err)
+ }
+ return nil
+ },
+ Annotations: map[string]string{
+ "commandType": "main",
+ },
+ }
+
+ cmd.PersistentFlags().StringVarP(&provider, "provider", "p", "github", "Git provider possible values [github, gitlab, bitbucket]")
+ cmd.PersistentFlags().StringVar(&hostname, "hostname", "", "The host name of git provider to authenticate user with")
+ cmd.PersistentFlags().StringVarP(&authToken, "token", "t", "", "Read token directly from standard input")
+ return cmd
+}
+
+func askForAuthToken() error {
+ err := survey.AskOne(&survey.Password{
+ Message: "Please enter you authentication token here:",
+ }, &authToken)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func askForHostname(hosts []string) error {
+ answers := struct {
+ HostName string `survey:"hostName"`
+ }{}
+ qs := []*survey.Question{
+ {
+ Name: "hostName",
+ Prompt: &survey.Select{
+ Message: "Which account do you want to log in to?",
+ Options: hosts,
+ Default: hosts[0],
+ },
+ },
+ }
+
+ err := survey.Ask(qs, &answers)
+ if err != nil {
+ return err
+ }
+ hostname = strings.ToLower(answers.HostName)
+
+ return nil
+}
+
+func askForAuthMode(authenticationMethods []string) error {
+ answers := struct {
+ LoginMethod string `survey:"loginMethod"`
+ }{}
+ qs := []*survey.Question{
+ {
+ Name: "loginMethod",
+ Prompt: &survey.Select{
+ Message: "How would you like to authenticate?",
+ Options: authenticationMethods,
+ Default: authenticationMethods[0],
+ },
+ },
+ }
+
+ err := survey.Ask(qs, &answers)
+ if err != nil {
+ return err
+ }
+ authMode = answers.LoginMethod
+
+ return nil
+}
+
+func askForEnterpriseHostName() (string, error) {
+ var hostName string
+ err := survey.Ask([]*survey.Question{{
+ Name: "enterpriseHostName",
+ Prompt: &survey.Input{Message: "Enter your GHE hostname:"},
+ Validate: survey.Required,
+ Transform: survey.Title,
+ }}, &hostName)
+ if err != nil {
+ return "", err
+ }
+
+ return hostName, nil
+}
diff --git a/pkg/cmd/tknpac/auth/login_flow.go b/pkg/cmd/tknpac/auth/login_flow.go
new file mode 100644
index 000000000..fc394a70c
--- /dev/null
+++ b/pkg/cmd/tknpac/auth/login_flow.go
@@ -0,0 +1,178 @@
+package auth
+
+import (
+ "bufio"
+ "fmt"
+ "io"
+ "net/http"
+ "net/url"
+ "strings"
+
+ "github.com/cli/cli/v2/api"
+ "github.com/cli/oauth"
+ "github.com/openshift-pipelines/pipelines-as-code/pkg/cli"
+ "github.com/openshift-pipelines/pipelines-as-code/pkg/cli/browser"
+)
+
+// DefaultGithubHostname is the domain name of the default GitHub instance.
+const defaultGithubHostname = "github.com"
+
+// DefaultGitlabHostname is the domain name of the default GitHub instance.
+// const defaultGitlabHostname = "gitlab.com"
+
+// DefaultBitbucketHostname is the domain name of the default GitHub instance.
+// const defaultBitbucketHostname = "bitbucket.org"
+
+// Localhost is the domain name of a local GitHub instance.
+const localhost = "github.localhost"
+
+// TenancyHost is the domain name of a tenancy GitHub instance.
+const tenancyHost = "ghe.com"
+
+var (
+ // oauth app client ID.
+ oauthClientID = "Ov23linjEIlP76Xz0qgC"
+ // #nosec G101: Potential hardcoded credentials
+ oauthClientSecret = "f38d05e5dcfa672ed0dd36ad81b98e263c68bab3"
+)
+
+func RunAuthFlow(oauthHost string, ioStreams *cli.IOStreams, notice string, additionalScopes []string, isInteractive, openBrowser bool) (string, error) {
+ w := ioStreams.ErrOut
+ cs := ioStreams.ColorScheme()
+
+ httpClient := &http.Client{}
+
+ scopes := []string{"repo", "read:org", "gist"}
+ scopes = append(scopes, additionalScopes...)
+
+ callbackURI := "http://127.0.0.1/callback"
+ if IsEnterprise(oauthHost) {
+ callbackURI = "http://localhost/"
+ }
+
+ flow := &oauth.Flow{
+ Host: oauth.GitHubHost(HostPrefix(oauthHost)),
+ ClientID: oauthClientID,
+ ClientSecret: oauthClientSecret,
+ CallbackURI: callbackURI,
+ Scopes: scopes,
+ DisplayCode: func(code, _ string) error {
+ fmt.Fprintf(w, "%s First copy your one-time code: %s\n", cs.Yellow("!"), cs.Bold(code))
+ return nil
+ },
+ BrowseURL: func(authURL string) error {
+ if u, err := url.Parse(authURL); err == nil {
+ if u.Scheme != "http" && u.Scheme != "https" {
+ return fmt.Errorf("invalid URL: %s", authURL)
+ }
+ } else {
+ return err
+ }
+
+ if !isInteractive {
+ fmt.Fprintf(w, "%s to continue in your web browser: %s\n", cs.Bold("Open this URL"), authURL)
+ return nil
+ }
+
+ fmt.Fprintf(w, "%s to open %s in your browser... ", cs.Bold("Press Enter"), oauthHost)
+ _ = waitForEnter(ioStreams.In)
+
+ // if it is not a test
+ if openBrowser {
+ if err := browser.OpenWebBrowser(authURL); err != nil {
+ fmt.Fprintf(w, "%s Failed opening a web browser at %s\n", cs.Red("!"), authURL)
+ fmt.Fprintf(w, " %s\n", err)
+ fmt.Fprint(w, " Please try entering the URL in your browser manually\n")
+ }
+ }
+ return nil
+ },
+ WriteSuccessHTML: func(w io.Writer) {
+ fmt.Fprint(w, oauthSuccessPage)
+ },
+ HTTPClient: httpClient,
+ Stdin: ioStreams.In,
+ Stdout: w,
+ }
+
+ fmt.Fprintln(w, notice)
+
+ token, err := flow.DetectFlow()
+ if err != nil {
+ return "", err
+ }
+
+ return token.Token, nil
+}
+
+func waitForEnter(r io.Reader) error {
+ scanner := bufio.NewScanner(r)
+ scanner.Scan()
+ return scanner.Err()
+}
+
+type cfg struct {
+ token string
+}
+
+func (c cfg) ActiveToken(_ string) (string, string) {
+ return c.token, "oauth_token"
+}
+
+func GetViewer(hostname, token string, logWriter io.Writer) (string, error) {
+ opts := api.HTTPClientOptions{
+ Config: cfg{token: token},
+ Log: logWriter,
+ }
+ client, err := api.NewHTTPClient(opts)
+ if err != nil {
+ return "", err
+ }
+
+ return api.CurrentLoginName(api.NewClientFromHTTP(client), hostname)
+}
+
+// IsEnterprise reports whether a non-normalized host name looks like a GHE instance.
+func IsEnterprise(h string) bool {
+ normalizedHostName := NormalizeHostname(h)
+ return normalizedHostName != defaultGithubHostname && normalizedHostName != localhost
+}
+
+// NormalizeHostname returns the canonical host name of a GitHub instance.
+func NormalizeHostname(h string) string {
+ hostname := strings.ToLower(h)
+ if strings.HasSuffix(hostname, "."+defaultGithubHostname) {
+ return defaultGithubHostname
+ }
+ if strings.HasSuffix(hostname, "."+localhost) {
+ return localhost
+ }
+ if before, found := cutSuffix(hostname, "."+tenancyHost); found {
+ idx := strings.LastIndex(before, ".")
+ return fmt.Sprintf("%s.%s", before[idx+1:], tenancyHost)
+ }
+ return hostname
+}
+
+func HostPrefix(hostname string) string {
+ if strings.EqualFold(hostname, localhost) {
+ return fmt.Sprintf("http://%s/", hostname)
+ }
+ return fmt.Sprintf("https://%s/", hostname)
+}
+
+// Backport strings.CutSuffix from Go 1.20.
+func cutSuffix(s, suffix string) (string, bool) {
+ if !strings.HasSuffix(s, suffix) {
+ return s, false
+ }
+ return s[:len(s)-len(suffix)], true
+}
+
+func scopesSentence(scopes []string) string {
+ quoted := make([]string, len(scopes))
+ for i, s := range scopes {
+ quoted[i] = fmt.Sprintf("'%s'", s)
+ }
+ return strings.Join(quoted, ", ")
+}
diff --git a/pkg/cmd/tknpac/auth/login_test.go b/pkg/cmd/tknpac/auth/login_test.go
new file mode 100644
index 000000000..29cea6f5c
--- /dev/null
+++ b/pkg/cmd/tknpac/auth/login_test.go
@@ -0,0 +1,151 @@
+package auth
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "testing"
+
+ "github.com/h2non/gock"
+ "github.com/openshift-pipelines/pipelines-as-code/pkg/cli"
+ "gotest.tools/v3/assert"
+)
+
+var (
+ host = "test.github.com"
+ token = "gho_16C7e42F292c6912E7710c838347Ae178B4a"
+)
+
+func newIOStream() *cli.IOStreams {
+ in := &bytes.Buffer{}
+ out := &bytes.Buffer{}
+ errOut := &bytes.Buffer{}
+ return &cli.IOStreams{
+ In: io.NopCloser(in),
+ Out: out,
+ ErrOut: errOut,
+ }
+}
+
+func TestAuthFlow(t *testing.T) {
+ baseURL := fmt.Sprintf("https://%s", host)
+
+ defer gock.OffAll()
+
+ ios := newIOStream()
+
+ tests := []struct {
+ name string
+ statusCode int
+ jsonResponse map[string]interface{}
+ wantError bool
+ errorMsg string
+ }{
+ {
+ name: "get verification code from github for authentication",
+ statusCode: 200,
+ jsonResponse: map[string]interface{}{
+ "device_code": "3584d83530557fdd1f46af8289938c8ef79f9dc5",
+ "user_code": "WDJB-MJHT",
+ "verification_uri": "https://github.com/login/device",
+ "expires_in": 900,
+ "interval": 5,
+ },
+ },
+ {
+ name: "error 500 unknown error",
+ statusCode: 500,
+ jsonResponse: map[string]interface{}{
+ "error": "internal server error",
+ },
+ wantError: true,
+ errorMsg: "internal server error",
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ defer gock.OffAll()
+
+ gock.New(baseURL).
+ Post("/login/device/code").
+ Reply(tt.statusCode).
+ JSON(tt.jsonResponse)
+
+ gock.New(baseURL).
+ Post("/login/oauth/access_token").
+ Reply(200).
+ JSON(map[string]interface{}{
+ "access_token": token,
+ "token_type": "bearer",
+ "scope": "repo,gist",
+ })
+
+ got, err := RunAuthFlow(host, ios, "", []string{}, true, false)
+ if tt.wantError {
+ assert.Equal(t, err.Error(), tt.errorMsg)
+ } else {
+ assert.NilError(t, err)
+ assert.Equal(t, token, got)
+ }
+ })
+ }
+}
+
+func TestGetUserName(t *testing.T) {
+ defer gock.Off()
+
+ fakeToken := "gho_16C7e42F292c6912E7710c838347Ae178B4a"
+ ios := newIOStream()
+ userName := "zakisk"
+
+ tests := []struct {
+ name string
+ hostname string
+ statusCode int
+ jsonResponse map[string]interface{}
+ wantError bool
+ errorMsg string
+ }{
+ {
+ name: "get user name from github",
+ hostname: "https://api.github.com",
+ statusCode: 200,
+ jsonResponse: map[string]interface{}{
+ "data": map[string]interface{}{
+ "viewer": map[string]interface{}{
+ "login": "zakisk",
+ },
+ },
+ },
+ },
+ {
+ name: "wrong github host name",
+ hostname: "wronghost.com",
+ statusCode: 200,
+ wantError: true,
+ errorMsg: "Post \"https://wronghost.com/api/graphql\": gock: cannot match any request",
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ defer gock.OffAll()
+
+ gock.New(tt.hostname).
+ Post("/graphql").
+ MatchType("json").
+ BodyString(`query UserCurrent\b`).
+ Reply(tt.statusCode).
+ JSON(tt.jsonResponse)
+
+ got, err := GetViewer(tt.hostname, fakeToken, ios.ErrOut)
+ if tt.wantError {
+ assert.Equal(t, err.Error(), tt.errorMsg)
+ } else {
+ assert.NilError(t, err)
+ assert.Equal(t, userName, got)
+ }
+ })
+ }
+}
diff --git a/pkg/cmd/tknpac/auth/root.go b/pkg/cmd/tknpac/auth/root.go
new file mode 100644
index 000000000..9cb4ae517
--- /dev/null
+++ b/pkg/cmd/tknpac/auth/root.go
@@ -0,0 +1,23 @@
+package auth
+
+import (
+ "github.com/openshift-pipelines/pipelines-as-code/pkg/cli"
+ "github.com/openshift-pipelines/pipelines-as-code/pkg/params"
+ "github.com/spf13/cobra"
+)
+
+func Root(clients *params.Run, ioStreams *cli.IOStreams) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "auth",
+ Aliases: []string{},
+ Short: "Authenticate user",
+ Long: `Authenticate users with git provider`,
+ SilenceUsage: true,
+ Annotations: map[string]string{
+ "commandType": "main",
+ },
+ }
+
+ cmd.AddCommand(loginCommand(clients, ioStreams))
+ return cmd
+}
diff --git a/pkg/cmd/tknpac/auth/success.go b/pkg/cmd/tknpac/auth/success.go
new file mode 100644
index 000000000..291a52141
--- /dev/null
+++ b/pkg/cmd/tknpac/auth/success.go
@@ -0,0 +1,42 @@
+package auth
+
+const oauthSuccessPage = `
+
+
+
Success: GitHub CLI
+
+
+
+
+
Successfully authenticated GitHub CLI
+
You may now close this tab and return to the terminal.
+
+
+`
diff --git a/pkg/cmd/tknpac/root.go b/pkg/cmd/tknpac/root.go
index 9f4defc92..bc3232e16 100644
--- a/pkg/cmd/tknpac/root.go
+++ b/pkg/cmd/tknpac/root.go
@@ -2,6 +2,7 @@ package tknpac
import (
"github.com/openshift-pipelines/pipelines-as-code/pkg/cli"
+ "github.com/openshift-pipelines/pipelines-as-code/pkg/cmd/tknpac/auth"
"github.com/openshift-pipelines/pipelines-as-code/pkg/cmd/tknpac/bootstrap"
"github.com/openshift-pipelines/pipelines-as-code/pkg/cmd/tknpac/completion"
"github.com/openshift-pipelines/pipelines-as-code/pkg/cmd/tknpac/create"
@@ -44,5 +45,6 @@ func Root(clients *params.Run) *cobra.Command {
cmd.AddCommand(bootstrap.Command(clients, ioStreams))
cmd.AddCommand(generate.Command(clients, ioStreams))
cmd.AddCommand(webhook.Root(clients, ioStreams))
+ cmd.AddCommand(auth.Root(clients, ioStreams))
return cmd
}
diff --git a/vendor/github.com/MakeNowJust/heredoc/LICENSE b/vendor/github.com/MakeNowJust/heredoc/LICENSE
new file mode 100644
index 000000000..6d0eb9d5d
--- /dev/null
+++ b/vendor/github.com/MakeNowJust/heredoc/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014-2019 TSUYUSATO Kitsune
+
+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/MakeNowJust/heredoc/README.md b/vendor/github.com/MakeNowJust/heredoc/README.md
new file mode 100644
index 000000000..e9924d297
--- /dev/null
+++ b/vendor/github.com/MakeNowJust/heredoc/README.md
@@ -0,0 +1,52 @@
+# heredoc
+
+[![Build Status](https://circleci.com/gh/MakeNowJust/heredoc.svg?style=svg)](https://circleci.com/gh/MakeNowJust/heredoc) [![GoDoc](https://godoc.org/github.com/MakeNowJusti/heredoc?status.svg)](https://godoc.org/github.com/MakeNowJust/heredoc)
+
+## About
+
+Package heredoc provides the here-document with keeping indent.
+
+## Install
+
+```console
+$ go get github.com/MakeNowJust/heredoc
+```
+
+## Import
+
+```go
+// usual
+import "github.com/MakeNowJust/heredoc"
+```
+
+## Example
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/MakeNowJust/heredoc"
+)
+
+func main() {
+ fmt.Println(heredoc.Doc(`
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit,
+ sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua. Ut enim ad minim veniam, ...
+ `))
+ // Output:
+ // Lorem ipsum dolor sit amet, consectetur adipisicing elit,
+ // sed do eiusmod tempor incididunt ut labore et dolore magna
+ // aliqua. Ut enim ad minim veniam, ...
+ //
+}
+```
+
+## API Document
+
+ - [heredoc - GoDoc](https://godoc.org/github.com/MakeNowJust/heredoc)
+
+## License
+
+This software is released under the MIT License, see LICENSE.
diff --git a/vendor/github.com/MakeNowJust/heredoc/heredoc.go b/vendor/github.com/MakeNowJust/heredoc/heredoc.go
new file mode 100644
index 000000000..1fc046955
--- /dev/null
+++ b/vendor/github.com/MakeNowJust/heredoc/heredoc.go
@@ -0,0 +1,105 @@
+// Copyright (c) 2014-2019 TSUYUSATO Kitsune
+// This software is released under the MIT License.
+// http://opensource.org/licenses/mit-license.php
+
+// Package heredoc provides creation of here-documents from raw strings.
+//
+// Golang supports raw-string syntax.
+//
+// doc := `
+// Foo
+// Bar
+// `
+//
+// But raw-string cannot recognize indentation. Thus such content is an indented string, equivalent to
+//
+// "\n\tFoo\n\tBar\n"
+//
+// I dont't want this!
+//
+// However this problem is solved by package heredoc.
+//
+// doc := heredoc.Doc(`
+// Foo
+// Bar
+// `)
+//
+// Is equivalent to
+//
+// "Foo\nBar\n"
+package heredoc
+
+import (
+ "fmt"
+ "strings"
+ "unicode"
+)
+
+const maxInt = int(^uint(0) >> 1)
+
+// Doc returns un-indented string as here-document.
+func Doc(raw string) string {
+ skipFirstLine := false
+ if len(raw) > 0 && raw[0] == '\n' {
+ raw = raw[1:]
+ } else {
+ skipFirstLine = true
+ }
+
+ lines := strings.Split(raw, "\n")
+
+ minIndentSize := getMinIndent(lines, skipFirstLine)
+ lines = removeIndentation(lines, minIndentSize, skipFirstLine)
+
+ return strings.Join(lines, "\n")
+}
+
+// getMinIndent calculates the minimum indentation in lines, excluding empty lines.
+func getMinIndent(lines []string, skipFirstLine bool) int {
+ minIndentSize := maxInt
+
+ for i, line := range lines {
+ if i == 0 && skipFirstLine {
+ continue
+ }
+
+ indentSize := 0
+ for _, r := range []rune(line) {
+ if unicode.IsSpace(r) {
+ indentSize += 1
+ } else {
+ break
+ }
+ }
+
+ if len(line) == indentSize {
+ if i == len(lines)-1 && indentSize < minIndentSize {
+ lines[i] = ""
+ }
+ } else if indentSize < minIndentSize {
+ minIndentSize = indentSize
+ }
+ }
+ return minIndentSize
+}
+
+// removeIndentation removes n characters from the front of each line in lines.
+// Skips first line if skipFirstLine is true, skips empty lines.
+func removeIndentation(lines []string, n int, skipFirstLine bool) []string {
+ for i, line := range lines {
+ if i == 0 && skipFirstLine {
+ continue
+ }
+
+ if len(lines[i]) >= n {
+ lines[i] = line[n:]
+ }
+ }
+ return lines
+}
+
+// Docf returns unindented and formatted string as here-document.
+// Formatting is done as for fmt.Printf().
+func Docf(raw string, args ...interface{}) string {
+ return fmt.Sprintf(Doc(raw), args...)
+}
diff --git a/vendor/github.com/alessio/shellescape/.gitignore b/vendor/github.com/alessio/shellescape/.gitignore
new file mode 100644
index 000000000..4ba7c2d13
--- /dev/null
+++ b/vendor/github.com/alessio/shellescape/.gitignore
@@ -0,0 +1,28 @@
+# 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
+
+.idea/
+
+escargs
diff --git a/vendor/github.com/alessio/shellescape/.golangci.yml b/vendor/github.com/alessio/shellescape/.golangci.yml
new file mode 100644
index 000000000..836dabbba
--- /dev/null
+++ b/vendor/github.com/alessio/shellescape/.golangci.yml
@@ -0,0 +1,59 @@
+# run:
+# # timeout for analysis, e.g. 30s, 5m, default is 1m
+# timeout: 5m
+
+linters:
+ disable-all: true
+ enable:
+ - bodyclose
+ - dogsled
+ - goconst
+ - gocritic
+ - gofmt
+ - goimports
+ - gosec
+ - gosimple
+ - govet
+ - ineffassign
+ - misspell
+ - prealloc
+ - exportloopref
+ - revive
+ - staticcheck
+ - stylecheck
+ - typecheck
+ - unconvert
+ - unparam
+ - unused
+ - misspell
+ - wsl
+
+issues:
+ exclude-rules:
+ - text: "Use of weak random number generator"
+ linters:
+ - gosec
+ - text: "comment on exported var"
+ linters:
+ - golint
+ - text: "don't use an underscore in package name"
+ linters:
+ - golint
+ - text: "ST1003:"
+ linters:
+ - stylecheck
+ # FIXME: Disabled until golangci-lint updates stylecheck with this fix:
+ # https://github.com/dominikh/go-tools/issues/389
+ - text: "ST1016:"
+ linters:
+ - stylecheck
+
+linters-settings:
+ dogsled:
+ max-blank-identifiers: 3
+ maligned:
+ # print struct with more effective memory layout or not, false by default
+ suggest-new: true
+
+run:
+ tests: false
diff --git a/vendor/github.com/alessio/shellescape/.goreleaser.yml b/vendor/github.com/alessio/shellescape/.goreleaser.yml
new file mode 100644
index 000000000..0915eb869
--- /dev/null
+++ b/vendor/github.com/alessio/shellescape/.goreleaser.yml
@@ -0,0 +1,54 @@
+# This is an example goreleaser.yaml file with some sane defaults.
+# Make sure to check the documentation at http://goreleaser.com
+before:
+ hooks:
+ # You may remove this if you don't use go modules.
+ - go mod download
+ # you may remove this if you don't need go generate
+ - go generate ./...
+builds:
+ - env:
+ - CGO_ENABLED=0
+ - >-
+ {{- if eq .Os "darwin" }}
+ {{- if eq .Arch "amd64"}}CC=o64-clang{{- end }}
+ {{- if eq .Arch "arm64"}}CC=aarch64-apple-darwin20.2-clang{{- end }}
+ {{- end }}
+ {{- if eq .Os "windows" }}
+ {{- if eq .Arch "amd64" }}CC=x86_64-w64-mingw32-gcc{{- end }}
+ {{- end }}
+ main: ./cmd/escargs
+ goos:
+ - linux
+ - windows
+ - darwin
+ - freebsd
+ goarch:
+ - amd64
+ - arm64
+ - arm
+ goarm:
+ - 6
+ - 7
+ goamd64:
+ - v2
+ - v3
+ ignore:
+ - goos: darwin
+ goarch: 386
+ - goos: linux
+ goarch: arm
+ goarm: 7
+ - goarm: mips64
+ - gomips: hardfloat
+ - goamd64: v4
+checksum:
+ name_template: 'checksums.txt'
+snapshot:
+ name_template: "{{ .Tag }}-next"
+changelog:
+ sort: asc
+ filters:
+ exclude:
+ - '^docs:'
+ - '^test:'
diff --git a/vendor/github.com/alessio/shellescape/AUTHORS b/vendor/github.com/alessio/shellescape/AUTHORS
new file mode 100644
index 000000000..4a647a6f4
--- /dev/null
+++ b/vendor/github.com/alessio/shellescape/AUTHORS
@@ -0,0 +1 @@
+Alessio Treglia
diff --git a/vendor/github.com/alessio/shellescape/CODE_OF_CONDUCT.md b/vendor/github.com/alessio/shellescape/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..e8eda6062
--- /dev/null
+++ b/vendor/github.com/alessio/shellescape/CODE_OF_CONDUCT.md
@@ -0,0 +1,76 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as
+contributors and maintainers pledge to making participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, sex characteristics, gender identity and expression,
+level of experience, education, socio-economic status, nationality, personal
+appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment
+include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or
+ advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic
+ address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable
+behavior and are expected to take appropriate and fair corrective action in
+response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or
+reject comments, commits, code, wiki edits, issues, and other contributions
+that are not aligned to this Code of Conduct, or to ban temporarily or
+permanently any contributor for other behaviors that they deem inappropriate,
+threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community. Examples of
+representing a project or community include using an official project e-mail
+address, posting via an official social media account, or acting as an appointed
+representative at an online or offline event. Representation of a project may be
+further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported by contacting the project team at alessio@debian.org. All
+complaints will be reviewed and investigated and will result in a response that
+is deemed necessary and appropriate to the circumstances. The project team is
+obligated to maintain confidentiality with regard to the reporter of an incident.
+Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good
+faith may face temporary or permanent repercussions as determined by other
+members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
+available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see
+https://www.contributor-covenant.org/faq
diff --git a/vendor/github.com/alessio/shellescape/LICENSE b/vendor/github.com/alessio/shellescape/LICENSE
new file mode 100644
index 000000000..9f760679f
--- /dev/null
+++ b/vendor/github.com/alessio/shellescape/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Alessio Treglia
+
+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/alessio/shellescape/README.md b/vendor/github.com/alessio/shellescape/README.md
new file mode 100644
index 000000000..910bb253b
--- /dev/null
+++ b/vendor/github.com/alessio/shellescape/README.md
@@ -0,0 +1,61 @@
+![Build](https://github.com/alessio/shellescape/workflows/Build/badge.svg)
+[![GoDoc](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat-square)](https://pkg.go.dev/github.com/alessio/shellescape?tab=overview)
+[![sourcegraph](https://sourcegraph.com/github.com/alessio/shellescape/-/badge.svg)](https://sourcegraph.com/github.com/alessio/shellescape)
+[![codecov](https://codecov.io/gh/alessio/shellescape/branch/master/graph/badge.svg)](https://codecov.io/gh/alessio/shellescape)
+[![Coverage](https://gocover.io/_badge/github.com/alessio/shellescape)](https://gocover.io/github.com/alessio/shellescape)
+[![Go Report Card](https://goreportcard.com/badge/github.com/alessio/shellescape)](https://goreportcard.com/report/github.com/alessio/shellescape)
+
+# shellescape
+Escape arbitrary strings for safe use as command line arguments.
+## Contents of the package
+
+This package provides the `shellescape.Quote()` function that returns a
+shell-escaped copy of a string. This functionality could be helpful
+in those cases where it is known that the output of a Go program will
+be appended to/used in the context of shell programs' command line arguments.
+
+This work was inspired by the Python original package
+[shellescape](https://pypi.python.org/pypi/shellescape).
+
+## Usage
+
+The following snippet shows a typical unsafe idiom:
+
+```go
+package main
+
+import (
+ "fmt"
+ "os"
+)
+
+func main() {
+ fmt.Printf("ls -l %s\n", os.Args[1])
+}
+```
+_[See in Go Playground](https://play.golang.org/p/Wj2WoUfH_d)_
+
+Especially when creating pipeline of commands which might end up being
+executed by a shell interpreter, it is particularly unsafe to not
+escape arguments.
+
+`shellescape.Quote()` comes in handy and to safely escape strings:
+
+```go
+package main
+
+import (
+ "fmt"
+ "os"
+
+ "gopkg.in/alessio/shellescape.v1"
+)
+
+func main() {
+ fmt.Printf("ls -l %s\n", shellescape.Quote(os.Args[1]))
+}
+```
+_[See in Go Playground](https://play.golang.org/p/HJ_CXgSrmp)_
+
+## The escargs utility
+__escargs__ reads lines from the standard input and prints shell-escaped versions. Unlinke __xargs__, blank lines on the standard input are not discarded.
diff --git a/vendor/github.com/alessio/shellescape/shellescape.go b/vendor/github.com/alessio/shellescape/shellescape.go
new file mode 100644
index 000000000..dc34a556a
--- /dev/null
+++ b/vendor/github.com/alessio/shellescape/shellescape.go
@@ -0,0 +1,66 @@
+/*
+Package shellescape provides the shellescape.Quote to escape arbitrary
+strings for a safe use as command line arguments in the most common
+POSIX shells.
+
+The original Python package which this work was inspired by can be found
+at https://pypi.python.org/pypi/shellescape.
+*/
+package shellescape // "import gopkg.in/alessio/shellescape.v1"
+
+/*
+The functionality provided by shellescape.Quote could be helpful
+in those cases where it is known that the output of a Go program will
+be appended to/used in the context of shell programs' command line arguments.
+*/
+
+import (
+ "regexp"
+ "strings"
+ "unicode"
+)
+
+var pattern *regexp.Regexp
+
+func init() {
+ pattern = regexp.MustCompile(`[^\w@%+=:,./-]`)
+}
+
+// Quote returns a shell-escaped version of the string s. The returned value
+// is a string that can safely be used as one token in a shell command line.
+func Quote(s string) string {
+ if len(s) == 0 {
+ return "''"
+ }
+
+ if pattern.MatchString(s) {
+ return "'" + strings.ReplaceAll(s, "'", "'\"'\"'") + "'"
+ }
+
+ return s
+}
+
+// QuoteCommand returns a shell-escaped version of the slice of strings.
+// The returned value is a string that can safely be used as shell command arguments.
+func QuoteCommand(args []string) string {
+ l := make([]string, len(args))
+
+ for i, s := range args {
+ l[i] = Quote(s)
+ }
+
+ return strings.Join(l, " ")
+}
+
+// StripUnsafe remove non-printable runes, e.g. control characters in
+// a string that is meant for consumption by terminals that support
+// control characters.
+func StripUnsafe(s string) string {
+ return strings.Map(func(r rune) rune {
+ if unicode.IsPrint(r) {
+ return r
+ }
+
+ return -1
+ }, s)
+}
diff --git a/vendor/github.com/aymanbagabas/go-osc52/v2/LICENSE b/vendor/github.com/aymanbagabas/go-osc52/v2/LICENSE
new file mode 100644
index 000000000..25cec1ed4
--- /dev/null
+++ b/vendor/github.com/aymanbagabas/go-osc52/v2/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+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
+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/aymanbagabas/go-osc52/v2/README.md b/vendor/github.com/aymanbagabas/go-osc52/v2/README.md
new file mode 100644
index 000000000..4de3a22d1
--- /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 000000000..dc758d286
--- /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/briandowns/spinner/.gitignore b/vendor/github.com/briandowns/spinner/.gitignore
new file mode 100644
index 000000000..21ec6b71b
--- /dev/null
+++ b/vendor/github.com/briandowns/spinner/.gitignore
@@ -0,0 +1,29 @@
+# Created by .gitignore support plugin (hsz.mobi)
+### Go template
+# 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
+
+.idea
+*.iml
diff --git a/vendor/github.com/briandowns/spinner/.travis.yml b/vendor/github.com/briandowns/spinner/.travis.yml
new file mode 100644
index 000000000..74d205aec
--- /dev/null
+++ b/vendor/github.com/briandowns/spinner/.travis.yml
@@ -0,0 +1,18 @@
+arch:
+ - amd64
+ - ppc64le
+language: go
+go:
+ - 1.16
+ - 1.17.5
+env:
+ - GOARCH: amd64
+ - GOARCH: 386
+script:
+ - go test -v
+notifications:
+ email:
+ recipients:
+ - brian.downs@gmail.com
+ on_success: change
+ on_failure: always
diff --git a/vendor/github.com/briandowns/spinner/LICENSE b/vendor/github.com/briandowns/spinner/LICENSE
new file mode 100644
index 000000000..dd5b3a58a
--- /dev/null
+++ b/vendor/github.com/briandowns/spinner/LICENSE
@@ -0,0 +1,174 @@
+ 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.
diff --git a/vendor/github.com/briandowns/spinner/Makefile b/vendor/github.com/briandowns/spinner/Makefile
new file mode 100644
index 000000000..3cfdeb23c
--- /dev/null
+++ b/vendor/github.com/briandowns/spinner/Makefile
@@ -0,0 +1,20 @@
+GO = go
+
+.PHONY: deps
+deps: go.mod
+
+go.mod:
+ go mod init
+ go mod tidy
+
+.PHONY: test
+test:
+ $(GO) test -v -cover ./...
+
+.PHONY: check
+check:
+ if [ -d vendor ]; then cp -r vendor/* ${GOPATH}/src/; fi
+
+.PHONY: clean
+clean:
+ $(GO) clean
diff --git a/vendor/github.com/briandowns/spinner/NOTICE.txt b/vendor/github.com/briandowns/spinner/NOTICE.txt
new file mode 100644
index 000000000..95e2a248b
--- /dev/null
+++ b/vendor/github.com/briandowns/spinner/NOTICE.txt
@@ -0,0 +1,4 @@
+Spinner
+Copyright (c) 2022 Brian J. Downs
+This product is licensed to you under the Apache 2.0 license (the "License"). You may not use this product except in compliance with the Apache 2.0 License.
+This product may include a number of subcomponents with separate copyright notices and license terms. Your use of these subcomponents is subject to the terms and conditions of the subcomponent's license, as noted in the LICENSE file.
diff --git a/vendor/github.com/briandowns/spinner/README.md b/vendor/github.com/briandowns/spinner/README.md
new file mode 100644
index 000000000..20b315fbe
--- /dev/null
+++ b/vendor/github.com/briandowns/spinner/README.md
@@ -0,0 +1,285 @@
+# Spinner
+
+[![GoDoc](https://godoc.org/github.com/briandowns/spinner?status.svg)](https://godoc.org/github.com/briandowns/spinner) [![Build Status](https://travis-ci.org/briandowns/spinner.svg?branch=master)](https://travis-ci.org/briandowns/spinner)
+
+spinner is a simple package to add a spinner / progress indicator to any terminal application. Examples can be found below as well as full examples in the examples directory.
+
+For more detail about the library and its features, reference your local godoc once installed.
+
+Contributions welcome!
+
+## Installation
+
+```bash
+go get github.com/briandowns/spinner
+```
+
+## Available Character Sets
+
+90 Character Sets. Some examples below:
+
+(Numbered by their slice index)
+
+| index | character set | sample gif |
+| ----- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- |
+| 0 | ```←↖↑↗→↘↓↙``` | ![Sample Gif](gifs/0.gif) |
+| 1 | ```▁▃▄▅▆▇█▇▆▅▄▃▁``` | ![Sample Gif](gifs/1.gif) |
+| 2 | ```▖▘▝▗``` | ![Sample Gif](gifs/2.gif) |
+| 3 | ```┤┘┴└├┌┬┐``` | ![Sample Gif](gifs/3.gif) |
+| 4 | ```◢◣◤◥``` | ![Sample Gif](gifs/4.gif) |
+| 5 | ```◰◳◲◱``` | ![Sample Gif](gifs/5.gif) |
+| 6 | ```◴◷◶◵``` | ![Sample Gif](gifs/6.gif) |
+| 7 | ```◐◓◑◒``` | ![Sample Gif](gifs/7.gif) |
+| 8 | ```.oO@*``` | ![Sample Gif](gifs/8.gif) |
+| 9 | ```\|/-\``` | ![Sample Gif](gifs/9.gif) |
+| 10 | ```◡◡⊙⊙◠◠``` | ![Sample Gif](gifs/10.gif) |
+| 11 | ```⣾⣽⣻⢿⡿⣟⣯⣷``` | ![Sample Gif](gifs/11.gif) |
+| 12 | ```>))'> >))'> >))'> >))'> >))'> <'((< <'((< <'((<``` | ![Sample Gif](gifs/12.gif) |
+| 13 | ```⠁⠂⠄⡀⢀⠠⠐⠈``` | ![Sample Gif](gifs/13.gif) |
+| 14 | ```⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏``` | ![Sample Gif](gifs/14.gif) |
+| 15 | ```abcdefghijklmnopqrstuvwxyz``` | ![Sample Gif](gifs/15.gif) |
+| 16 | ```▉▊▋▌▍▎▏▎▍▌▋▊▉``` | ![Sample Gif](gifs/16.gif) |
+| 17 | ```■□▪▫``` | ![Sample Gif](gifs/17.gif) |
+| 18 | ```←↑→↓``` | ![Sample Gif](gifs/18.gif) |
+| 19 | ```╫╪``` | ![Sample Gif](gifs/19.gif) |
+| 20 | ```⇐⇖⇑⇗⇒⇘⇓⇙``` | ![Sample Gif](gifs/20.gif) |
+| 21 | ```⠁⠁⠉⠙⠚⠒⠂⠂⠒⠲⠴⠤⠄⠄⠤⠠⠠⠤⠦⠖⠒⠐⠐⠒⠓⠋⠉⠈⠈``` | ![Sample Gif](gifs/21.gif) |
+| 22 | ```⠈⠉⠋⠓⠒⠐⠐⠒⠖⠦⠤⠠⠠⠤⠦⠖⠒⠐⠐⠒⠓⠋⠉⠈``` | ![Sample Gif](gifs/22.gif) |
+| 23 | ```⠁⠉⠙⠚⠒⠂⠂⠒⠲⠴⠤⠄⠄⠤⠴⠲⠒⠂⠂⠒⠚⠙⠉⠁``` | ![Sample Gif](gifs/23.gif) |
+| 24 | ```⠋⠙⠚⠒⠂⠂⠒⠲⠴⠦⠖⠒⠐⠐⠒⠓⠋``` | ![Sample Gif](gifs/24.gif) |
+| 25 | ```ヲァィゥェォャュョッアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン``` | ![Sample Gif](gifs/25.gif) |
+| 26 | ```. .. ...``` | ![Sample Gif](gifs/26.gif) |
+| 27 | ```▁▂▃▄▅▆▇█▉▊▋▌▍▎▏▏▎▍▌▋▊▉█▇▆▅▄▃▂▁``` | ![Sample Gif](gifs/27.gif) |
+| 28 | ```.oO°Oo.``` | ![Sample Gif](gifs/28.gif) |
+| 29 | ```+x``` | ![Sample Gif](gifs/29.gif) |
+| 30 | ```v<^>``` | ![Sample Gif](gifs/30.gif) |
+| 31 | ```>>---> >>---> >>---> >>---> >>---> <---<< <---<< <---<< <---<< <---<<``` | ![Sample Gif](gifs/31.gif) |
+| 32 | ```\| \|\| \|\|\| \|\|\|\| \|\|\|\|\| \|\|\|\|\|\| \|\|\|\|\| \|\|\|\| \|\|\| \|\| \|``` | ![Sample Gif](gifs/32.gif) |
+| 33 | ```[] [=] [==] [===] [====] [=====] [======] [=======] [========] [=========] [==========]``` | ![Sample Gif](gifs/33.gif) |
+| 34 | ```(*---------) (-*--------) (--*-------) (---*------) (----*-----) (-----*----) (------*---) (-------*--) (--------*-) (---------*)``` | ![Sample Gif](gifs/34.gif) |
+| 35 | ```█▒▒▒▒▒▒▒▒▒ ███▒▒▒▒▒▒▒ █████▒▒▒▒▒ ███████▒▒▒ ██████████``` | ![Sample Gif](gifs/35.gif) |
+| 36 | ```[ ] [=> ] [===> ] [=====> ] [======> ] [========> ] [==========> ] [============> ] [==============> ] [================> ] [==================> ] [===================>]``` | ![Sample Gif](gifs/36.gif) |
+| 37 | ```🕐 🕑 🕒 🕓 🕔 🕕 🕖 🕗 🕘 🕙 🕚 🕛``` | ![Sample Gif](gifs/37.gif) |
+| 38 | ```🕐 🕜 🕑 🕝 🕒 🕞 🕓 🕟 🕔 🕠 🕕 🕡 🕖 🕢 🕗 🕣 🕘 🕤 🕙 🕥 🕚 🕦 🕛 🕧``` | ![Sample Gif](gifs/38.gif) |
+| 39 | ```🌍 🌎 🌏``` | ![Sample Gif](gifs/39.gif) |
+| 40 | ```◜ ◝ ◞ ◟``` | ![Sample Gif](gifs/40.gif) |
+| 41 | ```⬒ ⬔ ⬓ ⬕``` | ![Sample Gif](gifs/41.gif) |
+| 42 | ```⬖ ⬘ ⬗ ⬙``` | ![Sample Gif](gifs/42.gif) |
+| 43 | ```[>>> >] []>>>> [] [] >>>> [] [] >>>> [] [] >>>> [] [] >>>>[] [>> >>]``` | ![Sample Gif](gifs/43.gif) |
+
+## Features
+
+* Start
+* Stop
+* Restart
+* Reverse direction
+* Update the spinner character set
+* Update the spinner speed
+* Prefix or append text
+* Change spinner color, background, and text attributes such as bold / italics
+* Get spinner status
+* Chain, pipe, redirect output
+* Output final string on spinner/indicator completion
+
+## Examples
+
+```Go
+package main
+
+import (
+ "github.com/briandowns/spinner"
+ "time"
+)
+
+func main() {
+ s := spinner.New(spinner.CharSets[9], 100*time.Millisecond) // Build our new spinner
+ s.Start() // Start the spinner
+ time.Sleep(4 * time.Second) // Run for some time to simulate work
+ s.Stop()
+}
+```
+
+## Update the character set and restart the spinner
+
+```Go
+s.UpdateCharSet(spinner.CharSets[1]) // Update spinner to use a different character set
+s.Restart() // Restart the spinner
+time.Sleep(4 * time.Second)
+s.Stop()
+```
+
+## Update spin speed and restart the spinner
+
+```Go
+s.UpdateSpeed(200 * time.Millisecond) // Update the speed the spinner spins at
+s.Restart()
+time.Sleep(4 * time.Second)
+s.Stop()
+```
+
+## Reverse the direction of the spinner
+
+```Go
+s.Reverse() // Reverse the direction the spinner is spinning
+s.Restart()
+time.Sleep(4 * time.Second)
+s.Stop()
+```
+
+## Provide your own spinner
+
+(or send me an issue or pull request to add to the project)
+
+```Go
+someSet := []string{"+", "-"}
+s := spinner.New(someSet, 100*time.Millisecond)
+```
+
+## Prefix or append text to the spinner
+
+```Go
+s.Prefix = "prefixed text: " // Prefix text before the spinner
+s.Suffix = " :appended text" // Append text after the spinner
+```
+
+## Set or change the color of the spinner. Default color is white. The spinner will need to be restarted to pick up the change.
+
+```Go
+s.Color("red") // Set the spinner color to red
+```
+
+You can specify both the background and foreground color, as well as additional attributes such as `bold` or `underline`.
+
+```Go
+s.Color("red", "bold") // Set the spinner color to a bold red
+```
+
+To set the background to black, the foreground to a bold red:
+
+```Go
+s.Color("bgBlack", "bold", "fgRed")
+```
+
+Below is the full color and attribute list:
+
+```Go
+// default colors
+red
+black
+green
+yellow
+blue
+magenta
+cyan
+white
+
+// attributes
+reset
+bold
+faint
+italic
+underline
+blinkslow
+blinkrapid
+reversevideo
+concealed
+crossedout
+
+// foreground text
+fgBlack
+fgRed
+fgGreen
+fgYellow
+fgBlue
+fgMagenta
+fgCyan
+fgWhite
+
+// foreground Hi-Intensity text
+fgHiBlack
+fgHiRed
+fgHiGreen
+fgHiYellow
+fgHiBlue
+fgHiMagenta
+fgHiCyan
+fgHiWhite
+
+// background text
+bgBlack
+bgRed
+bgGreen
+bgYellow
+bgBlue
+bgMagenta
+bgCyan
+bgWhite
+
+// background Hi-Intensity text
+bgHiBlack
+bgHiRed
+bgHiGreen
+bgHiYellow
+bgHiBlue
+bgHiMagenta
+bgHiCyan
+bgHiWhite
+```
+
+## Generate a sequence of numbers
+
+```Go
+setOfDigits := spinner.GenerateNumberSequence(25) // Generate a 25 digit string of numbers
+s := spinner.New(setOfDigits, 100*time.Millisecond)
+```
+
+## Get spinner status
+
+```Go
+fmt.Println(s.Active())
+```
+
+## Unix pipe and redirect
+
+Feature suggested and write up by [dekz](https://github.com/dekz)
+
+Setting the Spinner Writer to Stderr helps show progress to the user, with the enhancement to chain, pipe or redirect the output.
+
+This is the preferred method of setting a Writer at this time.
+
+```go
+s := spinner.New(spinner.CharSets[11], 100*time.Millisecond, spinner.WithWriter(os.Stderr))
+s.Suffix = " Encrypting data..."
+s.Start()
+// Encrypt the data into ciphertext
+fmt.Println(os.Stdout, ciphertext)
+```
+
+```sh
+> myprog encrypt "Secret text" > encrypted.txt
+⣯ Encrypting data...
+```
+
+```sh
+> cat encrypted.txt
+1243hjkbas23i9ah27sj39jghv237n2oa93hg83
+```
+
+## Final String Output
+
+Add additional output when the spinner/indicator has completed. The "final" output string can be multi-lined and will be written to wherever the `io.Writer` has been configured for.
+
+```Go
+s := spinner.New(spinner.CharSets[9], 100*time.Millisecond)
+s.FinalMSG = "Complete!\nNew line!\nAnother one!\n"
+s.Start()
+time.Sleep(4 * time.Second)
+s.Stop()
+```
+
+Output
+```sh
+Complete!
+New line!
+Another one!
+```
diff --git a/vendor/github.com/briandowns/spinner/character_sets.go b/vendor/github.com/briandowns/spinner/character_sets.go
new file mode 100644
index 000000000..df41a0f2c
--- /dev/null
+++ b/vendor/github.com/briandowns/spinner/character_sets.go
@@ -0,0 +1,121 @@
+// Copyright (c) 2022 Brian J. Downs
+//
+// 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.
+
+package spinner
+
+const (
+ clockOneOClock = '\U0001F550'
+ clockOneThirty = '\U0001F55C'
+)
+
+// CharSets contains the available character sets
+var CharSets = map[int][]string{
+ 0: {"←", "↖", "↑", "↗", "→", "↘", "↓", "↙"},
+ 1: {"▁", "▃", "▄", "▅", "▆", "▇", "█", "▇", "▆", "▅", "▄", "▃", "▁"},
+ 2: {"▖", "▘", "▝", "▗"},
+ 3: {"┤", "┘", "┴", "└", "├", "┌", "┬", "┐"},
+ 4: {"◢", "◣", "◤", "◥"},
+ 5: {"◰", "◳", "◲", "◱"},
+ 6: {"◴", "◷", "◶", "◵"},
+ 7: {"◐", "◓", "◑", "◒"},
+ 8: {".", "o", "O", "@", "*"},
+ 9: {"|", "/", "-", "\\"},
+ 10: {"◡◡", "⊙⊙", "◠◠"},
+ 11: {"⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷"},
+ 12: {">))'>", " >))'>", " >))'>", " >))'>", " >))'>", " <'((<", " <'((<", " <'((<"},
+ 13: {"⠁", "⠂", "⠄", "⡀", "⢀", "⠠", "⠐", "⠈"},
+ 14: {"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"},
+ 15: {"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"},
+ 16: {"▉", "▊", "▋", "▌", "▍", "▎", "▏", "▎", "▍", "▌", "▋", "▊", "▉"},
+ 17: {"■", "□", "▪", "▫"},
+
+ 18: {"←", "↑", "→", "↓"},
+ 19: {"╫", "╪"},
+ 20: {"⇐", "⇖", "⇑", "⇗", "⇒", "⇘", "⇓", "⇙"},
+ 21: {"⠁", "⠁", "⠉", "⠙", "⠚", "⠒", "⠂", "⠂", "⠒", "⠲", "⠴", "⠤", "⠄", "⠄", "⠤", "⠠", "⠠", "⠤", "⠦", "⠖", "⠒", "⠐", "⠐", "⠒", "⠓", "⠋", "⠉", "⠈", "⠈"},
+ 22: {"⠈", "⠉", "⠋", "⠓", "⠒", "⠐", "⠐", "⠒", "⠖", "⠦", "⠤", "⠠", "⠠", "⠤", "⠦", "⠖", "⠒", "⠐", "⠐", "⠒", "⠓", "⠋", "⠉", "⠈"},
+ 23: {"⠁", "⠉", "⠙", "⠚", "⠒", "⠂", "⠂", "⠒", "⠲", "⠴", "⠤", "⠄", "⠄", "⠤", "⠴", "⠲", "⠒", "⠂", "⠂", "⠒", "⠚", "⠙", "⠉", "⠁"},
+ 24: {"⠋", "⠙", "⠚", "⠒", "⠂", "⠂", "⠒", "⠲", "⠴", "⠦", "⠖", "⠒", "⠐", "⠐", "⠒", "⠓", "⠋"},
+ 25: {"ヲ", "ァ", "ィ", "ゥ", "ェ", "ォ", "ャ", "ュ", "ョ", "ッ", "ア", "イ", "ウ", "エ", "オ", "カ", "キ", "ク", "ケ", "コ", "サ", "シ", "ス", "セ", "ソ", "タ", "チ", "ツ", "テ", "ト", "ナ", "ニ", "ヌ", "ネ", "ノ", "ハ", "ヒ", "フ", "ヘ", "ホ", "マ", "ミ", "ム", "メ", "モ", "ヤ", "ユ", "ヨ", "ラ", "リ", "ル", "レ", "ロ", "ワ", "ン"},
+ 26: {".", "..", "..."},
+ 27: {"▁", "▂", "▃", "▄", "▅", "▆", "▇", "█", "▉", "▊", "▋", "▌", "▍", "▎", "▏", "▏", "▎", "▍", "▌", "▋", "▊", "▉", "█", "▇", "▆", "▅", "▄", "▃", "▂", "▁"},
+ 28: {".", "o", "O", "°", "O", "o", "."},
+ 29: {"+", "x"},
+ 30: {"v", "<", "^", ">"},
+ 31: {">>--->", " >>--->", " >>--->", " >>--->", " >>--->", " <---<<", " <---<<", " <---<<", " <---<<", "<---<<"},
+ 32: {"|", "||", "|||", "||||", "|||||", "|||||||", "||||||||", "|||||||", "||||||", "|||||", "||||", "|||", "||", "|"},
+ 33: {"[ ]", "[= ]", "[== ]", "[=== ]", "[==== ]", "[===== ]", "[====== ]", "[======= ]", "[======== ]", "[========= ]", "[==========]"},
+ 34: {"(*---------)", "(-*--------)", "(--*-------)", "(---*------)", "(----*-----)", "(-----*----)", "(------*---)", "(-------*--)", "(--------*-)", "(---------*)"},
+ 35: {"█▒▒▒▒▒▒▒▒▒", "███▒▒▒▒▒▒▒", "█████▒▒▒▒▒", "███████▒▒▒", "██████████"},
+ 36: {"[ ]", "[=> ]", "[===> ]", "[=====> ]", "[======> ]", "[========> ]", "[==========> ]", "[============> ]", "[==============> ]", "[================> ]", "[==================> ]", "[===================>]"},
+ 39: {"🌍", "🌎", "🌏"},
+ 40: {"◜", "◝", "◞", "◟"},
+ 41: {"⬒", "⬔", "⬓", "⬕"},
+ 42: {"⬖", "⬘", "⬗", "⬙"},
+ 43: {"[>>> >]", "[]>>>> []", "[] >>>> []", "[] >>>> []", "[] >>>> []", "[] >>>>[]", "[>> >>]"},
+ 44: {"♠", "♣", "♥", "♦"},
+ 45: {"➞", "➟", "➠", "➡", "➠", "➟"},
+ 46: {" | ", ` \ `, "_ ", ` \ `, " | ", " / ", " _", " / "},
+ 47: {" . . . .", ". . . .", ". . . .", ". . . .", ". . . . ", ". . . . ."},
+ 48: {" | ", " / ", " _ ", ` \ `, " | ", ` \ `, " _ ", " / "},
+ 49: {"⎺", "⎻", "⎼", "⎽", "⎼", "⎻"},
+ 50: {"▹▹▹▹▹", "▸▹▹▹▹", "▹▸▹▹▹", "▹▹▸▹▹", "▹▹▹▸▹", "▹▹▹▹▸"},
+ 51: {"[ ]", "[ =]", "[ ==]", "[ ===]", "[====]", "[=== ]", "[== ]", "[= ]"},
+ 52: {"( ● )", "( ● )", "( ● )", "( ● )", "( ●)", "( ● )", "( ● )", "( ● )", "( ● )"},
+ 53: {"✶", "✸", "✹", "✺", "✹", "✷"},
+ 54: {"▐|\\____________▌", "▐_|\\___________▌", "▐__|\\__________▌", "▐___|\\_________▌", "▐____|\\________▌", "▐_____|\\_______▌", "▐______|\\______▌", "▐_______|\\_____▌", "▐________|\\____▌", "▐_________|\\___▌", "▐__________|\\__▌", "▐___________|\\_▌", "▐____________|\\▌", "▐____________/|▌", "▐___________/|_▌", "▐__________/|__▌", "▐_________/|___▌", "▐________/|____▌", "▐_______/|_____▌", "▐______/|______▌", "▐_____/|_______▌", "▐____/|________▌", "▐___/|_________▌", "▐__/|__________▌", "▐_/|___________▌", "▐/|____________▌"},
+ 55: {"▐⠂ ▌", "▐⠈ ▌", "▐ ⠂ ▌", "▐ ⠠ ▌", "▐ ⡀ ▌", "▐ ⠠ ▌", "▐ ⠂ ▌", "▐ ⠈ ▌", "▐ ⠂ ▌", "▐ ⠠ ▌", "▐ ⡀ ▌", "▐ ⠠ ▌", "▐ ⠂ ▌", "▐ ⠈ ▌", "▐ ⠂▌", "▐ ⠠▌", "▐ ⡀▌", "▐ ⠠ ▌", "▐ ⠂ ▌", "▐ ⠈ ▌", "▐ ⠂ ▌", "▐ ⠠ ▌", "▐ ⡀ ▌", "▐ ⠠ ▌", "▐ ⠂ ▌", "▐ ⠈ ▌", "▐ ⠂ ▌", "▐ ⠠ ▌", "▐ ⡀ ▌", "▐⠠ ▌"},
+ 56: {"¿", "?"},
+ 57: {"⢹", "⢺", "⢼", "⣸", "⣇", "⡧", "⡗", "⡏"},
+ 58: {"⢄", "⢂", "⢁", "⡁", "⡈", "⡐", "⡠"},
+ 59: {". ", ".. ", "...", " ..", " .", " "},
+ 60: {".", "o", "O", "°", "O", "o", "."},
+ 61: {"▓", "▒", "░"},
+ 62: {"▌", "▀", "▐", "▄"},
+ 63: {"⊶", "⊷"},
+ 64: {"▪", "▫"},
+ 65: {"□", "■"},
+ 66: {"▮", "▯"},
+ 67: {"-", "=", "≡"},
+ 68: {"d", "q", "p", "b"},
+ 69: {"∙∙∙", "●∙∙", "∙●∙", "∙∙●", "∙∙∙"},
+ 70: {"🌑 ", "🌒 ", "🌓 ", "🌔 ", "🌕 ", "🌖 ", "🌗 ", "🌘 "},
+ 71: {"☗", "☖"},
+ 72: {"⧇", "⧆"},
+ 73: {"◉", "◎"},
+ 74: {"㊂", "㊀", "㊁"},
+ 75: {"⦾", "⦿"},
+ 76: {"ဝ", "၀"},
+ 77: {"▌", "▀", "▐▄"},
+ 78: {"⠈⠁", "⠈⠑", "⠈⠱", "⠈⡱", "⢀⡱", "⢄⡱", "⢄⡱", "⢆⡱", "⢎⡱", "⢎⡰", "⢎⡠", "⢎⡀", "⢎⠁", "⠎⠁", "⠊⠁"},
+ 79: {"________", "-_______", "_-______", "__-_____", "___-____", "____-___", "_____-__", "______-_", "_______-", "________", "_______-", "______-_", "_____-__", "____-___", "___-____", "__-_____", "_-______", "-_______", "________"},
+ 80: {"|_______", "_/______", "__-_____", "___\\____", "____|___", "_____/__", "______-_", "_______\\", "_______|", "______\\_", "_____-__", "____/___", "___|____", "__\\_____", "_-______"},
+ 81: {"□", "◱", "◧", "▣", "■"},
+ 82: {"□", "◱", "▨", "▩", "■"},
+ 83: {"░", "▒", "▓", "█"},
+ 84: {"░", "█"},
+ 85: {"⚪", "⚫"},
+ 86: {"◯", "⬤"},
+ 87: {"▱", "▰"},
+ 88: {"➊", "➋", "➌", "➍", "➎", "➏", "➐", "➑", "➒", "➓"},
+ 89: {"½", "⅓", "⅔", "¼", "¾", "⅛", "⅜", "⅝", "⅞"},
+ 90: {"↞", "↟", "↠", "↡"},
+}
+
+func init() {
+ for i := rune(0); i < 12; i++ {
+ CharSets[37] = append(CharSets[37], string([]rune{clockOneOClock + i}))
+ CharSets[38] = append(CharSets[38], string([]rune{clockOneOClock + i}), string([]rune{clockOneThirty + i}))
+ }
+}
diff --git a/vendor/github.com/briandowns/spinner/spinner.go b/vendor/github.com/briandowns/spinner/spinner.go
new file mode 100644
index 000000000..f6bb029f8
--- /dev/null
+++ b/vendor/github.com/briandowns/spinner/spinner.go
@@ -0,0 +1,447 @@
+// Copyright (c) 2021 Brian J. Downs
+//
+// 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.
+
+// Package spinner is a simple package to add a spinner / progress indicator to any terminal application.
+package spinner
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "runtime"
+ "strconv"
+ "strings"
+ "sync"
+ "time"
+ "unicode/utf8"
+
+ "github.com/fatih/color"
+ "github.com/mattn/go-isatty"
+)
+
+// errInvalidColor is returned when attempting to set an invalid color
+var errInvalidColor = errors.New("invalid color")
+
+// validColors holds an array of the only colors allowed
+var validColors = map[string]bool{
+ // default colors for backwards compatibility
+ "black": true,
+ "red": true,
+ "green": true,
+ "yellow": true,
+ "blue": true,
+ "magenta": true,
+ "cyan": true,
+ "white": true,
+
+ // attributes
+ "reset": true,
+ "bold": true,
+ "faint": true,
+ "italic": true,
+ "underline": true,
+ "blinkslow": true,
+ "blinkrapid": true,
+ "reversevideo": true,
+ "concealed": true,
+ "crossedout": true,
+
+ // foreground text
+ "fgBlack": true,
+ "fgRed": true,
+ "fgGreen": true,
+ "fgYellow": true,
+ "fgBlue": true,
+ "fgMagenta": true,
+ "fgCyan": true,
+ "fgWhite": true,
+
+ // foreground Hi-Intensity text
+ "fgHiBlack": true,
+ "fgHiRed": true,
+ "fgHiGreen": true,
+ "fgHiYellow": true,
+ "fgHiBlue": true,
+ "fgHiMagenta": true,
+ "fgHiCyan": true,
+ "fgHiWhite": true,
+
+ // background text
+ "bgBlack": true,
+ "bgRed": true,
+ "bgGreen": true,
+ "bgYellow": true,
+ "bgBlue": true,
+ "bgMagenta": true,
+ "bgCyan": true,
+ "bgWhite": true,
+
+ // background Hi-Intensity text
+ "bgHiBlack": true,
+ "bgHiRed": true,
+ "bgHiGreen": true,
+ "bgHiYellow": true,
+ "bgHiBlue": true,
+ "bgHiMagenta": true,
+ "bgHiCyan": true,
+ "bgHiWhite": true,
+}
+
+// returns true if the OS is windows and the WT_SESSION env variable is set.
+var isWindowsTerminalOnWindows = len(os.Getenv("WT_SESSION")) > 0 && runtime.GOOS == "windows"
+
+// returns a valid color's foreground text color attribute
+var colorAttributeMap = map[string]color.Attribute{
+ // default colors for backwards compatibility
+ "black": color.FgBlack,
+ "red": color.FgRed,
+ "green": color.FgGreen,
+ "yellow": color.FgYellow,
+ "blue": color.FgBlue,
+ "magenta": color.FgMagenta,
+ "cyan": color.FgCyan,
+ "white": color.FgWhite,
+
+ // attributes
+ "reset": color.Reset,
+ "bold": color.Bold,
+ "faint": color.Faint,
+ "italic": color.Italic,
+ "underline": color.Underline,
+ "blinkslow": color.BlinkSlow,
+ "blinkrapid": color.BlinkRapid,
+ "reversevideo": color.ReverseVideo,
+ "concealed": color.Concealed,
+ "crossedout": color.CrossedOut,
+
+ // foreground text colors
+ "fgBlack": color.FgBlack,
+ "fgRed": color.FgRed,
+ "fgGreen": color.FgGreen,
+ "fgYellow": color.FgYellow,
+ "fgBlue": color.FgBlue,
+ "fgMagenta": color.FgMagenta,
+ "fgCyan": color.FgCyan,
+ "fgWhite": color.FgWhite,
+
+ // foreground Hi-Intensity text colors
+ "fgHiBlack": color.FgHiBlack,
+ "fgHiRed": color.FgHiRed,
+ "fgHiGreen": color.FgHiGreen,
+ "fgHiYellow": color.FgHiYellow,
+ "fgHiBlue": color.FgHiBlue,
+ "fgHiMagenta": color.FgHiMagenta,
+ "fgHiCyan": color.FgHiCyan,
+ "fgHiWhite": color.FgHiWhite,
+
+ // background text colors
+ "bgBlack": color.BgBlack,
+ "bgRed": color.BgRed,
+ "bgGreen": color.BgGreen,
+ "bgYellow": color.BgYellow,
+ "bgBlue": color.BgBlue,
+ "bgMagenta": color.BgMagenta,
+ "bgCyan": color.BgCyan,
+ "bgWhite": color.BgWhite,
+
+ // background Hi-Intensity text colors
+ "bgHiBlack": color.BgHiBlack,
+ "bgHiRed": color.BgHiRed,
+ "bgHiGreen": color.BgHiGreen,
+ "bgHiYellow": color.BgHiYellow,
+ "bgHiBlue": color.BgHiBlue,
+ "bgHiMagenta": color.BgHiMagenta,
+ "bgHiCyan": color.BgHiCyan,
+ "bgHiWhite": color.BgHiWhite,
+}
+
+// validColor will make sure the given color is actually allowed.
+func validColor(c string) bool {
+ return validColors[c]
+}
+
+// Spinner struct to hold the provided options.
+type Spinner struct {
+ mu *sync.RWMutex
+ Delay time.Duration // Delay is the speed of the indicator
+ chars []string // chars holds the chosen character set
+ Prefix string // Prefix is the text preppended to the indicator
+ Suffix string // Suffix is the text appended to the indicator
+ FinalMSG string // string displayed after Stop() is called
+ lastOutput string // last character(set) written
+ color func(a ...interface{}) string // default color is white
+ Writer io.Writer // to make testing better, exported so users have access. Use `WithWriter` to update after initialization.
+ active bool // active holds the state of the spinner
+ stopChan chan struct{} // stopChan is a channel used to stop the indicator
+ HideCursor bool // hideCursor determines if the cursor is visible
+ PreUpdate func(s *Spinner) // will be triggered before every spinner update
+ PostUpdate func(s *Spinner) // will be triggered after every spinner update
+}
+
+// New provides a pointer to an instance of Spinner with the supplied options.
+func New(cs []string, d time.Duration, options ...Option) *Spinner {
+ s := &Spinner{
+ Delay: d,
+ chars: cs,
+ color: color.New(color.FgWhite).SprintFunc(),
+ mu: &sync.RWMutex{},
+ Writer: color.Output,
+ stopChan: make(chan struct{}, 1),
+ active: false,
+ HideCursor: true,
+ }
+
+ for _, option := range options {
+ option(s)
+ }
+
+ return s
+}
+
+// Option is a function that takes a spinner and applies
+// a given configuration.
+type Option func(*Spinner)
+
+// Options contains fields to configure the spinner.
+type Options struct {
+ Color string
+ Suffix string
+ FinalMSG string
+ HideCursor bool
+}
+
+// WithColor adds the given color to the spinner.
+func WithColor(color string) Option {
+ return func(s *Spinner) {
+ s.Color(color)
+ }
+}
+
+// WithSuffix adds the given string to the spinner
+// as the suffix.
+func WithSuffix(suffix string) Option {
+ return func(s *Spinner) {
+ s.Suffix = suffix
+ }
+}
+
+// WithFinalMSG adds the given string ot the spinner
+// as the final message to be written.
+func WithFinalMSG(finalMsg string) Option {
+ return func(s *Spinner) {
+ s.FinalMSG = finalMsg
+ }
+}
+
+// WithHiddenCursor hides the cursor
+// if hideCursor = true given.
+func WithHiddenCursor(hideCursor bool) Option {
+ return func(s *Spinner) {
+ s.HideCursor = hideCursor
+ }
+}
+
+// WithWriter adds the given writer to the spinner. This
+// function should be favored over directly assigning to
+// the struct value.
+func WithWriter(w io.Writer) Option {
+ return func(s *Spinner) {
+ s.mu.Lock()
+ s.Writer = w
+ s.mu.Unlock()
+ }
+}
+
+// Active will return whether or not the spinner is currently active.
+func (s *Spinner) Active() bool {
+ return s.active
+}
+
+// Start will start the indicator.
+func (s *Spinner) Start() {
+ s.mu.Lock()
+ if s.active || !isRunningInTerminal() {
+ s.mu.Unlock()
+ return
+ }
+ if s.HideCursor && !isWindowsTerminalOnWindows {
+ // hides the cursor
+ fmt.Fprint(s.Writer, "\033[?25l")
+ }
+ s.active = true
+ s.mu.Unlock()
+
+ go func() {
+ for {
+ for i := 0; i < len(s.chars); i++ {
+ select {
+ case <-s.stopChan:
+ return
+ default:
+ s.mu.Lock()
+ if !s.active {
+ s.mu.Unlock()
+ return
+ }
+ if !isWindowsTerminalOnWindows {
+ s.erase()
+ }
+
+ if s.PreUpdate != nil {
+ s.PreUpdate(s)
+ }
+
+ var outColor string
+ if runtime.GOOS == "windows" {
+ if s.Writer == os.Stderr {
+ outColor = fmt.Sprintf("\r%s%s%s", s.Prefix, s.chars[i], s.Suffix)
+ } else {
+ outColor = fmt.Sprintf("\r%s%s%s", s.Prefix, s.color(s.chars[i]), s.Suffix)
+ }
+ } else {
+ outColor = fmt.Sprintf("\r%s%s%s", s.Prefix, s.color(s.chars[i]), s.Suffix)
+ }
+ outPlain := fmt.Sprintf("\r%s%s%s", s.Prefix, s.chars[i], s.Suffix)
+ fmt.Fprint(s.Writer, outColor)
+ s.lastOutput = outPlain
+ delay := s.Delay
+
+ if s.PostUpdate != nil {
+ s.PostUpdate(s)
+ }
+
+ s.mu.Unlock()
+ time.Sleep(delay)
+ }
+ }
+ }
+ }()
+}
+
+// Stop stops the indicator.
+func (s *Spinner) Stop() {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ if s.active {
+ s.active = false
+ if s.HideCursor && !isWindowsTerminalOnWindows {
+ // makes the cursor visible
+ fmt.Fprint(s.Writer, "\033[?25h")
+ }
+ s.erase()
+ if s.FinalMSG != "" {
+ if isWindowsTerminalOnWindows {
+ fmt.Fprint(s.Writer, "\r", s.FinalMSG)
+ } else {
+ fmt.Fprint(s.Writer, s.FinalMSG)
+ }
+ }
+ s.stopChan <- struct{}{}
+ }
+}
+
+// Restart will stop and start the indicator.
+func (s *Spinner) Restart() {
+ s.Stop()
+ s.Start()
+}
+
+// Reverse will reverse the order of the slice assigned to the indicator.
+func (s *Spinner) Reverse() {
+ s.mu.Lock()
+ for i, j := 0, len(s.chars)-1; i < j; i, j = i+1, j-1 {
+ s.chars[i], s.chars[j] = s.chars[j], s.chars[i]
+ }
+ s.mu.Unlock()
+}
+
+// Color will set the struct field for the given color to be used. The spinner
+// will need to be explicitly restarted.
+func (s *Spinner) Color(colors ...string) error {
+ colorAttributes := make([]color.Attribute, len(colors))
+
+ // Verify colours are valid and place the appropriate attribute in the array
+ for index, c := range colors {
+ if !validColor(c) {
+ return errInvalidColor
+ }
+ colorAttributes[index] = colorAttributeMap[c]
+ }
+
+ s.mu.Lock()
+ s.color = color.New(colorAttributes...).SprintFunc()
+ s.mu.Unlock()
+ return nil
+}
+
+// UpdateSpeed will set the indicator delay to the given value.
+func (s *Spinner) UpdateSpeed(d time.Duration) {
+ s.mu.Lock()
+ s.Delay = d
+ s.mu.Unlock()
+}
+
+// UpdateCharSet will change the current character set to the given one.
+func (s *Spinner) UpdateCharSet(cs []string) {
+ s.mu.Lock()
+ s.chars = cs
+ s.mu.Unlock()
+}
+
+// erase deletes written characters on the current line.
+// Caller must already hold s.lock.
+func (s *Spinner) erase() {
+ n := utf8.RuneCountInString(s.lastOutput)
+ if runtime.GOOS == "windows" && !isWindowsTerminalOnWindows {
+ clearString := "\r" + strings.Repeat(" ", n) + "\r"
+ fmt.Fprint(s.Writer, clearString)
+ s.lastOutput = ""
+ return
+ }
+
+ // Taken from https://en.wikipedia.org/wiki/ANSI_escape_code:
+ // \r - Carriage return - Moves the cursor to column zero
+ // \033[K - Erases part of the line. If n is 0 (or missing), clear from
+ // cursor to the end of the line. If n is 1, clear from cursor to beginning
+ // of the line. If n is 2, clear entire line. Cursor position does not
+ // change.
+ fmt.Fprintf(s.Writer, "\r\033[K")
+ s.lastOutput = ""
+}
+
+// Lock allows for manual control to lock the spinner.
+func (s *Spinner) Lock() {
+ s.mu.Lock()
+}
+
+// Unlock allows for manual control to unlock the spinner.
+func (s *Spinner) Unlock() {
+ s.mu.Unlock()
+}
+
+// GenerateNumberSequence will generate a slice of integers at the
+// provided length and convert them each to a string.
+func GenerateNumberSequence(length int) []string {
+ numSeq := make([]string, length)
+ for i := 0; i < length; i++ {
+ numSeq[i] = strconv.Itoa(i)
+ }
+ return numSeq
+}
+
+// isRunningInTerminal check if stdout file descriptor is terminal
+func isRunningInTerminal() bool {
+ return isatty.IsTerminal(os.Stdout.Fd())
+}
diff --git a/vendor/github.com/charmbracelet/lipgloss/.gitignore b/vendor/github.com/charmbracelet/lipgloss/.gitignore
new file mode 100644
index 000000000..53e1c2b75
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/.gitignore
@@ -0,0 +1 @@
+ssh_example_ed25519*
diff --git a/vendor/github.com/charmbracelet/lipgloss/.golangci-soft.yml b/vendor/github.com/charmbracelet/lipgloss/.golangci-soft.yml
new file mode 100644
index 000000000..ef456e060
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/.golangci-soft.yml
@@ -0,0 +1,47 @@
+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
+ - gomnd
+ - gomoddirectives
+ - goprintffuncname
+ - ifshort
+ # - lll
+ - misspell
+ - nakedret
+ - nestif
+ - noctx
+ - nolintlint
+ - prealloc
+ - wrapcheck
+
+ # disable default linters, they are already enabled in .golangci.yml
+ disable:
+ - deadcode
+ - errcheck
+ - gosimple
+ - govet
+ - ineffassign
+ - staticcheck
+ - structcheck
+ - typecheck
+ - unused
+ - varcheck
diff --git a/vendor/github.com/charmbracelet/lipgloss/.golangci.yml b/vendor/github.com/charmbracelet/lipgloss/.golangci.yml
new file mode 100644
index 000000000..a5a91d0d9
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/.golangci.yml
@@ -0,0 +1,29 @@
+run:
+ tests: false
+
+issues:
+ include:
+ - EXC0001
+ - EXC0005
+ - EXC0011
+ - EXC0012
+ - EXC0013
+
+ max-issues-per-linter: 0
+ max-same-issues: 0
+
+linters:
+ enable:
+ - bodyclose
+ - exportloopref
+ - goimports
+ - gosec
+ - nilerr
+ - predeclared
+ - revive
+ - rowserrcheck
+ - sqlclosecheck
+ - tparallel
+ - unconvert
+ - unparam
+ - whitespace
diff --git a/vendor/github.com/charmbracelet/lipgloss/LICENSE b/vendor/github.com/charmbracelet/lipgloss/LICENSE
new file mode 100644
index 000000000..6f5b1fa62
--- /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 000000000..22defac7c
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/README.md
@@ -0,0 +1,564 @@
+Lip Gloss
+=========
+
+
+
+
+
+
+
+
+
+
+Style definitions for nice terminal layouts. Built with TUIs in mind.
+
+![Lip Gloss example](https://stuff.charm.sh/lipgloss/lipgloss-example.png)
+
+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 truecolor, ANSI256, and ANSI color
+profiles.
+
+```go
+lipgloss.CompleteColor{True: "#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 `Copy()`:
+
+```go
+var style = lipgloss.NewStyle().Foreground(lipgloss.Color("219"))
+
+var wildStyle = style.Copy().Blink(true)
+```
+
+`Copy()` performs a copy on the underlying data structure ensuring that you get
+a true, dereferenced copy of a style. Without copying, it's possible to mutate
+styles.
+
+
+## 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
+t := table.New().
+ Border(lipgloss.NormalBorder()).
+ BorderStyle(lipgloss.NewStyle().Foreground(lipgloss.Color("99"))).
+ StyleFunc(func(row, col int) lipgloss.Style {
+ switch {
+ case row == 0:
+ 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)
+```
+
+![Table Example](https://github.com/charmbracelet/lipgloss/assets/42545625/6e4b70c4-f494-45da-a467-bdd27df30d5d)
+
+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).
+
+***
+
+## 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
+
+
+## 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/align.go b/vendor/github.com/charmbracelet/lipgloss/align.go
new file mode 100644
index 000000000..4aec37175
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/align.go
@@ -0,0 +1,83 @@
+package lipgloss
+
+import (
+ "strings"
+
+ "github.com/charmbracelet/x/exp/term/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:gomnd
+ right := left + shortAmount%2 //nolint:gomnd
+
+ 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:gomnd
+ 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 000000000..d416b8c99
--- /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 000000000..0cf56e4c7
--- /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 000000000..38f875f1c
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/borders.go
@@ -0,0 +1,443 @@
+package lipgloss
+
+import (
+ "strings"
+
+ "github.com/charmbracelet/x/exp/term/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: "█",
+ }
+
+ 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: " ",
+ }
+)
+
+// 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
+}
+
+func (s Style) applyBorder(str string) string {
+ var (
+ topSet = s.isSet(borderTopKey)
+ rightSet = s.isSet(borderRightKey)
+ bottomSet = s.isSet(borderBottomKey)
+ leftSet = s.isSet(borderLeftKey)
+
+ 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 border != noBorder && !(topSet || rightSet || bottomSet || leftSet) {
+ 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 000000000..43f5b434b
--- /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.Copy().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:gomnd
+}
+
+// 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 000000000..d6c83a971
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/get.go
@@ -0,0 +1,502 @@
+package lipgloss
+
+import (
+ "strings"
+
+ "github.com/charmbracelet/x/exp/term/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) {
+ 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) {
+ 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) {
+ 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) {
+ 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 {
+ _, exists := s.rules[k]
+ return exists
+}
+
+func (s Style) getAsBool(k propKey, defaultVal bool) bool {
+ v, ok := s.rules[k]
+ if !ok {
+ return defaultVal
+ }
+ if b, ok := v.(bool); ok {
+ return b
+ }
+ return defaultVal
+}
+
+func (s Style) getAsColor(k propKey) TerminalColor {
+ v, ok := s.rules[k]
+ if !ok {
+ return noColor
+ }
+ if c, ok := v.(TerminalColor); ok {
+ return c
+ }
+ return noColor
+}
+
+func (s Style) getAsInt(k propKey) int {
+ v, ok := s.rules[k]
+ if !ok {
+ return 0
+ }
+ if i, ok := v.(int); ok {
+ return i
+ }
+ return 0
+}
+
+func (s Style) getAsPosition(k propKey) Position {
+ v, ok := s.rules[k]
+ if !ok {
+ return Position(0)
+ }
+ if p, ok := v.(Position); ok {
+ return p
+ }
+ return Position(0)
+}
+
+func (s Style) getBorderStyle() Border {
+ v, ok := s.rules[borderStyleKey]
+ if !ok {
+ return noBorder
+ }
+ if b, ok := v.(Border); ok {
+ return b
+ }
+ return noBorder
+}
+
+func (s Style) getAsTransform(k propKey) func(string) string {
+ v, ok := s.rules[k]
+ if !ok {
+ return nil
+ }
+ if fn, ok := v.(func(string) string); ok {
+ return fn
+ }
+ return nil
+}
+
+// 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 000000000..8e3115b05
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/join.go
@@ -0,0 +1,175 @@
+package lipgloss
+
+import (
+ "math"
+ "strings"
+
+ "github.com/charmbracelet/x/exp/term/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 000000000..f57b7bb91
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/position.go
@@ -0,0 +1,154 @@
+package lipgloss
+
+import (
+ "math"
+ "strings"
+
+ "github.com/charmbracelet/x/exp/term/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/renderer.go b/vendor/github.com/charmbracelet/lipgloss/renderer.go
new file mode 100644
index 000000000..85ffd2545
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/renderer.go
@@ -0,0 +1,184 @@
+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
+}
+
+// RendererOption is a function that can be used to configure a [Renderer].
+type RendererOption func(r *Renderer)
+
+// 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 000000000..7a49e326c
--- /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 000000000..5846b598a
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/set.go
@@ -0,0 +1,670 @@
+package lipgloss
+
+// This could (should) probably just be moved into NewStyle(). We've broken it
+// out, so we can call it in a lazy way.
+func (s *Style) init() {
+ if s.rules == nil {
+ s.rules = make(rules)
+ }
+}
+
+// Set a value on the underlying rules map.
+func (s *Style) set(key propKey, value interface{}) {
+ s.init()
+
+ switch v := value.(type) {
+ case int:
+ // TabWidth is the only property that may have a negative value (and
+ // that negative value can be no less than -1).
+ if key == tabWidthKey {
+ s.rules[key] = v
+ break
+ }
+
+ // 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.
+ s.rules[key] = max(0, v)
+ default:
+ s.rules[key] = v
+ }
+}
+
+// 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.
+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:gomnd
+ top = i[0]
+ bottom = i[0]
+ left = i[1]
+ right = i[1]
+ ok = true
+ case 3: //nolint:gomnd
+ top = i[0]
+ left = i[1]
+ right = i[1]
+ bottom = i[2]
+ ok = true
+ case 4: //nolint:gomnd
+ 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:gomnd
+ top = i[0]
+ bottom = i[0]
+ left = i[1]
+ right = i[1]
+ ok = true
+ case 3: //nolint:gomnd
+ top = i[0]
+ left = i[1]
+ right = i[1]
+ bottom = i[2]
+ ok = true
+ case 4: //nolint:gomnd
+ 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:gomnd
+ top = i[0]
+ bottom = i[0]
+ left = i[1]
+ right = i[1]
+ ok = true
+ case 3: //nolint:gomnd
+ top = i[0]
+ left = i[1]
+ right = i[1]
+ bottom = i[2]
+ ok = true
+ case 4: //nolint:gomnd
+ 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 000000000..0be4d13a7
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/size.go
@@ -0,0 +1,41 @@
+package lipgloss
+
+import (
+ "strings"
+
+ "github.com/charmbracelet/x/exp/term/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 000000000..98540ad78
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/style.go
@@ -0,0 +1,531 @@
+package lipgloss
+
+import (
+ "strings"
+ "unicode"
+
+ "github.com/charmbracelet/x/exp/term/ansi"
+ "github.com/muesli/termenv"
+)
+
+const tabWidthDefault = 4
+
+// Property for a key.
+type propKey int
+
+// Available properties.
+const (
+ boldKey propKey = iota
+ italicKey
+ underlineKey
+ strikethroughKey
+ reverseKey
+ blinkKey
+ faintKey
+ foregroundKey
+ backgroundKey
+ widthKey
+ heightKey
+ alignHorizontalKey
+ alignVerticalKey
+
+ // Padding.
+ paddingTopKey
+ paddingRightKey
+ paddingBottomKey
+ paddingLeftKey
+
+ colorWhitespaceKey
+
+ // 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
+ underlineSpacesKey
+ strikethroughSpacesKey
+
+ transformKey
+)
+
+// A set of properties.
+type rules map[propKey]interface{}
+
+// 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
+ rules map[propKey]interface{}
+ value 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.
+func (s Style) Copy() Style {
+ o := NewStyle()
+ o.init()
+ for k, v := range s.rules {
+ o.rules[k] = v
+ }
+ o.r = s.r
+ o.value = s.value
+ return o
+}
+
+// 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 {
+ s.init()
+
+ for k, v := range i.rules {
+ 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.rules[marginBackgroundKey] = v
+ }
+ }
+
+ if _, exists := s.rules[k]; exists {
+ continue
+ }
+ s.rules[k] = v
+ }
+ 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 = underline && s.getAsBool(underlineSpacesKey, true)
+ strikethroughSpaces = 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 = underlineSpaces || strikethroughSpaces
+
+ transform = s.getAsTransform(transformKey)
+ )
+
+ if transform != nil {
+ str = transform(str)
+ }
+
+ if len(s.rules) == 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 {
+ 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)
+
+ // Strip newlines in single line mode
+ if inline {
+ str = strings.ReplaceAll(str, "\n", "")
+ }
+
+ // Word wrap
+ if !inline && width > 0 {
+ wrapAt := width - leftPadding - rightPadding
+ str = ansi.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 {
+ 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 {
+ if a > b {
+ return a
+ }
+ return b
+}
+
+func min(a, b int) int {
+ 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 000000000..5387bcf73
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/unset.go
@@ -0,0 +1,318 @@
+package lipgloss
+
+// UnsetBold removes the bold style rule, if set.
+func (s Style) UnsetBold() Style {
+ delete(s.rules, boldKey)
+ return s
+}
+
+// UnsetItalic removes the italic style rule, if set.
+func (s Style) UnsetItalic() Style {
+ delete(s.rules, italicKey)
+ return s
+}
+
+// UnsetUnderline removes the underline style rule, if set.
+func (s Style) UnsetUnderline() Style {
+ delete(s.rules, underlineKey)
+ return s
+}
+
+// UnsetStrikethrough removes the strikethrough style rule, if set.
+func (s Style) UnsetStrikethrough() Style {
+ delete(s.rules, strikethroughKey)
+ return s
+}
+
+// UnsetReverse removes the reverse style rule, if set.
+func (s Style) UnsetReverse() Style {
+ delete(s.rules, reverseKey)
+ return s
+}
+
+// UnsetBlink removes the blink style rule, if set.
+func (s Style) UnsetBlink() Style {
+ delete(s.rules, blinkKey)
+ return s
+}
+
+// UnsetFaint removes the faint style rule, if set.
+func (s Style) UnsetFaint() Style {
+ delete(s.rules, faintKey)
+ return s
+}
+
+// UnsetForeground removes the foreground style rule, if set.
+func (s Style) UnsetForeground() Style {
+ delete(s.rules, foregroundKey)
+ return s
+}
+
+// UnsetBackground removes the background style rule, if set.
+func (s Style) UnsetBackground() Style {
+ delete(s.rules, backgroundKey)
+ return s
+}
+
+// UnsetWidth removes the width style rule, if set.
+func (s Style) UnsetWidth() Style {
+ delete(s.rules, widthKey)
+ return s
+}
+
+// UnsetHeight removes the height style rule, if set.
+func (s Style) UnsetHeight() Style {
+ delete(s.rules, heightKey)
+ return s
+}
+
+// UnsetAlign removes the horizontal and vertical text alignment style rule, if set.
+func (s Style) UnsetAlign() Style {
+ delete(s.rules, alignHorizontalKey)
+ delete(s.rules, alignVerticalKey)
+ return s
+}
+
+// UnsetAlignHorizontal removes the horizontal text alignment style rule, if set.
+func (s Style) UnsetAlignHorizontal() Style {
+ delete(s.rules, alignHorizontalKey)
+ return s
+}
+
+// UnsetAlignVertical removes the vertical text alignment style rule, if set.
+func (s Style) UnsetAlignVertical() Style {
+ delete(s.rules, alignVerticalKey)
+ return s
+}
+
+// UnsetPadding removes all padding style rules.
+func (s Style) UnsetPadding() Style {
+ delete(s.rules, paddingLeftKey)
+ delete(s.rules, paddingRightKey)
+ delete(s.rules, paddingTopKey)
+ delete(s.rules, paddingBottomKey)
+ return s
+}
+
+// UnsetPaddingLeft removes the left padding style rule, if set.
+func (s Style) UnsetPaddingLeft() Style {
+ delete(s.rules, paddingLeftKey)
+ return s
+}
+
+// UnsetPaddingRight removes the right padding style rule, if set.
+func (s Style) UnsetPaddingRight() Style {
+ delete(s.rules, paddingRightKey)
+ return s
+}
+
+// UnsetPaddingTop removes the top padding style rule, if set.
+func (s Style) UnsetPaddingTop() Style {
+ delete(s.rules, paddingTopKey)
+ return s
+}
+
+// UnsetPaddingBottom removes the bottom padding style rule, if set.
+func (s Style) UnsetPaddingBottom() Style {
+ delete(s.rules, paddingBottomKey)
+ return s
+}
+
+// UnsetColorWhitespace removes the rule for coloring padding, if set.
+func (s Style) UnsetColorWhitespace() Style {
+ delete(s.rules, colorWhitespaceKey)
+ return s
+}
+
+// UnsetMargins removes all margin style rules.
+func (s Style) UnsetMargins() Style {
+ delete(s.rules, marginLeftKey)
+ delete(s.rules, marginRightKey)
+ delete(s.rules, marginTopKey)
+ delete(s.rules, marginBottomKey)
+ return s
+}
+
+// UnsetMarginLeft removes the left margin style rule, if set.
+func (s Style) UnsetMarginLeft() Style {
+ delete(s.rules, marginLeftKey)
+ return s
+}
+
+// UnsetMarginRight removes the right margin style rule, if set.
+func (s Style) UnsetMarginRight() Style {
+ delete(s.rules, marginRightKey)
+ return s
+}
+
+// UnsetMarginTop removes the top margin style rule, if set.
+func (s Style) UnsetMarginTop() Style {
+ delete(s.rules, marginTopKey)
+ return s
+}
+
+// UnsetMarginBottom removes the bottom margin style rule, if set.
+func (s Style) UnsetMarginBottom() Style {
+ delete(s.rules, 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 {
+ delete(s.rules, marginBackgroundKey)
+ return s
+}
+
+// UnsetBorderStyle removes the border style rule, if set.
+func (s Style) UnsetBorderStyle() Style {
+ delete(s.rules, borderStyleKey)
+ return s
+}
+
+// UnsetBorderTop removes the border top style rule, if set.
+func (s Style) UnsetBorderTop() Style {
+ delete(s.rules, borderTopKey)
+ return s
+}
+
+// UnsetBorderRight removes the border right style rule, if set.
+func (s Style) UnsetBorderRight() Style {
+ delete(s.rules, borderRightKey)
+ return s
+}
+
+// UnsetBorderBottom removes the border bottom style rule, if set.
+func (s Style) UnsetBorderBottom() Style {
+ delete(s.rules, borderBottomKey)
+ return s
+}
+
+// UnsetBorderLeft removes the border left style rule, if set.
+func (s Style) UnsetBorderLeft() Style {
+ delete(s.rules, borderLeftKey)
+ return s
+}
+
+// UnsetBorderForeground removes all border foreground color styles, if set.
+func (s Style) UnsetBorderForeground() Style {
+ delete(s.rules, borderTopForegroundKey)
+ delete(s.rules, borderRightForegroundKey)
+ delete(s.rules, borderBottomForegroundKey)
+ delete(s.rules, borderLeftForegroundKey)
+ return s
+}
+
+// UnsetBorderTopForeground removes the top border foreground color rule,
+// if set.
+func (s Style) UnsetBorderTopForeground() Style {
+ delete(s.rules, borderTopForegroundKey)
+ return s
+}
+
+// UnsetBorderRightForeground removes the right border foreground color rule,
+// if set.
+func (s Style) UnsetBorderRightForeground() Style {
+ delete(s.rules, borderRightForegroundKey)
+ return s
+}
+
+// UnsetBorderBottomForeground removes the bottom border foreground color
+// rule, if set.
+func (s Style) UnsetBorderBottomForeground() Style {
+ delete(s.rules, borderBottomForegroundKey)
+ return s
+}
+
+// UnsetBorderLeftForeground removes the left border foreground color rule,
+// if set.
+func (s Style) UnsetBorderLeftForeground() Style {
+ delete(s.rules, borderLeftForegroundKey)
+ return s
+}
+
+// UnsetBorderBackground removes all border background color styles, if
+// set.
+func (s Style) UnsetBorderBackground() Style {
+ delete(s.rules, borderTopBackgroundKey)
+ delete(s.rules, borderRightBackgroundKey)
+ delete(s.rules, borderBottomBackgroundKey)
+ delete(s.rules, borderLeftBackgroundKey)
+ return s
+}
+
+// UnsetBorderTopBackgroundColor removes the top border background color rule,
+// if set.
+func (s Style) UnsetBorderTopBackgroundColor() Style {
+ delete(s.rules, borderTopBackgroundKey)
+ return s
+}
+
+// UnsetBorderRightBackground removes the right border background color
+// rule, if set.
+func (s Style) UnsetBorderRightBackground() Style {
+ delete(s.rules, borderRightBackgroundKey)
+ return s
+}
+
+// UnsetBorderBottomBackground removes the bottom border background color
+// rule, if set.
+func (s Style) UnsetBorderBottomBackground() Style {
+ delete(s.rules, borderBottomBackgroundKey)
+ return s
+}
+
+// UnsetBorderLeftBackground removes the left border color rule, if set.
+func (s Style) UnsetBorderLeftBackground() Style {
+ delete(s.rules, borderLeftBackgroundKey)
+ return s
+}
+
+// UnsetInline removes the inline style rule, if set.
+func (s Style) UnsetInline() Style {
+ delete(s.rules, inlineKey)
+ return s
+}
+
+// UnsetMaxWidth removes the max width style rule, if set.
+func (s Style) UnsetMaxWidth() Style {
+ delete(s.rules, maxWidthKey)
+ return s
+}
+
+// UnsetMaxHeight removes the max height style rule, if set.
+func (s Style) UnsetMaxHeight() Style {
+ delete(s.rules, maxHeightKey)
+ return s
+}
+
+// UnsetTabWidth removes the tab width style rule, if set.
+func (s Style) UnsetTabWidth() Style {
+ delete(s.rules, tabWidthKey)
+ return s
+}
+
+// UnsetUnderlineSpaces removes the value set by UnderlineSpaces.
+func (s Style) UnsetUnderlineSpaces() Style {
+ delete(s.rules, underlineSpacesKey)
+ return s
+}
+
+// UnsetStrikethroughSpaces removes the value set by StrikethroughSpaces.
+func (s Style) UnsetStrikethroughSpaces() Style {
+ delete(s.rules, strikethroughSpacesKey)
+ return s
+}
+
+// UnsetTransform removes the value set by Transform.
+func (s Style) UnsetTransform() Style {
+ delete(s.rules, 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 000000000..19656871d
--- /dev/null
+++ b/vendor/github.com/charmbracelet/lipgloss/whitespace.go
@@ -0,0 +1,83 @@
+package lipgloss
+
+import (
+ "strings"
+
+ "github.com/charmbracelet/x/exp/term/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/exp/term/LICENSE b/vendor/github.com/charmbracelet/x/exp/term/LICENSE
new file mode 100644
index 000000000..65a5654e2
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/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/exp/term/ansi/ansi.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/ansi.go
new file mode 100644
index 000000000..48d873c3f
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/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/exp/term/ansi/ascii.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/ascii.go
new file mode 100644
index 000000000..188582f7e
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/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/exp/term/ansi/background.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/background.go
new file mode 100644
index 000000000..f519af08f
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/ansi/background.go
@@ -0,0 +1,61 @@
+package ansi
+
+import (
+ "image/color"
+)
+
+// 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 {
+ return "\x1b]10;" + colorToHexString(c) + "\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"
+
+// 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 {
+ return "\x1b]11;" + colorToHexString(c) + "\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"
+
+// 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 {
+ return "\x1b]12;" + colorToHexString(c) + "\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"
diff --git a/vendor/github.com/charmbracelet/x/exp/term/ansi/c0.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/c0.go
new file mode 100644
index 000000000..13e3c6c31
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/ansi/c0.go
@@ -0,0 +1,72 @@
+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
+)
diff --git a/vendor/github.com/charmbracelet/x/exp/term/ansi/c1.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/c1.go
new file mode 100644
index 000000000..71058f539
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/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/exp/term/ansi/clipboard.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/clipboard.go
new file mode 100644
index 000000000..94d26c366
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/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/exp/term/ansi/color.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/color.go
new file mode 100644
index 000000000..11419768a
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/ansi/color.go
@@ -0,0 +1,191 @@
+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, 0xff
+ }
+
+ r, g, b := ansiToRGB(ansi)
+ r |= r << 8
+ g |= g << 8
+ b |= b << 8
+ return r, g, b, 0xff00
+}
+
+// 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))
+ r |= r << 8
+ g |= g << 8
+ b |= b << 8
+ return r, g, b, 0xff00
+}
+
+// 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))
+ r |= r << 8
+ g |= g << 8
+ b |= b << 8
+ return r, g, b, 0xff00
+}
+
+// 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, hex >> 8 & 0xff, hex & 0xff
+}
diff --git a/vendor/github.com/charmbracelet/x/exp/term/ansi/csi.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/csi.go
new file mode 100644
index 000000000..9879f0c27
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/ansi/csi.go
@@ -0,0 +1,141 @@
+package ansi
+
+import (
+ "bytes"
+ "strconv"
+
+ "github.com/charmbracelet/x/exp/term/ansi/parser"
+)
+
+// CsiSequence represents a control sequence introducer (CSI) sequence.
+//
+// The sequence starts with a CSI sequence, CSI (0x9B) in a 8-bit environment
+// or ESC [ (0x1B 0x5B) in a 7-bit environment, followed by any number of
+// parameters in the range of 0x30-0x3F, then by any number of intermediate
+// byte in the range of 0x20-0x2F, then finally with a single final byte in the
+// range of 0x20-0x7E.
+//
+// CSI P..P I..I F
+//
+// See ECMA-48 § 5.4.
+type CsiSequence struct {
+ // Params contains the raw parameters of the sequence.
+ // This is a slice of integers, where each integer is a 32-bit integer
+ // containing the parameter value in the lower 31 bits and a flag in the
+ // most significant bit indicating whether there are more sub-parameters.
+ Params []int
+
+ // Cmd contains the raw command of the sequence.
+ // The command is a 32-bit integer containing the CSI command byte in the
+ // lower 8 bits, the private marker in the next 8 bits, and the intermediate
+ // byte in the next 8 bits.
+ //
+ // CSI ? u
+ //
+ // Is represented as:
+ //
+ // 'u' | '?' << 8
+ Cmd int
+}
+
+var _ Sequence = CsiSequence{}
+
+// Marker returns the marker 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 marker.
+func (s CsiSequence) Marker() int {
+ return parser.Marker(s.Cmd)
+}
+
+// Intermediate returns the 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 (s CsiSequence) Intermediate() int {
+ return parser.Intermediate(s.Cmd)
+}
+
+// Command returns the command byte of the CSI sequence.
+func (s CsiSequence) Command() int {
+ return parser.Command(s.Cmd)
+}
+
+// Param returns the parameter at the given index.
+// It returns -1 if the parameter does not exist.
+func (s CsiSequence) Param(i int) int {
+ return parser.Param(s.Params, i)
+}
+
+// HasMore returns true if the parameter has more sub-parameters.
+func (s CsiSequence) HasMore(i int) bool {
+ return parser.HasMore(s.Params, i)
+}
+
+// Subparams returns the sub-parameters of the given parameter.
+// It returns nil if the parameter does not exist.
+func (s CsiSequence) Subparams(i int) []int {
+ return parser.Subparams(s.Params, i)
+}
+
+// Len returns the number of parameters in the sequence.
+// This will return the number of parameters in the sequence, excluding any
+// sub-parameters.
+func (s CsiSequence) Len() int {
+ return parser.Len(s.Params)
+}
+
+// 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 (s CsiSequence) Range(fn func(i int, param int, hasMore bool) bool) {
+ parser.Range(s.Params, fn)
+}
+
+// Clone returns a copy of the CSI sequence.
+func (s CsiSequence) Clone() Sequence {
+ return CsiSequence{
+ Params: append([]int(nil), s.Params...),
+ Cmd: s.Cmd,
+ }
+}
+
+// String returns a string representation of the sequence.
+// The string will always be in the 7-bit format i.e (ESC [ P..P I..I F).
+func (s CsiSequence) String() string {
+ return s.buffer().String()
+}
+
+// buffer returns a buffer containing the sequence.
+func (s CsiSequence) buffer() *bytes.Buffer {
+ var b bytes.Buffer
+ b.WriteString("\x1b[")
+ if m := s.Marker(); m != 0 {
+ b.WriteByte(byte(m))
+ }
+ s.Range(func(i, param int, hasMore bool) bool {
+ if param >= 0 {
+ b.WriteString(strconv.Itoa(param))
+ }
+ if i < len(s.Params)-1 {
+ if hasMore {
+ b.WriteByte(':')
+ } else {
+ b.WriteByte(';')
+ }
+ }
+ return true
+ })
+ if i := s.Intermediate(); i != 0 {
+ b.WriteByte(byte(i))
+ }
+ b.WriteByte(byte(s.Command()))
+ return &b
+}
+
+// Bytes returns the byte representation of the sequence.
+// The bytes will always be in the 7-bit format i.e (ESC [ P..P I..I F).
+func (s CsiSequence) Bytes() []byte {
+ return s.buffer().Bytes()
+}
diff --git a/vendor/github.com/charmbracelet/x/exp/term/ansi/ctrl.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/ctrl.go
new file mode 100644
index 000000000..21beb9cd1
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/ansi/ctrl.go
@@ -0,0 +1,17 @@
+package ansi
+
+// 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
+const RequestXTVersion = "\x1b[>0q"
+
+// 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"
diff --git a/vendor/github.com/charmbracelet/x/exp/term/ansi/cursor.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/cursor.go
new file mode 100644
index 000000000..5f010fd4c
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/ansi/cursor.go
@@ -0,0 +1,190 @@
+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"
+
+// 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"
+
+// RequestCursorPosition (CPR) 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 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
+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"
+}
+
+// CursorUp1 is a sequence for moving the cursor up one cell.
+//
+// This is equivalent to CursorUp(1).
+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"
+}
+
+// CursorDown1 is a sequence for moving the cursor down one cell.
+//
+// This is equivalent to CursorDown(1).
+const CursorDown1 = "\x1b[B"
+
+// CursorRight (CUF) returns a sequence for moving the cursor right n cells.
+//
+// CSI n C
+//
+// See: https://vt100.net/docs/vt510-rm/CUF.html
+func CursorRight(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "C"
+}
+
+// CursorRight1 is a sequence for moving the cursor right one cell.
+//
+// This is equivalent to CursorRight(1).
+const CursorRight1 = "\x1b[C"
+
+// CursorLeft (CUB) returns a sequence for moving the cursor left n cells.
+//
+// CSI n D
+//
+// See: https://vt100.net/docs/vt510-rm/CUB.html
+func CursorLeft(n int) string {
+ var s string
+ if n > 1 {
+ s = strconv.Itoa(n)
+ }
+ return "\x1b[" + s + "D"
+}
+
+// CursorLeft1 is a sequence for moving the cursor left one cell.
+//
+// This is equivalent to CursorLeft(1).
+const CursorLeft1 = "\x1b[D"
+
+// 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"
+}
+
+// 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"
+}
+
+// MoveCursor (CUP) returns a sequence for moving the cursor to the given row
+// and column.
+//
+// CSI n ; m H
+//
+// See: https://vt100.net/docs/vt510-rm/CUP.html
+func MoveCursor(row, col int) string {
+ if row < 0 {
+ row = 0
+ }
+ if col < 0 {
+ col = 0
+ }
+ return "\x1b[" + strconv.Itoa(row) + ";" + strconv.Itoa(col) + "H"
+}
+
+// MoveCursorOrigin is a sequence for moving the cursor to the upper left
+// corner of the screen. This is equivalent to MoveCursor(1, 1).
+const MoveCursorOrigin = "\x1b[1;1H"
+
+// 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
+const SaveCursorPosition = "\x1b[s"
+
+// 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
+const RestoreCursorPosition = "\x1b[u"
diff --git a/vendor/github.com/charmbracelet/x/exp/term/ansi/dcs.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/dcs.go
new file mode 100644
index 000000000..896dfb11e
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/ansi/dcs.go
@@ -0,0 +1,148 @@
+package ansi
+
+import (
+ "bytes"
+ "strconv"
+
+ "github.com/charmbracelet/x/exp/term/ansi/parser"
+)
+
+// DcsSequence represents a Device Control String (DCS) escape sequence.
+//
+// The DCS sequence is used to send device control strings to the terminal. The
+// sequence starts with the C1 control code character DCS (0x9B) or ESC P in
+// 7-bit environments, followed by parameter bytes, intermediate bytes, a
+// command byte, followed by data bytes, and ends with the C1 control code
+// character ST (0x9C) or ESC \ in 7-bit environments.
+//
+// This follows the parameter string format.
+// See ECMA-48 § 5.4.1
+type DcsSequence struct {
+ // Params contains the raw parameters of the sequence.
+ // This is a slice of integers, where each integer is a 32-bit integer
+ // containing the parameter value in the lower 31 bits and a flag in the
+ // most significant bit indicating whether there are more sub-parameters.
+ Params []int
+
+ // Data contains the string raw data of the sequence.
+ // This is the data between the final byte and the escape sequence terminator.
+ Data []byte
+
+ // Cmd contains the raw command of the sequence.
+ // The command is a 32-bit integer containing the DCS command byte in the
+ // lower 8 bits, the private marker in the next 8 bits, and the intermediate
+ // byte in the next 8 bits.
+ //
+ // DCS > 0 ; 1 $ r ST
+ //
+ // Is represented as:
+ //
+ // 'r' | '>' << 8 | '$' << 16
+ Cmd int
+}
+
+var _ Sequence = DcsSequence{}
+
+// Marker returns the marker byte of the DCS 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 marker.
+func (s DcsSequence) Marker() int {
+ return parser.Marker(s.Cmd)
+}
+
+// Intermediate returns the intermediate byte of the DCS 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 (s DcsSequence) Intermediate() int {
+ return parser.Intermediate(s.Cmd)
+}
+
+// Command returns the command byte of the CSI sequence.
+func (s DcsSequence) Command() int {
+ return parser.Command(s.Cmd)
+}
+
+// Param returns the parameter at the given index.
+// It returns -1 if the parameter does not exist.
+func (s DcsSequence) Param(i int) int {
+ return parser.Param(s.Params, i)
+}
+
+// HasMore returns true if the parameter has more sub-parameters.
+func (s DcsSequence) HasMore(i int) bool {
+ return parser.HasMore(s.Params, i)
+}
+
+// Subparams returns the sub-parameters of the given parameter.
+// It returns nil if the parameter does not exist.
+func (s DcsSequence) Subparams(i int) []int {
+ return parser.Subparams(s.Params, i)
+}
+
+// Len returns the number of parameters in the sequence.
+// This will return the number of parameters in the sequence, excluding any
+// sub-parameters.
+func (s DcsSequence) Len() int {
+ return parser.Len(s.Params)
+}
+
+// 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 (s DcsSequence) Range(fn func(i int, param int, hasMore bool) bool) {
+ parser.Range(s.Params, fn)
+}
+
+// Clone returns a copy of the DCS sequence.
+func (s DcsSequence) Clone() Sequence {
+ return DcsSequence{
+ Params: append([]int(nil), s.Params...),
+ Data: append([]byte(nil), s.Data...),
+ Cmd: s.Cmd,
+ }
+}
+
+// String returns a string representation of the sequence.
+// The string will always be in the 7-bit format i.e (ESC P p..p i..i f ESC \).
+func (s DcsSequence) String() string {
+ return s.buffer().String()
+}
+
+// buffer returns a buffer containing the sequence.
+func (s DcsSequence) buffer() *bytes.Buffer {
+ var b bytes.Buffer
+ b.WriteString("\x1bP")
+ if m := s.Marker(); m != 0 {
+ b.WriteByte(byte(m))
+ }
+ s.Range(func(i, param int, hasMore bool) bool {
+ if param >= -1 {
+ b.WriteString(strconv.Itoa(param))
+ }
+ if i < len(s.Params)-1 {
+ if hasMore {
+ b.WriteByte(':')
+ } else {
+ b.WriteByte(';')
+ }
+ }
+ return true
+ })
+ if i := s.Intermediate(); i != 0 {
+ b.WriteByte(byte(i))
+ }
+ b.WriteByte(byte(s.Command()))
+ b.Write(s.Data)
+ b.WriteByte(ESC)
+ b.WriteByte('\\')
+ return &b
+}
+
+// Bytes returns the byte representation of the sequence.
+// The bytes will always be in the 7-bit format i.e (ESC P p..p i..i F ESC \).
+func (s DcsSequence) Bytes() []byte {
+ return s.buffer().Bytes()
+}
diff --git a/vendor/github.com/charmbracelet/x/exp/term/ansi/doc.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/doc.go
new file mode 100644
index 000000000..e955e9f1b
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/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/exp/term/ansi/hyperlink.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/hyperlink.go
new file mode 100644
index 000000000..323bfe932
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/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/exp/term/ansi/kitty.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/kitty.go
new file mode 100644
index 000000000..5bf89814a
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/ansi/kitty.go
@@ -0,0 +1,58 @@
+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
+ KittyReportAllKeys
+ KittyReportAssociatedKeys
+
+ KittyAllFlags = KittyDisambiguateEscapeCodes | KittyReportEventTypes |
+ KittyReportAlternateKeys | KittyReportAllKeys | 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"
+
+// PushKittyKeyboard returns a sequence to push the given flags to the terminal
+// Kitty Keyboard stack.
+//
+// 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[>0u"
+
+// 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/exp/term/ansi/mode.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/mode.go
new file mode 100644
index 000000000..4c39e78d3
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/ansi/mode.go
@@ -0,0 +1,132 @@
+package ansi
+
+// This file define uses multiple sequences to set (SM), reset (RM), and request
+// (DECRQM) different ANSI and DEC modes.
+//
+// See: https://vt100.net/docs/vt510-rm/SM.html
+// See: https://vt100.net/docs/vt510-rm/RM.html
+// See: https://vt100.net/docs/vt510-rm/DECRQM.html
+//
+// The terminal then responds to the request with a Report Mode function
+// (DECRPM) in the format:
+//
+// ANSI format:
+//
+// CSI Pa ; Ps ; $ y
+//
+// DEC format:
+//
+// CSI ? Pa ; Ps $ y
+//
+// Where Pa is the mode number, and Ps is the mode value.
+// See: https://vt100.net/docs/vt510-rm/DECRPM.html
+
+// Application Cursor Keys (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 (
+ EnableCursorKeys = "\x1b[?1h"
+ DisableCursorKeys = "\x1b[?1l"
+ RequestCursorKeys = "\x1b[?1$p"
+)
+
+// Text Cursor Enable Mode (DECTCEM) is a mode that shows/hides the cursor.
+//
+// See: https://vt100.net/docs/vt510-rm/DECTCEM.html
+const (
+ ShowCursor = "\x1b[?25h"
+ HideCursor = "\x1b[?25l"
+ RequestCursorVisibility = "\x1b[?25$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
+const (
+ EnableMouse = "\x1b[?1000h"
+ DisableMouse = "\x1b[?1000l"
+ RequestMouse = "\x1b[?1000$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
+const (
+ EnableMouseHilite = "\x1b[?1001h"
+ DisableMouseHilite = "\x1b[?1001l"
+ RequestMouseHilite = "\x1b[?1001$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
+const (
+ EnableMouseCellMotion = "\x1b[?1002h"
+ DisableMouseCellMotion = "\x1b[?1002l"
+ RequestMouseCellMotion = "\x1b[?1002$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
+const (
+ EnableMouseAllMotion = "\x1b[?1003h"
+ DisableMouseAllMotion = "\x1b[?1003l"
+ RequestMouseAllMotion = "\x1b[?1003$p"
+)
+
+// SGR Mouse Extension is a mode that determines whether the mouse reports events
+// formatted with SGR parameters.
+//
+// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-Mouse-Tracking
+const (
+ EnableMouseSgrExt = "\x1b[?1006h"
+ DisableMouseSgrExt = "\x1b[?1006l"
+ RequestMouseSgrExt = "\x1b[?1006$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
+const (
+ 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 (
+ 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 (
+ EnableSyncdOutput = "\x1b[?2026h"
+ DisableSyncdOutput = "\x1b[?2026l"
+ RequestSyncdOutput = "\x1b[?2026$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 (
+ EnableWin32Input = "\x1b[?9001h"
+ DisableWin32Input = "\x1b[?9001l"
+ RequestWin32Input = "\x1b[?9001$p"
+)
diff --git a/vendor/github.com/charmbracelet/x/exp/term/ansi/osc.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/osc.go
new file mode 100644
index 000000000..40b543c29
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/ansi/osc.go
@@ -0,0 +1,69 @@
+package ansi
+
+import (
+ "bytes"
+ "strings"
+)
+
+// OscSequence represents an OSC sequence.
+//
+// The sequence starts with a OSC sequence, OSC (0x9D) in a 8-bit environment
+// or ESC ] (0x1B 0x5D) in a 7-bit environment, followed by positive integer identifier,
+// then by arbitrary data terminated by a ST (0x9C) in a 8-bit environment,
+// ESC \ (0x1B 0x5C) in a 7-bit environment, or BEL (0x07) for backwards compatibility.
+//
+// OSC Ps ; Pt ST
+// OSC Ps ; Pt BEL
+//
+// See ECMA-48 § 5.7.
+type OscSequence struct {
+ // Data contains the raw data of the sequence including the identifier
+ // command.
+ Data []byte
+
+ // Cmd contains the raw command of the sequence.
+ Cmd int
+}
+
+var _ Sequence = OscSequence{}
+
+// Command returns the command of the OSC sequence.
+func (s OscSequence) Command() int {
+ return s.Cmd
+}
+
+// Params returns the parameters of the OSC sequence split by ';'.
+// The first element is the identifier command.
+func (s OscSequence) Params() []string {
+ return strings.Split(string(s.Data), ";")
+}
+
+// Clone returns a copy of the OSC sequence.
+func (s OscSequence) Clone() Sequence {
+ return OscSequence{
+ Data: append([]byte(nil), s.Data...),
+ Cmd: s.Cmd,
+ }
+}
+
+// String returns the string representation of the OSC sequence.
+// To be more compatible with different terminal, this will always return a
+// 7-bit formatted sequence, terminated by BEL.
+func (s OscSequence) String() string {
+ return s.buffer().String()
+}
+
+// Bytes returns the byte representation of the OSC sequence.
+// To be more compatible with different terminal, this will always return a
+// 7-bit formatted sequence, terminated by BEL.
+func (s OscSequence) Bytes() []byte {
+ return s.buffer().Bytes()
+}
+
+func (s OscSequence) buffer() *bytes.Buffer {
+ var b bytes.Buffer
+ b.WriteString("\x1b]")
+ b.Write(s.Data)
+ b.WriteByte(BEL)
+ return &b
+}
diff --git a/vendor/github.com/charmbracelet/x/exp/term/ansi/params.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/params.go
new file mode 100644
index 000000000..a1bb42498
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/ansi/params.go
@@ -0,0 +1,45 @@
+package ansi
+
+import (
+ "bytes"
+)
+
+// Params parses and returns a list of control sequence parameters.
+//
+// Parameters are positive integers separated by semicolons. Empty parameters
+// default to zero. Parameters can have sub-parameters separated by colons.
+//
+// Any non-parameter bytes are ignored. This includes bytes that are not in the
+// range of 0x30-0x3B.
+//
+// See ECMA-48 § 5.4.1.
+func Params(p []byte) [][]uint {
+ if len(p) == 0 {
+ return [][]uint{}
+ }
+
+ // Filter out non-parameter bytes i.e. non 0x30-0x3B.
+ p = bytes.TrimFunc(p, func(r rune) bool {
+ return r < 0x30 || r > 0x3B
+ })
+
+ parts := bytes.Split(p, []byte{';'})
+ params := make([][]uint, len(parts))
+ for i, part := range parts {
+ sparts := bytes.Split(part, []byte{':'})
+ params[i] = make([]uint, len(sparts))
+ for j, spart := range sparts {
+ params[i][j] = bytesToUint16(spart)
+ }
+ }
+
+ return params
+}
+
+func bytesToUint16(b []byte) uint {
+ var n uint
+ for _, c := range b {
+ n = n*10 + uint(c-'0')
+ }
+ return n
+}
diff --git a/vendor/github.com/charmbracelet/x/exp/term/ansi/parser.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/parser.go
new file mode 100644
index 000000000..f40278ee8
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/ansi/parser.go
@@ -0,0 +1,357 @@
+package ansi
+
+import (
+ "unicode/utf8"
+
+ "github.com/charmbracelet/x/exp/term/ansi/parser"
+)
+
+// ParserDispatcher is a function that dispatches a sequence.
+type ParserDispatcher func(Sequence)
+
+// 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 {
+ // 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.
+ ParamsLen int
+
+ // Cmd contains the raw command along with the private marker and
+ // intermediate bytes of the sequence.
+ // The first lower byte contains the command byte, the next byte contains
+ // the private marker, and the next byte contains the intermediate byte.
+ Cmd int
+
+ // RuneLen keeps track of the number of bytes collected for a UTF-8 rune.
+ RuneLen int
+
+ // RuneBuf contains the bytes collected for a UTF-8 rune.
+ RuneBuf [utf8.MaxRune]byte
+
+ // State is the current state of the parser.
+ State byte
+}
+
+// NewParser returns a new parser with the given sizes allocated.
+// If dataSize is zero, the underlying data buffer will be unlimited and will
+// grow as needed.
+func NewParser(paramsSize, dataSize int) *Parser {
+ s := &Parser{
+ Params: make([]int, paramsSize),
+ Data: make([]byte, dataSize),
+ }
+ if dataSize <= 0 {
+ s.DataLen = -1
+ }
+ return s
+}
+
+// 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
+ p.RuneLen = 0
+}
+
+// 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.
+func (p *Parser) Parse(dispatcher ParserDispatcher, b []byte) {
+ for i := 0; i < len(b); i++ {
+ p.Advance(dispatcher, b[i], i < len(b)-1)
+ }
+}
+
+// Advance advances the parser with the given dispatcher and byte.
+func (p *Parser) Advance(dispatcher ParserDispatcher, b byte, more bool) parser.Action {
+ switch p.State {
+ case parser.Utf8State:
+ // We handle UTF-8 here.
+ return p.advanceUtf8(dispatcher, b)
+ default:
+ return p.advance(dispatcher, b, more)
+ }
+}
+
+func (p *Parser) collectRune(b byte) {
+ if p.RuneLen < utf8.UTFMax {
+ p.RuneBuf[p.RuneLen] = b
+ p.RuneLen++
+ }
+}
+
+func (p *Parser) advanceUtf8(dispatcher ParserDispatcher, b byte) parser.Action {
+ // Collect UTF-8 rune bytes.
+ p.collectRune(b)
+ rw := utf8ByteLen(p.RuneBuf[0])
+ 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.RuneLen < rw {
+ return parser.NoneAction
+ }
+
+ // We have enough bytes to decode the rune
+ bts := p.RuneBuf[:rw]
+ r, _ := utf8.DecodeRune(bts)
+ if dispatcher != nil {
+ dispatcher(Rune(r))
+ }
+
+ p.State = parser.GroundState
+ p.RuneLen = 0
+
+ return parser.NoneAction
+}
+
+func (p *Parser) advance(d ParserDispatcher, b byte, more bool) 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 {
+ switch p.State {
+ case parser.EscapeState:
+ p.performAction(d, parser.ClearAction, 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(d, parser.StartAction, 0)
+ }
+ }
+
+ // Handle special cases
+ switch {
+ case b == ESC && p.State == parser.EscapeState:
+ // Two ESCs in a row
+ p.performAction(d, parser.ExecuteAction, b)
+ if !more {
+ // Two ESCs at the end of the buffer
+ p.performAction(d, parser.ExecuteAction, b)
+ }
+ case b == ESC && !more:
+ // Last byte is an ESC
+ p.performAction(d, parser.ExecuteAction, b)
+ case p.State == parser.EscapeState && b == 'P' && !more:
+ // ESC P (DCS) at the end of the buffer
+ p.performAction(d, parser.DispatchAction, b)
+ case p.State == parser.EscapeState && b == 'X' && !more:
+ // ESC X (SOS) at the end of the buffer
+ p.performAction(d, parser.DispatchAction, b)
+ case p.State == parser.EscapeState && b == '[' && !more:
+ // ESC [ (CSI) at the end of the buffer
+ p.performAction(d, parser.DispatchAction, b)
+ case p.State == parser.EscapeState && b == ']' && !more:
+ // ESC ] (OSC) at the end of the buffer
+ p.performAction(d, parser.DispatchAction, b)
+ case p.State == parser.EscapeState && b == '^' && !more:
+ // ESC ^ (PM) at the end of the buffer
+ p.performAction(d, parser.DispatchAction, b)
+ case p.State == parser.EscapeState && b == '_' && !more:
+ // ESC _ (APC) at the end of the buffer
+ p.performAction(d, parser.DispatchAction, b)
+ default:
+ p.performAction(d, action, b)
+ }
+
+ p.State = state
+
+ return action
+}
+
+func (p *Parser) performAction(dispatcher ParserDispatcher, action parser.Action, b byte) {
+ switch action {
+ case parser.IgnoreAction:
+ break
+
+ case parser.ClearAction:
+ p.clear()
+
+ case parser.PrintAction:
+ if utf8ByteLen(b) > 1 {
+ p.collectRune(b)
+ } else if dispatcher != nil {
+ dispatcher(Rune(b))
+ }
+
+ case parser.ExecuteAction:
+ if dispatcher != nil {
+ dispatcher(ControlCode(b))
+ }
+
+ case parser.MarkerAction:
+ // Collect private marker
+ // we only store the last marker
+ p.Cmd &^= 0xff << parser.MarkerShift
+ p.Cmd |= int(b) << parser.MarkerShift
+
+ case parser.CollectAction:
+ // 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 = make([]byte, 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 {
+ // 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')
+ }
+ }
+ }
+
+ 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 dispatcher == nil {
+ break
+ }
+
+ var seq Sequence
+ 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)
+ seq = CsiSequence{Cmd: p.Cmd, Params: p.Params[:p.ParamsLen]}
+ case parser.EscapeState, parser.EscapeIntermediateState:
+ p.Cmd |= int(b)
+ seq = EscSequence(p.Cmd)
+ case parser.DcsEntryState, parser.DcsParamState, parser.DcsIntermediateState, parser.DcsStringState:
+ seq = DcsSequence{Cmd: p.Cmd, Params: p.Params[:p.ParamsLen], Data: data}
+ case parser.OscStringState:
+ seq = OscSequence{Cmd: p.Cmd, Data: data}
+ case parser.SosStringState:
+ seq = SosSequence{Data: data}
+ case parser.PmStringState:
+ seq = PmSequence{Data: data}
+ case parser.ApcStringState:
+ seq = ApcSequence{Data: data}
+ }
+
+ dispatcher(seq)
+ }
+}
+
+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/exp/term/ansi/parser/const.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/parser/const.go
new file mode 100644
index 000000000..54b7383b4
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/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
+ MarkerAction
+ 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",
+ "MarkerAction",
+ "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/exp/term/ansi/parser/seq.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/parser/seq.go
new file mode 100644
index 000000000..c99f1632f
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/ansi/parser/seq.go
@@ -0,0 +1,136 @@
+package parser
+
+import "math"
+
+// Shift and masks for sequence parameters and intermediates.
+const (
+ MarkerShift = 8
+ IntermedShift = 16
+ CommandMask = 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
+)
+
+// Marker returns the marker 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 marker.
+func Marker(cmd int) int {
+ return (cmd >> MarkerShift) & CommandMask
+}
+
+// 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) & CommandMask
+}
+
+// Command returns the command byte of the CSI sequence.
+func Command(cmd int) int {
+ return cmd & CommandMask
+}
+
+// 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/exp/term/ansi/parser/transition_table.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/parser/transition_table.go
new file mode 100644
index 000000000..febde15dd
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/ansi/parser/transition_table.go
@@ -0,0 +1,269 @@
+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.
+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, IgnoreAction, 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, PrintAction, Utf8State) // UTF8 2 byte sequence
+ table.AddRange(0xE0, 0xEF, state, PrintAction, Utf8State) // UTF8 3 byte sequence
+ table.AddRange(0xF0, 0xF4, state, PrintAction, 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, 0x7F, GroundState, PrintAction, 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, MarkerAction, 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, IgnoreAction, 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, MarkerAction, 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/exp/term/ansi/passthrough.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/passthrough.go
new file mode 100644
index 000000000..14a745220
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/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/exp/term/ansi/screen.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/screen.go
new file mode 100644
index 000000000..4909cf07c
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/ansi/screen.go
@@ -0,0 +1,126 @@
+package ansi
+
+import "strconv"
+
+// EraseDisplay (ED) clears the screen or parts of the screen. Possible values:
+//
+// 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 screen and delete all lines saved in the scrollback buffer.
+//
+// CSI J
+//
+// See: https://vt100.net/docs/vt510-rm/ED.html
+func EraseDisplay(n int) string {
+ if n < 0 {
+ n = 0
+ }
+ return "\x1b[" + strconv.Itoa(n) + "J"
+}
+
+// EraseDisplay constants.
+// These are the possible values for the EraseDisplay function.
+const (
+ EraseDisplayRight = "\x1b[0J"
+ EraseDisplayLeft = "\x1b[1J"
+ EraseEntireDisplay = "\x1b[2J"
+)
+
+// 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 {
+ if n < 0 {
+ n = 0
+ }
+ return "\x1b[" + strconv.Itoa(n) + "K"
+}
+
+// EraseLine constants.
+// These are the possible values for the EraseLine function.
+const (
+ EraseLineRight = "\x1b[0K"
+ 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 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"
+}
+
+// ScrollDown (SD) scrolls the screen down n lines. New lines are added at the
+// top of the screen.
+//
+// CSI 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"
+}
+
+// InsertLine (IL) inserts n blank lines at the current cursor position.
+// Existing lines are moved down.
+//
+// CSI 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"
+}
+
+// DeleteLine (DL) deletes n lines at the current cursor position. Existing
+// lines are moved up.
+//
+// CSI 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"
+}
+
+// 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
+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"
+}
diff --git a/vendor/github.com/charmbracelet/x/exp/term/ansi/sequence.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/sequence.go
new file mode 100644
index 000000000..86bbc3564
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/ansi/sequence.go
@@ -0,0 +1,199 @@
+package ansi
+
+import (
+ "bytes"
+
+ "github.com/charmbracelet/x/exp/term/ansi/parser"
+)
+
+// Sequence represents an ANSI sequence. This can be a control sequence, escape
+// sequence, a printable character, etc.
+type Sequence interface {
+ // String returns the string representation of the sequence.
+ String() string
+ // Bytes returns the byte representation of the sequence.
+ Bytes() []byte
+ // Clone returns a copy of the sequence.
+ Clone() Sequence
+}
+
+// Rune represents a printable character.
+type Rune rune
+
+var _ Sequence = Rune(0)
+
+// Bytes implements Sequence.
+func (r Rune) Bytes() []byte {
+ return []byte(string(r))
+}
+
+// String implements Sequence.
+func (r Rune) String() string {
+ return string(r)
+}
+
+// Clone implements Sequence.
+func (r Rune) Clone() Sequence {
+ return r
+}
+
+// ControlCode represents a control code character. This is a character that
+// is not printable and is used to control the terminal. This would be a
+// character in the C0 or C1 set in the range of 0x00-0x1F and 0x80-0x9F.
+type ControlCode byte
+
+var _ Sequence = ControlCode(0)
+
+// Bytes implements Sequence.
+func (c ControlCode) Bytes() []byte {
+ return []byte{byte(c)}
+}
+
+// String implements Sequence.
+func (c ControlCode) String() string {
+ return string(c)
+}
+
+// Clone implements Sequence.
+func (c ControlCode) Clone() Sequence {
+ return c
+}
+
+// EscSequence represents an escape sequence.
+type EscSequence int
+
+var _ Sequence = EscSequence(0)
+
+// buffer returns the buffer of the escape sequence.
+func (e EscSequence) buffer() *bytes.Buffer {
+ var b bytes.Buffer
+ b.WriteByte('\x1b')
+ if i := parser.Intermediate(int(e)); i != 0 {
+ b.WriteByte(byte(i))
+ }
+ b.WriteByte(byte(e.Command()))
+ return &b
+}
+
+// Bytes implements Sequence.
+func (e EscSequence) Bytes() []byte {
+ return e.buffer().Bytes()
+}
+
+// String implements Sequence.
+func (e EscSequence) String() string {
+ return e.buffer().String()
+}
+
+// Clone implements Sequence.
+func (e EscSequence) Clone() Sequence {
+ return e
+}
+
+// Command returns the command byte of the escape sequence.
+func (e EscSequence) Command() int {
+ return parser.Command(int(e))
+}
+
+// Intermediate returns the intermediate byte of the escape sequence.
+func (e EscSequence) Intermediate() int {
+ return parser.Intermediate(int(e))
+}
+
+// SosSequence represents a SOS sequence.
+type SosSequence struct {
+ // Data contains the raw data of the sequence.
+ Data []byte
+}
+
+var _ Sequence = &SosSequence{}
+
+// Clone implements Sequence.
+func (s SosSequence) Clone() Sequence {
+ return SosSequence{Data: append([]byte(nil), s.Data...)}
+}
+
+// Bytes implements Sequence.
+func (s SosSequence) Bytes() []byte {
+ return s.buffer().Bytes()
+}
+
+// String implements Sequence.
+func (s SosSequence) String() string {
+ return s.buffer().String()
+}
+
+func (s SosSequence) buffer() *bytes.Buffer {
+ var b bytes.Buffer
+ b.WriteByte('\x1b')
+ b.WriteByte('X')
+ b.Write(s.Data)
+ b.WriteString("\x1b\\")
+ return &b
+}
+
+// PmSequence represents a PM sequence.
+type PmSequence struct {
+ // Data contains the raw data of the sequence.
+ Data []byte
+}
+
+var _ Sequence = &PmSequence{}
+
+// Clone implements Sequence.
+func (s PmSequence) Clone() Sequence {
+ return PmSequence{Data: append([]byte(nil), s.Data...)}
+}
+
+// Bytes implements Sequence.
+func (s PmSequence) Bytes() []byte {
+ return s.buffer().Bytes()
+}
+
+// String implements Sequence.
+func (s PmSequence) String() string {
+ return s.buffer().String()
+}
+
+// buffer returns the buffer of the PM sequence.
+func (s PmSequence) buffer() *bytes.Buffer {
+ var b bytes.Buffer
+ b.WriteByte('\x1b')
+ b.WriteByte('^')
+ b.Write(s.Data)
+ b.WriteString("\x1b\\")
+ return &b
+}
+
+// ApcSequence represents an APC sequence.
+type ApcSequence struct {
+ // Data contains the raw data of the sequence.
+ Data []byte
+}
+
+var _ Sequence = &ApcSequence{}
+
+// Clone implements Sequence.
+func (s ApcSequence) Clone() Sequence {
+ return ApcSequence{Data: append([]byte(nil), s.Data...)}
+}
+
+// Bytes implements Sequence.
+func (s ApcSequence) Bytes() []byte {
+ return s.buffer().Bytes()
+}
+
+// String implements Sequence.
+func (s ApcSequence) String() string {
+ return s.buffer().String()
+}
+
+// buffer returns the buffer of the APC sequence.
+func (s ApcSequence) buffer() *bytes.Buffer {
+ var b bytes.Buffer
+ b.WriteByte('\x1b')
+ b.WriteByte('_')
+ b.Write(s.Data)
+ b.WriteString("\x1b\\")
+ return &b
+}
diff --git a/vendor/github.com/charmbracelet/x/exp/term/ansi/style.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/style.go
new file mode 100644
index 000000000..33421850d
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/ansi/style.go
@@ -0,0 +1,290 @@
+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 = string
+
+// Style represents an ANSI SGR (Select Graphic Rendition) style.
+type Style []Attr
+
+// 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)
+}
+
+// DoubleUnderline appends the double underline style attribute to the style.
+func (s Style) DoubleUnderline() Style {
+ return append(s, DoubleUnderlineAttr)
+}
+
+// CurlyUnderline appends the curly underline style attribute to the style.
+func (s Style) CurlyUnderline() Style {
+ return append(s, CurlyUnderlineAttr)
+}
+
+// DottedUnderline appends the dotted underline style attribute to the style.
+func (s Style) DottedUnderline() Style {
+ return append(s, DottedUnderlineAttr)
+}
+
+// DashedUnderline appends the dashed underline style attribute to the style.
+func (s Style) DashedUnderline() Style {
+ return append(s, DashedUnderlineAttr)
+}
+
+// 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)
+}
+
+// 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, ForegroundColorAttr(c))
+}
+
+// BackgroundColor appends the background color style attribute to the style.
+func (s Style) BackgroundColor(c Color) Style {
+ return append(s, BackgroundColorAttr(c))
+}
+
+// UnderlineColor appends the underline color style attribute to the style.
+func (s Style) UnderlineColor(c Color) Style {
+ return append(s, UnderlineColorAttr(c))
+}
+
+// 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"
+ DoubleUnderlineAttr Attr = "4:2"
+ CurlyUnderlineAttr Attr = "4:3"
+ DottedUnderlineAttr Attr = "4:4"
+ DashedUnderlineAttr Attr = "4:5"
+ 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"
+ NoStrikethroughAttr Attr = "29"
+ DefaultForegroundColorAttr Attr = "39"
+ DefaultBackgroundColorAttr Attr = "49"
+ DefaultUnderlineColorAttr Attr = "59"
+)
+
+// ForegroundColorAttr 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 ForegroundColorAttr(c Color) Attr {
+ 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
+ if c < 8 {
+ return "3" + string('0'+c)
+ } else if c < 16 {
+ return "9" + string('0'+c-8)
+ }
+ 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
+}
+
+// BackgroundColorAttr 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 BackgroundColorAttr(c Color) Attr {
+ 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
+ if c < 8 {
+ return "4" + string('0'+c)
+ } else {
+ return "10" + string('0'+c-8)
+ }
+ 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
+}
+
+// UnderlineColorAttr 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 UnderlineColorAttr(c Color) Attr {
+ 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
+}
+
+func shift(v uint32) uint32 {
+ if v > 0xff {
+ return v >> 8
+ }
+ return v
+}
diff --git a/vendor/github.com/charmbracelet/x/exp/term/ansi/termcap.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/termcap.go
new file mode 100644
index 000000000..1dfc52a6e
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/ansi/termcap.go
@@ -0,0 +1,31 @@
+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 RequestTermcap(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\\"
+}
diff --git a/vendor/github.com/charmbracelet/x/exp/term/ansi/title.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/title.go
new file mode 100644
index 000000000..8fd8bf98d
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/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/exp/term/ansi/truncate.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/truncate.go
new file mode 100644
index 000000000..8d107c0a2
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/ansi/truncate.go
@@ -0,0 +1,108 @@
+package ansi
+
+import (
+ "bytes"
+
+ "github.com/charmbracelet/x/exp/term/ansi/parser"
+ "github.com/rivo/uniseg"
+)
+
+// 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 Asians and emojis).
+func Truncate(s string, length int, tail string) string {
+ tw := StringWidth(tail)
+ length -= tw
+ if length < 0 {
+ return ""
+ }
+
+ var cluster []byte
+ var buf bytes.Buffer
+ curWidth := 0
+ ignoring := false
+ gstate := -1
+ 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])
+
+ switch action {
+ case parser.PrintAction:
+ if utf8ByteLen(b[i]) > 1 {
+ // This action happens when we transition to the Utf8State.
+ var width int
+ cluster, _, width, gstate = uniseg.FirstGraphemeCluster(b[i:], gstate)
+
+ // 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
+ for _, r := range cluster {
+ buf.WriteByte(r)
+ }
+
+ gstate = -1 // reset grapheme state otherwise, width calculation might be off
+ // Done collecting, now we're back in the ground state.
+ pstate = parser.GroundState
+ continue
+ }
+
+ // 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()
+}
diff --git a/vendor/github.com/charmbracelet/x/exp/term/ansi/util.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/util.go
new file mode 100644
index 000000000..767093f92
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/ansi/util.go
@@ -0,0 +1,29 @@
+package ansi
+
+import (
+ "fmt"
+ "image/color"
+)
+
+// 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
+}
diff --git a/vendor/github.com/charmbracelet/x/exp/term/ansi/width.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/width.go
new file mode 100644
index 000000000..71ce3b683
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/ansi/width.go
@@ -0,0 +1,73 @@
+package ansi
+
+import (
+ "bytes"
+
+ "github.com/charmbracelet/x/exp/term/ansi/parser"
+ "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++ {
+ var state, action byte
+ if pstate != parser.Utf8State {
+ state, action = parser.Table.Transition(pstate, s[i])
+ }
+
+ switch {
+ case 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
+ case action == parser.PrintAction:
+ // This action happens when we transition to the Utf8State.
+ if w := utf8ByteLen(s[i]); w > 1 {
+ rw = w
+ buf.WriteByte(s[i])
+ ri++
+ break
+ }
+ fallthrough
+ case action == 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.
+func StringWidth(s string) int {
+ if s == "" {
+ return 0
+ }
+ return uniseg.StringWidth(Strip(s))
+}
diff --git a/vendor/github.com/charmbracelet/x/exp/term/ansi/wrap.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/wrap.go
new file mode 100644
index 000000000..5413d0c64
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/ansi/wrap.go
@@ -0,0 +1,406 @@
+package ansi
+
+import (
+ "bytes"
+ "unicode"
+ "unicode/utf8"
+
+ "github.com/charmbracelet/x/exp/term/ansi/parser"
+ "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.
+func Hardwrap(s string, limit int, preserveSpace bool) string {
+ if limit < 1 {
+ return s
+ }
+
+ var (
+ cluster []byte
+ buf bytes.Buffer
+ curWidth int
+ forceNewline bool
+ gstate = -1
+ 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])
+
+ switch action {
+ case parser.PrintAction:
+ if utf8ByteLen(b[i]) > 1 {
+ var width int
+ cluster, _, width, gstate = uniseg.FirstGraphemeCluster(b[i:], gstate)
+ 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
+ gstate = -1 // reset grapheme state otherwise, width calculation might be off
+ pstate = parser.GroundState
+ continue
+ }
+ fallthrough
+ case 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])
+ 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.
+func Wordwrap(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
+ gstate = -1
+ 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])
+
+ switch action {
+ case parser.PrintAction:
+ if utf8ByteLen(b[i]) > 1 {
+ var width int
+ cluster, _, width, gstate = uniseg.FirstGraphemeCluster(b[i:], gstate)
+ 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
+ }
+ fallthrough
+ case 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.
+func Wrap(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
+ gstate = -1
+ 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])
+
+ switch action {
+ case parser.PrintAction:
+ if utf8ByteLen(b[i]) > 1 {
+ var width int
+ cluster, _, width, gstate = uniseg.FirstGraphemeCluster(b[i:], gstate)
+ 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
+ }
+
+ fallthrough
+ case 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:
+ 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 word.Len() != 0 {
+ // Preserve ANSI wrapped spaces at the end of string
+ if curWidth+space.Len() > limit {
+ buf.WriteByte('\n')
+ }
+ addSpace()
+ }
+ buf.Write(word.Bytes())
+
+ 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/exp/term/ansi/xterm.go b/vendor/github.com/charmbracelet/x/exp/term/ansi/xterm.go
new file mode 100644
index 000000000..e2eb10a15
--- /dev/null
+++ b/vendor/github.com/charmbracelet/x/exp/term/ansi/xterm.go
@@ -0,0 +1,33 @@
+package ansi
+
+// 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
+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
+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
+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
+const RequestModifyOtherKeys = "\x1b[?4m"
diff --git a/vendor/github.com/cli/browser/LICENSE b/vendor/github.com/cli/browser/LICENSE
new file mode 100644
index 000000000..65f78fb62
--- /dev/null
+++ b/vendor/github.com/cli/browser/LICENSE
@@ -0,0 +1,23 @@
+Copyright (c) 2014, Dave Cheney
+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.
+
+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 HOLDER 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.
diff --git a/vendor/github.com/cli/browser/README.md b/vendor/github.com/cli/browser/README.md
new file mode 100644
index 000000000..8a463155f
--- /dev/null
+++ b/vendor/github.com/cli/browser/README.md
@@ -0,0 +1,20 @@
+
+# browser
+
+Helpers to open URLs, readers, or files in the system default web browser.
+
+This fork adds:
+
+- `OpenReader` error wrapping;
+- `ErrNotFound` error wrapping on BSD;
+- Go 1.21 support.
+
+## Usage
+
+``` go
+import "github.com/cli/browser"
+
+err = browser.OpenURL(url)
+err = browser.OpenFile(path)
+err = browser.OpenReader(reader)
+```
diff --git a/vendor/github.com/cli/browser/browser.go b/vendor/github.com/cli/browser/browser.go
new file mode 100644
index 000000000..a0bd87ea9
--- /dev/null
+++ b/vendor/github.com/cli/browser/browser.go
@@ -0,0 +1,57 @@
+// Package browser provides helpers to open files, readers, and urls in a browser window.
+//
+// The choice of which browser is started is entirely client dependent.
+package browser
+
+import (
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+)
+
+// Stdout is the io.Writer to which executed commands write standard output.
+var Stdout io.Writer = os.Stdout
+
+// Stderr is the io.Writer to which executed commands write standard error.
+var Stderr io.Writer = os.Stderr
+
+// OpenFile opens new browser window for the file path.
+func OpenFile(path string) error {
+ path, err := filepath.Abs(path)
+ if err != nil {
+ return err
+ }
+ return OpenURL("file://" + path)
+}
+
+// OpenReader consumes the contents of r and presents the
+// results in a new browser window.
+func OpenReader(r io.Reader) error {
+ f, err := ioutil.TempFile("", "browser.*.html")
+ if err != nil {
+ return fmt.Errorf("browser: could not create temporary file: %w", err)
+ }
+ if _, err := io.Copy(f, r); err != nil {
+ f.Close()
+ return fmt.Errorf("browser: caching temporary file failed: %w", err)
+ }
+ if err := f.Close(); err != nil {
+ return fmt.Errorf("browser: caching temporary file failed: %w", err)
+ }
+ return OpenFile(f.Name())
+}
+
+// OpenURL opens a new browser window pointing to url.
+func OpenURL(url string) error {
+ return openBrowser(url)
+}
+
+func runCmd(prog string, args ...string) error {
+ cmd := exec.Command(prog, args...)
+ cmd.Stdout = Stdout
+ cmd.Stderr = Stderr
+ return cmd.Run()
+}
diff --git a/vendor/github.com/cli/browser/browser_darwin.go b/vendor/github.com/cli/browser/browser_darwin.go
new file mode 100644
index 000000000..8507cf7c2
--- /dev/null
+++ b/vendor/github.com/cli/browser/browser_darwin.go
@@ -0,0 +1,5 @@
+package browser
+
+func openBrowser(url string) error {
+ return runCmd("open", url)
+}
diff --git a/vendor/github.com/cli/browser/browser_freebsd.go b/vendor/github.com/cli/browser/browser_freebsd.go
new file mode 100644
index 000000000..2a3c9a2e8
--- /dev/null
+++ b/vendor/github.com/cli/browser/browser_freebsd.go
@@ -0,0 +1,15 @@
+package browser
+
+import (
+ "errors"
+ "fmt"
+ "os/exec"
+)
+
+func openBrowser(url string) error {
+ err := runCmd("xdg-open", url)
+ if errors.Is(err, exec.ErrNotFound) {
+ return fmt.Errorf("%w - install xdg-utils from ports(8)", err)
+ }
+ return err
+}
diff --git a/vendor/github.com/cli/browser/browser_linux.go b/vendor/github.com/cli/browser/browser_linux.go
new file mode 100644
index 000000000..b30325015
--- /dev/null
+++ b/vendor/github.com/cli/browser/browser_linux.go
@@ -0,0 +1,21 @@
+package browser
+
+import (
+ "os/exec"
+ "strings"
+)
+
+func openBrowser(url string) error {
+ providers := []string{"xdg-open", "x-www-browser", "www-browser", "wslview"}
+
+ // There are multiple possible providers to open a browser on linux
+ // One of them is xdg-open, another is x-www-browser, then there's www-browser, etc.
+ // Look for one that exists and run it
+ for _, provider := range providers {
+ if _, err := exec.LookPath(provider); err == nil {
+ return runCmd(provider, url)
+ }
+ }
+
+ return &exec.Error{Name: strings.Join(providers, ","), Err: exec.ErrNotFound}
+}
diff --git a/vendor/github.com/cli/browser/browser_netbsd.go b/vendor/github.com/cli/browser/browser_netbsd.go
new file mode 100644
index 000000000..65a5e5a29
--- /dev/null
+++ b/vendor/github.com/cli/browser/browser_netbsd.go
@@ -0,0 +1,14 @@
+package browser
+
+import (
+ "errors"
+ "os/exec"
+)
+
+func openBrowser(url string) error {
+ err := runCmd("xdg-open", url)
+ if e, ok := err.(*exec.Error); ok && e.Err == exec.ErrNotFound {
+ return errors.New("xdg-open: command not found - install xdg-utils from pkgsrc(7)")
+ }
+ return err
+}
diff --git a/vendor/github.com/cli/browser/browser_openbsd.go b/vendor/github.com/cli/browser/browser_openbsd.go
new file mode 100644
index 000000000..2a3c9a2e8
--- /dev/null
+++ b/vendor/github.com/cli/browser/browser_openbsd.go
@@ -0,0 +1,15 @@
+package browser
+
+import (
+ "errors"
+ "fmt"
+ "os/exec"
+)
+
+func openBrowser(url string) error {
+ err := runCmd("xdg-open", url)
+ if errors.Is(err, exec.ErrNotFound) {
+ return fmt.Errorf("%w - install xdg-utils from ports(8)", err)
+ }
+ return err
+}
diff --git a/vendor/github.com/cli/browser/browser_unsupported.go b/vendor/github.com/cli/browser/browser_unsupported.go
new file mode 100644
index 000000000..7c5c17d34
--- /dev/null
+++ b/vendor/github.com/cli/browser/browser_unsupported.go
@@ -0,0 +1,12 @@
+// +build !linux,!windows,!darwin,!openbsd,!freebsd,!netbsd
+
+package browser
+
+import (
+ "fmt"
+ "runtime"
+)
+
+func openBrowser(url string) error {
+ return fmt.Errorf("openBrowser: unsupported operating system: %v", runtime.GOOS)
+}
diff --git a/vendor/github.com/cli/browser/browser_windows.go b/vendor/github.com/cli/browser/browser_windows.go
new file mode 100644
index 000000000..63e192959
--- /dev/null
+++ b/vendor/github.com/cli/browser/browser_windows.go
@@ -0,0 +1,7 @@
+package browser
+
+import "golang.org/x/sys/windows"
+
+func openBrowser(url string) error {
+ return windows.ShellExecute(0, nil, windows.StringToUTF16Ptr(url), nil, nil, windows.SW_SHOWNORMAL)
+}
diff --git a/vendor/github.com/cli/cli/v2/LICENSE b/vendor/github.com/cli/cli/v2/LICENSE
new file mode 100644
index 000000000..b6a58a957
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 GitHub 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/cli/cli/v2/api/client.go b/vendor/github.com/cli/cli/v2/api/client.go
new file mode 100644
index 000000000..e32856554
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/api/client.go
@@ -0,0 +1,273 @@
+package api
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "net/http"
+ "regexp"
+ "strings"
+
+ "github.com/cli/cli/v2/internal/ghinstance"
+ ghAPI "github.com/cli/go-gh/v2/pkg/api"
+)
+
+const (
+ accept = "Accept"
+ authorization = "Authorization"
+ cacheTTL = "X-GH-CACHE-TTL"
+ graphqlFeatures = "GraphQL-Features"
+ features = "merge_queue"
+ userAgent = "User-Agent"
+)
+
+var linkRE = regexp.MustCompile(`<([^>]+)>;\s*rel="([^"]+)"`)
+
+func NewClientFromHTTP(httpClient *http.Client) *Client {
+ client := &Client{http: httpClient}
+ return client
+}
+
+type Client struct {
+ http *http.Client
+}
+
+func (c *Client) HTTP() *http.Client {
+ return c.http
+}
+
+type GraphQLError struct {
+ *ghAPI.GraphQLError
+}
+
+type HTTPError struct {
+ *ghAPI.HTTPError
+ scopesSuggestion string
+}
+
+func (err HTTPError) ScopesSuggestion() string {
+ return err.scopesSuggestion
+}
+
+// GraphQL performs a GraphQL request using the query string and parses the response into data receiver. If there are errors in the response,
+// GraphQLError will be returned, but the receiver will also be partially populated.
+func (c Client) GraphQL(hostname string, query string, variables map[string]interface{}, data interface{}) error {
+ opts := clientOptions(hostname, c.http.Transport)
+ opts.Headers[graphqlFeatures] = features
+ gqlClient, err := ghAPI.NewGraphQLClient(opts)
+ if err != nil {
+ return err
+ }
+ return handleResponse(gqlClient.Do(query, variables, data))
+}
+
+// Mutate performs a GraphQL mutation based on a struct and parses the response with the same struct as the receiver. If there are errors in the response,
+// GraphQLError will be returned, but the receiver will also be partially populated.
+func (c Client) Mutate(hostname, name string, mutation interface{}, variables map[string]interface{}) error {
+ opts := clientOptions(hostname, c.http.Transport)
+ opts.Headers[graphqlFeatures] = features
+ gqlClient, err := ghAPI.NewGraphQLClient(opts)
+ if err != nil {
+ return err
+ }
+ return handleResponse(gqlClient.Mutate(name, mutation, variables))
+}
+
+// Query performs a GraphQL query based on a struct and parses the response with the same struct as the receiver. If there are errors in the response,
+// GraphQLError will be returned, but the receiver will also be partially populated.
+func (c Client) Query(hostname, name string, query interface{}, variables map[string]interface{}) error {
+ opts := clientOptions(hostname, c.http.Transport)
+ opts.Headers[graphqlFeatures] = features
+ gqlClient, err := ghAPI.NewGraphQLClient(opts)
+ if err != nil {
+ return err
+ }
+ return handleResponse(gqlClient.Query(name, query, variables))
+}
+
+// QueryWithContext performs a GraphQL query based on a struct and parses the response with the same struct as the receiver. If there are errors in the response,
+// GraphQLError will be returned, but the receiver will also be partially populated.
+func (c Client) QueryWithContext(ctx context.Context, hostname, name string, query interface{}, variables map[string]interface{}) error {
+ opts := clientOptions(hostname, c.http.Transport)
+ opts.Headers[graphqlFeatures] = features
+ gqlClient, err := ghAPI.NewGraphQLClient(opts)
+ if err != nil {
+ return err
+ }
+ return handleResponse(gqlClient.QueryWithContext(ctx, name, query, variables))
+}
+
+// REST performs a REST request and parses the response.
+func (c Client) REST(hostname string, method string, p string, body io.Reader, data interface{}) error {
+ opts := clientOptions(hostname, c.http.Transport)
+ restClient, err := ghAPI.NewRESTClient(opts)
+ if err != nil {
+ return err
+ }
+ return handleResponse(restClient.Do(method, p, body, data))
+}
+
+func (c Client) RESTWithNext(hostname string, method string, p string, body io.Reader, data interface{}) (string, error) {
+ opts := clientOptions(hostname, c.http.Transport)
+ restClient, err := ghAPI.NewRESTClient(opts)
+ if err != nil {
+ return "", err
+ }
+
+ resp, err := restClient.Request(method, p, body)
+ if err != nil {
+ return "", err
+ }
+ defer resp.Body.Close()
+
+ success := resp.StatusCode >= 200 && resp.StatusCode < 300
+ if !success {
+ return "", HandleHTTPError(resp)
+ }
+
+ if resp.StatusCode == http.StatusNoContent {
+ return "", nil
+ }
+
+ b, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return "", err
+ }
+
+ err = json.Unmarshal(b, &data)
+ if err != nil {
+ return "", err
+ }
+
+ var next string
+ for _, m := range linkRE.FindAllStringSubmatch(resp.Header.Get("Link"), -1) {
+ if len(m) > 2 && m[2] == "next" {
+ next = m[1]
+ }
+ }
+
+ return next, nil
+}
+
+// HandleHTTPError parses a http.Response into a HTTPError.
+func HandleHTTPError(resp *http.Response) error {
+ return handleResponse(ghAPI.HandleHTTPError(resp))
+}
+
+// handleResponse takes a ghAPI.HTTPError or ghAPI.GraphQLError and converts it into an
+// HTTPError or GraphQLError respectively.
+func handleResponse(err error) error {
+ if err == nil {
+ return nil
+ }
+
+ var restErr *ghAPI.HTTPError
+ if errors.As(err, &restErr) {
+ return HTTPError{
+ HTTPError: restErr,
+ scopesSuggestion: generateScopesSuggestion(restErr.StatusCode,
+ restErr.Headers.Get("X-Accepted-Oauth-Scopes"),
+ restErr.Headers.Get("X-Oauth-Scopes"),
+ restErr.RequestURL.Hostname()),
+ }
+ }
+
+ var gqlErr *ghAPI.GraphQLError
+ if errors.As(err, &gqlErr) {
+ return GraphQLError{
+ GraphQLError: gqlErr,
+ }
+ }
+
+ return err
+}
+
+// ScopesSuggestion is an error messaging utility that prints the suggestion to request additional OAuth
+// scopes in case a server response indicates that there are missing scopes.
+func ScopesSuggestion(resp *http.Response) string {
+ return generateScopesSuggestion(resp.StatusCode,
+ resp.Header.Get("X-Accepted-Oauth-Scopes"),
+ resp.Header.Get("X-Oauth-Scopes"),
+ resp.Request.URL.Hostname())
+}
+
+// EndpointNeedsScopes adds additional OAuth scopes to an HTTP response as if they were returned from the
+// server endpoint. This improves HTTP 4xx error messaging for endpoints that don't explicitly list the
+// OAuth scopes they need.
+func EndpointNeedsScopes(resp *http.Response, s string) *http.Response {
+ if resp.StatusCode >= 400 && resp.StatusCode < 500 {
+ oldScopes := resp.Header.Get("X-Accepted-Oauth-Scopes")
+ resp.Header.Set("X-Accepted-Oauth-Scopes", fmt.Sprintf("%s, %s", oldScopes, s))
+ }
+ return resp
+}
+
+func generateScopesSuggestion(statusCode int, endpointNeedsScopes, tokenHasScopes, hostname string) string {
+ if statusCode < 400 || statusCode > 499 || statusCode == 422 {
+ return ""
+ }
+
+ if tokenHasScopes == "" {
+ return ""
+ }
+
+ gotScopes := map[string]struct{}{}
+ for _, s := range strings.Split(tokenHasScopes, ",") {
+ s = strings.TrimSpace(s)
+ gotScopes[s] = struct{}{}
+
+ // Certain scopes may be grouped under a single "top-level" scope. The following branch
+ // statements include these grouped/implied scopes when the top-level scope is encountered.
+ // See https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps.
+ if s == "repo" {
+ gotScopes["repo:status"] = struct{}{}
+ gotScopes["repo_deployment"] = struct{}{}
+ gotScopes["public_repo"] = struct{}{}
+ gotScopes["repo:invite"] = struct{}{}
+ gotScopes["security_events"] = struct{}{}
+ } else if s == "user" {
+ gotScopes["read:user"] = struct{}{}
+ gotScopes["user:email"] = struct{}{}
+ gotScopes["user:follow"] = struct{}{}
+ } else if s == "codespace" {
+ gotScopes["codespace:secrets"] = struct{}{}
+ } else if strings.HasPrefix(s, "admin:") {
+ gotScopes["read:"+strings.TrimPrefix(s, "admin:")] = struct{}{}
+ gotScopes["write:"+strings.TrimPrefix(s, "admin:")] = struct{}{}
+ } else if strings.HasPrefix(s, "write:") {
+ gotScopes["read:"+strings.TrimPrefix(s, "write:")] = struct{}{}
+ }
+ }
+
+ for _, s := range strings.Split(endpointNeedsScopes, ",") {
+ s = strings.TrimSpace(s)
+ if _, gotScope := gotScopes[s]; s == "" || gotScope {
+ continue
+ }
+ return fmt.Sprintf(
+ "This API operation needs the %[1]q scope. To request it, run: gh auth refresh -h %[2]s -s %[1]s",
+ s,
+ ghinstance.NormalizeHostname(hostname),
+ )
+ }
+
+ return ""
+}
+
+func clientOptions(hostname string, transport http.RoundTripper) ghAPI.ClientOptions {
+ // AuthToken, and Headers are being handled by transport,
+ // so let go-gh know that it does not need to resolve them.
+ opts := ghAPI.ClientOptions{
+ AuthToken: "none",
+ Headers: map[string]string{
+ authorization: "",
+ },
+ Host: hostname,
+ SkipDefaultHeaders: true,
+ Transport: transport,
+ LogIgnoreEnv: true,
+ }
+ return opts
+}
diff --git a/vendor/github.com/cli/cli/v2/api/export_pr.go b/vendor/github.com/cli/cli/v2/api/export_pr.go
new file mode 100644
index 000000000..bb3310811
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/api/export_pr.go
@@ -0,0 +1,155 @@
+package api
+
+import (
+ "reflect"
+ "strings"
+)
+
+func (issue *Issue) ExportData(fields []string) map[string]interface{} {
+ v := reflect.ValueOf(issue).Elem()
+ data := map[string]interface{}{}
+
+ for _, f := range fields {
+ switch f {
+ case "comments":
+ data[f] = issue.Comments.Nodes
+ case "assignees":
+ data[f] = issue.Assignees.Nodes
+ case "labels":
+ data[f] = issue.Labels.Nodes
+ case "projectCards":
+ data[f] = issue.ProjectCards.Nodes
+ case "projectItems":
+ items := make([]map[string]interface{}, 0, len(issue.ProjectItems.Nodes))
+ for _, n := range issue.ProjectItems.Nodes {
+ items = append(items, map[string]interface{}{
+ "status": n.Status,
+ "title": n.Project.Title,
+ })
+ }
+ data[f] = items
+ default:
+ sf := fieldByName(v, f)
+ data[f] = sf.Interface()
+ }
+ }
+
+ return data
+}
+
+func (pr *PullRequest) ExportData(fields []string) map[string]interface{} {
+ v := reflect.ValueOf(pr).Elem()
+ data := map[string]interface{}{}
+
+ for _, f := range fields {
+ switch f {
+ case "headRepository":
+ data[f] = pr.HeadRepository
+ case "statusCheckRollup":
+ if n := pr.StatusCheckRollup.Nodes; len(n) > 0 {
+ checks := make([]interface{}, 0, len(n[0].Commit.StatusCheckRollup.Contexts.Nodes))
+ for _, c := range n[0].Commit.StatusCheckRollup.Contexts.Nodes {
+ if c.TypeName == "CheckRun" {
+ checks = append(checks, map[string]interface{}{
+ "__typename": c.TypeName,
+ "name": c.Name,
+ "workflowName": c.CheckSuite.WorkflowRun.Workflow.Name,
+ "status": c.Status,
+ "conclusion": c.Conclusion,
+ "startedAt": c.StartedAt,
+ "completedAt": c.CompletedAt,
+ "detailsUrl": c.DetailsURL,
+ })
+ } else {
+ checks = append(checks, map[string]interface{}{
+ "__typename": c.TypeName,
+ "context": c.Context,
+ "state": c.State,
+ "targetUrl": c.TargetURL,
+ "startedAt": c.CreatedAt,
+ })
+ }
+ }
+ data[f] = checks
+ } else {
+ data[f] = nil
+ }
+ case "commits":
+ commits := make([]interface{}, 0, len(pr.Commits.Nodes))
+ for _, c := range pr.Commits.Nodes {
+ commit := c.Commit
+ authors := make([]interface{}, 0, len(commit.Authors.Nodes))
+ for _, author := range commit.Authors.Nodes {
+ authors = append(authors, map[string]interface{}{
+ "name": author.Name,
+ "email": author.Email,
+ "id": author.User.ID,
+ "login": author.User.Login,
+ })
+ }
+ commits = append(commits, map[string]interface{}{
+ "oid": commit.OID,
+ "messageHeadline": commit.MessageHeadline,
+ "messageBody": commit.MessageBody,
+ "committedDate": commit.CommittedDate,
+ "authoredDate": commit.AuthoredDate,
+ "authors": authors,
+ })
+ }
+ data[f] = commits
+ case "comments":
+ data[f] = pr.Comments.Nodes
+ case "assignees":
+ data[f] = pr.Assignees.Nodes
+ case "labels":
+ data[f] = pr.Labels.Nodes
+ case "projectCards":
+ data[f] = pr.ProjectCards.Nodes
+ case "projectItems":
+ items := make([]map[string]interface{}, 0, len(pr.ProjectItems.Nodes))
+ for _, n := range pr.ProjectItems.Nodes {
+ items = append(items, map[string]interface{}{
+ "status": n.Status,
+ "title": n.Project.Title,
+ })
+ }
+ data[f] = items
+ case "reviews":
+ data[f] = pr.Reviews.Nodes
+ case "latestReviews":
+ data[f] = pr.LatestReviews.Nodes
+ case "files":
+ data[f] = pr.Files.Nodes
+ case "reviewRequests":
+ requests := make([]interface{}, 0, len(pr.ReviewRequests.Nodes))
+ for _, req := range pr.ReviewRequests.Nodes {
+ r := req.RequestedReviewer
+ switch r.TypeName {
+ case "User":
+ requests = append(requests, map[string]string{
+ "__typename": r.TypeName,
+ "login": r.Login,
+ })
+ case "Team":
+ requests = append(requests, map[string]string{
+ "__typename": r.TypeName,
+ "name": r.Name,
+ "slug": r.LoginOrSlug(),
+ })
+ }
+ }
+ data[f] = &requests
+ default:
+ sf := fieldByName(v, f)
+ data[f] = sf.Interface()
+ }
+ }
+
+ return data
+}
+
+func fieldByName(v reflect.Value, field string) reflect.Value {
+ return v.FieldByNameFunc(func(s string) bool {
+ return strings.EqualFold(field, s)
+ })
+}
diff --git a/vendor/github.com/cli/cli/v2/api/export_repo.go b/vendor/github.com/cli/cli/v2/api/export_repo.go
new file mode 100644
index 000000000..a07246ab9
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/api/export_repo.go
@@ -0,0 +1,53 @@
+package api
+
+import (
+ "reflect"
+)
+
+func (repo *Repository) ExportData(fields []string) map[string]interface{} {
+ v := reflect.ValueOf(repo).Elem()
+ data := map[string]interface{}{}
+
+ for _, f := range fields {
+ switch f {
+ case "parent":
+ data[f] = miniRepoExport(repo.Parent)
+ case "templateRepository":
+ data[f] = miniRepoExport(repo.TemplateRepository)
+ case "languages":
+ data[f] = repo.Languages.Edges
+ case "labels":
+ data[f] = repo.Labels.Nodes
+ case "assignableUsers":
+ data[f] = repo.AssignableUsers.Nodes
+ case "mentionableUsers":
+ data[f] = repo.MentionableUsers.Nodes
+ case "milestones":
+ data[f] = repo.Milestones.Nodes
+ case "projects":
+ data[f] = repo.Projects.Nodes
+ case "repositoryTopics":
+ var topics []RepositoryTopic
+ for _, n := range repo.RepositoryTopics.Nodes {
+ topics = append(topics, n.Topic)
+ }
+ data[f] = topics
+ default:
+ sf := fieldByName(v, f)
+ data[f] = sf.Interface()
+ }
+ }
+
+ return data
+}
+
+func miniRepoExport(r *Repository) map[string]interface{} {
+ if r == nil {
+ return nil
+ }
+ return map[string]interface{}{
+ "id": r.ID,
+ "name": r.Name,
+ "owner": r.Owner,
+ }
+}
diff --git a/vendor/github.com/cli/cli/v2/api/http_client.go b/vendor/github.com/cli/cli/v2/api/http_client.go
new file mode 100644
index 000000000..f6e133f1f
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/api/http_client.go
@@ -0,0 +1,140 @@
+package api
+
+import (
+ "fmt"
+ "io"
+ "net/http"
+ "strings"
+ "time"
+
+ "github.com/cli/cli/v2/internal/ghinstance"
+ "github.com/cli/cli/v2/utils"
+ ghAPI "github.com/cli/go-gh/v2/pkg/api"
+)
+
+type tokenGetter interface {
+ ActiveToken(string) (string, string)
+}
+
+type HTTPClientOptions struct {
+ AppVersion string
+ CacheTTL time.Duration
+ Config tokenGetter
+ EnableCache bool
+ Log io.Writer
+ LogColorize bool
+ LogVerboseHTTP bool
+}
+
+func NewHTTPClient(opts HTTPClientOptions) (*http.Client, error) {
+ // Provide invalid host, and token values so gh.HTTPClient will not automatically resolve them.
+ // The real host and token are inserted at request time.
+ clientOpts := ghAPI.ClientOptions{
+ Host: "none",
+ AuthToken: "none",
+ LogIgnoreEnv: true,
+ }
+
+ debugEnabled, debugValue := utils.IsDebugEnabled()
+ if strings.Contains(debugValue, "api") {
+ opts.LogVerboseHTTP = true
+ }
+
+ if opts.LogVerboseHTTP || debugEnabled {
+ clientOpts.Log = opts.Log
+ clientOpts.LogColorize = opts.LogColorize
+ clientOpts.LogVerboseHTTP = opts.LogVerboseHTTP
+ }
+
+ headers := map[string]string{
+ userAgent: fmt.Sprintf("GitHub CLI %s", opts.AppVersion),
+ }
+ clientOpts.Headers = headers
+
+ if opts.EnableCache {
+ clientOpts.EnableCache = opts.EnableCache
+ clientOpts.CacheTTL = opts.CacheTTL
+ }
+
+ client, err := ghAPI.NewHTTPClient(clientOpts)
+ if err != nil {
+ return nil, err
+ }
+
+ if opts.Config != nil {
+ client.Transport = AddAuthTokenHeader(client.Transport, opts.Config)
+ }
+
+ return client, nil
+}
+
+func NewCachedHTTPClient(httpClient *http.Client, ttl time.Duration) *http.Client {
+ newClient := *httpClient
+ newClient.Transport = AddCacheTTLHeader(httpClient.Transport, ttl)
+ return &newClient
+}
+
+// AddCacheTTLHeader adds an header to the request telling the cache that the request
+// should be cached for a specified amount of time.
+func AddCacheTTLHeader(rt http.RoundTripper, ttl time.Duration) http.RoundTripper {
+ return &funcTripper{roundTrip: func(req *http.Request) (*http.Response, error) {
+ // If the header is already set in the request, don't overwrite it.
+ if req.Header.Get(cacheTTL) == "" {
+ req.Header.Set(cacheTTL, ttl.String())
+ }
+ return rt.RoundTrip(req)
+ }}
+}
+
+// AddAuthToken adds an authentication token header for the host specified by the request.
+func AddAuthTokenHeader(rt http.RoundTripper, cfg tokenGetter) http.RoundTripper {
+ return &funcTripper{roundTrip: func(req *http.Request) (*http.Response, error) {
+ // If the header is already set in the request, don't overwrite it.
+ if req.Header.Get(authorization) == "" {
+ var redirectHostnameChange bool
+ if req.Response != nil && req.Response.Request != nil {
+ redirectHostnameChange = getHost(req) != getHost(req.Response.Request)
+ }
+ // Only set header if an initial request or redirect request to the same host as the initial request.
+ // If the host has changed during a redirect do not add the authentication token header.
+ if !redirectHostnameChange {
+ hostname := ghinstance.NormalizeHostname(getHost(req))
+ if token, _ := cfg.ActiveToken(hostname); token != "" {
+ req.Header.Set(authorization, fmt.Sprintf("token %s", token))
+ }
+ }
+ }
+ return rt.RoundTrip(req)
+ }}
+}
+
+// ExtractHeader extracts a named header from any response received by this client and,
+// if non-blank, saves it to dest.
+func ExtractHeader(name string, dest *string) func(http.RoundTripper) http.RoundTripper {
+ return func(tr http.RoundTripper) http.RoundTripper {
+ return &funcTripper{roundTrip: func(req *http.Request) (*http.Response, error) {
+ res, err := tr.RoundTrip(req)
+ if err == nil {
+ if value := res.Header.Get(name); value != "" {
+ *dest = value
+ }
+ }
+ return res, err
+ }}
+ }
+}
+
+type funcTripper struct {
+ roundTrip func(*http.Request) (*http.Response, error)
+}
+
+func (tr funcTripper) RoundTrip(req *http.Request) (*http.Response, error) {
+ return tr.roundTrip(req)
+}
+
+func getHost(r *http.Request) string {
+ if r.Host != "" {
+ return r.Host
+ }
+ return r.URL.Host
+}
diff --git a/vendor/github.com/cli/cli/v2/api/queries_branch_issue_reference.go b/vendor/github.com/cli/cli/v2/api/queries_branch_issue_reference.go
new file mode 100644
index 000000000..16e36831b
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/api/queries_branch_issue_reference.go
@@ -0,0 +1,145 @@
+package api
+
+import (
+ "fmt"
+
+ "github.com/cli/cli/v2/internal/ghrepo"
+ "github.com/shurcooL/githubv4"
+)
+
+type LinkedBranch struct {
+ BranchName string
+ URL string
+}
+
+func CreateLinkedBranch(client *Client, host string, repoID, issueID, branchID, branchName string) (string, error) {
+ var mutation struct {
+ CreateLinkedBranch struct {
+ LinkedBranch struct {
+ ID string
+ Ref struct {
+ Name string
+ }
+ }
+ } `graphql:"createLinkedBranch(input: $input)"`
+ }
+
+ input := githubv4.CreateLinkedBranchInput{
+ IssueID: githubv4.ID(issueID),
+ Oid: githubv4.GitObjectID(branchID),
+ }
+ if repoID != "" {
+ repo := githubv4.ID(repoID)
+ input.RepositoryID = &repo
+ }
+ if branchName != "" {
+ name := githubv4.String(branchName)
+ input.Name = &name
+ }
+ variables := map[string]interface{}{
+ "input": input,
+ }
+
+ err := client.Mutate(host, "CreateLinkedBranch", &mutation, variables)
+ if err != nil {
+ return "", err
+ }
+
+ return mutation.CreateLinkedBranch.LinkedBranch.Ref.Name, nil
+}
+
+func ListLinkedBranches(client *Client, repo ghrepo.Interface, issueNumber int) ([]LinkedBranch, error) {
+ var query struct {
+ Repository struct {
+ Issue struct {
+ LinkedBranches struct {
+ Nodes []struct {
+ Ref struct {
+ Name string
+ Repository struct {
+ Url string
+ }
+ }
+ }
+ } `graphql:"linkedBranches(first: 30)"`
+ } `graphql:"issue(number: $number)"`
+ } `graphql:"repository(owner: $owner, name: $name)"`
+ }
+
+ variables := map[string]interface{}{
+ "number": githubv4.Int(issueNumber),
+ "owner": githubv4.String(repo.RepoOwner()),
+ "name": githubv4.String(repo.RepoName()),
+ }
+
+ if err := client.Query(repo.RepoHost(), "ListLinkedBranches", &query, variables); err != nil {
+ return []LinkedBranch{}, err
+ }
+
+ var branchNames []LinkedBranch
+
+ for _, node := range query.Repository.Issue.LinkedBranches.Nodes {
+ branch := LinkedBranch{
+ BranchName: node.Ref.Name,
+ URL: fmt.Sprintf("%s/tree/%s", node.Ref.Repository.Url, node.Ref.Name),
+ }
+ branchNames = append(branchNames, branch)
+ }
+
+ return branchNames, nil
+}
+
+func CheckLinkedBranchFeature(client *Client, host string) error {
+ var query struct {
+ Name struct {
+ Fields []struct {
+ Name string
+ }
+ } `graphql:"LinkedBranch: __type(name: \"LinkedBranch\")"`
+ }
+
+ if err := client.Query(host, "LinkedBranchFeature", &query, nil); err != nil {
+ return err
+ }
+
+ if len(query.Name.Fields) == 0 {
+ return fmt.Errorf("the `gh issue develop` command is not currently available")
+ }
+
+ return nil
+}
+
+func FindRepoBranchID(client *Client, repo ghrepo.Interface, ref string) (string, string, error) {
+ var query struct {
+ Repository struct {
+ Id string
+ DefaultBranchRef struct {
+ Target struct {
+ Oid string
+ }
+ }
+ Ref struct {
+ Target struct {
+ Oid string
+ }
+ } `graphql:"ref(qualifiedName: $ref)"`
+ } `graphql:"repository(owner: $owner, name: $name)"`
+ }
+
+ variables := map[string]interface{}{
+ "ref": githubv4.String(ref),
+ "owner": githubv4.String(repo.RepoOwner()),
+ "name": githubv4.String(repo.RepoName()),
+ }
+
+ if err := client.Query(repo.RepoHost(), "FindRepoBranchID", &query, variables); err != nil {
+ return "", "", err
+ }
+
+ branchID := query.Repository.Ref.Target.Oid
+ if branchID == "" {
+ branchID = query.Repository.DefaultBranchRef.Target.Oid
+ }
+
+ return query.Repository.Id, branchID, nil
+}
diff --git a/vendor/github.com/cli/cli/v2/api/queries_comments.go b/vendor/github.com/cli/cli/v2/api/queries_comments.go
new file mode 100644
index 000000000..5cc84a3e4
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/api/queries_comments.go
@@ -0,0 +1,144 @@
+package api
+
+import (
+ "time"
+
+ "github.com/shurcooL/githubv4"
+)
+
+type Comments struct {
+ Nodes []Comment
+ TotalCount int
+ PageInfo struct {
+ HasNextPage bool
+ EndCursor string
+ }
+}
+
+func (cs Comments) CurrentUserComments() []Comment {
+ var comments []Comment
+ for _, c := range cs.Nodes {
+ if c.ViewerDidAuthor {
+ comments = append(comments, c)
+ }
+ }
+ return comments
+}
+
+type Comment struct {
+ ID string `json:"id"`
+ Author CommentAuthor `json:"author"`
+ AuthorAssociation string `json:"authorAssociation"`
+ Body string `json:"body"`
+ CreatedAt time.Time `json:"createdAt"`
+ IncludesCreatedEdit bool `json:"includesCreatedEdit"`
+ IsMinimized bool `json:"isMinimized"`
+ MinimizedReason string `json:"minimizedReason"`
+ ReactionGroups ReactionGroups `json:"reactionGroups"`
+ URL string `json:"url,omitempty"`
+ ViewerDidAuthor bool `json:"viewerDidAuthor"`
+}
+
+type CommentCreateInput struct {
+ Body string
+ SubjectId string
+}
+
+type CommentUpdateInput struct {
+ Body string
+ CommentId string
+}
+
+func CommentCreate(client *Client, repoHost string, params CommentCreateInput) (string, error) {
+ var mutation struct {
+ AddComment struct {
+ CommentEdge struct {
+ Node struct {
+ URL string
+ }
+ }
+ } `graphql:"addComment(input: $input)"`
+ }
+
+ variables := map[string]interface{}{
+ "input": githubv4.AddCommentInput{
+ Body: githubv4.String(params.Body),
+ SubjectID: githubv4.ID(params.SubjectId),
+ },
+ }
+
+ err := client.Mutate(repoHost, "CommentCreate", &mutation, variables)
+ if err != nil {
+ return "", err
+ }
+
+ return mutation.AddComment.CommentEdge.Node.URL, nil
+}
+
+func CommentUpdate(client *Client, repoHost string, params CommentUpdateInput) (string, error) {
+ var mutation struct {
+ UpdateIssueComment struct {
+ IssueComment struct {
+ URL string
+ }
+ } `graphql:"updateIssueComment(input: $input)"`
+ }
+
+ variables := map[string]interface{}{
+ "input": githubv4.UpdateIssueCommentInput{
+ Body: githubv4.String(params.Body),
+ ID: githubv4.ID(params.CommentId),
+ },
+ }
+
+ err := client.Mutate(repoHost, "CommentUpdate", &mutation, variables)
+ if err != nil {
+ return "", err
+ }
+
+ return mutation.UpdateIssueComment.IssueComment.URL, nil
+}
+
+func (c Comment) Identifier() string {
+ return c.ID
+}
+
+func (c Comment) AuthorLogin() string {
+ return c.Author.Login
+}
+
+func (c Comment) Association() string {
+ return c.AuthorAssociation
+}
+
+func (c Comment) Content() string {
+ return c.Body
+}
+
+func (c Comment) Created() time.Time {
+ return c.CreatedAt
+}
+
+func (c Comment) HiddenReason() string {
+ return c.MinimizedReason
+}
+
+func (c Comment) IsEdited() bool {
+ return c.IncludesCreatedEdit
+}
+
+func (c Comment) IsHidden() bool {
+ return c.IsMinimized
+}
+
+func (c Comment) Link() string {
+ return c.URL
+}
+
+func (c Comment) Reactions() ReactionGroups {
+ return c.ReactionGroups
+}
+
+func (c Comment) Status() string {
+ return ""
+}
diff --git a/vendor/github.com/cli/cli/v2/api/queries_issue.go b/vendor/github.com/cli/cli/v2/api/queries_issue.go
new file mode 100644
index 000000000..62531e84e
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/api/queries_issue.go
@@ -0,0 +1,335 @@
+package api
+
+import (
+ "encoding/json"
+ "fmt"
+ "time"
+
+ "github.com/cli/cli/v2/internal/ghrepo"
+)
+
+type IssuesPayload struct {
+ Assigned IssuesAndTotalCount
+ Mentioned IssuesAndTotalCount
+ Authored IssuesAndTotalCount
+}
+
+type IssuesAndTotalCount struct {
+ Issues []Issue
+ TotalCount int
+ SearchCapped bool
+}
+
+type Issue struct {
+ Typename string `json:"__typename"`
+ ID string
+ Number int
+ Title string
+ URL string
+ State string
+ StateReason string
+ Closed bool
+ Body string
+ ActiveLockReason string
+ Locked bool
+ CreatedAt time.Time
+ UpdatedAt time.Time
+ ClosedAt *time.Time
+ Comments Comments
+ Author Author
+ Assignees Assignees
+ Labels Labels
+ ProjectCards ProjectCards
+ ProjectItems ProjectItems
+ Milestone *Milestone
+ ReactionGroups ReactionGroups
+ IsPinned bool
+}
+
+// return values for Issue.Typename
+const (
+ TypeIssue string = "Issue"
+ TypePullRequest string = "PullRequest"
+)
+
+func (i Issue) IsPullRequest() bool {
+ return i.Typename == TypePullRequest
+}
+
+type Assignees struct {
+ Nodes []GitHubUser
+ TotalCount int
+}
+
+func (a Assignees) Logins() []string {
+ logins := make([]string, len(a.Nodes))
+ for i, a := range a.Nodes {
+ logins[i] = a.Login
+ }
+ return logins
+}
+
+type Labels struct {
+ Nodes []IssueLabel
+ TotalCount int
+}
+
+func (l Labels) Names() []string {
+ names := make([]string, len(l.Nodes))
+ for i, l := range l.Nodes {
+ names[i] = l.Name
+ }
+ return names
+}
+
+type ProjectCards struct {
+ Nodes []*ProjectInfo
+ TotalCount int
+}
+
+type ProjectItems struct {
+ Nodes []*ProjectV2Item
+}
+
+type ProjectInfo struct {
+ Project struct {
+ Name string `json:"name"`
+ } `json:"project"`
+ Column struct {
+ Name string `json:"name"`
+ } `json:"column"`
+}
+
+type ProjectV2Item struct {
+ ID string `json:"id"`
+ Project ProjectV2ItemProject
+ Status ProjectV2ItemStatus
+}
+
+type ProjectV2ItemProject struct {
+ ID string `json:"id"`
+ Title string `json:"title"`
+}
+
+type ProjectV2ItemStatus struct {
+ OptionID string `json:"optionId"`
+ Name string `json:"name"`
+}
+
+func (p ProjectCards) ProjectNames() []string {
+ names := make([]string, len(p.Nodes))
+ for i, c := range p.Nodes {
+ names[i] = c.Project.Name
+ }
+ return names
+}
+
+func (p ProjectItems) ProjectTitles() []string {
+ titles := make([]string, len(p.Nodes))
+ for i, c := range p.Nodes {
+ titles[i] = c.Project.Title
+ }
+ return titles
+}
+
+type Milestone struct {
+ Number int `json:"number"`
+ Title string `json:"title"`
+ Description string `json:"description"`
+ DueOn *time.Time `json:"dueOn"`
+}
+
+type IssuesDisabledError struct {
+ error
+}
+
+type Owner struct {
+ ID string `json:"id,omitempty"`
+ Name string `json:"name,omitempty"`
+ Login string `json:"login"`
+}
+
+type Author struct {
+ ID string
+ Name string
+ Login string
+}
+
+func (author Author) MarshalJSON() ([]byte, error) {
+ if author.ID == "" {
+ return json.Marshal(map[string]interface{}{
+ "is_bot": true,
+ "login": "app/" + author.Login,
+ })
+ }
+ return json.Marshal(map[string]interface{}{
+ "is_bot": false,
+ "login": author.Login,
+ "id": author.ID,
+ "name": author.Name,
+ })
+}
+
+type CommentAuthor struct {
+ Login string `json:"login"`
+ // Unfortunately, there is no easy way to add "id" and "name" fields to this struct because it's being
+ // used in both shurcool-graphql type queries and string-based queries where the response gets parsed
+ // by an ordinary JSON decoder that doesn't understand "graphql" directives via struct tags.
+ // User *struct {
+ // ID string
+ // Name string
+ // } `graphql:"... on User"`
+}
+
+// IssueCreate creates an issue in a GitHub repository
+func IssueCreate(client *Client, repo *Repository, params map[string]interface{}) (*Issue, error) {
+ query := `
+ mutation IssueCreate($input: CreateIssueInput!) {
+ createIssue(input: $input) {
+ issue {
+ id
+ url
+ }
+ }
+ }`
+
+ inputParams := map[string]interface{}{
+ "repositoryId": repo.ID,
+ }
+ for key, val := range params {
+ switch key {
+ case "assigneeIds", "body", "issueTemplate", "labelIds", "milestoneId", "projectIds", "repositoryId", "title":
+ inputParams[key] = val
+ case "projectV2Ids":
+ default:
+ return nil, fmt.Errorf("invalid IssueCreate mutation parameter %s", key)
+ }
+ }
+ variables := map[string]interface{}{
+ "input": inputParams,
+ }
+
+ result := struct {
+ CreateIssue struct {
+ Issue Issue
+ }
+ }{}
+
+ err := client.GraphQL(repo.RepoHost(), query, variables, &result)
+ if err != nil {
+ return nil, err
+ }
+ issue := &result.CreateIssue.Issue
+
+ // projectV2 parameters aren't supported in the `createIssue` mutation,
+ // so add them after the issue has been created.
+ projectV2Ids, ok := params["projectV2Ids"].([]string)
+ if ok {
+ projectItems := make(map[string]string, len(projectV2Ids))
+ for _, p := range projectV2Ids {
+ projectItems[p] = issue.ID
+ }
+ err = UpdateProjectV2Items(client, repo, projectItems, nil)
+ if err != nil {
+ return issue, err
+ }
+ }
+
+ return issue, nil
+}
+
+type IssueStatusOptions struct {
+ Username string
+ Fields []string
+}
+
+func IssueStatus(client *Client, repo ghrepo.Interface, options IssueStatusOptions) (*IssuesPayload, error) {
+ type response struct {
+ Repository struct {
+ Assigned struct {
+ TotalCount int
+ Nodes []Issue
+ }
+ Mentioned struct {
+ TotalCount int
+ Nodes []Issue
+ }
+ Authored struct {
+ TotalCount int
+ Nodes []Issue
+ }
+ HasIssuesEnabled bool
+ }
+ }
+
+ fragments := fmt.Sprintf("fragment issue on Issue{%s}", IssueGraphQL(options.Fields))
+ query := fragments + `
+ query IssueStatus($owner: String!, $repo: String!, $viewer: String!, $per_page: Int = 10) {
+ repository(owner: $owner, name: $repo) {
+ hasIssuesEnabled
+ assigned: issues(filterBy: {assignee: $viewer, states: OPEN}, first: $per_page, orderBy: {field: UPDATED_AT, direction: DESC}) {
+ totalCount
+ nodes {
+ ...issue
+ }
+ }
+ mentioned: issues(filterBy: {mentioned: $viewer, states: OPEN}, first: $per_page, orderBy: {field: UPDATED_AT, direction: DESC}) {
+ totalCount
+ nodes {
+ ...issue
+ }
+ }
+ authored: issues(filterBy: {createdBy: $viewer, states: OPEN}, first: $per_page, orderBy: {field: UPDATED_AT, direction: DESC}) {
+ totalCount
+ nodes {
+ ...issue
+ }
+ }
+ }
+ }`
+
+ variables := map[string]interface{}{
+ "owner": repo.RepoOwner(),
+ "repo": repo.RepoName(),
+ "viewer": options.Username,
+ }
+
+ var resp response
+ err := client.GraphQL(repo.RepoHost(), query, variables, &resp)
+ if err != nil {
+ return nil, err
+ }
+
+ if !resp.Repository.HasIssuesEnabled {
+ return nil, fmt.Errorf("the '%s' repository has disabled issues", ghrepo.FullName(repo))
+ }
+
+ payload := IssuesPayload{
+ Assigned: IssuesAndTotalCount{
+ Issues: resp.Repository.Assigned.Nodes,
+ TotalCount: resp.Repository.Assigned.TotalCount,
+ },
+ Mentioned: IssuesAndTotalCount{
+ Issues: resp.Repository.Mentioned.Nodes,
+ TotalCount: resp.Repository.Mentioned.TotalCount,
+ },
+ Authored: IssuesAndTotalCount{
+ Issues: resp.Repository.Authored.Nodes,
+ TotalCount: resp.Repository.Authored.TotalCount,
+ },
+ }
+
+ return &payload, nil
+}
+
+func (i Issue) Link() string {
+ return i.URL
+}
+
+func (i Issue) Identifier() string {
+ return i.ID
+}
+
+func (i Issue) CurrentUserComments() []Comment {
+ return i.Comments.CurrentUserComments()
+}
diff --git a/vendor/github.com/cli/cli/v2/api/queries_org.go b/vendor/github.com/cli/cli/v2/api/queries_org.go
new file mode 100644
index 000000000..f2e93342e
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/api/queries_org.go
@@ -0,0 +1,111 @@
+package api
+
+import (
+ "fmt"
+ "github.com/cli/cli/v2/internal/ghrepo"
+ "github.com/shurcooL/githubv4"
+)
+
+// OrganizationProjects fetches all open projects for an organization.
+func OrganizationProjects(client *Client, repo ghrepo.Interface) ([]RepoProject, error) {
+ type responseData struct {
+ Organization struct {
+ Projects struct {
+ Nodes []RepoProject
+ PageInfo struct {
+ HasNextPage bool
+ EndCursor string
+ }
+ } `graphql:"projects(states: [OPEN], first: 100, orderBy: {field: NAME, direction: ASC}, after: $endCursor)"`
+ } `graphql:"organization(login: $owner)"`
+ }
+
+ variables := map[string]interface{}{
+ "owner": githubv4.String(repo.RepoOwner()),
+ "endCursor": (*githubv4.String)(nil),
+ }
+
+ var projects []RepoProject
+ for {
+ var query responseData
+ err := client.Query(repo.RepoHost(), "OrganizationProjectList", &query, variables)
+ if err != nil {
+ return nil, err
+ }
+
+ projects = append(projects, query.Organization.Projects.Nodes...)
+ if !query.Organization.Projects.PageInfo.HasNextPage {
+ break
+ }
+ variables["endCursor"] = githubv4.String(query.Organization.Projects.PageInfo.EndCursor)
+ }
+
+ return projects, nil
+}
+
+type OrgTeam struct {
+ ID string
+ Slug string
+}
+
+// OrganizationTeam fetch the team in an organization with the given slug
+func OrganizationTeam(client *Client, hostname string, org string, teamSlug string) (*OrgTeam, error) {
+ type responseData struct {
+ Organization struct {
+ Team OrgTeam `graphql:"team(slug: $teamSlug)"`
+ } `graphql:"organization(login: $owner)"`
+ }
+
+ variables := map[string]interface{}{
+ "owner": githubv4.String(org),
+ "teamSlug": githubv4.String(teamSlug),
+ }
+
+ var query responseData
+ err := client.Query(hostname, "OrganizationTeam", &query, variables)
+ if err != nil {
+ return nil, err
+ }
+ if query.Organization.Team.ID == "" {
+ return nil, fmt.Errorf("could not resolve to a Team with the slug of '%s'", teamSlug)
+ }
+
+ return &query.Organization.Team, nil
+}
+
+// OrganizationTeams fetches all the teams in an organization
+func OrganizationTeams(client *Client, repo ghrepo.Interface) ([]OrgTeam, error) {
+ type responseData struct {
+ Organization struct {
+ Teams struct {
+ Nodes []OrgTeam
+ PageInfo struct {
+ HasNextPage bool
+ EndCursor string
+ }
+ } `graphql:"teams(first: 100, orderBy: {field: NAME, direction: ASC}, after: $endCursor)"`
+ } `graphql:"organization(login: $owner)"`
+ }
+
+ variables := map[string]interface{}{
+ "owner": githubv4.String(repo.RepoOwner()),
+ "endCursor": (*githubv4.String)(nil),
+ }
+
+ var teams []OrgTeam
+ for {
+ var query responseData
+ err := client.Query(repo.RepoHost(), "OrganizationTeamList", &query, variables)
+ if err != nil {
+ return nil, err
+ }
+
+ teams = append(teams, query.Organization.Teams.Nodes...)
+ if !query.Organization.Teams.PageInfo.HasNextPage {
+ break
+ }
+ variables["endCursor"] = githubv4.String(query.Organization.Teams.PageInfo.EndCursor)
+ }
+
+ return teams, nil
+}
diff --git a/vendor/github.com/cli/cli/v2/api/queries_pr.go b/vendor/github.com/cli/cli/v2/api/queries_pr.go
new file mode 100644
index 000000000..36f3c2eef
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/api/queries_pr.go
@@ -0,0 +1,698 @@
+package api
+
+import (
+ "fmt"
+ "net/http"
+ "net/url"
+ "time"
+
+ "github.com/cli/cli/v2/internal/ghrepo"
+ "github.com/shurcooL/githubv4"
+)
+
+type PullRequestAndTotalCount struct {
+ TotalCount int
+ PullRequests []PullRequest
+ SearchCapped bool
+}
+
+type PullRequest struct {
+ ID string
+ Number int
+ Title string
+ State string
+ Closed bool
+ URL string
+ BaseRefName string
+ HeadRefName string
+ HeadRefOid string
+ Body string
+ Mergeable string
+ Additions int
+ Deletions int
+ ChangedFiles int
+ MergeStateStatus string
+ IsInMergeQueue bool
+ IsMergeQueueEnabled bool // Indicates whether the pull request's base ref has a merge queue enabled.
+ CreatedAt time.Time
+ UpdatedAt time.Time
+ ClosedAt *time.Time
+ MergedAt *time.Time
+
+ AutoMergeRequest *AutoMergeRequest
+
+ MergeCommit *Commit
+ PotentialMergeCommit *Commit
+
+ Files struct {
+ Nodes []PullRequestFile
+ }
+
+ Author Author
+ MergedBy *Author
+ HeadRepositoryOwner Owner
+ HeadRepository *PRRepository
+ IsCrossRepository bool
+ IsDraft bool
+ MaintainerCanModify bool
+
+ BaseRef struct {
+ BranchProtectionRule struct {
+ RequiresStrictStatusChecks bool
+ RequiredApprovingReviewCount int
+ }
+ }
+
+ ReviewDecision string
+
+ Commits struct {
+ TotalCount int
+ Nodes []PullRequestCommit
+ }
+ StatusCheckRollup struct {
+ Nodes []StatusCheckRollupNode
+ }
+
+ Assignees Assignees
+ Labels Labels
+ ProjectCards ProjectCards
+ ProjectItems ProjectItems
+ Milestone *Milestone
+ Comments Comments
+ ReactionGroups ReactionGroups
+ Reviews PullRequestReviews
+ LatestReviews PullRequestReviews
+ ReviewRequests ReviewRequests
+}
+
+type StatusCheckRollupNode struct {
+ Commit StatusCheckRollupCommit
+}
+
+type StatusCheckRollupCommit struct {
+ StatusCheckRollup CommitStatusCheckRollup
+}
+
+type CommitStatusCheckRollup struct {
+ Contexts CheckContexts
+}
+
+// https://docs.github.com/en/graphql/reference/enums#checkrunstate
+type CheckRunState string
+
+const (
+ CheckRunStateActionRequired CheckRunState = "ACTION_REQUIRED"
+ CheckRunStateCancelled CheckRunState = "CANCELLED"
+ CheckRunStateCompleted CheckRunState = "COMPLETED"
+ CheckRunStateFailure CheckRunState = "FAILURE"
+ CheckRunStateInProgress CheckRunState = "IN_PROGRESS"
+ CheckRunStateNeutral CheckRunState = "NEUTRAL"
+ CheckRunStatePending CheckRunState = "PENDING"
+ CheckRunStateQueued CheckRunState = "QUEUED"
+ CheckRunStateSkipped CheckRunState = "SKIPPED"
+ CheckRunStateStale CheckRunState = "STALE"
+ CheckRunStateStartupFailure CheckRunState = "STARTUP_FAILURE"
+ CheckRunStateSuccess CheckRunState = "SUCCESS"
+ CheckRunStateTimedOut CheckRunState = "TIMED_OUT"
+ CheckRunStateWaiting CheckRunState = "WAITING"
+)
+
+type CheckRunCountByState struct {
+ State CheckRunState
+ Count int
+}
+
+// https://docs.github.com/en/graphql/reference/enums#statusstate
+type StatusState string
+
+const (
+ StatusStateError StatusState = "ERROR"
+ StatusStateExpected StatusState = "EXPECTED"
+ StatusStateFailure StatusState = "FAILURE"
+ StatusStatePending StatusState = "PENDING"
+ StatusStateSuccess StatusState = "SUCCESS"
+)
+
+type StatusContextCountByState struct {
+ State StatusState
+ Count int
+}
+
+// https://docs.github.com/en/graphql/reference/enums#checkstatusstate
+type CheckStatusState string
+
+const (
+ CheckStatusStateCompleted CheckStatusState = "COMPLETED"
+ CheckStatusStateInProgress CheckStatusState = "IN_PROGRESS"
+ CheckStatusStatePending CheckStatusState = "PENDING"
+ CheckStatusStateQueued CheckStatusState = "QUEUED"
+ CheckStatusStateRequested CheckStatusState = "REQUESTED"
+ CheckStatusStateWaiting CheckStatusState = "WAITING"
+)
+
+// https://docs.github.com/en/graphql/reference/enums#checkconclusionstate
+type CheckConclusionState string
+
+const (
+ CheckConclusionStateActionRequired CheckConclusionState = "ACTION_REQUIRED"
+ CheckConclusionStateCancelled CheckConclusionState = "CANCELLED"
+ CheckConclusionStateFailure CheckConclusionState = "FAILURE"
+ CheckConclusionStateNeutral CheckConclusionState = "NEUTRAL"
+ CheckConclusionStateSkipped CheckConclusionState = "SKIPPED"
+ CheckConclusionStateStale CheckConclusionState = "STALE"
+ CheckConclusionStateStartupFailure CheckConclusionState = "STARTUP_FAILURE"
+ CheckConclusionStateSuccess CheckConclusionState = "SUCCESS"
+ CheckConclusionStateTimedOut CheckConclusionState = "TIMED_OUT"
+)
+
+type CheckContexts struct {
+ // These fields are available on newer versions of the GraphQL API
+ // to support summary counts by state
+ CheckRunCount int
+ CheckRunCountsByState []CheckRunCountByState
+ StatusContextCount int
+ StatusContextCountsByState []StatusContextCountByState
+
+ // These are available on older versions and provide more details
+ // required for checks
+ Nodes []CheckContext
+ PageInfo struct {
+ HasNextPage bool
+ EndCursor string
+ }
+}
+
+type CheckContext struct {
+ TypeName string `json:"__typename"`
+ Name string `json:"name"`
+ IsRequired bool `json:"isRequired"`
+ CheckSuite CheckSuite `json:"checkSuite"`
+ // QUEUED IN_PROGRESS COMPLETED WAITING PENDING REQUESTED
+ Status string `json:"status"`
+ // ACTION_REQUIRED TIMED_OUT CANCELLED FAILURE SUCCESS NEUTRAL SKIPPED STARTUP_FAILURE STALE
+ Conclusion CheckConclusionState `json:"conclusion"`
+ StartedAt time.Time `json:"startedAt"`
+ CompletedAt time.Time `json:"completedAt"`
+ DetailsURL string `json:"detailsUrl"`
+
+ /* StatusContext fields */
+ Context string `json:"context"`
+ Description string `json:"description"`
+ // EXPECTED ERROR FAILURE PENDING SUCCESS
+ State StatusState `json:"state"`
+ TargetURL string `json:"targetUrl"`
+ CreatedAt time.Time `json:"createdAt"`
+}
+
+type CheckSuite struct {
+ WorkflowRun WorkflowRun `json:"workflowRun"`
+}
+
+type WorkflowRun struct {
+ Event string `json:"event"`
+ Workflow Workflow `json:"workflow"`
+}
+
+type Workflow struct {
+ Name string `json:"name"`
+}
+
+type PRRepository struct {
+ ID string `json:"id"`
+ Name string `json:"name"`
+}
+
+type AutoMergeRequest struct {
+ AuthorEmail *string `json:"authorEmail"`
+ CommitBody *string `json:"commitBody"`
+ CommitHeadline *string `json:"commitHeadline"`
+ // MERGE, REBASE, SQUASH
+ MergeMethod string `json:"mergeMethod"`
+ EnabledAt time.Time `json:"enabledAt"`
+ EnabledBy Author `json:"enabledBy"`
+}
+
+// Commit loads just the commit SHA and nothing else
+type Commit struct {
+ OID string `json:"oid"`
+}
+
+type PullRequestCommit struct {
+ Commit PullRequestCommitCommit
+}
+
+// PullRequestCommitCommit contains full information about a commit
+type PullRequestCommitCommit struct {
+ OID string `json:"oid"`
+ Authors struct {
+ Nodes []struct {
+ Name string
+ Email string
+ User GitHubUser
+ }
+ }
+ MessageHeadline string
+ MessageBody string
+ CommittedDate time.Time
+ AuthoredDate time.Time
+}
+
+type PullRequestFile struct {
+ Path string `json:"path"`
+ Additions int `json:"additions"`
+ Deletions int `json:"deletions"`
+}
+
+type ReviewRequests struct {
+ Nodes []struct {
+ RequestedReviewer RequestedReviewer
+ }
+}
+
+type RequestedReviewer struct {
+ TypeName string `json:"__typename"`
+ Login string `json:"login"`
+ Name string `json:"name"`
+ Slug string `json:"slug"`
+ Organization struct {
+ Login string `json:"login"`
+ } `json:"organization"`
+}
+
+func (r RequestedReviewer) LoginOrSlug() string {
+ if r.TypeName == teamTypeName {
+ return fmt.Sprintf("%s/%s", r.Organization.Login, r.Slug)
+ }
+ return r.Login
+}
+
+const teamTypeName = "Team"
+
+func (r ReviewRequests) Logins() []string {
+ logins := make([]string, len(r.Nodes))
+ for i, r := range r.Nodes {
+ logins[i] = r.RequestedReviewer.LoginOrSlug()
+ }
+ return logins
+}
+
+func (pr PullRequest) HeadLabel() string {
+ if pr.IsCrossRepository {
+ return fmt.Sprintf("%s:%s", pr.HeadRepositoryOwner.Login, pr.HeadRefName)
+ }
+ return pr.HeadRefName
+}
+
+func (pr PullRequest) Link() string {
+ return pr.URL
+}
+
+func (pr PullRequest) Identifier() string {
+ return pr.ID
+}
+
+func (pr PullRequest) CurrentUserComments() []Comment {
+ return pr.Comments.CurrentUserComments()
+}
+
+func (pr PullRequest) IsOpen() bool {
+ return pr.State == "OPEN"
+}
+
+type PullRequestReviewStatus struct {
+ ChangesRequested bool
+ Approved bool
+ ReviewRequired bool
+}
+
+func (pr *PullRequest) ReviewStatus() PullRequestReviewStatus {
+ var status PullRequestReviewStatus
+ switch pr.ReviewDecision {
+ case "CHANGES_REQUESTED":
+ status.ChangesRequested = true
+ case "APPROVED":
+ status.Approved = true
+ case "REVIEW_REQUIRED":
+ status.ReviewRequired = true
+ }
+ return status
+}
+
+type PullRequestChecksStatus struct {
+ Pending int
+ Failing int
+ Passing int
+ Total int
+}
+
+func (pr *PullRequest) ChecksStatus() PullRequestChecksStatus {
+ var summary PullRequestChecksStatus
+
+ if len(pr.StatusCheckRollup.Nodes) == 0 {
+ return summary
+ }
+
+ contexts := pr.StatusCheckRollup.Nodes[0].Commit.StatusCheckRollup.Contexts
+
+ // If this commit has counts by state then we can summarise check status from those
+ if len(contexts.CheckRunCountsByState) != 0 && len(contexts.StatusContextCountsByState) != 0 {
+ summary.Total = contexts.CheckRunCount + contexts.StatusContextCount
+ for _, countByState := range contexts.CheckRunCountsByState {
+ switch parseCheckStatusFromCheckRunState(countByState.State) {
+ case passing:
+ summary.Passing += countByState.Count
+ case failing:
+ summary.Failing += countByState.Count
+ default:
+ summary.Pending += countByState.Count
+ }
+ }
+
+ for _, countByState := range contexts.StatusContextCountsByState {
+ switch parseCheckStatusFromStatusState(countByState.State) {
+ case passing:
+ summary.Passing += countByState.Count
+ case failing:
+ summary.Failing += countByState.Count
+ default:
+ summary.Pending += countByState.Count
+ }
+ }
+
+ return summary
+ }
+
+ // If we don't have the counts by state, then we'll need to summarise by looking at the more detailed contexts
+ for _, c := range contexts.Nodes {
+ // Nodes are a discriminated union of CheckRun or StatusContext and we can match on
+ // the TypeName to narrow the type.
+ if c.TypeName == "CheckRun" {
+ // https://docs.github.com/en/graphql/reference/enums#checkstatusstate
+ // If the status is completed then we can check the conclusion field
+ if c.Status == "COMPLETED" {
+ switch parseCheckStatusFromCheckConclusionState(c.Conclusion) {
+ case passing:
+ summary.Passing++
+ case failing:
+ summary.Failing++
+ default:
+ summary.Pending++
+ }
+ // otherwise we're in some form of pending state:
+ // "COMPLETED", "IN_PROGRESS", "PENDING", "QUEUED", "REQUESTED", "WAITING" or otherwise unknown
+ } else {
+ summary.Pending++
+ }
+
+ } else { // c.TypeName == StatusContext
+ switch parseCheckStatusFromStatusState(c.State) {
+ case passing:
+ summary.Passing++
+ case failing:
+ summary.Failing++
+ default:
+ summary.Pending++
+ }
+ }
+ summary.Total++
+ }
+
+ return summary
+}
+
+type checkStatus int
+
+const (
+ passing checkStatus = iota
+ failing
+ pending
+)
+
+func parseCheckStatusFromStatusState(state StatusState) checkStatus {
+ switch state {
+ case StatusStateSuccess:
+ return passing
+ case StatusStateFailure, StatusStateError:
+ return failing
+ case StatusStateExpected, StatusStatePending:
+ return pending
+ // Currently, we treat anything unknown as pending, which includes any future unknown
+ // states we might get back from the API. It might be interesting to do some work to add an additional
+ // unknown state.
+ default:
+ return pending
+ }
+}
+
+func parseCheckStatusFromCheckRunState(state CheckRunState) checkStatus {
+ switch state {
+ case CheckRunStateNeutral, CheckRunStateSkipped, CheckRunStateSuccess:
+ return passing
+ case CheckRunStateActionRequired, CheckRunStateCancelled, CheckRunStateFailure, CheckRunStateTimedOut:
+ return failing
+ case CheckRunStateCompleted, CheckRunStateInProgress, CheckRunStatePending, CheckRunStateQueued,
+ CheckRunStateStale, CheckRunStateStartupFailure, CheckRunStateWaiting:
+ return pending
+ // Currently, we treat anything unknown as pending, which includes any future unknown
+ // states we might get back from the API. It might be interesting to do some work to add an additional
+ // unknown state.
+ default:
+ return pending
+ }
+}
+
+func parseCheckStatusFromCheckConclusionState(state CheckConclusionState) checkStatus {
+ switch state {
+ case CheckConclusionStateNeutral, CheckConclusionStateSkipped, CheckConclusionStateSuccess:
+ return passing
+ case CheckConclusionStateActionRequired, CheckConclusionStateCancelled, CheckConclusionStateFailure, CheckConclusionStateTimedOut:
+ return failing
+ case CheckConclusionStateStale, CheckConclusionStateStartupFailure:
+ return pending
+ // Currently, we treat anything unknown as pending, which includes any future unknown
+ // states we might get back from the API. It might be interesting to do some work to add an additional
+ // unknown state.
+ default:
+ return pending
+ }
+}
+
+func (pr *PullRequest) DisplayableReviews() PullRequestReviews {
+ published := []PullRequestReview{}
+ for _, prr := range pr.Reviews.Nodes {
+ //Dont display pending reviews
+ //Dont display commenting reviews without top level comment body
+ if prr.State != "PENDING" && !(prr.State == "COMMENTED" && prr.Body == "") {
+ published = append(published, prr)
+ }
+ }
+ return PullRequestReviews{Nodes: published, TotalCount: len(published)}
+}
+
+// CreatePullRequest creates a pull request in a GitHub repository
+func CreatePullRequest(client *Client, repo *Repository, params map[string]interface{}) (*PullRequest, error) {
+ query := `
+ mutation PullRequestCreate($input: CreatePullRequestInput!) {
+ createPullRequest(input: $input) {
+ pullRequest {
+ id
+ url
+ }
+ }
+ }`
+
+ inputParams := map[string]interface{}{
+ "repositoryId": repo.ID,
+ }
+ for key, val := range params {
+ switch key {
+ case "title", "body", "draft", "baseRefName", "headRefName", "maintainerCanModify":
+ inputParams[key] = val
+ }
+ }
+ variables := map[string]interface{}{
+ "input": inputParams,
+ }
+
+ result := struct {
+ CreatePullRequest struct {
+ PullRequest PullRequest
+ }
+ }{}
+
+ err := client.GraphQL(repo.RepoHost(), query, variables, &result)
+ if err != nil {
+ return nil, err
+ }
+ pr := &result.CreatePullRequest.PullRequest
+
+ // metadata parameters aren't currently available in `createPullRequest`,
+ // but they are in `updatePullRequest`
+ updateParams := make(map[string]interface{})
+ for key, val := range params {
+ switch key {
+ case "assigneeIds", "labelIds", "projectIds", "milestoneId":
+ if !isBlank(val) {
+ updateParams[key] = val
+ }
+ }
+ }
+ if len(updateParams) > 0 {
+ updateQuery := `
+ mutation PullRequestCreateMetadata($input: UpdatePullRequestInput!) {
+ updatePullRequest(input: $input) { clientMutationId }
+ }`
+ updateParams["pullRequestId"] = pr.ID
+ variables := map[string]interface{}{
+ "input": updateParams,
+ }
+ err := client.GraphQL(repo.RepoHost(), updateQuery, variables, &result)
+ if err != nil {
+ return pr, err
+ }
+ }
+
+ // reviewers are requested in yet another additional mutation
+ reviewParams := make(map[string]interface{})
+ if ids, ok := params["userReviewerIds"]; ok && !isBlank(ids) {
+ reviewParams["userIds"] = ids
+ }
+ if ids, ok := params["teamReviewerIds"]; ok && !isBlank(ids) {
+ reviewParams["teamIds"] = ids
+ }
+
+ //TODO: How much work to extract this into own method and use for create and edit?
+ if len(reviewParams) > 0 {
+ reviewQuery := `
+ mutation PullRequestCreateRequestReviews($input: RequestReviewsInput!) {
+ requestReviews(input: $input) { clientMutationId }
+ }`
+ reviewParams["pullRequestId"] = pr.ID
+ reviewParams["union"] = true
+ variables := map[string]interface{}{
+ "input": reviewParams,
+ }
+ err := client.GraphQL(repo.RepoHost(), reviewQuery, variables, &result)
+ if err != nil {
+ return pr, err
+ }
+ }
+
+ // projectsV2 are added in yet another mutation
+ projectV2Ids, ok := params["projectV2Ids"].([]string)
+ if ok {
+ projectItems := make(map[string]string, len(projectV2Ids))
+ for _, p := range projectV2Ids {
+ projectItems[p] = pr.ID
+ }
+ err = UpdateProjectV2Items(client, repo, projectItems, nil)
+ if err != nil {
+ return pr, err
+ }
+ }
+
+ return pr, nil
+}
+
+func UpdatePullRequestReviews(client *Client, repo ghrepo.Interface, params githubv4.RequestReviewsInput) error {
+ var mutation struct {
+ RequestReviews struct {
+ PullRequest struct {
+ ID string
+ }
+ } `graphql:"requestReviews(input: $input)"`
+ }
+ variables := map[string]interface{}{"input": params}
+ err := client.Mutate(repo.RepoHost(), "PullRequestUpdateRequestReviews", &mutation, variables)
+ return err
+}
+
+func isBlank(v interface{}) bool {
+ switch vv := v.(type) {
+ case string:
+ return vv == ""
+ case []string:
+ return len(vv) == 0
+ default:
+ return true
+ }
+}
+
+func PullRequestClose(httpClient *http.Client, repo ghrepo.Interface, prID string) error {
+ var mutation struct {
+ ClosePullRequest struct {
+ PullRequest struct {
+ ID githubv4.ID
+ }
+ } `graphql:"closePullRequest(input: $input)"`
+ }
+
+ variables := map[string]interface{}{
+ "input": githubv4.ClosePullRequestInput{
+ PullRequestID: prID,
+ },
+ }
+
+ client := NewClientFromHTTP(httpClient)
+ return client.Mutate(repo.RepoHost(), "PullRequestClose", &mutation, variables)
+}
+
+func PullRequestReopen(httpClient *http.Client, repo ghrepo.Interface, prID string) error {
+ var mutation struct {
+ ReopenPullRequest struct {
+ PullRequest struct {
+ ID githubv4.ID
+ }
+ } `graphql:"reopenPullRequest(input: $input)"`
+ }
+
+ variables := map[string]interface{}{
+ "input": githubv4.ReopenPullRequestInput{
+ PullRequestID: prID,
+ },
+ }
+
+ client := NewClientFromHTTP(httpClient)
+ return client.Mutate(repo.RepoHost(), "PullRequestReopen", &mutation, variables)
+}
+
+func PullRequestReady(client *Client, repo ghrepo.Interface, pr *PullRequest) error {
+ var mutation struct {
+ MarkPullRequestReadyForReview struct {
+ PullRequest struct {
+ ID githubv4.ID
+ }
+ } `graphql:"markPullRequestReadyForReview(input: $input)"`
+ }
+
+ variables := map[string]interface{}{
+ "input": githubv4.MarkPullRequestReadyForReviewInput{
+ PullRequestID: pr.ID,
+ },
+ }
+
+ return client.Mutate(repo.RepoHost(), "PullRequestReadyForReview", &mutation, variables)
+}
+
+func ConvertPullRequestToDraft(client *Client, repo ghrepo.Interface, pr *PullRequest) error {
+ var mutation struct {
+ ConvertPullRequestToDraft struct {
+ PullRequest struct {
+ ID githubv4.ID
+ }
+ } `graphql:"convertPullRequestToDraft(input: $input)"`
+ }
+
+ variables := map[string]interface{}{
+ "input": githubv4.ConvertPullRequestToDraftInput{
+ PullRequestID: pr.ID,
+ },
+ }
+
+ return client.Mutate(repo.RepoHost(), "ConvertPullRequestToDraft", &mutation, variables)
+}
+
+func BranchDeleteRemote(client *Client, repo ghrepo.Interface, branch string) error {
+ path := fmt.Sprintf("repos/%s/%s/git/refs/heads/%s", repo.RepoOwner(), repo.RepoName(), url.PathEscape(branch))
+ return client.REST(repo.RepoHost(), "DELETE", path, nil, nil)
+}
diff --git a/vendor/github.com/cli/cli/v2/api/queries_pr_review.go b/vendor/github.com/cli/cli/v2/api/queries_pr_review.go
new file mode 100644
index 000000000..d5565b54b
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/api/queries_pr_review.go
@@ -0,0 +1,117 @@
+package api
+
+import (
+ "time"
+
+ "github.com/cli/cli/v2/internal/ghrepo"
+ "github.com/shurcooL/githubv4"
+)
+
+type PullRequestReviewState int
+
+const (
+ ReviewApprove PullRequestReviewState = iota
+ ReviewRequestChanges
+ ReviewComment
+)
+
+type PullRequestReviewInput struct {
+ Body string
+ State PullRequestReviewState
+}
+
+type PullRequestReviews struct {
+ Nodes []PullRequestReview
+ PageInfo struct {
+ HasNextPage bool
+ EndCursor string
+ }
+ TotalCount int
+}
+
+type PullRequestReview struct {
+ ID string `json:"id"`
+ Author CommentAuthor `json:"author"`
+ AuthorAssociation string `json:"authorAssociation"`
+ Body string `json:"body"`
+ SubmittedAt *time.Time `json:"submittedAt"`
+ IncludesCreatedEdit bool `json:"includesCreatedEdit"`
+ ReactionGroups ReactionGroups `json:"reactionGroups"`
+ State string `json:"state"`
+ URL string `json:"url,omitempty"`
+ Commit Commit `json:"commit"`
+}
+
+func AddReview(client *Client, repo ghrepo.Interface, pr *PullRequest, input *PullRequestReviewInput) error {
+ var mutation struct {
+ AddPullRequestReview struct {
+ ClientMutationID string
+ } `graphql:"addPullRequestReview(input:$input)"`
+ }
+
+ state := githubv4.PullRequestReviewEventComment
+ switch input.State {
+ case ReviewApprove:
+ state = githubv4.PullRequestReviewEventApprove
+ case ReviewRequestChanges:
+ state = githubv4.PullRequestReviewEventRequestChanges
+ }
+
+ body := githubv4.String(input.Body)
+ variables := map[string]interface{}{
+ "input": githubv4.AddPullRequestReviewInput{
+ PullRequestID: pr.ID,
+ Event: &state,
+ Body: &body,
+ },
+ }
+
+ return client.Mutate(repo.RepoHost(), "PullRequestReviewAdd", &mutation, variables)
+}
+
+func (prr PullRequestReview) Identifier() string {
+ return prr.ID
+}
+
+func (prr PullRequestReview) AuthorLogin() string {
+ return prr.Author.Login
+}
+
+func (prr PullRequestReview) Association() string {
+ return prr.AuthorAssociation
+}
+
+func (prr PullRequestReview) Content() string {
+ return prr.Body
+}
+
+func (prr PullRequestReview) Created() time.Time {
+ if prr.SubmittedAt == nil {
+ return time.Time{}
+ }
+ return *prr.SubmittedAt
+}
+
+func (prr PullRequestReview) HiddenReason() string {
+ return ""
+}
+
+func (prr PullRequestReview) IsEdited() bool {
+ return prr.IncludesCreatedEdit
+}
+
+func (prr PullRequestReview) IsHidden() bool {
+ return false
+}
+
+func (prr PullRequestReview) Link() string {
+ return prr.URL
+}
+
+func (prr PullRequestReview) Reactions() ReactionGroups {
+ return prr.ReactionGroups
+}
+
+func (prr PullRequestReview) Status() string {
+ return prr.State
+}
diff --git a/vendor/github.com/cli/cli/v2/api/queries_projects_v2.go b/vendor/github.com/cli/cli/v2/api/queries_projects_v2.go
new file mode 100644
index 000000000..958be6616
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/api/queries_projects_v2.go
@@ -0,0 +1,330 @@
+package api
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/cli/cli/v2/internal/ghrepo"
+ "github.com/shurcooL/githubv4"
+)
+
+const (
+ errorProjectsV2ReadScope = "field requires one of the following scopes: ['read:project']"
+ errorProjectsV2UserField = "Field 'projectsV2' doesn't exist on type 'User'"
+ errorProjectsV2RepositoryField = "Field 'projectsV2' doesn't exist on type 'Repository'"
+ errorProjectsV2OrganizationField = "Field 'projectsV2' doesn't exist on type 'Organization'"
+ errorProjectsV2IssueField = "Field 'projectItems' doesn't exist on type 'Issue'"
+ errorProjectsV2PullRequestField = "Field 'projectItems' doesn't exist on type 'PullRequest'"
+)
+
+type ProjectV2 struct {
+ ID string `json:"id"`
+ Title string `json:"title"`
+ Number int `json:"number"`
+ ResourcePath string `json:"resourcePath"`
+ Closed bool `json:"closed"`
+}
+
+// UpdateProjectV2Items uses the addProjectV2ItemById and the deleteProjectV2Item mutations
+// to add and delete items from projects. The addProjectItems and deleteProjectItems arguments are
+// mappings between a project and an item. This function can be used across multiple projects
+// and items. Note that the deleteProjectV2Item mutation requires the item id from the project not
+// the global id.
+func UpdateProjectV2Items(client *Client, repo ghrepo.Interface, addProjectItems, deleteProjectItems map[string]string) error {
+ l := len(addProjectItems) + len(deleteProjectItems)
+ if l == 0 {
+ return nil
+ }
+ inputs := make([]string, 0, l)
+ mutations := make([]string, 0, l)
+ variables := make(map[string]interface{}, l)
+ var i int
+
+ for project, item := range addProjectItems {
+ inputs = append(inputs, fmt.Sprintf("$input_%03d: AddProjectV2ItemByIdInput!", i))
+ mutations = append(mutations, fmt.Sprintf("add_%03d: addProjectV2ItemById(input: $input_%03d) { item { id } }", i, i))
+ variables[fmt.Sprintf("input_%03d", i)] = map[string]interface{}{"contentId": item, "projectId": project}
+ i++
+ }
+
+ for project, item := range deleteProjectItems {
+ inputs = append(inputs, fmt.Sprintf("$input_%03d: DeleteProjectV2ItemInput!", i))
+ mutations = append(mutations, fmt.Sprintf("delete_%03d: deleteProjectV2Item(input: $input_%03d) { deletedItemId }", i, i))
+ variables[fmt.Sprintf("input_%03d", i)] = map[string]interface{}{"itemId": item, "projectId": project}
+ i++
+ }
+
+ query := fmt.Sprintf(`mutation UpdateProjectV2Items(%s) {%s}`, strings.Join(inputs, " "), strings.Join(mutations, " "))
+
+ return client.GraphQL(repo.RepoHost(), query, variables, nil)
+}
+
+// ProjectsV2ItemsForIssue fetches all ProjectItems for an issue.
+func ProjectsV2ItemsForIssue(client *Client, repo ghrepo.Interface, issue *Issue) error {
+ type projectV2ItemStatus struct {
+ StatusFragment struct {
+ OptionID string `json:"optionId"`
+ Name string `json:"name"`
+ } `graphql:"... on ProjectV2ItemFieldSingleSelectValue"`
+ }
+
+ type projectV2Item struct {
+ ID string `json:"id"`
+ Project struct {
+ ID string `json:"id"`
+ Title string `json:"title"`
+ }
+ Status projectV2ItemStatus `graphql:"status:fieldValueByName(name: \"Status\")"`
+ }
+
+ type response struct {
+ Repository struct {
+ Issue struct {
+ ProjectItems struct {
+ Nodes []*projectV2Item
+ PageInfo struct {
+ HasNextPage bool
+ EndCursor string
+ }
+ } `graphql:"projectItems(first: 100, after: $endCursor)"`
+ } `graphql:"issue(number: $number)"`
+ } `graphql:"repository(owner: $owner, name: $name)"`
+ }
+ variables := map[string]interface{}{
+ "owner": githubv4.String(repo.RepoOwner()),
+ "name": githubv4.String(repo.RepoName()),
+ "number": githubv4.Int(issue.Number),
+ "endCursor": (*githubv4.String)(nil),
+ }
+ var items ProjectItems
+ for {
+ var query response
+ err := client.Query(repo.RepoHost(), "IssueProjectItems", &query, variables)
+ if err != nil {
+ return err
+ }
+ for _, projectItemNode := range query.Repository.Issue.ProjectItems.Nodes {
+ items.Nodes = append(items.Nodes, &ProjectV2Item{
+ ID: projectItemNode.ID,
+ Project: ProjectV2ItemProject{
+ ID: projectItemNode.Project.ID,
+ Title: projectItemNode.Project.Title,
+ },
+ Status: ProjectV2ItemStatus{
+ OptionID: projectItemNode.Status.StatusFragment.OptionID,
+ Name: projectItemNode.Status.StatusFragment.Name,
+ },
+ })
+ }
+
+ if !query.Repository.Issue.ProjectItems.PageInfo.HasNextPage {
+ break
+ }
+ variables["endCursor"] = githubv4.String(query.Repository.Issue.ProjectItems.PageInfo.EndCursor)
+ }
+ issue.ProjectItems = items
+ return nil
+}
+
+// ProjectsV2ItemsForPullRequest fetches all ProjectItems for a pull request.
+func ProjectsV2ItemsForPullRequest(client *Client, repo ghrepo.Interface, pr *PullRequest) error {
+ type projectV2ItemStatus struct {
+ StatusFragment struct {
+ OptionID string `json:"optionId"`
+ Name string `json:"name"`
+ } `graphql:"... on ProjectV2ItemFieldSingleSelectValue"`
+ }
+
+ type projectV2Item struct {
+ ID string `json:"id"`
+ Project struct {
+ ID string `json:"id"`
+ Title string `json:"title"`
+ }
+ Status projectV2ItemStatus `graphql:"status:fieldValueByName(name: \"Status\")"`
+ }
+
+ type response struct {
+ Repository struct {
+ PullRequest struct {
+ ProjectItems struct {
+ Nodes []*projectV2Item
+ PageInfo struct {
+ HasNextPage bool
+ EndCursor string
+ }
+ } `graphql:"projectItems(first: 100, after: $endCursor)"`
+ } `graphql:"pullRequest(number: $number)"`
+ } `graphql:"repository(owner: $owner, name: $name)"`
+ }
+ variables := map[string]interface{}{
+ "owner": githubv4.String(repo.RepoOwner()),
+ "name": githubv4.String(repo.RepoName()),
+ "number": githubv4.Int(pr.Number),
+ "endCursor": (*githubv4.String)(nil),
+ }
+ var items ProjectItems
+ for {
+ var query response
+ err := client.Query(repo.RepoHost(), "PullRequestProjectItems", &query, variables)
+ if err != nil {
+ return err
+ }
+
+ for _, projectItemNode := range query.Repository.PullRequest.ProjectItems.Nodes {
+ items.Nodes = append(items.Nodes, &ProjectV2Item{
+ ID: projectItemNode.ID,
+ Project: ProjectV2ItemProject{
+ ID: projectItemNode.Project.ID,
+ Title: projectItemNode.Project.Title,
+ },
+ Status: ProjectV2ItemStatus{
+ OptionID: projectItemNode.Status.StatusFragment.OptionID,
+ Name: projectItemNode.Status.StatusFragment.Name,
+ },
+ })
+ }
+
+ if !query.Repository.PullRequest.ProjectItems.PageInfo.HasNextPage {
+ break
+ }
+ variables["endCursor"] = githubv4.String(query.Repository.PullRequest.ProjectItems.PageInfo.EndCursor)
+ }
+ pr.ProjectItems = items
+ return nil
+}
+
+// OrganizationProjectsV2 fetches all open projectsV2 for an organization.
+func OrganizationProjectsV2(client *Client, repo ghrepo.Interface) ([]ProjectV2, error) {
+ type responseData struct {
+ Organization struct {
+ ProjectsV2 struct {
+ Nodes []ProjectV2
+ PageInfo struct {
+ HasNextPage bool
+ EndCursor string
+ }
+ } `graphql:"projectsV2(first: 100, orderBy: {field: TITLE, direction: ASC}, after: $endCursor, query: $query)"`
+ } `graphql:"organization(login: $owner)"`
+ }
+
+ variables := map[string]interface{}{
+ "owner": githubv4.String(repo.RepoOwner()),
+ "endCursor": (*githubv4.String)(nil),
+ "query": githubv4.String("is:open"),
+ }
+
+ var projectsV2 []ProjectV2
+ for {
+ var query responseData
+ err := client.Query(repo.RepoHost(), "OrganizationProjectV2List", &query, variables)
+ if err != nil {
+ return nil, err
+ }
+
+ projectsV2 = append(projectsV2, query.Organization.ProjectsV2.Nodes...)
+
+ if !query.Organization.ProjectsV2.PageInfo.HasNextPage {
+ break
+ }
+ variables["endCursor"] = githubv4.String(query.Organization.ProjectsV2.PageInfo.EndCursor)
+ }
+
+ return projectsV2, nil
+}
+
+// RepoProjectsV2 fetches all open projectsV2 for a repository.
+func RepoProjectsV2(client *Client, repo ghrepo.Interface) ([]ProjectV2, error) {
+ type responseData struct {
+ Repository struct {
+ ProjectsV2 struct {
+ Nodes []ProjectV2
+ PageInfo struct {
+ HasNextPage bool
+ EndCursor string
+ }
+ } `graphql:"projectsV2(first: 100, orderBy: {field: TITLE, direction: ASC}, after: $endCursor, query: $query)"`
+ } `graphql:"repository(owner: $owner, name: $name)"`
+ }
+
+ variables := map[string]interface{}{
+ "owner": githubv4.String(repo.RepoOwner()),
+ "name": githubv4.String(repo.RepoName()),
+ "endCursor": (*githubv4.String)(nil),
+ "query": githubv4.String("is:open"),
+ }
+
+ var projectsV2 []ProjectV2
+ for {
+ var query responseData
+ err := client.Query(repo.RepoHost(), "RepositoryProjectV2List", &query, variables)
+ if err != nil {
+ return nil, err
+ }
+
+ projectsV2 = append(projectsV2, query.Repository.ProjectsV2.Nodes...)
+
+ if !query.Repository.ProjectsV2.PageInfo.HasNextPage {
+ break
+ }
+ variables["endCursor"] = githubv4.String(query.Repository.ProjectsV2.PageInfo.EndCursor)
+ }
+
+ return projectsV2, nil
+}
+
+// CurrentUserProjectsV2 fetches all open projectsV2 for current user.
+func CurrentUserProjectsV2(client *Client, hostname string) ([]ProjectV2, error) {
+ type responseData struct {
+ Viewer struct {
+ ProjectsV2 struct {
+ Nodes []ProjectV2
+ PageInfo struct {
+ HasNextPage bool
+ EndCursor string
+ }
+ } `graphql:"projectsV2(first: 100, orderBy: {field: TITLE, direction: ASC}, after: $endCursor, query: $query)"`
+ } `graphql:"viewer"`
+ }
+
+ variables := map[string]interface{}{
+ "endCursor": (*githubv4.String)(nil),
+ "query": githubv4.String("is:open"),
+ }
+
+ var projectsV2 []ProjectV2
+ for {
+ var query responseData
+ err := client.Query(hostname, "UserProjectV2List", &query, variables)
+ if err != nil {
+ return nil, err
+ }
+
+ projectsV2 = append(projectsV2, query.Viewer.ProjectsV2.Nodes...)
+
+ if !query.Viewer.ProjectsV2.PageInfo.HasNextPage {
+ break
+ }
+ variables["endCursor"] = githubv4.String(query.Viewer.ProjectsV2.PageInfo.EndCursor)
+ }
+
+ return projectsV2, nil
+}
+
+// When querying ProjectsV2 fields we generally dont want to show the user
+// scope errors and field does not exist errors. ProjectsV2IgnorableError
+// checks against known error strings to see if an error can be safely ignored.
+// Due to the fact that the GraphQLClient can return multiple types of errors
+// this uses brittle string comparison to check against the known error strings.
+func ProjectsV2IgnorableError(err error) bool {
+ msg := err.Error()
+ if strings.Contains(msg, errorProjectsV2ReadScope) ||
+ strings.Contains(msg, errorProjectsV2UserField) ||
+ strings.Contains(msg, errorProjectsV2RepositoryField) ||
+ strings.Contains(msg, errorProjectsV2OrganizationField) ||
+ strings.Contains(msg, errorProjectsV2IssueField) ||
+ strings.Contains(msg, errorProjectsV2PullRequestField) {
+ return true
+ }
+ return false
+}
diff --git a/vendor/github.com/cli/cli/v2/api/queries_repo.go b/vendor/github.com/cli/cli/v2/api/queries_repo.go
new file mode 100644
index 000000000..01f85354f
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/api/queries_repo.go
@@ -0,0 +1,1390 @@
+package api
+
+import (
+ "bytes"
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "net/http"
+ "sort"
+ "strings"
+ "time"
+
+ "github.com/cli/cli/v2/internal/ghinstance"
+ "golang.org/x/sync/errgroup"
+
+ "github.com/cli/cli/v2/internal/ghrepo"
+ ghAPI "github.com/cli/go-gh/v2/pkg/api"
+ "github.com/shurcooL/githubv4"
+)
+
+const (
+ errorResolvingOrganization = "Could not resolve to an Organization"
+)
+
+// Repository contains information about a GitHub repo
+type Repository struct {
+ ID string
+ Name string
+ NameWithOwner string
+ Owner RepositoryOwner
+ Parent *Repository
+ TemplateRepository *Repository
+ Description string
+ HomepageURL string
+ OpenGraphImageURL string
+ UsesCustomOpenGraphImage bool
+ URL string
+ SSHURL string
+ MirrorURL string
+ SecurityPolicyURL string
+
+ CreatedAt time.Time
+ PushedAt *time.Time
+ UpdatedAt time.Time
+
+ IsBlankIssuesEnabled bool
+ IsSecurityPolicyEnabled bool
+ HasIssuesEnabled bool
+ HasProjectsEnabled bool
+ HasDiscussionsEnabled bool
+ HasWikiEnabled bool
+ MergeCommitAllowed bool
+ SquashMergeAllowed bool
+ RebaseMergeAllowed bool
+ AutoMergeAllowed bool
+
+ ForkCount int
+ StargazerCount int
+ Watchers struct {
+ TotalCount int `json:"totalCount"`
+ }
+ Issues struct {
+ TotalCount int `json:"totalCount"`
+ }
+ PullRequests struct {
+ TotalCount int `json:"totalCount"`
+ }
+
+ CodeOfConduct *CodeOfConduct
+ ContactLinks []ContactLink
+ DefaultBranchRef BranchRef
+ DeleteBranchOnMerge bool
+ DiskUsage int
+ FundingLinks []FundingLink
+ IsArchived bool
+ IsEmpty bool
+ IsFork bool
+ ForkingAllowed bool
+ IsInOrganization bool
+ IsMirror bool
+ IsPrivate bool
+ IsTemplate bool
+ IsUserConfigurationRepository bool
+ LicenseInfo *RepositoryLicense
+ ViewerCanAdminister bool
+ ViewerDefaultCommitEmail string
+ ViewerDefaultMergeMethod string
+ ViewerHasStarred bool
+ ViewerPermission string
+ ViewerPossibleCommitEmails []string
+ ViewerSubscription string
+ Visibility string
+
+ RepositoryTopics struct {
+ Nodes []struct {
+ Topic RepositoryTopic
+ }
+ }
+ PrimaryLanguage *CodingLanguage
+ Languages struct {
+ Edges []struct {
+ Size int `json:"size"`
+ Node CodingLanguage `json:"node"`
+ }
+ }
+ IssueTemplates []IssueTemplate
+ PullRequestTemplates []PullRequestTemplate
+ Labels struct {
+ Nodes []IssueLabel
+ }
+ Milestones struct {
+ Nodes []Milestone
+ }
+ LatestRelease *RepositoryRelease
+
+ AssignableUsers struct {
+ Nodes []GitHubUser
+ }
+ MentionableUsers struct {
+ Nodes []GitHubUser
+ }
+ Projects struct {
+ Nodes []RepoProject
+ }
+
+ // pseudo-field that keeps track of host name of this repo
+ hostname string
+}
+
+// RepositoryOwner is the owner of a GitHub repository
+type RepositoryOwner struct {
+ ID string `json:"id"`
+ Login string `json:"login"`
+}
+
+type GitHubUser struct {
+ ID string `json:"id"`
+ Login string `json:"login"`
+ Name string `json:"name"`
+}
+
+// BranchRef is the branch name in a GitHub repository
+type BranchRef struct {
+ Name string `json:"name"`
+}
+
+type CodeOfConduct struct {
+ Key string `json:"key"`
+ Name string `json:"name"`
+ URL string `json:"url"`
+}
+
+type RepositoryLicense struct {
+ Key string `json:"key"`
+ Name string `json:"name"`
+ Nickname string `json:"nickname"`
+}
+
+type ContactLink struct {
+ About string `json:"about"`
+ Name string `json:"name"`
+ URL string `json:"url"`
+}
+
+type FundingLink struct {
+ Platform string `json:"platform"`
+ URL string `json:"url"`
+}
+
+type CodingLanguage struct {
+ Name string `json:"name"`
+}
+
+type IssueTemplate struct {
+ Name string `json:"name"`
+ Title string `json:"title"`
+ Body string `json:"body"`
+ About string `json:"about"`
+}
+
+type PullRequestTemplate struct {
+ Filename string `json:"filename"`
+ Body string `json:"body"`
+}
+
+type RepositoryTopic struct {
+ Name string `json:"name"`
+}
+
+type RepositoryRelease struct {
+ Name string `json:"name"`
+ TagName string `json:"tagName"`
+ URL string `json:"url"`
+ PublishedAt time.Time `json:"publishedAt"`
+}
+
+type IssueLabel struct {
+ ID string `json:"id"`
+ Name string `json:"name"`
+ Description string `json:"description"`
+ Color string `json:"color"`
+}
+
+type License struct {
+ Key string `json:"key"`
+ Name string `json:"name"`
+}
+
+// RepoOwner is the login name of the owner
+func (r Repository) RepoOwner() string {
+ return r.Owner.Login
+}
+
+// RepoName is the name of the repository
+func (r Repository) RepoName() string {
+ return r.Name
+}
+
+// RepoHost is the GitHub hostname of the repository
+func (r Repository) RepoHost() string {
+ return r.hostname
+}
+
+// ViewerCanPush is true when the requesting user has push access
+func (r Repository) ViewerCanPush() bool {
+ switch r.ViewerPermission {
+ case "ADMIN", "MAINTAIN", "WRITE":
+ return true
+ default:
+ return false
+ }
+}
+
+// ViewerCanTriage is true when the requesting user can triage issues and pull requests
+func (r Repository) ViewerCanTriage() bool {
+ switch r.ViewerPermission {
+ case "ADMIN", "MAINTAIN", "WRITE", "TRIAGE":
+ return true
+ default:
+ return false
+ }
+}
+
+func FetchRepository(client *Client, repo ghrepo.Interface, fields []string) (*Repository, error) {
+ query := fmt.Sprintf(`query RepositoryInfo($owner: String!, $name: String!) {
+ repository(owner: $owner, name: $name) {%s}
+ }`, RepositoryGraphQL(fields))
+
+ variables := map[string]interface{}{
+ "owner": repo.RepoOwner(),
+ "name": repo.RepoName(),
+ }
+
+ var result struct {
+ Repository *Repository
+ }
+ if err := client.GraphQL(repo.RepoHost(), query, variables, &result); err != nil {
+ return nil, err
+ }
+ // The GraphQL API should have returned an error in case of a missing repository, but this isn't
+ // guaranteed to happen when an authentication token with insufficient permissions is being used.
+ if result.Repository == nil {
+ return nil, GraphQLError{
+ GraphQLError: &ghAPI.GraphQLError{
+ Errors: []ghAPI.GraphQLErrorItem{{
+ Type: "NOT_FOUND",
+ Message: fmt.Sprintf("Could not resolve to a Repository with the name '%s/%s'.", repo.RepoOwner(), repo.RepoName()),
+ }},
+ },
+ }
+ }
+
+ return InitRepoHostname(result.Repository, repo.RepoHost()), nil
+}
+
+func GitHubRepo(client *Client, repo ghrepo.Interface) (*Repository, error) {
+ query := `
+ fragment repo on Repository {
+ id
+ name
+ owner { login }
+ hasIssuesEnabled
+ description
+ hasWikiEnabled
+ viewerPermission
+ defaultBranchRef {
+ name
+ }
+ }
+
+ query RepositoryInfo($owner: String!, $name: String!) {
+ repository(owner: $owner, name: $name) {
+ ...repo
+ parent {
+ ...repo
+ }
+ mergeCommitAllowed
+ rebaseMergeAllowed
+ squashMergeAllowed
+ }
+ }`
+ variables := map[string]interface{}{
+ "owner": repo.RepoOwner(),
+ "name": repo.RepoName(),
+ }
+
+ var result struct {
+ Repository *Repository
+ }
+ if err := client.GraphQL(repo.RepoHost(), query, variables, &result); err != nil {
+ return nil, err
+ }
+ // The GraphQL API should have returned an error in case of a missing repository, but this isn't
+ // guaranteed to happen when an authentication token with insufficient permissions is being used.
+ if result.Repository == nil {
+ return nil, GraphQLError{
+ GraphQLError: &ghAPI.GraphQLError{
+ Errors: []ghAPI.GraphQLErrorItem{{
+ Type: "NOT_FOUND",
+ Message: fmt.Sprintf("Could not resolve to a Repository with the name '%s/%s'.", repo.RepoOwner(), repo.RepoName()),
+ }},
+ },
+ }
+ }
+
+ return InitRepoHostname(result.Repository, repo.RepoHost()), nil
+}
+
+func RepoDefaultBranch(client *Client, repo ghrepo.Interface) (string, error) {
+ if r, ok := repo.(*Repository); ok && r.DefaultBranchRef.Name != "" {
+ return r.DefaultBranchRef.Name, nil
+ }
+
+ r, err := GitHubRepo(client, repo)
+ if err != nil {
+ return "", err
+ }
+ return r.DefaultBranchRef.Name, nil
+}
+
+func CanPushToRepo(httpClient *http.Client, repo ghrepo.Interface) (bool, error) {
+ if r, ok := repo.(*Repository); ok && r.ViewerPermission != "" {
+ return r.ViewerCanPush(), nil
+ }
+
+ apiClient := NewClientFromHTTP(httpClient)
+ r, err := GitHubRepo(apiClient, repo)
+ if err != nil {
+ return false, err
+ }
+ return r.ViewerCanPush(), nil
+}
+
+// RepoParent finds out the parent repository of a fork
+func RepoParent(client *Client, repo ghrepo.Interface) (ghrepo.Interface, error) {
+ var query struct {
+ Repository struct {
+ Parent *struct {
+ Name string
+ Owner struct {
+ Login string
+ }
+ }
+ } `graphql:"repository(owner: $owner, name: $name)"`
+ }
+
+ variables := map[string]interface{}{
+ "owner": githubv4.String(repo.RepoOwner()),
+ "name": githubv4.String(repo.RepoName()),
+ }
+
+ err := client.Query(repo.RepoHost(), "RepositoryFindParent", &query, variables)
+ if err != nil {
+ return nil, err
+ }
+ if query.Repository.Parent == nil {
+ return nil, nil
+ }
+
+ parent := ghrepo.NewWithHost(query.Repository.Parent.Owner.Login, query.Repository.Parent.Name, repo.RepoHost())
+ return parent, nil
+}
+
+// RepoNetworkResult describes the relationship between related repositories
+type RepoNetworkResult struct {
+ ViewerLogin string
+ Repositories []*Repository
+}
+
+// RepoNetwork inspects the relationship between multiple GitHub repositories
+func RepoNetwork(client *Client, repos []ghrepo.Interface) (RepoNetworkResult, error) {
+ var hostname string
+ if len(repos) > 0 {
+ hostname = repos[0].RepoHost()
+ }
+
+ queries := make([]string, 0, len(repos))
+ for i, repo := range repos {
+ queries = append(queries, fmt.Sprintf(`
+ repo_%03d: repository(owner: %q, name: %q) {
+ ...repo
+ parent {
+ ...repo
+ }
+ }
+ `, i, repo.RepoOwner(), repo.RepoName()))
+ }
+
+ // Since the query is constructed dynamically, we can't parse a response
+ // format using a static struct. Instead, hold the raw JSON data until we
+ // decide how to parse it manually.
+ graphqlResult := make(map[string]*json.RawMessage)
+ var result RepoNetworkResult
+
+ err := client.GraphQL(hostname, fmt.Sprintf(`
+ fragment repo on Repository {
+ id
+ name
+ owner { login }
+ viewerPermission
+ defaultBranchRef {
+ name
+ }
+ isPrivate
+ }
+ query RepositoryNetwork {
+ viewer { login }
+ %s
+ }
+ `, strings.Join(queries, "")), nil, &graphqlResult)
+ var graphqlError GraphQLError
+ if errors.As(err, &graphqlError) {
+ // If the only errors are that certain repositories are not found,
+ // continue processing this response instead of returning an error
+ tolerated := true
+ for _, ge := range graphqlError.Errors {
+ if ge.Type != "NOT_FOUND" {
+ tolerated = false
+ }
+ }
+ if tolerated {
+ err = nil
+ }
+ }
+ if err != nil {
+ return result, err
+ }
+
+ keys := make([]string, 0, len(graphqlResult))
+ for key := range graphqlResult {
+ keys = append(keys, key)
+ }
+ // sort keys to ensure `repo_{N}` entries are processed in order
+ sort.Strings(keys)
+
+ // Iterate over keys of GraphQL response data and, based on its name,
+ // dynamically allocate the target struct an individual message gets decoded to.
+ for _, name := range keys {
+ jsonMessage := graphqlResult[name]
+ if name == "viewer" {
+ viewerResult := struct {
+ Login string
+ }{}
+ decoder := json.NewDecoder(bytes.NewReader([]byte(*jsonMessage)))
+ if err := decoder.Decode(&viewerResult); err != nil {
+ return result, err
+ }
+ result.ViewerLogin = viewerResult.Login
+ } else if strings.HasPrefix(name, "repo_") {
+ if jsonMessage == nil {
+ result.Repositories = append(result.Repositories, nil)
+ continue
+ }
+ var repo Repository
+ decoder := json.NewDecoder(bytes.NewReader(*jsonMessage))
+ if err := decoder.Decode(&repo); err != nil {
+ return result, err
+ }
+ result.Repositories = append(result.Repositories, InitRepoHostname(&repo, hostname))
+ } else {
+ return result, fmt.Errorf("unknown GraphQL result key %q", name)
+ }
+ }
+ return result, nil
+}
+
+func InitRepoHostname(repo *Repository, hostname string) *Repository {
+ repo.hostname = hostname
+ if repo.Parent != nil {
+ repo.Parent.hostname = hostname
+ }
+ return repo
+}
+
+// RepositoryV3 is the repository result from GitHub API v3
+type repositoryV3 struct {
+ NodeID string `json:"node_id"`
+ Name string
+ CreatedAt time.Time `json:"created_at"`
+ Owner struct {
+ Login string
+ }
+ Private bool
+ HTMLUrl string `json:"html_url"`
+ Parent *repositoryV3
+}
+
+// ForkRepo forks the repository on GitHub and returns the new repository
+func ForkRepo(client *Client, repo ghrepo.Interface, org, newName string, defaultBranchOnly bool) (*Repository, error) {
+ path := fmt.Sprintf("repos/%s/forks", ghrepo.FullName(repo))
+
+ params := map[string]interface{}{}
+ if org != "" {
+ params["organization"] = org
+ }
+ if newName != "" {
+ params["name"] = newName
+ }
+ if defaultBranchOnly {
+ params["default_branch_only"] = true
+ }
+
+ body := &bytes.Buffer{}
+ enc := json.NewEncoder(body)
+ if err := enc.Encode(params); err != nil {
+ return nil, err
+ }
+
+ result := repositoryV3{}
+ err := client.REST(repo.RepoHost(), "POST", path, body, &result)
+ if err != nil {
+ return nil, err
+ }
+
+ newRepo := &Repository{
+ ID: result.NodeID,
+ Name: result.Name,
+ CreatedAt: result.CreatedAt,
+ Owner: RepositoryOwner{
+ Login: result.Owner.Login,
+ },
+ ViewerPermission: "WRITE",
+ hostname: repo.RepoHost(),
+ }
+
+ // The GitHub API will happily return a HTTP 200 when attempting to fork own repo even though no forking
+ // actually took place. Ensure that we raise an error instead.
+ if ghrepo.IsSame(repo, newRepo) {
+ return newRepo, fmt.Errorf("%s cannot be forked. A single user account cannot own both a parent and fork.", ghrepo.FullName(repo))
+ }
+
+ return newRepo, nil
+}
+
+// RenameRepo renames the repository on GitHub and returns the renamed repository
+func RenameRepo(client *Client, repo ghrepo.Interface, newRepoName string) (*Repository, error) {
+ input := map[string]string{"name": newRepoName}
+ body := &bytes.Buffer{}
+ enc := json.NewEncoder(body)
+ if err := enc.Encode(input); err != nil {
+ return nil, err
+ }
+
+ path := fmt.Sprintf("%srepos/%s",
+ ghinstance.RESTPrefix(repo.RepoHost()),
+ ghrepo.FullName(repo))
+
+ result := repositoryV3{}
+ err := client.REST(repo.RepoHost(), "PATCH", path, body, &result)
+ if err != nil {
+ return nil, err
+ }
+
+ return &Repository{
+ ID: result.NodeID,
+ Name: result.Name,
+ CreatedAt: result.CreatedAt,
+ Owner: RepositoryOwner{
+ Login: result.Owner.Login,
+ },
+ ViewerPermission: "WRITE",
+ hostname: repo.RepoHost(),
+ }, nil
+}
+
+func LastCommit(client *Client, repo ghrepo.Interface) (*Commit, error) {
+ var responseData struct {
+ Repository struct {
+ DefaultBranchRef struct {
+ Target struct {
+ Commit `graphql:"... on Commit"`
+ }
+ }
+ } `graphql:"repository(owner: $owner, name: $repo)"`
+ }
+ variables := map[string]interface{}{
+ "owner": githubv4.String(repo.RepoOwner()), "repo": githubv4.String(repo.RepoName()),
+ }
+ if err := client.Query(repo.RepoHost(), "LastCommit", &responseData, variables); err != nil {
+ return nil, err
+ }
+ return &responseData.Repository.DefaultBranchRef.Target.Commit, nil
+}
+
+// RepoFindForks finds forks of the repo that are affiliated with the viewer
+func RepoFindForks(client *Client, repo ghrepo.Interface, limit int) ([]*Repository, error) {
+ result := struct {
+ Repository struct {
+ Forks struct {
+ Nodes []Repository
+ }
+ }
+ }{}
+
+ variables := map[string]interface{}{
+ "owner": repo.RepoOwner(),
+ "repo": repo.RepoName(),
+ "limit": limit,
+ }
+
+ if err := client.GraphQL(repo.RepoHost(), `
+ query RepositoryFindFork($owner: String!, $repo: String!, $limit: Int!) {
+ repository(owner: $owner, name: $repo) {
+ forks(first: $limit, affiliations: [OWNER, COLLABORATOR]) {
+ nodes {
+ id
+ name
+ owner { login }
+ url
+ viewerPermission
+ }
+ }
+ }
+ }
+ `, variables, &result); err != nil {
+ return nil, err
+ }
+
+ var results []*Repository
+ for _, r := range result.Repository.Forks.Nodes {
+ // we check ViewerCanPush, even though we expect it to always be true per
+ // `affiliations` condition, to guard against versions of GitHub with a
+ // faulty `affiliations` implementation
+ if !r.ViewerCanPush() {
+ continue
+ }
+ results = append(results, InitRepoHostname(&r, repo.RepoHost()))
+ }
+
+ return results, nil
+}
+
+type RepoMetadataResult struct {
+ CurrentLogin string
+ AssignableUsers []RepoAssignee
+ Labels []RepoLabel
+ Projects []RepoProject
+ ProjectsV2 []ProjectV2
+ Milestones []RepoMilestone
+ Teams []OrgTeam
+}
+
+func (m *RepoMetadataResult) MembersToIDs(names []string) ([]string, error) {
+ var ids []string
+ for _, assigneeLogin := range names {
+ found := false
+ for _, u := range m.AssignableUsers {
+ if strings.EqualFold(assigneeLogin, u.Login) {
+ ids = append(ids, u.ID)
+ found = true
+ break
+ }
+ }
+ if !found {
+ return nil, fmt.Errorf("'%s' not found", assigneeLogin)
+ }
+ }
+ return ids, nil
+}
+
+func (m *RepoMetadataResult) TeamsToIDs(names []string) ([]string, error) {
+ var ids []string
+ for _, teamSlug := range names {
+ found := false
+ slug := teamSlug[strings.IndexRune(teamSlug, '/')+1:]
+ for _, t := range m.Teams {
+ if strings.EqualFold(slug, t.Slug) {
+ ids = append(ids, t.ID)
+ found = true
+ break
+ }
+ }
+ if !found {
+ return nil, fmt.Errorf("'%s' not found", teamSlug)
+ }
+ }
+ return ids, nil
+}
+
+func (m *RepoMetadataResult) LabelsToIDs(names []string) ([]string, error) {
+ var ids []string
+ for _, labelName := range names {
+ found := false
+ for _, l := range m.Labels {
+ if strings.EqualFold(labelName, l.Name) {
+ ids = append(ids, l.ID)
+ found = true
+ break
+ }
+ }
+ if !found {
+ return nil, fmt.Errorf("'%s' not found", labelName)
+ }
+ }
+ return ids, nil
+}
+
+// ProjectsToIDs returns two arrays:
+// - the first contains IDs of projects V1
+// - the second contains IDs of projects V2
+// - if neither project V1 or project V2 can be found with a given name, then an error is returned
+func (m *RepoMetadataResult) ProjectsToIDs(names []string) ([]string, []string, error) {
+ var ids []string
+ var idsV2 []string
+ for _, projectName := range names {
+ id, found := m.projectNameToID(projectName)
+ if found {
+ ids = append(ids, id)
+ continue
+ }
+
+ idV2, found := m.projectV2TitleToID(projectName)
+ if found {
+ idsV2 = append(idsV2, idV2)
+ continue
+ }
+
+ return nil, nil, fmt.Errorf("'%s' not found", projectName)
+ }
+ return ids, idsV2, nil
+}
+
+func (m *RepoMetadataResult) projectNameToID(projectName string) (string, bool) {
+ for _, p := range m.Projects {
+ if strings.EqualFold(projectName, p.Name) {
+ return p.ID, true
+ }
+ }
+
+ return "", false
+}
+
+func (m *RepoMetadataResult) projectV2TitleToID(projectTitle string) (string, bool) {
+ for _, p := range m.ProjectsV2 {
+ if strings.EqualFold(projectTitle, p.Title) {
+ return p.ID, true
+ }
+ }
+
+ return "", false
+}
+
+func ProjectsToPaths(projects []RepoProject, projectsV2 []ProjectV2, names []string) ([]string, error) {
+ var paths []string
+ for _, projectName := range names {
+ found := false
+ for _, p := range projects {
+ if strings.EqualFold(projectName, p.Name) {
+ // format of ResourcePath: /OWNER/REPO/projects/PROJECT_NUMBER or /orgs/ORG/projects/PROJECT_NUMBER or /users/USER/projects/PROJECT_NUBER
+ // required format of path: OWNER/REPO/PROJECT_NUMBER or ORG/PROJECT_NUMBER or USER/PROJECT_NUMBER
+ var path string
+ pathParts := strings.Split(p.ResourcePath, "/")
+ if pathParts[1] == "orgs" || pathParts[1] == "users" {
+ path = fmt.Sprintf("%s/%s", pathParts[2], pathParts[4])
+ } else {
+ path = fmt.Sprintf("%s/%s/%s", pathParts[1], pathParts[2], pathParts[4])
+ }
+ paths = append(paths, path)
+ found = true
+ break
+ }
+ }
+ if found {
+ continue
+ }
+ for _, p := range projectsV2 {
+ if strings.EqualFold(projectName, p.Title) {
+ // format of ResourcePath: /OWNER/REPO/projects/PROJECT_NUMBER or /orgs/ORG/projects/PROJECT_NUMBER or /users/USER/projects/PROJECT_NUBER
+ // required format of path: OWNER/REPO/PROJECT_NUMBER or ORG/PROJECT_NUMBER or USER/PROJECT_NUMBER
+ var path string
+ pathParts := strings.Split(p.ResourcePath, "/")
+ if pathParts[1] == "orgs" || pathParts[1] == "users" {
+ path = fmt.Sprintf("%s/%s", pathParts[2], pathParts[4])
+ } else {
+ path = fmt.Sprintf("%s/%s/%s", pathParts[1], pathParts[2], pathParts[4])
+ }
+ paths = append(paths, path)
+ found = true
+ break
+ }
+ }
+ if !found {
+ return nil, fmt.Errorf("'%s' not found", projectName)
+ }
+ }
+ return paths, nil
+}
+
+func (m *RepoMetadataResult) MilestoneToID(title string) (string, error) {
+ for _, m := range m.Milestones {
+ if strings.EqualFold(title, m.Title) {
+ return m.ID, nil
+ }
+ }
+ return "", fmt.Errorf("'%s' not found", title)
+}
+
+func (m *RepoMetadataResult) Merge(m2 *RepoMetadataResult) {
+ if len(m2.AssignableUsers) > 0 || len(m.AssignableUsers) == 0 {
+ m.AssignableUsers = m2.AssignableUsers
+ }
+
+ if len(m2.Teams) > 0 || len(m.Teams) == 0 {
+ m.Teams = m2.Teams
+ }
+
+ if len(m2.Labels) > 0 || len(m.Labels) == 0 {
+ m.Labels = m2.Labels
+ }
+
+ if len(m2.Projects) > 0 || len(m.Projects) == 0 {
+ m.Projects = m2.Projects
+ }
+
+ if len(m2.Milestones) > 0 || len(m.Milestones) == 0 {
+ m.Milestones = m2.Milestones
+ }
+}
+
+type RepoMetadataInput struct {
+ Assignees bool
+ Reviewers bool
+ Labels bool
+ Projects bool
+ Milestones bool
+}
+
+// RepoMetadata pre-fetches the metadata for attaching to issues and pull requests
+func RepoMetadata(client *Client, repo ghrepo.Interface, input RepoMetadataInput) (*RepoMetadataResult, error) {
+ var result RepoMetadataResult
+ var g errgroup.Group
+
+ if input.Assignees || input.Reviewers {
+ g.Go(func() error {
+ users, err := RepoAssignableUsers(client, repo)
+ if err != nil {
+ err = fmt.Errorf("error fetching assignees: %w", err)
+ }
+ result.AssignableUsers = users
+ return err
+ })
+ }
+ if input.Reviewers {
+ g.Go(func() error {
+ teams, err := OrganizationTeams(client, repo)
+ // TODO: better detection of non-org repos
+ if err != nil && !strings.Contains(err.Error(), errorResolvingOrganization) {
+ err = fmt.Errorf("error fetching organization teams: %w", err)
+ return err
+ }
+ result.Teams = teams
+ return nil
+ })
+ }
+ if input.Reviewers {
+ g.Go(func() error {
+ login, err := CurrentLoginName(client, repo.RepoHost())
+ if err != nil {
+ err = fmt.Errorf("error fetching current login: %w", err)
+ }
+ result.CurrentLogin = login
+ return err
+ })
+ }
+ if input.Labels {
+ g.Go(func() error {
+ labels, err := RepoLabels(client, repo)
+ if err != nil {
+ err = fmt.Errorf("error fetching labels: %w", err)
+ }
+ result.Labels = labels
+ return err
+ })
+ }
+ if input.Projects {
+ g.Go(func() error {
+ var err error
+ result.Projects, result.ProjectsV2, err = relevantProjects(client, repo)
+ return err
+ })
+ }
+ if input.Milestones {
+ g.Go(func() error {
+ milestones, err := RepoMilestones(client, repo, "open")
+ if err != nil {
+ err = fmt.Errorf("error fetching milestones: %w", err)
+ }
+ result.Milestones = milestones
+ return err
+ })
+ }
+
+ if err := g.Wait(); err != nil {
+ return nil, err
+ }
+
+ return &result, nil
+}
+
+type RepoResolveInput struct {
+ Assignees []string
+ Reviewers []string
+ Labels []string
+ Projects []string
+ Milestones []string
+}
+
+// RepoResolveMetadataIDs looks up GraphQL node IDs in bulk
+func RepoResolveMetadataIDs(client *Client, repo ghrepo.Interface, input RepoResolveInput) (*RepoMetadataResult, error) {
+ users := input.Assignees
+ hasUser := func(target string) bool {
+ for _, u := range users {
+ if strings.EqualFold(u, target) {
+ return true
+ }
+ }
+ return false
+ }
+
+ var teams []string
+ for _, r := range input.Reviewers {
+ if i := strings.IndexRune(r, '/'); i > -1 {
+ teams = append(teams, r[i+1:])
+ } else if !hasUser(r) {
+ users = append(users, r)
+ }
+ }
+
+ // there is no way to look up projects nor milestones by name, so preload them all
+ mi := RepoMetadataInput{
+ Projects: len(input.Projects) > 0,
+ Milestones: len(input.Milestones) > 0,
+ }
+ result, err := RepoMetadata(client, repo, mi)
+ if err != nil {
+ return result, err
+ }
+ if len(users) == 0 && len(teams) == 0 && len(input.Labels) == 0 {
+ return result, nil
+ }
+
+ query := &bytes.Buffer{}
+ fmt.Fprint(query, "query RepositoryResolveMetadataIDs {\n")
+ for i, u := range users {
+ fmt.Fprintf(query, "u%03d: user(login:%q){id,login}\n", i, u)
+ }
+ if len(input.Labels) > 0 {
+ fmt.Fprintf(query, "repository(owner:%q,name:%q){\n", repo.RepoOwner(), repo.RepoName())
+ for i, l := range input.Labels {
+ fmt.Fprintf(query, "l%03d: label(name:%q){id,name}\n", i, l)
+ }
+ fmt.Fprint(query, "}\n")
+ }
+ if len(teams) > 0 {
+ fmt.Fprintf(query, "organization(login:%q){\n", repo.RepoOwner())
+ for i, t := range teams {
+ fmt.Fprintf(query, "t%03d: team(slug:%q){id,slug}\n", i, t)
+ }
+ fmt.Fprint(query, "}\n")
+ }
+ fmt.Fprint(query, "}\n")
+
+ response := make(map[string]json.RawMessage)
+ err = client.GraphQL(repo.RepoHost(), query.String(), nil, &response)
+ if err != nil {
+ return result, err
+ }
+
+ for key, v := range response {
+ switch key {
+ case "repository":
+ repoResponse := make(map[string]RepoLabel)
+ err := json.Unmarshal(v, &repoResponse)
+ if err != nil {
+ return result, err
+ }
+ for _, l := range repoResponse {
+ result.Labels = append(result.Labels, l)
+ }
+ case "organization":
+ orgResponse := make(map[string]OrgTeam)
+ err := json.Unmarshal(v, &orgResponse)
+ if err != nil {
+ return result, err
+ }
+ for _, t := range orgResponse {
+ result.Teams = append(result.Teams, t)
+ }
+ default:
+ user := RepoAssignee{}
+ err := json.Unmarshal(v, &user)
+ if err != nil {
+ return result, err
+ }
+ result.AssignableUsers = append(result.AssignableUsers, user)
+ }
+ }
+
+ return result, nil
+}
+
+type RepoProject struct {
+ ID string `json:"id"`
+ Name string `json:"name"`
+ Number int `json:"number"`
+ ResourcePath string `json:"resourcePath"`
+}
+
+// RepoProjects fetches all open projects for a repository.
+func RepoProjects(client *Client, repo ghrepo.Interface) ([]RepoProject, error) {
+ type responseData struct {
+ Repository struct {
+ Projects struct {
+ Nodes []RepoProject
+ PageInfo struct {
+ HasNextPage bool
+ EndCursor string
+ }
+ } `graphql:"projects(states: [OPEN], first: 100, orderBy: {field: NAME, direction: ASC}, after: $endCursor)"`
+ } `graphql:"repository(owner: $owner, name: $name)"`
+ }
+
+ variables := map[string]interface{}{
+ "owner": githubv4.String(repo.RepoOwner()),
+ "name": githubv4.String(repo.RepoName()),
+ "endCursor": (*githubv4.String)(nil),
+ }
+
+ var projects []RepoProject
+ for {
+ var query responseData
+ err := client.Query(repo.RepoHost(), "RepositoryProjectList", &query, variables)
+ if err != nil {
+ return nil, err
+ }
+
+ projects = append(projects, query.Repository.Projects.Nodes...)
+ if !query.Repository.Projects.PageInfo.HasNextPage {
+ break
+ }
+ variables["endCursor"] = githubv4.String(query.Repository.Projects.PageInfo.EndCursor)
+ }
+
+ return projects, nil
+}
+
+type RepoAssignee struct {
+ ID string
+ Login string
+ Name string
+}
+
+// DisplayName returns a formatted string that uses Login and Name to be displayed e.g. 'Login (Name)' or 'Login'
+func (ra RepoAssignee) DisplayName() string {
+ if ra.Name != "" {
+ return fmt.Sprintf("%s (%s)", ra.Login, ra.Name)
+ }
+ return ra.Login
+}
+
+// RepoAssignableUsers fetches all the assignable users for a repository
+func RepoAssignableUsers(client *Client, repo ghrepo.Interface) ([]RepoAssignee, error) {
+ type responseData struct {
+ Repository struct {
+ AssignableUsers struct {
+ Nodes []RepoAssignee
+ PageInfo struct {
+ HasNextPage bool
+ EndCursor string
+ }
+ } `graphql:"assignableUsers(first: 100, after: $endCursor)"`
+ } `graphql:"repository(owner: $owner, name: $name)"`
+ }
+
+ variables := map[string]interface{}{
+ "owner": githubv4.String(repo.RepoOwner()),
+ "name": githubv4.String(repo.RepoName()),
+ "endCursor": (*githubv4.String)(nil),
+ }
+
+ var users []RepoAssignee
+ for {
+ var query responseData
+ err := client.Query(repo.RepoHost(), "RepositoryAssignableUsers", &query, variables)
+ if err != nil {
+ return nil, err
+ }
+
+ users = append(users, query.Repository.AssignableUsers.Nodes...)
+ if !query.Repository.AssignableUsers.PageInfo.HasNextPage {
+ break
+ }
+ variables["endCursor"] = githubv4.String(query.Repository.AssignableUsers.PageInfo.EndCursor)
+ }
+
+ return users, nil
+}
+
+type RepoLabel struct {
+ ID string
+ Name string
+}
+
+// RepoLabels fetches all the labels in a repository
+func RepoLabels(client *Client, repo ghrepo.Interface) ([]RepoLabel, error) {
+ type responseData struct {
+ Repository struct {
+ Labels struct {
+ Nodes []RepoLabel
+ PageInfo struct {
+ HasNextPage bool
+ EndCursor string
+ }
+ } `graphql:"labels(first: 100, orderBy: {field: NAME, direction: ASC}, after: $endCursor)"`
+ } `graphql:"repository(owner: $owner, name: $name)"`
+ }
+
+ variables := map[string]interface{}{
+ "owner": githubv4.String(repo.RepoOwner()),
+ "name": githubv4.String(repo.RepoName()),
+ "endCursor": (*githubv4.String)(nil),
+ }
+
+ var labels []RepoLabel
+ for {
+ var query responseData
+ err := client.Query(repo.RepoHost(), "RepositoryLabelList", &query, variables)
+ if err != nil {
+ return nil, err
+ }
+
+ labels = append(labels, query.Repository.Labels.Nodes...)
+ if !query.Repository.Labels.PageInfo.HasNextPage {
+ break
+ }
+ variables["endCursor"] = githubv4.String(query.Repository.Labels.PageInfo.EndCursor)
+ }
+
+ return labels, nil
+}
+
+type RepoMilestone struct {
+ ID string
+ Title string
+}
+
+// RepoMilestones fetches milestones in a repository
+func RepoMilestones(client *Client, repo ghrepo.Interface, state string) ([]RepoMilestone, error) {
+ type responseData struct {
+ Repository struct {
+ Milestones struct {
+ Nodes []RepoMilestone
+ PageInfo struct {
+ HasNextPage bool
+ EndCursor string
+ }
+ } `graphql:"milestones(states: $states, first: 100, after: $endCursor)"`
+ } `graphql:"repository(owner: $owner, name: $name)"`
+ }
+
+ var states []githubv4.MilestoneState
+ switch state {
+ case "open":
+ states = []githubv4.MilestoneState{"OPEN"}
+ case "closed":
+ states = []githubv4.MilestoneState{"CLOSED"}
+ case "all":
+ states = []githubv4.MilestoneState{"OPEN", "CLOSED"}
+ default:
+ return nil, fmt.Errorf("invalid state: %s", state)
+ }
+
+ variables := map[string]interface{}{
+ "owner": githubv4.String(repo.RepoOwner()),
+ "name": githubv4.String(repo.RepoName()),
+ "states": states,
+ "endCursor": (*githubv4.String)(nil),
+ }
+
+ var milestones []RepoMilestone
+ for {
+ var query responseData
+ err := client.Query(repo.RepoHost(), "RepositoryMilestoneList", &query, variables)
+ if err != nil {
+ return nil, err
+ }
+
+ milestones = append(milestones, query.Repository.Milestones.Nodes...)
+ if !query.Repository.Milestones.PageInfo.HasNextPage {
+ break
+ }
+ variables["endCursor"] = githubv4.String(query.Repository.Milestones.PageInfo.EndCursor)
+ }
+
+ return milestones, nil
+}
+
+func ProjectNamesToPaths(client *Client, repo ghrepo.Interface, projectNames []string) ([]string, error) {
+ projects, projectsV2, err := relevantProjects(client, repo)
+ if err != nil {
+ return nil, err
+ }
+ return ProjectsToPaths(projects, projectsV2, projectNames)
+}
+
+// RelevantProjects retrieves set of Projects and ProjectsV2 relevant to given repository:
+// - Projects for repository
+// - Projects for repository organization, if it belongs to one
+// - ProjectsV2 owned by current user
+// - ProjectsV2 linked to repository
+// - ProjectsV2 owned by repository organization, if it belongs to one
+func relevantProjects(client *Client, repo ghrepo.Interface) ([]RepoProject, []ProjectV2, error) {
+ var repoProjects []RepoProject
+ var orgProjects []RepoProject
+ var userProjectsV2 []ProjectV2
+ var repoProjectsV2 []ProjectV2
+ var orgProjectsV2 []ProjectV2
+
+ g, _ := errgroup.WithContext(context.Background())
+
+ g.Go(func() error {
+ var err error
+ repoProjects, err = RepoProjects(client, repo)
+ if err != nil {
+ err = fmt.Errorf("error fetching repo projects (classic): %w", err)
+ }
+ return err
+ })
+ g.Go(func() error {
+ var err error
+ orgProjects, err = OrganizationProjects(client, repo)
+ if err != nil && !strings.Contains(err.Error(), errorResolvingOrganization) {
+ err = fmt.Errorf("error fetching organization projects (classic): %w", err)
+ return err
+ }
+ return nil
+ })
+ g.Go(func() error {
+ var err error
+ userProjectsV2, err = CurrentUserProjectsV2(client, repo.RepoHost())
+ if err != nil && !ProjectsV2IgnorableError(err) {
+ err = fmt.Errorf("error fetching user projects: %w", err)
+ return err
+ }
+ return nil
+ })
+ g.Go(func() error {
+ var err error
+ repoProjectsV2, err = RepoProjectsV2(client, repo)
+ if err != nil && !ProjectsV2IgnorableError(err) {
+ err = fmt.Errorf("error fetching repo projects: %w", err)
+ return err
+ }
+ return nil
+ })
+ g.Go(func() error {
+ var err error
+ orgProjectsV2, err = OrganizationProjectsV2(client, repo)
+ if err != nil &&
+ !ProjectsV2IgnorableError(err) &&
+ !strings.Contains(err.Error(), errorResolvingOrganization) {
+ err = fmt.Errorf("error fetching organization projects: %w", err)
+ return err
+ }
+ return nil
+ })
+
+ if err := g.Wait(); err != nil {
+ return nil, nil, err
+ }
+
+ projects := make([]RepoProject, 0, len(repoProjects)+len(orgProjects))
+ projects = append(projects, repoProjects...)
+ projects = append(projects, orgProjects...)
+
+ // ProjectV2 might appear across multiple queries so use a map to keep them deduplicated.
+ m := make(map[string]ProjectV2, len(userProjectsV2)+len(repoProjectsV2)+len(orgProjectsV2))
+ for _, p := range userProjectsV2 {
+ m[p.ID] = p
+ }
+ for _, p := range repoProjectsV2 {
+ m[p.ID] = p
+ }
+ for _, p := range orgProjectsV2 {
+ m[p.ID] = p
+ }
+ projectsV2 := make([]ProjectV2, 0, len(m))
+ for _, p := range m {
+ projectsV2 = append(projectsV2, p)
+ }
+
+ return projects, projectsV2, nil
+}
+
+func CreateRepoTransformToV4(apiClient *Client, hostname string, method string, path string, body io.Reader) (*Repository, error) {
+ var responsev3 repositoryV3
+ err := apiClient.REST(hostname, method, path, body, &responsev3)
+
+ if err != nil {
+ return nil, err
+ }
+
+ return &Repository{
+ Name: responsev3.Name,
+ CreatedAt: responsev3.CreatedAt,
+ Owner: RepositoryOwner{
+ Login: responsev3.Owner.Login,
+ },
+ ID: responsev3.NodeID,
+ hostname: hostname,
+ URL: responsev3.HTMLUrl,
+ IsPrivate: responsev3.Private,
+ }, nil
+}
+
+// MapReposToIDs retrieves a set of IDs for the given set of repositories.
+// This is similar logic to RepoNetwork, but only fetches databaseId and does not
+// discover parent repositories.
+func GetRepoIDs(client *Client, host string, repositories []ghrepo.Interface) ([]int64, error) {
+ queries := make([]string, 0, len(repositories))
+ for i, repo := range repositories {
+ queries = append(queries, fmt.Sprintf(`
+ repo_%03d: repository(owner: %q, name: %q) {
+ databaseId
+ }
+ `, i, repo.RepoOwner(), repo.RepoName()))
+ }
+
+ query := fmt.Sprintf(`query MapRepositoryNames { %s }`, strings.Join(queries, ""))
+
+ graphqlResult := make(map[string]*struct {
+ DatabaseID int64 `json:"databaseId"`
+ })
+
+ if err := client.GraphQL(host, query, nil, &graphqlResult); err != nil {
+ return nil, fmt.Errorf("failed to look up repositories: %w", err)
+ }
+
+ repoKeys := make([]string, 0, len(repositories))
+ for k := range graphqlResult {
+ repoKeys = append(repoKeys, k)
+ }
+ sort.Strings(repoKeys)
+
+ result := make([]int64, len(repositories))
+ for i, k := range repoKeys {
+ result[i] = graphqlResult[k].DatabaseID
+ }
+ return result, nil
+}
+
+func RepoExists(client *Client, repo ghrepo.Interface) (bool, error) {
+ path := fmt.Sprintf("%srepos/%s/%s", ghinstance.RESTPrefix(repo.RepoHost()), repo.RepoOwner(), repo.RepoName())
+
+ resp, err := client.HTTP().Head(path)
+ if err != nil {
+ return false, err
+ }
+
+ switch resp.StatusCode {
+ case 200:
+ return true, nil
+ case 404:
+ return false, nil
+ default:
+ return false, ghAPI.HandleHTTPError(resp)
+ }
+}
diff --git a/vendor/github.com/cli/cli/v2/api/queries_user.go b/vendor/github.com/cli/cli/v2/api/queries_user.go
new file mode 100644
index 000000000..cf0121a8b
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/api/queries_user.go
@@ -0,0 +1,45 @@
+package api
+
+type Organization struct {
+ Login string
+}
+
+func CurrentLoginName(client *Client, hostname string) (string, error) {
+ var query struct {
+ Viewer struct {
+ Login string
+ }
+ }
+ err := client.Query(hostname, "UserCurrent", &query, nil)
+ return query.Viewer.Login, err
+}
+
+func CurrentLoginNameAndOrgs(client *Client, hostname string) (string, []string, error) {
+ var query struct {
+ Viewer struct {
+ Login string
+ Organizations struct {
+ Nodes []Organization
+ } `graphql:"organizations(first: 100)"`
+ }
+ }
+ err := client.Query(hostname, "UserCurrent", &query, nil)
+ if err != nil {
+ return "", nil, err
+ }
+ orgNames := []string{}
+ for _, org := range query.Viewer.Organizations.Nodes {
+ orgNames = append(orgNames, org.Login)
+ }
+ return query.Viewer.Login, orgNames, err
+}
+
+func CurrentUserID(client *Client, hostname string) (string, error) {
+ var query struct {
+ Viewer struct {
+ ID string
+ }
+ }
+ err := client.Query(hostname, "UserCurrent", &query, nil)
+ return query.Viewer.ID, err
+}
diff --git a/vendor/github.com/cli/cli/v2/api/query_builder.go b/vendor/github.com/cli/cli/v2/api/query_builder.go
new file mode 100644
index 000000000..9c8aaac17
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/api/query_builder.go
@@ -0,0 +1,503 @@
+package api
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/cli/cli/v2/pkg/set"
+)
+
+func squeeze(r rune) rune {
+ switch r {
+ case '\n', '\t':
+ return -1
+ default:
+ return r
+ }
+}
+
+func shortenQuery(q string) string {
+ return strings.Map(squeeze, q)
+}
+
+var issueComments = shortenQuery(`
+ comments(first: 100) {
+ nodes {
+ id,
+ author{login,...on User{id,name}},
+ authorAssociation,
+ body,
+ createdAt,
+ includesCreatedEdit,
+ isMinimized,
+ minimizedReason,
+ reactionGroups{content,users{totalCount}},
+ url,
+ viewerDidAuthor
+ },
+ pageInfo{hasNextPage,endCursor},
+ totalCount
+ }
+`)
+
+var issueCommentLast = shortenQuery(`
+ comments(last: 1) {
+ nodes {
+ author{login,...on User{id,name}},
+ authorAssociation,
+ body,
+ createdAt,
+ includesCreatedEdit,
+ isMinimized,
+ minimizedReason,
+ reactionGroups{content,users{totalCount}}
+ },
+ totalCount
+ }
+`)
+
+var prReviewRequests = shortenQuery(`
+ reviewRequests(first: 100) {
+ nodes {
+ requestedReviewer {
+ __typename,
+ ...on User{login},
+ ...on Team{
+ organization{login}
+ name,
+ slug
+ }
+ }
+ }
+ }
+`)
+
+var prReviews = shortenQuery(`
+ reviews(first: 100) {
+ nodes {
+ id,
+ author{login},
+ authorAssociation,
+ submittedAt,
+ body,
+ state,
+ commit{oid},
+ reactionGroups{content,users{totalCount}}
+ }
+ pageInfo{hasNextPage,endCursor}
+ totalCount
+ }
+`)
+
+var prLatestReviews = shortenQuery(`
+ latestReviews(first: 100) {
+ nodes {
+ author{login},
+ authorAssociation,
+ submittedAt,
+ body,
+ state
+ }
+ }
+`)
+
+var prFiles = shortenQuery(`
+ files(first: 100) {
+ nodes {
+ additions,
+ deletions,
+ path
+ }
+ }
+`)
+
+var prCommits = shortenQuery(`
+ commits(first: 100) {
+ nodes {
+ commit {
+ authors(first:100) {
+ nodes {
+ name,
+ email,
+ user{id,login}
+ }
+ },
+ messageHeadline,
+ messageBody,
+ oid,
+ committedDate,
+ authoredDate
+ }
+ }
+ }
+`)
+
+var autoMergeRequest = shortenQuery(`
+ autoMergeRequest {
+ authorEmail,
+ commitBody,
+ commitHeadline,
+ mergeMethod,
+ enabledAt,
+ enabledBy{login,...on User{id,name}}
+ }
+`)
+
+func StatusCheckRollupGraphQLWithCountByState() string {
+ return shortenQuery(`
+ statusCheckRollup: commits(last: 1) {
+ nodes {
+ commit {
+ statusCheckRollup {
+ contexts {
+ checkRunCount,
+ checkRunCountsByState {
+ state,
+ count
+ },
+ statusContextCount,
+ statusContextCountsByState {
+ state,
+ count
+ }
+ }
+ }
+ }
+ }
+ }`)
+}
+
+func StatusCheckRollupGraphQLWithoutCountByState(after string) string {
+ var afterClause string
+ if after != "" {
+ afterClause = ",after:" + after
+ }
+ return fmt.Sprintf(shortenQuery(`
+ statusCheckRollup: commits(last: 1) {
+ nodes {
+ commit {
+ statusCheckRollup {
+ contexts(first:100%s) {
+ nodes {
+ __typename
+ ...on StatusContext {
+ context,
+ state,
+ targetUrl,
+ createdAt,
+ description
+ },
+ ...on CheckRun {
+ name,
+ checkSuite{workflowRun{workflow{name}}},
+ status,
+ conclusion,
+ startedAt,
+ completedAt,
+ detailsUrl
+ }
+ },
+ pageInfo{hasNextPage,endCursor}
+ }
+ }
+ }
+ }
+ }`), afterClause)
+}
+
+func RequiredStatusCheckRollupGraphQL(prID, after string, includeEvent bool) string {
+ var afterClause string
+ if after != "" {
+ afterClause = ",after:" + after
+ }
+ eventField := "event,"
+ if !includeEvent {
+ eventField = ""
+ }
+ return fmt.Sprintf(shortenQuery(`
+ statusCheckRollup: commits(last: 1) {
+ nodes {
+ commit {
+ statusCheckRollup {
+ contexts(first:100%[1]s) {
+ nodes {
+ __typename
+ ...on StatusContext {
+ context,
+ state,
+ targetUrl,
+ createdAt,
+ description,
+ isRequired(pullRequestId: %[2]s)
+ },
+ ...on CheckRun {
+ name,
+ checkSuite{workflowRun{%[3]sworkflow{name}}},
+ status,
+ conclusion,
+ startedAt,
+ completedAt,
+ detailsUrl,
+ isRequired(pullRequestId: %[2]s)
+ }
+ },
+ pageInfo{hasNextPage,endCursor}
+ }
+ }
+ }
+ }
+ }`), afterClause, prID, eventField)
+}
+
+var IssueFields = []string{
+ "assignees",
+ "author",
+ "body",
+ "closed",
+ "comments",
+ "createdAt",
+ "closedAt",
+ "id",
+ "labels",
+ "milestone",
+ "number",
+ "projectCards",
+ "projectItems",
+ "reactionGroups",
+ "state",
+ "title",
+ "updatedAt",
+ "url",
+}
+
+var PullRequestFields = append(IssueFields,
+ "additions",
+ "autoMergeRequest",
+ "baseRefName",
+ "changedFiles",
+ "commits",
+ "deletions",
+ "files",
+ "headRefName",
+ "headRefOid",
+ "headRepository",
+ "headRepositoryOwner",
+ "isCrossRepository",
+ "isDraft",
+ "latestReviews",
+ "maintainerCanModify",
+ "mergeable",
+ "mergeCommit",
+ "mergedAt",
+ "mergedBy",
+ "mergeStateStatus",
+ "potentialMergeCommit",
+ "reviewDecision",
+ "reviewRequests",
+ "reviews",
+ "statusCheckRollup",
+)
+
+// IssueGraphQL constructs a GraphQL query fragment for a set of issue fields.
+func IssueGraphQL(fields []string) string {
+ var q []string
+ for _, field := range fields {
+ switch field {
+ case "author":
+ q = append(q, `author{login,...on User{id,name}}`)
+ case "mergedBy":
+ q = append(q, `mergedBy{login,...on User{id,name}}`)
+ case "headRepositoryOwner":
+ q = append(q, `headRepositoryOwner{id,login,...on User{name}}`)
+ case "headRepository":
+ q = append(q, `headRepository{id,name}`)
+ case "assignees":
+ q = append(q, `assignees(first:100){nodes{id,login,name},totalCount}`)
+ case "labels":
+ q = append(q, `labels(first:100){nodes{id,name,description,color},totalCount}`)
+ case "projectCards":
+ q = append(q, `projectCards(first:100){nodes{project{name}column{name}},totalCount}`)
+ case "projectItems":
+ q = append(q, `projectItems(first:100){nodes{id, project{id,title}, status:fieldValueByName(name: "Status") { ... on ProjectV2ItemFieldSingleSelectValue{optionId,name}}},totalCount}`)
+ case "milestone":
+ q = append(q, `milestone{number,title,description,dueOn}`)
+ case "reactionGroups":
+ q = append(q, `reactionGroups{content,users{totalCount}}`)
+ case "mergeCommit":
+ q = append(q, `mergeCommit{oid}`)
+ case "potentialMergeCommit":
+ q = append(q, `potentialMergeCommit{oid}`)
+ case "autoMergeRequest":
+ q = append(q, autoMergeRequest)
+ case "comments":
+ q = append(q, issueComments)
+ case "lastComment": // pseudo-field
+ q = append(q, issueCommentLast)
+ case "reviewRequests":
+ q = append(q, prReviewRequests)
+ case "reviews":
+ q = append(q, prReviews)
+ case "latestReviews":
+ q = append(q, prLatestReviews)
+ case "files":
+ q = append(q, prFiles)
+ case "commits":
+ q = append(q, prCommits)
+ case "lastCommit": // pseudo-field
+ q = append(q, `commits(last:1){nodes{commit{oid}}}`)
+ case "commitsCount": // pseudo-field
+ q = append(q, `commits{totalCount}`)
+ case "requiresStrictStatusChecks": // pseudo-field
+ q = append(q, `baseRef{branchProtectionRule{requiresStrictStatusChecks}}`)
+ case "statusCheckRollup":
+ q = append(q, StatusCheckRollupGraphQLWithoutCountByState(""))
+ case "statusCheckRollupWithCountByState": // pseudo-field
+ q = append(q, StatusCheckRollupGraphQLWithCountByState())
+ default:
+ q = append(q, field)
+ }
+ }
+ return strings.Join(q, ",")
+}
+
+// PullRequestGraphQL constructs a GraphQL query fragment for a set of pull request fields.
+// It will try to sanitize the fields to just those available on pull request.
+func PullRequestGraphQL(fields []string) string {
+ invalidFields := []string{"isPinned", "stateReason"}
+ s := set.NewStringSet()
+ s.AddValues(fields)
+ s.RemoveValues(invalidFields)
+ return IssueGraphQL(s.ToSlice())
+}
+
+var RepositoryFields = []string{
+ "id",
+ "name",
+ "nameWithOwner",
+ "owner",
+ "parent",
+ "templateRepository",
+ "description",
+ "homepageUrl",
+ "openGraphImageUrl",
+ "usesCustomOpenGraphImage",
+ "url",
+ "sshUrl",
+ "mirrorUrl",
+ "securityPolicyUrl",
+
+ "createdAt",
+ "pushedAt",
+ "updatedAt",
+
+ "isBlankIssuesEnabled",
+ "isSecurityPolicyEnabled",
+ "hasIssuesEnabled",
+ "hasProjectsEnabled",
+ "hasWikiEnabled",
+ "hasDiscussionsEnabled",
+ "mergeCommitAllowed",
+ "squashMergeAllowed",
+ "rebaseMergeAllowed",
+
+ "forkCount",
+ "stargazerCount",
+ "watchers",
+ "issues",
+ "pullRequests",
+
+ "codeOfConduct",
+ "contactLinks",
+ "defaultBranchRef",
+ "deleteBranchOnMerge",
+ "diskUsage",
+ "fundingLinks",
+ "isArchived",
+ "isEmpty",
+ "isFork",
+ "isInOrganization",
+ "isMirror",
+ "isPrivate",
+ "visibility",
+ "isTemplate",
+ "isUserConfigurationRepository",
+ "licenseInfo",
+ "viewerCanAdminister",
+ "viewerDefaultCommitEmail",
+ "viewerDefaultMergeMethod",
+ "viewerHasStarred",
+ "viewerPermission",
+ "viewerPossibleCommitEmails",
+ "viewerSubscription",
+
+ "repositoryTopics",
+ "primaryLanguage",
+ "languages",
+ "issueTemplates",
+ "pullRequestTemplates",
+ "labels",
+ "milestones",
+ "latestRelease",
+
+ "assignableUsers",
+ "mentionableUsers",
+ "projects",
+
+ // "branchProtectionRules", // too complex to expose
+ // "collaborators", // does it make sense to expose without affiliation filter?
+}
+
+func RepositoryGraphQL(fields []string) string {
+ var q []string
+ for _, field := range fields {
+ switch field {
+ case "codeOfConduct":
+ q = append(q, "codeOfConduct{key,name,url}")
+ case "contactLinks":
+ q = append(q, "contactLinks{about,name,url}")
+ case "fundingLinks":
+ q = append(q, "fundingLinks{platform,url}")
+ case "licenseInfo":
+ q = append(q, "licenseInfo{key,name,nickname}")
+ case "owner":
+ q = append(q, "owner{id,login}")
+ case "parent":
+ q = append(q, "parent{id,name,owner{id,login}}")
+ case "templateRepository":
+ q = append(q, "templateRepository{id,name,owner{id,login}}")
+ case "repositoryTopics":
+ q = append(q, "repositoryTopics(first:100){nodes{topic{name}}}")
+ case "issueTemplates":
+ q = append(q, "issueTemplates{name,title,body,about}")
+ case "pullRequestTemplates":
+ q = append(q, "pullRequestTemplates{body,filename}")
+ case "labels":
+ q = append(q, "labels(first:100){nodes{id,color,name,description}}")
+ case "languages":
+ q = append(q, "languages(first:100){edges{size,node{name}}}")
+ case "primaryLanguage":
+ q = append(q, "primaryLanguage{name}")
+ case "latestRelease":
+ q = append(q, "latestRelease{publishedAt,tagName,name,url}")
+ case "milestones":
+ q = append(q, "milestones(first:100,states:OPEN){nodes{number,title,description,dueOn}}")
+ case "assignableUsers":
+ q = append(q, "assignableUsers(first:100){nodes{id,login,name}}")
+ case "mentionableUsers":
+ q = append(q, "mentionableUsers(first:100){nodes{id,login,name}}")
+ case "projects":
+ q = append(q, "projects(first:100,states:OPEN){nodes{id,name,number,body,resourcePath}}")
+ case "watchers":
+ q = append(q, "watchers{totalCount}")
+ case "issues":
+ q = append(q, "issues(states:OPEN){totalCount}")
+ case "pullRequests":
+ q = append(q, "pullRequests(states:OPEN){totalCount}")
+ case "defaultBranchRef":
+ q = append(q, "defaultBranchRef{name}")
+ default:
+ q = append(q, field)
+ }
+ }
+ return strings.Join(q, ",")
+}
diff --git a/vendor/github.com/cli/cli/v2/api/reaction_groups.go b/vendor/github.com/cli/cli/v2/api/reaction_groups.go
new file mode 100644
index 000000000..08ae53040
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/api/reaction_groups.go
@@ -0,0 +1,59 @@
+package api
+
+import (
+ "bytes"
+ "encoding/json"
+)
+
+type ReactionGroups []ReactionGroup
+
+func (rg ReactionGroups) MarshalJSON() ([]byte, error) {
+ buf := bytes.Buffer{}
+ buf.WriteRune('[')
+ encoder := json.NewEncoder(&buf)
+ encoder.SetEscapeHTML(false)
+
+ hasPrev := false
+ for _, g := range rg {
+ if g.Users.TotalCount == 0 {
+ continue
+ }
+ if hasPrev {
+ buf.WriteRune(',')
+ }
+ if err := encoder.Encode(&g); err != nil {
+ return nil, err
+ }
+ hasPrev = true
+ }
+ buf.WriteRune(']')
+ return buf.Bytes(), nil
+}
+
+type ReactionGroup struct {
+ Content string `json:"content"`
+ Users ReactionGroupUsers `json:"users"`
+}
+
+type ReactionGroupUsers struct {
+ TotalCount int `json:"totalCount"`
+}
+
+func (rg ReactionGroup) Count() int {
+ return rg.Users.TotalCount
+}
+
+func (rg ReactionGroup) Emoji() string {
+ return reactionEmoji[rg.Content]
+}
+
+var reactionEmoji = map[string]string{
+ "THUMBS_UP": "\U0001f44d",
+ "THUMBS_DOWN": "\U0001f44e",
+ "LAUGH": "\U0001f604",
+ "HOORAY": "\U0001f389",
+ "CONFUSED": "\U0001f615",
+ "HEART": "\u2764\ufe0f",
+ "ROCKET": "\U0001f680",
+ "EYES": "\U0001f440",
+}
diff --git a/vendor/github.com/cli/cli/v2/context/context.go b/vendor/github.com/cli/cli/v2/context/context.go
new file mode 100644
index 000000000..06ef8ca7d
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/context/context.go
@@ -0,0 +1,172 @@
+// TODO: rename this package to avoid clash with stdlib
+package context
+
+import (
+ "errors"
+ "fmt"
+ "slices"
+ "sort"
+
+ "github.com/cli/cli/v2/api"
+ "github.com/cli/cli/v2/internal/ghrepo"
+ "github.com/cli/cli/v2/pkg/iostreams"
+)
+
+// Cap the number of git remotes to look up, since the user might have an
+// unusually large number of git remotes.
+const defaultRemotesForLookup = 5
+
+func ResolveRemotesToRepos(remotes Remotes, client *api.Client, base string) (*ResolvedRemotes, error) {
+ sort.Stable(remotes)
+
+ result := &ResolvedRemotes{
+ remotes: remotes,
+ apiClient: client,
+ }
+
+ var baseOverride ghrepo.Interface
+ if base != "" {
+ var err error
+ baseOverride, err = ghrepo.FromFullName(base)
+ if err != nil {
+ return result, err
+ }
+ result.baseOverride = baseOverride
+ }
+
+ return result, nil
+}
+
+func resolveNetwork(result *ResolvedRemotes, remotesForLookup int) error {
+ var repos []ghrepo.Interface
+ for _, r := range result.remotes {
+ repos = append(repos, r)
+ if len(repos) == remotesForLookup {
+ break
+ }
+ }
+
+ networkResult, err := api.RepoNetwork(result.apiClient, repos)
+ result.network = &networkResult
+ return err
+}
+
+type ResolvedRemotes struct {
+ baseOverride ghrepo.Interface
+ remotes Remotes
+ network *api.RepoNetworkResult
+ apiClient *api.Client
+}
+
+func (r *ResolvedRemotes) BaseRepo(io *iostreams.IOStreams) (ghrepo.Interface, error) {
+ if r.baseOverride != nil {
+ return r.baseOverride, nil
+ }
+
+ if len(r.remotes) == 0 {
+ return nil, errors.New("no git remotes")
+ }
+
+ // if any of the remotes already has a resolution, respect that
+ for _, r := range r.remotes {
+ if r.Resolved == "base" {
+ return r, nil
+ } else if r.Resolved != "" {
+ repo, err := ghrepo.FromFullName(r.Resolved)
+ if err != nil {
+ return nil, err
+ }
+ return ghrepo.NewWithHost(repo.RepoOwner(), repo.RepoName(), r.RepoHost()), nil
+ }
+ }
+
+ if !io.CanPrompt() {
+ // we cannot prompt, so just resort to the 1st remote
+ return r.remotes[0], nil
+ }
+
+ repos, err := r.NetworkRepos(defaultRemotesForLookup)
+ if err != nil {
+ return nil, err
+ }
+
+ if len(repos) == 0 {
+ return r.remotes[0], nil
+ } else if len(repos) == 1 {
+ return repos[0], nil
+ }
+
+ cs := io.ColorScheme()
+
+ fmt.Fprintf(io.ErrOut,
+ "%s No default remote repository has been set for this directory.\n",
+ cs.FailureIcon())
+
+ fmt.Fprintln(io.Out)
+
+ return nil, errors.New(
+ "please run `gh repo set-default` to select a default remote repository.")
+}
+
+func (r *ResolvedRemotes) HeadRepos() ([]*api.Repository, error) {
+ if r.network == nil {
+ err := resolveNetwork(r, defaultRemotesForLookup)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ var results []*api.Repository
+ var ids []string // Check if repo duplicates
+ for _, repo := range r.network.Repositories {
+ if repo != nil && repo.ViewerCanPush() && !slices.Contains(ids, repo.ID) {
+ results = append(results, repo)
+ ids = append(ids, repo.ID)
+ }
+ }
+ return results, nil
+}
+
+// NetworkRepos fetches info about remotes for the network of repos.
+// Pass a value of 0 to fetch info on all remotes.
+func (r *ResolvedRemotes) NetworkRepos(remotesForLookup int) ([]*api.Repository, error) {
+ if r.network == nil {
+ err := resolveNetwork(r, remotesForLookup)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ var repos []*api.Repository
+ repoMap := map[string]bool{}
+
+ add := func(r *api.Repository) {
+ fn := ghrepo.FullName(r)
+ if _, ok := repoMap[fn]; !ok {
+ repoMap[fn] = true
+ repos = append(repos, r)
+ }
+ }
+
+ for _, repo := range r.network.Repositories {
+ if repo == nil {
+ continue
+ }
+ if repo.Parent != nil {
+ add(repo.Parent)
+ }
+ add(repo)
+ }
+
+ return repos, nil
+}
+
+// RemoteForRepo finds the git remote that points to a repository
+func (r *ResolvedRemotes) RemoteForRepo(repo ghrepo.Interface) (*Remote, error) {
+ for _, remote := range r.remotes {
+ if ghrepo.IsSame(remote, repo) {
+ return remote, nil
+ }
+ }
+ return nil, errors.New("not found")
+}
diff --git a/vendor/github.com/cli/cli/v2/context/remote.go b/vendor/github.com/cli/cli/v2/context/remote.go
new file mode 100644
index 000000000..3540ad95d
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/context/remote.go
@@ -0,0 +1,123 @@
+package context
+
+import (
+ "fmt"
+ "net/url"
+ "strings"
+
+ "github.com/cli/cli/v2/git"
+ "github.com/cli/cli/v2/internal/ghrepo"
+)
+
+// Remotes represents a set of git remotes
+type Remotes []*Remote
+
+// FindByName returns the first Remote whose name matches the list
+func (r Remotes) FindByName(names ...string) (*Remote, error) {
+ for _, name := range names {
+ for _, rem := range r {
+ if rem.Name == name || name == "*" {
+ return rem, nil
+ }
+ }
+ }
+ return nil, fmt.Errorf("no matching remote found")
+}
+
+// FindByRepo returns the first Remote that points to a specific GitHub repository
+func (r Remotes) FindByRepo(owner, name string) (*Remote, error) {
+ for _, rem := range r {
+ if strings.EqualFold(rem.RepoOwner(), owner) && strings.EqualFold(rem.RepoName(), name) {
+ return rem, nil
+ }
+ }
+ return nil, fmt.Errorf("no matching remote found")
+}
+
+// Filter remotes by given hostnames, maintains original order
+func (r Remotes) FilterByHosts(hosts []string) Remotes {
+ filtered := make(Remotes, 0)
+ for _, rr := range r {
+ for _, host := range hosts {
+ if strings.EqualFold(rr.RepoHost(), host) {
+ filtered = append(filtered, rr)
+ break
+ }
+ }
+ }
+ return filtered
+}
+
+func (r Remotes) ResolvedRemote() (*Remote, error) {
+ for _, rr := range r {
+ if rr.Resolved != "" {
+ return rr, nil
+ }
+ }
+ return nil, fmt.Errorf("no resolved remote found")
+}
+
+func remoteNameSortScore(name string) int {
+ switch strings.ToLower(name) {
+ case "upstream":
+ return 3
+ case "github":
+ return 2
+ case "origin":
+ return 1
+ default:
+ return 0
+ }
+}
+
+// https://golang.org/pkg/sort/#Interface
+func (r Remotes) Len() int { return len(r) }
+func (r Remotes) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
+func (r Remotes) Less(i, j int) bool {
+ return remoteNameSortScore(r[i].Name) > remoteNameSortScore(r[j].Name)
+}
+
+// Remote represents a git remote mapped to a GitHub repository
+type Remote struct {
+ *git.Remote
+ Repo ghrepo.Interface
+}
+
+// RepoName is the name of the GitHub repository
+func (r Remote) RepoName() string {
+ return r.Repo.RepoName()
+}
+
+// RepoOwner is the name of the GitHub account that owns the repo
+func (r Remote) RepoOwner() string {
+ return r.Repo.RepoOwner()
+}
+
+// RepoHost is the GitHub hostname that the remote points to
+func (r Remote) RepoHost() string {
+ return r.Repo.RepoHost()
+}
+
+type Translator interface {
+ Translate(*url.URL) *url.URL
+}
+
+func TranslateRemotes(gitRemotes git.RemoteSet, translator Translator) (remotes Remotes) {
+ for _, r := range gitRemotes {
+ var repo ghrepo.Interface
+ if r.FetchURL != nil {
+ repo, _ = ghrepo.FromURL(translator.Translate(r.FetchURL))
+ }
+ if r.PushURL != nil && repo == nil {
+ repo, _ = ghrepo.FromURL(translator.Translate(r.PushURL))
+ }
+ if repo == nil {
+ continue
+ }
+ remotes = append(remotes, &Remote{
+ Remote: r,
+ Repo: repo,
+ })
+ }
+ return
+}
diff --git a/vendor/github.com/cli/cli/v2/git/client.go b/vendor/github.com/cli/cli/v2/git/client.go
new file mode 100644
index 000000000..b0194affc
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/git/client.go
@@ -0,0 +1,726 @@
+package git
+
+import (
+ "bytes"
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "net/url"
+ "os/exec"
+ "path"
+ "regexp"
+ "runtime"
+ "sort"
+ "strings"
+ "sync"
+
+ "github.com/cli/safeexec"
+)
+
+var remoteRE = regexp.MustCompile(`(.+)\s+(.+)\s+\((push|fetch)\)`)
+
+// This regexp exists to match lines of the following form:
+// 6a6872b918c601a0e730710ad8473938a7516d30\u0000title 1\u0000Body 1\u0000\n
+// 7a6872b918c601a0e730710ad8473938a7516d31\u0000title 2\u0000Body 2\u0000
+//
+// This is the format we use when collecting commit information,
+// with null bytes as separators. Using null bytes this way allows for us
+// to easily maintain newlines that might be in the body.
+//
+// The ?m modifier is the multi-line modifier, meaning that ^ and $
+// match the beginning and end of lines, respectively.
+//
+// The [\S\s] matches any whitespace or non-whitespace character,
+// which is different from .* because it allows for newlines as well.
+//
+// The ? following .* and [\S\s] is a lazy modifier, meaning that it will
+// match as few characters as possible while still satisfying the rest of the regexp.
+// This is important because it allows us to match the first null byte after the title and body,
+// rather than the last null byte in the entire string.
+var commitLogRE = regexp.MustCompile(`(?m)^[0-9a-fA-F]{7,40}\x00.*?\x00[\S\s]*?\x00$`)
+
+type errWithExitCode interface {
+ ExitCode() int
+}
+
+type Client struct {
+ GhPath string
+ RepoDir string
+ GitPath string
+ Stderr io.Writer
+ Stdin io.Reader
+ Stdout io.Writer
+
+ commandContext commandCtx
+ mu sync.Mutex
+}
+
+func (c *Client) Copy() *Client {
+ return &Client{
+ GhPath: c.GhPath,
+ RepoDir: c.RepoDir,
+ GitPath: c.GitPath,
+ Stderr: c.Stderr,
+ Stdin: c.Stdin,
+ Stdout: c.Stdout,
+
+ commandContext: c.commandContext,
+ }
+}
+
+func (c *Client) Command(ctx context.Context, args ...string) (*Command, error) {
+ if c.RepoDir != "" {
+ args = append([]string{"-C", c.RepoDir}, args...)
+ }
+ commandContext := exec.CommandContext
+ if c.commandContext != nil {
+ commandContext = c.commandContext
+ }
+ var err error
+ c.mu.Lock()
+ if c.GitPath == "" {
+ c.GitPath, err = resolveGitPath()
+ }
+ c.mu.Unlock()
+ if err != nil {
+ return nil, err
+ }
+ cmd := commandContext(ctx, c.GitPath, args...)
+ cmd.Stderr = c.Stderr
+ cmd.Stdin = c.Stdin
+ cmd.Stdout = c.Stdout
+ return &Command{cmd}, nil
+}
+
+// AuthenticatedCommand is a wrapper around Command that included configuration to use gh
+// as the credential helper for git.
+func (c *Client) AuthenticatedCommand(ctx context.Context, args ...string) (*Command, error) {
+ preArgs := []string{"-c", "credential.helper="}
+ if c.GhPath == "" {
+ // Assumes that gh is in PATH.
+ c.GhPath = "gh"
+ }
+ credHelper := fmt.Sprintf("!%q auth git-credential", c.GhPath)
+ preArgs = append(preArgs, "-c", fmt.Sprintf("credential.helper=%s", credHelper))
+ args = append(preArgs, args...)
+ return c.Command(ctx, args...)
+}
+
+func (c *Client) Remotes(ctx context.Context) (RemoteSet, error) {
+ remoteArgs := []string{"remote", "-v"}
+ remoteCmd, err := c.Command(ctx, remoteArgs...)
+ if err != nil {
+ return nil, err
+ }
+ remoteOut, remoteErr := remoteCmd.Output()
+ if remoteErr != nil {
+ return nil, remoteErr
+ }
+
+ configArgs := []string{"config", "--get-regexp", `^remote\..*\.gh-resolved$`}
+ configCmd, err := c.Command(ctx, configArgs...)
+ if err != nil {
+ return nil, err
+ }
+ configOut, configErr := configCmd.Output()
+ if configErr != nil {
+ // Ignore exit code 1 as it means there are no resolved remotes.
+ var gitErr *GitError
+ if ok := errors.As(configErr, &gitErr); ok && gitErr.ExitCode != 1 {
+ return nil, gitErr
+ }
+ }
+
+ remotes := parseRemotes(outputLines(remoteOut))
+ populateResolvedRemotes(remotes, outputLines(configOut))
+ sort.Sort(remotes)
+ return remotes, nil
+}
+
+func (c *Client) UpdateRemoteURL(ctx context.Context, name, url string) error {
+ args := []string{"remote", "set-url", name, url}
+ cmd, err := c.Command(ctx, args...)
+ if err != nil {
+ return err
+ }
+ _, err = cmd.Output()
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func (c *Client) SetRemoteResolution(ctx context.Context, name, resolution string) error {
+ args := []string{"config", "--add", fmt.Sprintf("remote.%s.gh-resolved", name), resolution}
+ cmd, err := c.Command(ctx, args...)
+ if err != nil {
+ return err
+ }
+ _, err = cmd.Output()
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+// CurrentBranch reads the checked-out branch for the git repository.
+func (c *Client) CurrentBranch(ctx context.Context) (string, error) {
+ args := []string{"symbolic-ref", "--quiet", "HEAD"}
+ cmd, err := c.Command(ctx, args...)
+ if err != nil {
+ return "", err
+ }
+ out, err := cmd.Output()
+ if err != nil {
+ var gitErr *GitError
+ if ok := errors.As(err, &gitErr); ok && len(gitErr.Stderr) == 0 {
+ gitErr.err = ErrNotOnAnyBranch
+ gitErr.Stderr = "not on any branch"
+ return "", gitErr
+ }
+ return "", err
+ }
+ branch := firstLine(out)
+ return strings.TrimPrefix(branch, "refs/heads/"), nil
+}
+
+// ShowRefs resolves fully-qualified refs to commit hashes.
+func (c *Client) ShowRefs(ctx context.Context, refs []string) ([]Ref, error) {
+ args := append([]string{"show-ref", "--verify", "--"}, refs...)
+ cmd, err := c.Command(ctx, args...)
+ if err != nil {
+ return nil, err
+ }
+ // This functionality relies on parsing output from the git command despite
+ // an error status being returned from git.
+ out, err := cmd.Output()
+ var verified []Ref
+ for _, line := range outputLines(out) {
+ parts := strings.SplitN(line, " ", 2)
+ if len(parts) < 2 {
+ continue
+ }
+ verified = append(verified, Ref{
+ Hash: parts[0],
+ Name: parts[1],
+ })
+ }
+ return verified, err
+}
+
+func (c *Client) Config(ctx context.Context, name string) (string, error) {
+ args := []string{"config", name}
+ cmd, err := c.Command(ctx, args...)
+ if err != nil {
+ return "", err
+ }
+ out, err := cmd.Output()
+ if err != nil {
+ var gitErr *GitError
+ if ok := errors.As(err, &gitErr); ok && gitErr.ExitCode == 1 {
+ gitErr.Stderr = fmt.Sprintf("unknown config key %s", name)
+ return "", gitErr
+ }
+ return "", err
+ }
+ return firstLine(out), nil
+}
+
+func (c *Client) UncommittedChangeCount(ctx context.Context) (int, error) {
+ args := []string{"status", "--porcelain"}
+ cmd, err := c.Command(ctx, args...)
+ if err != nil {
+ return 0, err
+ }
+ out, err := cmd.Output()
+ if err != nil {
+ return 0, err
+ }
+ lines := strings.Split(string(out), "\n")
+ count := 0
+ for _, l := range lines {
+ if l != "" {
+ count++
+ }
+ }
+ return count, nil
+}
+
+func (c *Client) Commits(ctx context.Context, baseRef, headRef string) ([]*Commit, error) {
+ // The formatting directive %x00 indicates that git should include the null byte as a separator.
+ // We use this because it is not a valid character to include in a commit message. Previously,
+ // commas were used here but when we Split on them, we would get incorrect results if commit titles
+ // happened to contain them.
+ // https://git-scm.com/docs/pretty-formats#Documentation/pretty-formats.txt-emx00em
+ args := []string{"-c", "log.ShowSignature=false", "log", "--pretty=format:%H%x00%s%x00%b%x00", "--cherry", fmt.Sprintf("%s...%s", baseRef, headRef)}
+ cmd, err := c.Command(ctx, args...)
+ if err != nil {
+ return nil, err
+ }
+ out, err := cmd.Output()
+ if err != nil {
+ return nil, err
+ }
+
+ commits := []*Commit{}
+ commitLogs := commitLogRE.FindAllString(string(out), -1)
+ for _, commitLog := range commitLogs {
+ // Each line looks like this:
+ // 6a6872b918c601a0e730710ad8473938a7516d30\u0000title 1\u0000Body 1\u0000\n
+
+ // Or with an optional body:
+ // 6a6872b918c601a0e730710ad8473938a7516d30\u0000title 1\u0000\u0000\n
+
+ // Therefore after splitting we will have:
+ // ["6a6872b918c601a0e730710ad8473938a7516d30", "title 1", "Body 1", ""]
+
+ // Or with an optional body:
+ // ["6a6872b918c601a0e730710ad8473938a7516d30", "title 1", "", ""]
+ commitLogParts := strings.Split(commitLog, "\u0000")
+ commits = append(commits, &Commit{
+ Sha: commitLogParts[0],
+ Title: commitLogParts[1],
+ Body: commitLogParts[2],
+ })
+ }
+
+ if len(commits) == 0 {
+ return nil, fmt.Errorf("could not find any commits between %s and %s", baseRef, headRef)
+ }
+
+ return commits, nil
+}
+
+func (c *Client) LastCommit(ctx context.Context) (*Commit, error) {
+ output, err := c.lookupCommit(ctx, "HEAD", "%H,%s")
+ if err != nil {
+ return nil, err
+ }
+ idx := bytes.IndexByte(output, ',')
+ return &Commit{
+ Sha: string(output[0:idx]),
+ Title: strings.TrimSpace(string(output[idx+1:])),
+ }, nil
+}
+
+func (c *Client) CommitBody(ctx context.Context, sha string) (string, error) {
+ output, err := c.lookupCommit(ctx, sha, "%b")
+ return string(output), err
+}
+
+func (c *Client) lookupCommit(ctx context.Context, sha, format string) ([]byte, error) {
+ args := []string{"-c", "log.ShowSignature=false", "show", "-s", "--pretty=format:" + format, sha}
+ cmd, err := c.Command(ctx, args...)
+ if err != nil {
+ return nil, err
+ }
+ out, err := cmd.Output()
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+// ReadBranchConfig parses the `branch.BRANCH.(remote|merge)` part of git config.
+func (c *Client) ReadBranchConfig(ctx context.Context, branch string) (cfg BranchConfig) {
+ prefix := regexp.QuoteMeta(fmt.Sprintf("branch.%s.", branch))
+ args := []string{"config", "--get-regexp", fmt.Sprintf("^%s(remote|merge)$", prefix)}
+ cmd, err := c.Command(ctx, args...)
+ if err != nil {
+ return
+ }
+ out, err := cmd.Output()
+ if err != nil {
+ return
+ }
+ for _, line := range outputLines(out) {
+ parts := strings.SplitN(line, " ", 2)
+ if len(parts) < 2 {
+ continue
+ }
+ keys := strings.Split(parts[0], ".")
+ switch keys[len(keys)-1] {
+ case "remote":
+ if strings.Contains(parts[1], ":") {
+ u, err := ParseURL(parts[1])
+ if err != nil {
+ continue
+ }
+ cfg.RemoteURL = u
+ } else if !isFilesystemPath(parts[1]) {
+ cfg.RemoteName = parts[1]
+ }
+ case "merge":
+ cfg.MergeRef = parts[1]
+ }
+ }
+ return
+}
+
+func (c *Client) DeleteLocalTag(ctx context.Context, tag string) error {
+ args := []string{"tag", "-d", tag}
+ cmd, err := c.Command(ctx, args...)
+ if err != nil {
+ return err
+ }
+ _, err = cmd.Output()
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func (c *Client) DeleteLocalBranch(ctx context.Context, branch string) error {
+ args := []string{"branch", "-D", branch}
+ cmd, err := c.Command(ctx, args...)
+ if err != nil {
+ return err
+ }
+ _, err = cmd.Output()
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func (c *Client) CheckoutBranch(ctx context.Context, branch string) error {
+ args := []string{"checkout", branch}
+ cmd, err := c.Command(ctx, args...)
+ if err != nil {
+ return err
+ }
+ _, err = cmd.Output()
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func (c *Client) CheckoutNewBranch(ctx context.Context, remoteName, branch string) error {
+ track := fmt.Sprintf("%s/%s", remoteName, branch)
+ args := []string{"checkout", "-b", branch, "--track", track}
+ cmd, err := c.Command(ctx, args...)
+ if err != nil {
+ return err
+ }
+ _, err = cmd.Output()
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func (c *Client) HasLocalBranch(ctx context.Context, branch string) bool {
+ _, err := c.revParse(ctx, "--verify", "refs/heads/"+branch)
+ return err == nil
+}
+
+func (c *Client) TrackingBranchNames(ctx context.Context, prefix string) []string {
+ args := []string{"branch", "-r", "--format", "%(refname:strip=3)"}
+ if prefix != "" {
+ args = append(args, "--list", fmt.Sprintf("*/%s*", escapeGlob(prefix)))
+ }
+ cmd, err := c.Command(ctx, args...)
+ if err != nil {
+ return nil
+ }
+ output, err := cmd.Output()
+ if err != nil {
+ return nil
+ }
+ return strings.Split(string(output), "\n")
+}
+
+// ToplevelDir returns the top-level directory path of the current repository.
+func (c *Client) ToplevelDir(ctx context.Context) (string, error) {
+ out, err := c.revParse(ctx, "--show-toplevel")
+ if err != nil {
+ return "", err
+ }
+ return firstLine(out), nil
+}
+
+func (c *Client) GitDir(ctx context.Context) (string, error) {
+ out, err := c.revParse(ctx, "--git-dir")
+ if err != nil {
+ return "", err
+ }
+ return firstLine(out), nil
+}
+
+// Show current directory relative to the top-level directory of repository.
+func (c *Client) PathFromRoot(ctx context.Context) string {
+ out, err := c.revParse(ctx, "--show-prefix")
+ if err != nil {
+ return ""
+ }
+ if path := firstLine(out); path != "" {
+ return path[:len(path)-1]
+ }
+ return ""
+}
+
+func (c *Client) revParse(ctx context.Context, args ...string) ([]byte, error) {
+ args = append([]string{"rev-parse"}, args...)
+ cmd, err := c.Command(ctx, args...)
+ if err != nil {
+ return nil, err
+ }
+ return cmd.Output()
+}
+
+func (c *Client) IsLocalGitRepo(ctx context.Context) (bool, error) {
+ _, err := c.GitDir(ctx)
+ if err != nil {
+ var execError errWithExitCode
+ if errors.As(err, &execError) && execError.ExitCode() == 128 {
+ return false, nil
+ }
+ return false, err
+ }
+ return true, nil
+}
+
+func (c *Client) UnsetRemoteResolution(ctx context.Context, name string) error {
+ args := []string{"config", "--unset", fmt.Sprintf("remote.%s.gh-resolved", name)}
+ cmd, err := c.Command(ctx, args...)
+ if err != nil {
+ return err
+ }
+ _, err = cmd.Output()
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func (c *Client) SetRemoteBranches(ctx context.Context, remote string, refspec string) error {
+ args := []string{"remote", "set-branches", remote, refspec}
+ cmd, err := c.Command(ctx, args...)
+ if err != nil {
+ return err
+ }
+ _, err = cmd.Output()
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func (c *Client) AddRemote(ctx context.Context, name, urlStr string, trackingBranches []string) (*Remote, error) {
+ args := []string{"remote", "add"}
+ for _, branch := range trackingBranches {
+ args = append(args, "-t", branch)
+ }
+ args = append(args, name, urlStr)
+ cmd, err := c.Command(ctx, args...)
+ if err != nil {
+ return nil, err
+ }
+ if _, err := cmd.Output(); err != nil {
+ return nil, err
+ }
+ var urlParsed *url.URL
+ if strings.HasPrefix(urlStr, "https") {
+ urlParsed, err = url.Parse(urlStr)
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ urlParsed, err = ParseURL(urlStr)
+ if err != nil {
+ return nil, err
+ }
+ }
+ remote := &Remote{
+ Name: name,
+ FetchURL: urlParsed,
+ PushURL: urlParsed,
+ }
+ return remote, nil
+}
+
+// Below are commands that make network calls and need authentication credentials supplied from gh.
+
+func (c *Client) Fetch(ctx context.Context, remote string, refspec string, mods ...CommandModifier) error {
+ args := []string{"fetch", remote}
+ if refspec != "" {
+ args = append(args, refspec)
+ }
+ cmd, err := c.AuthenticatedCommand(ctx, args...)
+ if err != nil {
+ return err
+ }
+ for _, mod := range mods {
+ mod(cmd)
+ }
+ return cmd.Run()
+}
+
+func (c *Client) Pull(ctx context.Context, remote, branch string, mods ...CommandModifier) error {
+ args := []string{"pull", "--ff-only"}
+ if remote != "" && branch != "" {
+ args = append(args, remote, branch)
+ }
+ cmd, err := c.AuthenticatedCommand(ctx, args...)
+ if err != nil {
+ return err
+ }
+ for _, mod := range mods {
+ mod(cmd)
+ }
+ return cmd.Run()
+}
+
+func (c *Client) Push(ctx context.Context, remote string, ref string, mods ...CommandModifier) error {
+ args := []string{"push", "--set-upstream", remote, ref}
+ cmd, err := c.AuthenticatedCommand(ctx, args...)
+ if err != nil {
+ return err
+ }
+ for _, mod := range mods {
+ mod(cmd)
+ }
+ return cmd.Run()
+}
+
+func (c *Client) Clone(ctx context.Context, cloneURL string, args []string, mods ...CommandModifier) (string, error) {
+ cloneArgs, target := parseCloneArgs(args)
+ cloneArgs = append(cloneArgs, cloneURL)
+ // If the args contain an explicit target, pass it to clone otherwise,
+ // parse the URL to determine where git cloned it to so we can return it.
+ if target != "" {
+ cloneArgs = append(cloneArgs, target)
+ } else {
+ target = path.Base(strings.TrimSuffix(cloneURL, ".git"))
+ }
+ cloneArgs = append([]string{"clone"}, cloneArgs...)
+ cmd, err := c.AuthenticatedCommand(ctx, cloneArgs...)
+ if err != nil {
+ return "", err
+ }
+ for _, mod := range mods {
+ mod(cmd)
+ }
+ err = cmd.Run()
+ if err != nil {
+ return "", err
+ }
+ return target, nil
+}
+
+func resolveGitPath() (string, error) {
+ path, err := safeexec.LookPath("git")
+ if err != nil {
+ if errors.Is(err, exec.ErrNotFound) {
+ programName := "git"
+ if runtime.GOOS == "windows" {
+ programName = "Git for Windows"
+ }
+ return "", &NotInstalled{
+ message: fmt.Sprintf("unable to find git executable in PATH; please install %s before retrying", programName),
+ err: err,
+ }
+ }
+ return "", err
+ }
+ return path, nil
+}
+
+func isFilesystemPath(p string) bool {
+ return p == "." || strings.HasPrefix(p, "./") || strings.HasPrefix(p, "/")
+}
+
+func outputLines(output []byte) []string {
+ lines := strings.TrimSuffix(string(output), "\n")
+ return strings.Split(lines, "\n")
+}
+
+func firstLine(output []byte) string {
+ if i := bytes.IndexAny(output, "\n"); i >= 0 {
+ return string(output)[0:i]
+ }
+ return string(output)
+}
+
+func parseCloneArgs(extraArgs []string) (args []string, target string) {
+ args = extraArgs
+ if len(args) > 0 {
+ if !strings.HasPrefix(args[0], "-") {
+ target, args = args[0], args[1:]
+ }
+ }
+ return
+}
+
+func parseRemotes(remotesStr []string) RemoteSet {
+ remotes := RemoteSet{}
+ for _, r := range remotesStr {
+ match := remoteRE.FindStringSubmatch(r)
+ if match == nil {
+ continue
+ }
+ name := strings.TrimSpace(match[1])
+ urlStr := strings.TrimSpace(match[2])
+ urlType := strings.TrimSpace(match[3])
+
+ url, err := ParseURL(urlStr)
+ if err != nil {
+ continue
+ }
+
+ var rem *Remote
+ if len(remotes) > 0 {
+ rem = remotes[len(remotes)-1]
+ if name != rem.Name {
+ rem = nil
+ }
+ }
+ if rem == nil {
+ rem = &Remote{Name: name}
+ remotes = append(remotes, rem)
+ }
+
+ switch urlType {
+ case "fetch":
+ rem.FetchURL = url
+ case "push":
+ rem.PushURL = url
+ }
+ }
+ return remotes
+}
+
+func populateResolvedRemotes(remotes RemoteSet, resolved []string) {
+ for _, l := range resolved {
+ parts := strings.SplitN(l, " ", 2)
+ if len(parts) < 2 {
+ continue
+ }
+ rp := strings.SplitN(parts[0], ".", 3)
+ if len(rp) < 2 {
+ continue
+ }
+ name := rp[1]
+ for _, r := range remotes {
+ if r.Name == name {
+ r.Resolved = parts[1]
+ break
+ }
+ }
+ }
+}
+
+var globReplacer = strings.NewReplacer(
+ "*", `\*`,
+ "?", `\?`,
+ "[", `\[`,
+ "]", `\]`,
+ "{", `\{`,
+ "}", `\}`,
+)
+
+func escapeGlob(p string) string {
+ return globReplacer.Replace(p)
+}
diff --git a/vendor/github.com/cli/cli/v2/git/command.go b/vendor/github.com/cli/cli/v2/git/command.go
new file mode 100644
index 000000000..8065ffd86
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/git/command.go
@@ -0,0 +1,100 @@
+package git
+
+import (
+ "bytes"
+ "context"
+ "errors"
+ "io"
+ "os/exec"
+
+ "github.com/cli/cli/v2/internal/run"
+)
+
+type commandCtx = func(ctx context.Context, name string, args ...string) *exec.Cmd
+
+type Command struct {
+ *exec.Cmd
+}
+
+func (gc *Command) Run() error {
+ stderr := &bytes.Buffer{}
+ if gc.Cmd.Stderr == nil {
+ gc.Cmd.Stderr = stderr
+ }
+ // This is a hack in order to not break the hundreds of
+ // existing tests that rely on `run.PrepareCmd` to be invoked.
+ err := run.PrepareCmd(gc.Cmd).Run()
+ if err != nil {
+ ge := GitError{err: err, Stderr: stderr.String()}
+ var exitError *exec.ExitError
+ if errors.As(err, &exitError) {
+ ge.ExitCode = exitError.ExitCode()
+ }
+ return &ge
+ }
+ return nil
+}
+
+func (gc *Command) Output() ([]byte, error) {
+ gc.Stdout = nil
+ gc.Stderr = nil
+ // This is a hack in order to not break the hundreds of
+ // existing tests that rely on `run.PrepareCmd` to be invoked.
+ out, err := run.PrepareCmd(gc.Cmd).Output()
+ if err != nil {
+ ge := GitError{err: err}
+ var exitError *exec.ExitError
+ if errors.As(err, &exitError) {
+ ge.Stderr = string(exitError.Stderr)
+ ge.ExitCode = exitError.ExitCode()
+ }
+ err = &ge
+ }
+ return out, err
+}
+
+func (gc *Command) setRepoDir(repoDir string) {
+ for i, arg := range gc.Args {
+ if arg == "-C" {
+ gc.Args[i+1] = repoDir
+ return
+ }
+ }
+ // Handle "--" invocations for testing purposes.
+ var index int
+ for i, arg := range gc.Args {
+ if arg == "--" {
+ index = i + 1
+ }
+ }
+ gc.Args = append(gc.Args[:index+3], gc.Args[index+1:]...)
+ gc.Args[index+1] = "-C"
+ gc.Args[index+2] = repoDir
+}
+
+// Allow individual commands to be modified from the default client options.
+type CommandModifier func(*Command)
+
+func WithStderr(stderr io.Writer) CommandModifier {
+ return func(gc *Command) {
+ gc.Stderr = stderr
+ }
+}
+
+func WithStdout(stdout io.Writer) CommandModifier {
+ return func(gc *Command) {
+ gc.Stdout = stdout
+ }
+}
+
+func WithStdin(stdin io.Reader) CommandModifier {
+ return func(gc *Command) {
+ gc.Stdin = stdin
+ }
+}
+
+func WithRepoDir(repoDir string) CommandModifier {
+ return func(gc *Command) {
+ gc.setRepoDir(repoDir)
+ }
+}
diff --git a/vendor/github.com/cli/cli/v2/git/errors.go b/vendor/github.com/cli/cli/v2/git/errors.go
new file mode 100644
index 000000000..a3f1645aa
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/git/errors.go
@@ -0,0 +1,39 @@
+package git
+
+import (
+ "errors"
+ "fmt"
+)
+
+// ErrNotOnAnyBranch indicates that the user is in detached HEAD state.
+var ErrNotOnAnyBranch = errors.New("git: not on any branch")
+
+type NotInstalled struct {
+ message string
+ err error
+}
+
+func (e *NotInstalled) Error() string {
+ return e.message
+}
+
+func (e *NotInstalled) Unwrap() error {
+ return e.err
+}
+
+type GitError struct {
+ ExitCode int
+ Stderr string
+ err error
+}
+
+func (ge *GitError) Error() string {
+ if ge.Stderr == "" {
+ return fmt.Sprintf("failed to run git: %v", ge.err)
+ }
+ return fmt.Sprintf("failed to run git: %s", ge.Stderr)
+}
+
+func (ge *GitError) Unwrap() error {
+ return ge.err
+}
diff --git a/vendor/github.com/cli/cli/v2/git/objects.go b/vendor/github.com/cli/cli/v2/git/objects.go
new file mode 100644
index 000000000..c33d92b7c
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/git/objects.go
@@ -0,0 +1,77 @@
+package git
+
+import (
+ "net/url"
+ "strings"
+)
+
+// RemoteSet is a slice of git remotes.
+type RemoteSet []*Remote
+
+func (r RemoteSet) Len() int { return len(r) }
+func (r RemoteSet) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
+func (r RemoteSet) Less(i, j int) bool {
+ return remoteNameSortScore(r[i].Name) > remoteNameSortScore(r[j].Name)
+}
+
+func remoteNameSortScore(name string) int {
+ switch strings.ToLower(name) {
+ case "upstream":
+ return 3
+ case "github":
+ return 2
+ case "origin":
+ return 1
+ default:
+ return 0
+ }
+}
+
+// Remote is a parsed git remote.
+type Remote struct {
+ Name string
+ Resolved string
+ FetchURL *url.URL
+ PushURL *url.URL
+}
+
+func (r *Remote) String() string {
+ return r.Name
+}
+
+func NewRemote(name string, u string) *Remote {
+ pu, _ := url.Parse(u)
+ return &Remote{
+ Name: name,
+ FetchURL: pu,
+ PushURL: pu,
+ }
+}
+
+// Ref represents a git commit reference.
+type Ref struct {
+ Hash string
+ Name string
+}
+
+// TrackingRef represents a ref for a remote tracking branch.
+type TrackingRef struct {
+ RemoteName string
+ BranchName string
+}
+
+func (r TrackingRef) String() string {
+ return "refs/remotes/" + r.RemoteName + "/" + r.BranchName
+}
+
+type Commit struct {
+ Sha string
+ Title string
+ Body string
+}
+
+type BranchConfig struct {
+ RemoteName string
+ RemoteURL *url.URL
+ MergeRef string
+}
diff --git a/vendor/github.com/cli/cli/v2/git/url.go b/vendor/github.com/cli/cli/v2/git/url.go
new file mode 100644
index 000000000..1a3e97fd6
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/git/url.go
@@ -0,0 +1,64 @@
+package git
+
+import (
+ "net/url"
+ "strings"
+)
+
+func IsURL(u string) bool {
+ return strings.HasPrefix(u, "git@") || isSupportedProtocol(u)
+}
+
+func isSupportedProtocol(u string) bool {
+ return strings.HasPrefix(u, "ssh:") ||
+ strings.HasPrefix(u, "git+ssh:") ||
+ strings.HasPrefix(u, "git:") ||
+ strings.HasPrefix(u, "http:") ||
+ strings.HasPrefix(u, "git+https:") ||
+ strings.HasPrefix(u, "https:")
+}
+
+func isPossibleProtocol(u string) bool {
+ return isSupportedProtocol(u) ||
+ strings.HasPrefix(u, "ftp:") ||
+ strings.HasPrefix(u, "ftps:") ||
+ strings.HasPrefix(u, "file:")
+}
+
+// ParseURL normalizes git remote urls
+func ParseURL(rawURL string) (u *url.URL, err error) {
+ if !isPossibleProtocol(rawURL) &&
+ strings.ContainsRune(rawURL, ':') &&
+ // not a Windows path
+ !strings.ContainsRune(rawURL, '\\') {
+ // support scp-like syntax for ssh protocol
+ rawURL = "ssh://" + strings.Replace(rawURL, ":", "/", 1)
+ }
+
+ u, err = url.Parse(rawURL)
+ if err != nil {
+ return
+ }
+
+ if u.Scheme == "git+ssh" {
+ u.Scheme = "ssh"
+ }
+
+ if u.Scheme == "git+https" {
+ u.Scheme = "https"
+ }
+
+ if u.Scheme != "ssh" {
+ return
+ }
+
+ if strings.HasPrefix(u.Path, "//") {
+ u.Path = strings.TrimPrefix(u.Path, "/")
+ }
+
+ if idx := strings.Index(u.Host, ":"); idx >= 0 {
+ u.Host = u.Host[0:idx]
+ }
+
+ return
+}
diff --git a/vendor/github.com/cli/cli/v2/internal/authflow/flow.go b/vendor/github.com/cli/cli/v2/internal/authflow/flow.go
new file mode 100644
index 000000000..370e08784
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/internal/authflow/flow.go
@@ -0,0 +1,157 @@
+package authflow
+
+import (
+ "bufio"
+ "fmt"
+ "io"
+ "net/http"
+ "net/url"
+ "regexp"
+ "strings"
+
+ "github.com/cli/cli/v2/api"
+ "github.com/cli/cli/v2/internal/browser"
+ "github.com/cli/cli/v2/internal/ghinstance"
+ "github.com/cli/cli/v2/pkg/iostreams"
+ "github.com/cli/cli/v2/utils"
+ "github.com/cli/oauth"
+ "github.com/henvic/httpretty"
+)
+
+var (
+ // The "GitHub CLI" OAuth app
+ oauthClientID = "178c6fc778ccc68e1d6a"
+ // This value is safe to be embedded in version control
+ oauthClientSecret = "34ddeff2b558a23d38fba8a6de74f086ede1cc0b"
+
+ jsonTypeRE = regexp.MustCompile(`[/+]json($|;)`)
+)
+
+func AuthFlow(oauthHost string, IO *iostreams.IOStreams, notice string, additionalScopes []string, isInteractive bool, b browser.Browser) (string, string, error) {
+ w := IO.ErrOut
+ cs := IO.ColorScheme()
+
+ httpClient := &http.Client{}
+ debugEnabled, debugValue := utils.IsDebugEnabled()
+ if debugEnabled {
+ logTraffic := strings.Contains(debugValue, "api")
+ httpClient.Transport = verboseLog(IO.ErrOut, logTraffic, IO.ColorEnabled())(httpClient.Transport)
+ }
+
+ minimumScopes := []string{"repo", "read:org", "gist"}
+ scopes := append(minimumScopes, additionalScopes...)
+
+ callbackURI := "http://127.0.0.1/callback"
+ if ghinstance.IsEnterprise(oauthHost) {
+ // the OAuth app on Enterprise hosts is still registered with a legacy callback URL
+ // see https://github.com/cli/cli/pull/222, https://github.com/cli/cli/pull/650
+ callbackURI = "http://localhost/"
+ }
+
+ flow := &oauth.Flow{
+ Host: oauth.GitHubHost(ghinstance.HostPrefix(oauthHost)),
+ ClientID: oauthClientID,
+ ClientSecret: oauthClientSecret,
+ CallbackURI: callbackURI,
+ Scopes: scopes,
+ DisplayCode: func(code, verificationURL string) error {
+ fmt.Fprintf(w, "%s First copy your one-time code: %s\n", cs.Yellow("!"), cs.Bold(code))
+ return nil
+ },
+ BrowseURL: func(authURL string) error {
+ if u, err := url.Parse(authURL); err == nil {
+ if u.Scheme != "http" && u.Scheme != "https" {
+ return fmt.Errorf("invalid URL: %s", authURL)
+ }
+ } else {
+ return err
+ }
+
+ if !isInteractive {
+ fmt.Fprintf(w, "%s to continue in your web browser: %s\n", cs.Bold("Open this URL"), authURL)
+ return nil
+ }
+
+ fmt.Fprintf(w, "%s to open %s in your browser... ", cs.Bold("Press Enter"), oauthHost)
+ _ = waitForEnter(IO.In)
+
+ if err := b.Browse(authURL); err != nil {
+ fmt.Fprintf(w, "%s Failed opening a web browser at %s\n", cs.Red("!"), authURL)
+ fmt.Fprintf(w, " %s\n", err)
+ fmt.Fprint(w, " Please try entering the URL in your browser manually\n")
+ }
+ return nil
+ },
+ WriteSuccessHTML: func(w io.Writer) {
+ fmt.Fprint(w, oauthSuccessPage)
+ },
+ HTTPClient: httpClient,
+ Stdin: IO.In,
+ Stdout: w,
+ }
+
+ fmt.Fprintln(w, notice)
+
+ token, err := flow.DetectFlow()
+ if err != nil {
+ return "", "", err
+ }
+
+ userLogin, err := getViewer(oauthHost, token.Token, IO.ErrOut)
+ if err != nil {
+ return "", "", err
+ }
+
+ return token.Token, userLogin, nil
+}
+
+type cfg struct {
+ token string
+}
+
+func (c cfg) ActiveToken(hostname string) (string, string) {
+ return c.token, "oauth_token"
+}
+
+func getViewer(hostname, token string, logWriter io.Writer) (string, error) {
+ opts := api.HTTPClientOptions{
+ Config: cfg{token: token},
+ Log: logWriter,
+ }
+ client, err := api.NewHTTPClient(opts)
+ if err != nil {
+ return "", err
+ }
+ return api.CurrentLoginName(api.NewClientFromHTTP(client), hostname)
+}
+
+func waitForEnter(r io.Reader) error {
+ scanner := bufio.NewScanner(r)
+ scanner.Scan()
+ return scanner.Err()
+}
+
+func verboseLog(out io.Writer, logTraffic bool, colorize bool) func(http.RoundTripper) http.RoundTripper {
+ logger := &httpretty.Logger{
+ Time: true,
+ TLS: false,
+ Colors: colorize,
+ RequestHeader: logTraffic,
+ RequestBody: logTraffic,
+ ResponseHeader: logTraffic,
+ ResponseBody: logTraffic,
+ Formatters: []httpretty.Formatter{&httpretty.JSONFormatter{}},
+ MaxResponseBody: 10000,
+ }
+ logger.SetOutput(out)
+ logger.SetBodyFilter(func(h http.Header) (skip bool, err error) {
+ return !inspectableMIMEType(h.Get("Content-Type")), nil
+ })
+ return logger.RoundTripper
+}
+
+func inspectableMIMEType(t string) bool {
+ return strings.HasPrefix(t, "text/") ||
+ strings.HasPrefix(t, "application/x-www-form-urlencoded") ||
+ jsonTypeRE.MatchString(t)
+}
diff --git a/vendor/github.com/cli/cli/v2/internal/authflow/success.go b/vendor/github.com/cli/cli/v2/internal/authflow/success.go
new file mode 100644
index 000000000..a546e58d7
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/internal/authflow/success.go
@@ -0,0 +1,42 @@
+package authflow
+
+const oauthSuccessPage = `
+
+
+Success: GitHub CLI
+
+
+
+
+
Successfully authenticated GitHub CLI
+
You may now close this tab and return to the terminal.
+
+
+`
diff --git a/vendor/github.com/cli/cli/v2/internal/browser/browser.go b/vendor/github.com/cli/cli/v2/internal/browser/browser.go
new file mode 100644
index 000000000..0f231ddc8
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/internal/browser/browser.go
@@ -0,0 +1,16 @@
+package browser
+
+import (
+ "io"
+
+ ghBrowser "github.com/cli/go-gh/v2/pkg/browser"
+)
+
+type Browser interface {
+ Browse(string) error
+}
+
+func New(launcher string, stdout, stderr io.Writer) Browser {
+ b := ghBrowser.New(launcher, stdout, stderr)
+ return b
+}
diff --git a/vendor/github.com/cli/cli/v2/internal/browser/stub.go b/vendor/github.com/cli/cli/v2/internal/browser/stub.go
new file mode 100644
index 000000000..52548affd
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/internal/browser/stub.go
@@ -0,0 +1,40 @@
+package browser
+
+type Stub struct {
+ urls []string
+}
+
+func (b *Stub) Browse(url string) error {
+ b.urls = append(b.urls, url)
+ return nil
+}
+
+func (b *Stub) BrowsedURL() string {
+ if len(b.urls) > 0 {
+ return b.urls[0]
+ }
+ return ""
+}
+
+type _testing interface {
+ Errorf(string, ...interface{})
+ Helper()
+}
+
+func (b *Stub) Verify(t _testing, url string) {
+ t.Helper()
+ if url != "" {
+ switch len(b.urls) {
+ case 0:
+ t.Errorf("expected browser to open URL %q, but it was never invoked", url)
+ case 1:
+ if url != b.urls[0] {
+ t.Errorf("expected browser to open URL %q, got %q", url, b.urls[0])
+ }
+ default:
+ t.Errorf("expected browser to open one URL, but was invoked %d times", len(b.urls))
+ }
+ } else if len(b.urls) > 0 {
+ t.Errorf("expected no browser to open, but was invoked %d times: %v", len(b.urls), b.urls)
+ }
+}
diff --git a/vendor/github.com/cli/cli/v2/internal/config/config.go b/vendor/github.com/cli/cli/v2/internal/config/config.go
new file mode 100644
index 000000000..25f3e01e9
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/internal/config/config.go
@@ -0,0 +1,604 @@
+package config
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "path/filepath"
+ "slices"
+
+ "github.com/cli/cli/v2/internal/keyring"
+ ghAuth "github.com/cli/go-gh/v2/pkg/auth"
+ ghConfig "github.com/cli/go-gh/v2/pkg/config"
+)
+
+const (
+ aliasesKey = "aliases"
+ browserKey = "browser"
+ editorKey = "editor"
+ gitProtocolKey = "git_protocol"
+ hostsKey = "hosts"
+ httpUnixSocketKey = "http_unix_socket"
+ oauthTokenKey = "oauth_token"
+ pagerKey = "pager"
+ promptKey = "prompt"
+ userKey = "user"
+ usersKey = "users"
+ versionKey = "version"
+)
+
+// This interface describes interacting with some persistent configuration for gh.
+//
+//go:generate moq -rm -out config_mock.go . Config
+type Config interface {
+ GetOrDefault(string, string) (string, error)
+ Set(string, string, string)
+ Write() error
+ Migrate(Migration) error
+
+ Aliases() *AliasConfig
+ Authentication() *AuthConfig
+ Browser(string) string
+ Editor(string) string
+ GitProtocol(string) string
+ HTTPUnixSocket(string) string
+ Pager(string) string
+ Prompt(string) string
+ Version() string
+}
+
+// Migration is the interface that config migrations must implement.
+//
+// Migrations will receive a copy of the config, and should modify that copy
+// as necessary. After migration has completed, the modified config contents
+// will be used.
+//
+// The calling code is expected to verify that the current version of the config
+// matches the PreVersion of the migration before calling Do, and will set the
+// config version to the PostVersion after the migration has completed successfully.
+//
+//go:generate moq -rm -out migration_mock.go . Migration
+type Migration interface {
+ // PreVersion is the required config version for this to be applied
+ PreVersion() string
+ // PostVersion is the config version that must be applied after migration
+ PostVersion() string
+ // Do is expected to apply any necessary changes to the config in place
+ Do(*ghConfig.Config) error
+}
+
+func NewConfig() (Config, error) {
+ c, err := ghConfig.Read(fallbackConfig())
+ if err != nil {
+ return nil, err
+ }
+ return &cfg{c}, nil
+}
+
+// Implements Config interface
+type cfg struct {
+ cfg *ghConfig.Config
+}
+
+func (c *cfg) Get(hostname, key string) (string, error) {
+ if hostname != "" {
+ val, err := c.cfg.Get([]string{hostsKey, hostname, key})
+ if err == nil {
+ return val, err
+ }
+ }
+
+ return c.cfg.Get([]string{key})
+}
+
+func (c *cfg) GetOrDefault(hostname, key string) (string, error) {
+ val, err := c.Get(hostname, key)
+ if err == nil {
+ return val, err
+ }
+
+ if val, ok := defaultFor(key); ok {
+ return val, nil
+ }
+
+ return val, err
+}
+
+func (c *cfg) Set(hostname, key, value string) {
+ if hostname == "" {
+ c.cfg.Set([]string{key}, value)
+ return
+ }
+
+ c.cfg.Set([]string{hostsKey, hostname, key}, value)
+
+ if user, _ := c.cfg.Get([]string{hostsKey, hostname, userKey}); user != "" {
+ c.cfg.Set([]string{hostsKey, hostname, usersKey, user, key}, value)
+ }
+}
+
+func (c *cfg) Write() error {
+ return ghConfig.Write(c.cfg)
+}
+
+func (c *cfg) Aliases() *AliasConfig {
+ return &AliasConfig{cfg: c.cfg}
+}
+
+func (c *cfg) Authentication() *AuthConfig {
+ return &AuthConfig{cfg: c.cfg}
+}
+
+func (c *cfg) Browser(hostname string) string {
+ val, _ := c.GetOrDefault(hostname, browserKey)
+ return val
+}
+
+func (c *cfg) Editor(hostname string) string {
+ val, _ := c.GetOrDefault(hostname, editorKey)
+ return val
+}
+
+func (c *cfg) GitProtocol(hostname string) string {
+ val, _ := c.GetOrDefault(hostname, gitProtocolKey)
+ return val
+}
+
+func (c *cfg) HTTPUnixSocket(hostname string) string {
+ val, _ := c.GetOrDefault(hostname, httpUnixSocketKey)
+ return val
+}
+
+func (c *cfg) Pager(hostname string) string {
+ val, _ := c.GetOrDefault(hostname, pagerKey)
+ return val
+}
+
+func (c *cfg) Prompt(hostname string) string {
+ val, _ := c.GetOrDefault(hostname, promptKey)
+ return val
+}
+
+func (c *cfg) Version() string {
+ val, _ := c.GetOrDefault("", versionKey)
+ return val
+}
+
+func (c *cfg) Migrate(m Migration) error {
+ version := c.Version()
+
+ // If migration has already occurred then do not attempt to migrate again.
+ if m.PostVersion() == version {
+ return nil
+ }
+
+ // If migration is incompatible with current version then return an error.
+ if m.PreVersion() != version {
+ return fmt.Errorf("failed to migrate as %q pre migration version did not match config version %q", m.PreVersion(), version)
+ }
+
+ if err := m.Do(c.cfg); err != nil {
+ return fmt.Errorf("failed to migrate config: %s", err)
+ }
+
+ c.Set("", versionKey, m.PostVersion())
+
+ // Then write out our migrated config.
+ if err := c.Write(); err != nil {
+ return fmt.Errorf("failed to write config after migration: %s", err)
+ }
+
+ return nil
+}
+
+func defaultFor(key string) (string, bool) {
+ for _, co := range ConfigOptions() {
+ if co.Key == key {
+ return co.DefaultValue, true
+ }
+ }
+ return "", false
+}
+
+// AuthConfig is used for interacting with some persistent configuration for gh,
+// with knowledge on how to access encrypted storage when neccesarry.
+// Behavior is scoped to authentication specific tasks.
+type AuthConfig struct {
+ cfg *ghConfig.Config
+ defaultHostOverride func() (string, string)
+ hostsOverride func() []string
+ tokenOverride func(string) (string, string)
+}
+
+// ActiveToken will retrieve the active auth token for the given hostname,
+// searching environment variables, plain text config, and
+// lastly encrypted storage.
+func (c *AuthConfig) ActiveToken(hostname string) (string, string) {
+ if c.tokenOverride != nil {
+ return c.tokenOverride(hostname)
+ }
+ token, source := ghAuth.TokenFromEnvOrConfig(hostname)
+ if token == "" {
+ var err error
+ token, err = c.TokenFromKeyring(hostname)
+ if err == nil {
+ source = "keyring"
+ }
+ }
+ return token, source
+}
+
+// HasEnvToken returns true when a token has been specified in an
+// environment variable, else returns false.
+func (c *AuthConfig) HasEnvToken() bool {
+ // This will check if there are any environment variable
+ // authentication tokens set for enterprise hosts.
+ // Any non-github.com hostname is fine here
+ hostname := "example.com"
+ if c.tokenOverride != nil {
+ token, _ := c.tokenOverride(hostname)
+ if token != "" {
+ return true
+ }
+ }
+ // TODO: This is _extremely_ knowledgeable about the implementation of TokenFromEnvOrConfig
+ // It has to use a hostname that is not going to be found in the hosts so that it
+ // can guarantee that tokens will only be returned from a set env var.
+ // Discussed here, but maybe worth revisiting: https://github.com/cli/cli/pull/7169#discussion_r1136979033
+ token, _ := ghAuth.TokenFromEnvOrConfig(hostname)
+ return token != ""
+}
+
+// SetActiveToken will override any token resolution and return the given
+// token and source for all calls to ActiveToken. Use for testing purposes only.
+func (c *AuthConfig) SetActiveToken(token, source string) {
+ c.tokenOverride = func(_ string) (string, string) {
+ return token, source
+ }
+}
+
+// TokenFromKeyring will retrieve the auth token for the given hostname,
+// only searching in encrypted storage.
+func (c *AuthConfig) TokenFromKeyring(hostname string) (string, error) {
+ return keyring.Get(keyringServiceName(hostname), "")
+}
+
+// TokenFromKeyringForUser will retrieve the auth token for the given hostname
+// and username, only searching in encrypted storage.
+//
+// An empty username will return an error because the potential to return
+// the currently active token under surprising cases is just too high to risk
+// compared to the utility of having the function being smart.
+func (c *AuthConfig) TokenFromKeyringForUser(hostname, username string) (string, error) {
+ if username == "" {
+ return "", errors.New("username cannot be blank")
+ }
+
+ return keyring.Get(keyringServiceName(hostname), username)
+}
+
+// ActiveUser will retrieve the username for the active user at the given hostname.
+// This will not be accurate if the oauth token is set from an environment variable.
+func (c *AuthConfig) ActiveUser(hostname string) (string, error) {
+ return c.cfg.Get([]string{hostsKey, hostname, userKey})
+}
+
+func (c *AuthConfig) Hosts() []string {
+ if c.hostsOverride != nil {
+ return c.hostsOverride()
+ }
+ return ghAuth.KnownHosts()
+}
+
+// SetHosts will override any hosts resolution and return the given
+// hosts for all calls to Hosts. Use for testing purposes only.
+func (c *AuthConfig) SetHosts(hosts []string) {
+ c.hostsOverride = func() []string {
+ return hosts
+ }
+}
+
+func (c *AuthConfig) DefaultHost() (string, string) {
+ if c.defaultHostOverride != nil {
+ return c.defaultHostOverride()
+ }
+ return ghAuth.DefaultHost()
+}
+
+// SetDefaultHost will override any host resolution and return the given
+// host and source for all calls to DefaultHost. Use for testing purposes only.
+func (c *AuthConfig) SetDefaultHost(host, source string) {
+ c.defaultHostOverride = func() (string, string) {
+ return host, source
+ }
+}
+
+// Login will set user, git protocol, and auth token for the given hostname.
+// If the encrypt option is specified it will first try to store the auth token
+// in encrypted storage and will fall back to the plain text config file.
+func (c *AuthConfig) Login(hostname, username, token, gitProtocol string, secureStorage bool) (bool, error) {
+ // In this section we set up the users config
+ var setErr error
+ if secureStorage {
+ // Try to set the token for this user in the encrypted storage for later switching
+ setErr = keyring.Set(keyringServiceName(hostname), username, token)
+ if setErr == nil {
+ // Clean up the previous oauth_token from the config file, if there were one
+ _ = c.cfg.Remove([]string{hostsKey, hostname, usersKey, username, oauthTokenKey})
+ }
+ }
+ insecureStorageUsed := false
+ if !secureStorage || setErr != nil {
+ // And set the oauth token under the user for later switching
+ c.cfg.Set([]string{hostsKey, hostname, usersKey, username, oauthTokenKey}, token)
+ insecureStorageUsed = true
+ }
+
+ if gitProtocol != "" {
+ // Set the host level git protocol
+ // Although it might be expected that this is handled by switch, git protocol
+ // is currently a host level config and not a user level config, so any change
+ // will overwrite the protocol for all users on the host.
+ c.cfg.Set([]string{hostsKey, hostname, gitProtocolKey}, gitProtocol)
+ }
+
+ // Create the username key with an empty value so it will be
+ // written even when there are no keys set under it.
+ if _, getErr := c.cfg.Get([]string{hostsKey, hostname, usersKey, username}); getErr != nil {
+ c.cfg.Set([]string{hostsKey, hostname, usersKey, username}, "")
+ }
+
+ // Then we activate the new user
+ return insecureStorageUsed, c.activateUser(hostname, username)
+}
+
+func (c *AuthConfig) SwitchUser(hostname, user string) error {
+ previouslyActiveUser, err := c.ActiveUser(hostname)
+ if err != nil {
+ return fmt.Errorf("failed to get active user: %s", err)
+ }
+
+ previouslyActiveToken, previousSource := c.ActiveToken(hostname)
+ if previousSource != "keyring" && previousSource != "oauth_token" {
+ return fmt.Errorf("currently active token for %s is from %s", hostname, previousSource)
+ }
+
+ err = c.activateUser(hostname, user)
+ if err != nil {
+ // Given that activateUser can only fail before the config is written, or when writing the config
+ // we know for sure that the config has not been written. However, we still should restore it back
+ // to its previous clean state just in case something else tries to make use of the config, or tries
+ // to write it again.
+ if previousSource == "keyring" {
+ if setErr := keyring.Set(keyringServiceName(hostname), "", previouslyActiveToken); setErr != nil {
+ err = errors.Join(err, setErr)
+ }
+ }
+
+ if previousSource == "oauth_token" {
+ c.cfg.Set([]string{hostsKey, hostname, oauthTokenKey}, previouslyActiveToken)
+ }
+ c.cfg.Set([]string{hostsKey, hostname, userKey}, previouslyActiveUser)
+
+ return err
+ }
+
+ return nil
+}
+
+// Logout will remove user, git protocol, and auth token for the given hostname.
+// It will remove the auth token from the encrypted storage if it exists there.
+func (c *AuthConfig) Logout(hostname, username string) error {
+ users := c.UsersForHost(hostname)
+
+ // If there is only one (or zero) users, then we remove the host
+ // and unset the keyring tokens.
+ if len(users) < 2 {
+ _ = c.cfg.Remove([]string{hostsKey, hostname})
+ _ = keyring.Delete(keyringServiceName(hostname), "")
+ _ = keyring.Delete(keyringServiceName(hostname), username)
+ return ghConfig.Write(c.cfg)
+ }
+
+ // Otherwise, we remove the user from this host
+ _ = c.cfg.Remove([]string{hostsKey, hostname, usersKey, username})
+
+ // This error is ignorable because we already know there is an active user for the host
+ activeUser, _ := c.ActiveUser(hostname)
+
+ // If the user we're removing isn't active, then we just write the config
+ if activeUser != username {
+ return ghConfig.Write(c.cfg)
+ }
+
+ // Otherwise we get the first user in the slice that isn't the user we're removing
+ switchUserIdx := slices.IndexFunc(users, func(n string) bool {
+ return n != username
+ })
+
+ // And activate them
+ return c.activateUser(hostname, users[switchUserIdx])
+}
+
+func (c *AuthConfig) activateUser(hostname, user string) error {
+ // We first need to idempotently clear out any set tokens for the host
+ _ = keyring.Delete(keyringServiceName(hostname), "")
+ _ = c.cfg.Remove([]string{hostsKey, hostname, oauthTokenKey})
+
+ // Then we'll move the keyring token or insecure token as necessary, only one of the
+ // following branches should be true.
+
+ // If there is a token in the secure keyring for the user, move it to the active slot
+ var tokenSwitched bool
+ if token, err := keyring.Get(keyringServiceName(hostname), user); err == nil {
+ if err = keyring.Set(keyringServiceName(hostname), "", token); err != nil {
+ return fmt.Errorf("failed to move active token in keyring: %v", err)
+ }
+ tokenSwitched = true
+ }
+
+ // If there is a token in the insecure config for the user, move it to the active field
+ if token, err := c.cfg.Get([]string{hostsKey, hostname, usersKey, user, oauthTokenKey}); err == nil {
+ c.cfg.Set([]string{hostsKey, hostname, oauthTokenKey}, token)
+ tokenSwitched = true
+ }
+
+ if !tokenSwitched {
+ return fmt.Errorf("no token found for %s", user)
+ }
+
+ // Then we'll update the active user for the host
+ c.cfg.Set([]string{hostsKey, hostname, userKey}, user)
+
+ return ghConfig.Write(c.cfg)
+}
+
+func (c *AuthConfig) UsersForHost(hostname string) []string {
+ users, err := c.cfg.Keys([]string{hostsKey, hostname, usersKey})
+ if err != nil {
+ return nil
+ }
+
+ return users
+}
+
+func (c *AuthConfig) TokenForUser(hostname, user string) (string, string, error) {
+ if token, err := keyring.Get(keyringServiceName(hostname), user); err == nil {
+ return token, "keyring", nil
+ }
+
+ if token, err := c.cfg.Get([]string{hostsKey, hostname, usersKey, user, oauthTokenKey}); err == nil {
+ return token, "oauth_token", nil
+ }
+
+ return "", "default", fmt.Errorf("no token found for '%s'", user)
+}
+
+func keyringServiceName(hostname string) string {
+ return "gh:" + hostname
+}
+
+type AliasConfig struct {
+ cfg *ghConfig.Config
+}
+
+func (a *AliasConfig) Get(alias string) (string, error) {
+ return a.cfg.Get([]string{aliasesKey, alias})
+}
+
+func (a *AliasConfig) Add(alias, expansion string) {
+ a.cfg.Set([]string{aliasesKey, alias}, expansion)
+}
+
+func (a *AliasConfig) Delete(alias string) error {
+ return a.cfg.Remove([]string{aliasesKey, alias})
+}
+
+func (a *AliasConfig) All() map[string]string {
+ out := map[string]string{}
+ keys, err := a.cfg.Keys([]string{aliasesKey})
+ if err != nil {
+ return out
+ }
+ for _, key := range keys {
+ val, _ := a.cfg.Get([]string{aliasesKey, key})
+ out[key] = val
+ }
+ return out
+}
+
+func fallbackConfig() *ghConfig.Config {
+ return ghConfig.ReadFromString(defaultConfigStr)
+}
+
+// The schema version in here should match the PostVersion of whatever the
+// last migration we decided to run is. Therefore, if we run a new migration,
+// this should be bumped.
+const defaultConfigStr = `
+# The default config file, auto-generated by gh. Run 'gh environment' to learn more about
+# environment variables respected by gh and their precedence.
+
+# The current version of the config schema
+version: 1
+# What protocol to use when performing git operations. Supported values: ssh, https
+git_protocol: https
+# What editor gh should run when creating issues, pull requests, etc. If blank, will refer to environment.
+editor:
+# When to interactively prompt. This is a global config that cannot be overridden by hostname. Supported values: enabled, disabled
+prompt: enabled
+# A pager program to send command output to, e.g. "less". If blank, will refer to environment. Set the value to "cat" to disable the pager.
+pager:
+# Aliases allow you to create nicknames for gh commands
+aliases:
+ co: pr checkout
+# The path to a unix socket through which send HTTP connections. If blank, HTTP traffic will be handled by net/http.DefaultTransport.
+http_unix_socket:
+# What web browser gh should use when opening URLs. If blank, will refer to environment.
+browser:
+`
+
+type ConfigOption struct {
+ Key string
+ Description string
+ DefaultValue string
+ AllowedValues []string
+}
+
+func ConfigOptions() []ConfigOption {
+ return []ConfigOption{
+ {
+ Key: gitProtocolKey,
+ Description: "the protocol to use for git clone and push operations",
+ DefaultValue: "https",
+ AllowedValues: []string{"https", "ssh"},
+ },
+ {
+ Key: editorKey,
+ Description: "the text editor program to use for authoring text",
+ DefaultValue: "",
+ },
+ {
+ Key: promptKey,
+ Description: "toggle interactive prompting in the terminal",
+ DefaultValue: "enabled",
+ AllowedValues: []string{"enabled", "disabled"},
+ },
+ {
+ Key: pagerKey,
+ Description: "the terminal pager program to send standard output to",
+ DefaultValue: "",
+ },
+ {
+ Key: httpUnixSocketKey,
+ Description: "the path to a Unix socket through which to make an HTTP connection",
+ DefaultValue: "",
+ },
+ {
+ Key: browserKey,
+ Description: "the web browser to use for opening URLs",
+ DefaultValue: "",
+ },
+ }
+}
+
+func HomeDirPath(subdir string) (string, error) {
+ homeDir, err := os.UserHomeDir()
+ if err != nil {
+ return "", err
+ }
+
+ newPath := filepath.Join(homeDir, subdir)
+ return newPath, nil
+}
+
+func StateDir() string {
+ return ghConfig.StateDir()
+}
+
+func DataDir() string {
+ return ghConfig.DataDir()
+}
+
+func ConfigDir() string {
+ return ghConfig.ConfigDir()
+}
diff --git a/vendor/github.com/cli/cli/v2/internal/config/config_mock.go b/vendor/github.com/cli/cli/v2/internal/config/config_mock.go
new file mode 100644
index 000000000..586078a2c
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/internal/config/config_mock.go
@@ -0,0 +1,592 @@
+// Code generated by moq; DO NOT EDIT.
+// github.com/matryer/moq
+
+package config
+
+import (
+ "sync"
+)
+
+// Ensure, that ConfigMock does implement Config.
+// If this is not the case, regenerate this file with moq.
+var _ Config = &ConfigMock{}
+
+// ConfigMock is a mock implementation of Config.
+//
+// func TestSomethingThatUsesConfig(t *testing.T) {
+//
+// // make and configure a mocked Config
+// mockedConfig := &ConfigMock{
+// AliasesFunc: func() *AliasConfig {
+// panic("mock out the Aliases method")
+// },
+// AuthenticationFunc: func() *AuthConfig {
+// panic("mock out the Authentication method")
+// },
+// BrowserFunc: func(s string) string {
+// panic("mock out the Browser method")
+// },
+// EditorFunc: func(s string) string {
+// panic("mock out the Editor method")
+// },
+// GetOrDefaultFunc: func(s1 string, s2 string) (string, error) {
+// panic("mock out the GetOrDefault method")
+// },
+// GitProtocolFunc: func(s string) string {
+// panic("mock out the GitProtocol method")
+// },
+// HTTPUnixSocketFunc: func(s string) string {
+// panic("mock out the HTTPUnixSocket method")
+// },
+// MigrateFunc: func(migration Migration) error {
+// panic("mock out the Migrate method")
+// },
+// PagerFunc: func(s string) string {
+// panic("mock out the Pager method")
+// },
+// PromptFunc: func(s string) string {
+// panic("mock out the Prompt method")
+// },
+// SetFunc: func(s1 string, s2 string, s3 string) {
+// panic("mock out the Set method")
+// },
+// VersionFunc: func() string {
+// panic("mock out the Version method")
+// },
+// WriteFunc: func() error {
+// panic("mock out the Write method")
+// },
+// }
+//
+// // use mockedConfig in code that requires Config
+// // and then make assertions.
+//
+// }
+type ConfigMock struct {
+ // AliasesFunc mocks the Aliases method.
+ AliasesFunc func() *AliasConfig
+
+ // AuthenticationFunc mocks the Authentication method.
+ AuthenticationFunc func() *AuthConfig
+
+ // BrowserFunc mocks the Browser method.
+ BrowserFunc func(s string) string
+
+ // EditorFunc mocks the Editor method.
+ EditorFunc func(s string) string
+
+ // GetOrDefaultFunc mocks the GetOrDefault method.
+ GetOrDefaultFunc func(s1 string, s2 string) (string, error)
+
+ // GitProtocolFunc mocks the GitProtocol method.
+ GitProtocolFunc func(s string) string
+
+ // HTTPUnixSocketFunc mocks the HTTPUnixSocket method.
+ HTTPUnixSocketFunc func(s string) string
+
+ // MigrateFunc mocks the Migrate method.
+ MigrateFunc func(migration Migration) error
+
+ // PagerFunc mocks the Pager method.
+ PagerFunc func(s string) string
+
+ // PromptFunc mocks the Prompt method.
+ PromptFunc func(s string) string
+
+ // SetFunc mocks the Set method.
+ SetFunc func(s1 string, s2 string, s3 string)
+
+ // VersionFunc mocks the Version method.
+ VersionFunc func() string
+
+ // WriteFunc mocks the Write method.
+ WriteFunc func() error
+
+ // calls tracks calls to the methods.
+ calls struct {
+ // Aliases holds details about calls to the Aliases method.
+ Aliases []struct {
+ }
+ // Authentication holds details about calls to the Authentication method.
+ Authentication []struct {
+ }
+ // Browser holds details about calls to the Browser method.
+ Browser []struct {
+ // S is the s argument value.
+ S string
+ }
+ // Editor holds details about calls to the Editor method.
+ Editor []struct {
+ // S is the s argument value.
+ S string
+ }
+ // GetOrDefault holds details about calls to the GetOrDefault method.
+ GetOrDefault []struct {
+ // S1 is the s1 argument value.
+ S1 string
+ // S2 is the s2 argument value.
+ S2 string
+ }
+ // GitProtocol holds details about calls to the GitProtocol method.
+ GitProtocol []struct {
+ // S is the s argument value.
+ S string
+ }
+ // HTTPUnixSocket holds details about calls to the HTTPUnixSocket method.
+ HTTPUnixSocket []struct {
+ // S is the s argument value.
+ S string
+ }
+ // Migrate holds details about calls to the Migrate method.
+ Migrate []struct {
+ // Migration is the migration argument value.
+ Migration Migration
+ }
+ // Pager holds details about calls to the Pager method.
+ Pager []struct {
+ // S is the s argument value.
+ S string
+ }
+ // Prompt holds details about calls to the Prompt method.
+ Prompt []struct {
+ // S is the s argument value.
+ S string
+ }
+ // Set holds details about calls to the Set method.
+ Set []struct {
+ // S1 is the s1 argument value.
+ S1 string
+ // S2 is the s2 argument value.
+ S2 string
+ // S3 is the s3 argument value.
+ S3 string
+ }
+ // Version holds details about calls to the Version method.
+ Version []struct {
+ }
+ // Write holds details about calls to the Write method.
+ Write []struct {
+ }
+ }
+ lockAliases sync.RWMutex
+ lockAuthentication sync.RWMutex
+ lockBrowser sync.RWMutex
+ lockEditor sync.RWMutex
+ lockGetOrDefault sync.RWMutex
+ lockGitProtocol sync.RWMutex
+ lockHTTPUnixSocket sync.RWMutex
+ lockMigrate sync.RWMutex
+ lockPager sync.RWMutex
+ lockPrompt sync.RWMutex
+ lockSet sync.RWMutex
+ lockVersion sync.RWMutex
+ lockWrite sync.RWMutex
+}
+
+// Aliases calls AliasesFunc.
+func (mock *ConfigMock) Aliases() *AliasConfig {
+ if mock.AliasesFunc == nil {
+ panic("ConfigMock.AliasesFunc: method is nil but Config.Aliases was just called")
+ }
+ callInfo := struct {
+ }{}
+ mock.lockAliases.Lock()
+ mock.calls.Aliases = append(mock.calls.Aliases, callInfo)
+ mock.lockAliases.Unlock()
+ return mock.AliasesFunc()
+}
+
+// AliasesCalls gets all the calls that were made to Aliases.
+// Check the length with:
+//
+// len(mockedConfig.AliasesCalls())
+func (mock *ConfigMock) AliasesCalls() []struct {
+} {
+ var calls []struct {
+ }
+ mock.lockAliases.RLock()
+ calls = mock.calls.Aliases
+ mock.lockAliases.RUnlock()
+ return calls
+}
+
+// Authentication calls AuthenticationFunc.
+func (mock *ConfigMock) Authentication() *AuthConfig {
+ if mock.AuthenticationFunc == nil {
+ panic("ConfigMock.AuthenticationFunc: method is nil but Config.Authentication was just called")
+ }
+ callInfo := struct {
+ }{}
+ mock.lockAuthentication.Lock()
+ mock.calls.Authentication = append(mock.calls.Authentication, callInfo)
+ mock.lockAuthentication.Unlock()
+ return mock.AuthenticationFunc()
+}
+
+// AuthenticationCalls gets all the calls that were made to Authentication.
+// Check the length with:
+//
+// len(mockedConfig.AuthenticationCalls())
+func (mock *ConfigMock) AuthenticationCalls() []struct {
+} {
+ var calls []struct {
+ }
+ mock.lockAuthentication.RLock()
+ calls = mock.calls.Authentication
+ mock.lockAuthentication.RUnlock()
+ return calls
+}
+
+// Browser calls BrowserFunc.
+func (mock *ConfigMock) Browser(s string) string {
+ if mock.BrowserFunc == nil {
+ panic("ConfigMock.BrowserFunc: method is nil but Config.Browser was just called")
+ }
+ callInfo := struct {
+ S string
+ }{
+ S: s,
+ }
+ mock.lockBrowser.Lock()
+ mock.calls.Browser = append(mock.calls.Browser, callInfo)
+ mock.lockBrowser.Unlock()
+ return mock.BrowserFunc(s)
+}
+
+// BrowserCalls gets all the calls that were made to Browser.
+// Check the length with:
+//
+// len(mockedConfig.BrowserCalls())
+func (mock *ConfigMock) BrowserCalls() []struct {
+ S string
+} {
+ var calls []struct {
+ S string
+ }
+ mock.lockBrowser.RLock()
+ calls = mock.calls.Browser
+ mock.lockBrowser.RUnlock()
+ return calls
+}
+
+// Editor calls EditorFunc.
+func (mock *ConfigMock) Editor(s string) string {
+ if mock.EditorFunc == nil {
+ panic("ConfigMock.EditorFunc: method is nil but Config.Editor was just called")
+ }
+ callInfo := struct {
+ S string
+ }{
+ S: s,
+ }
+ mock.lockEditor.Lock()
+ mock.calls.Editor = append(mock.calls.Editor, callInfo)
+ mock.lockEditor.Unlock()
+ return mock.EditorFunc(s)
+}
+
+// EditorCalls gets all the calls that were made to Editor.
+// Check the length with:
+//
+// len(mockedConfig.EditorCalls())
+func (mock *ConfigMock) EditorCalls() []struct {
+ S string
+} {
+ var calls []struct {
+ S string
+ }
+ mock.lockEditor.RLock()
+ calls = mock.calls.Editor
+ mock.lockEditor.RUnlock()
+ return calls
+}
+
+// GetOrDefault calls GetOrDefaultFunc.
+func (mock *ConfigMock) GetOrDefault(s1 string, s2 string) (string, error) {
+ if mock.GetOrDefaultFunc == nil {
+ panic("ConfigMock.GetOrDefaultFunc: method is nil but Config.GetOrDefault was just called")
+ }
+ callInfo := struct {
+ S1 string
+ S2 string
+ }{
+ S1: s1,
+ S2: s2,
+ }
+ mock.lockGetOrDefault.Lock()
+ mock.calls.GetOrDefault = append(mock.calls.GetOrDefault, callInfo)
+ mock.lockGetOrDefault.Unlock()
+ return mock.GetOrDefaultFunc(s1, s2)
+}
+
+// GetOrDefaultCalls gets all the calls that were made to GetOrDefault.
+// Check the length with:
+//
+// len(mockedConfig.GetOrDefaultCalls())
+func (mock *ConfigMock) GetOrDefaultCalls() []struct {
+ S1 string
+ S2 string
+} {
+ var calls []struct {
+ S1 string
+ S2 string
+ }
+ mock.lockGetOrDefault.RLock()
+ calls = mock.calls.GetOrDefault
+ mock.lockGetOrDefault.RUnlock()
+ return calls
+}
+
+// GitProtocol calls GitProtocolFunc.
+func (mock *ConfigMock) GitProtocol(s string) string {
+ if mock.GitProtocolFunc == nil {
+ panic("ConfigMock.GitProtocolFunc: method is nil but Config.GitProtocol was just called")
+ }
+ callInfo := struct {
+ S string
+ }{
+ S: s,
+ }
+ mock.lockGitProtocol.Lock()
+ mock.calls.GitProtocol = append(mock.calls.GitProtocol, callInfo)
+ mock.lockGitProtocol.Unlock()
+ return mock.GitProtocolFunc(s)
+}
+
+// GitProtocolCalls gets all the calls that were made to GitProtocol.
+// Check the length with:
+//
+// len(mockedConfig.GitProtocolCalls())
+func (mock *ConfigMock) GitProtocolCalls() []struct {
+ S string
+} {
+ var calls []struct {
+ S string
+ }
+ mock.lockGitProtocol.RLock()
+ calls = mock.calls.GitProtocol
+ mock.lockGitProtocol.RUnlock()
+ return calls
+}
+
+// HTTPUnixSocket calls HTTPUnixSocketFunc.
+func (mock *ConfigMock) HTTPUnixSocket(s string) string {
+ if mock.HTTPUnixSocketFunc == nil {
+ panic("ConfigMock.HTTPUnixSocketFunc: method is nil but Config.HTTPUnixSocket was just called")
+ }
+ callInfo := struct {
+ S string
+ }{
+ S: s,
+ }
+ mock.lockHTTPUnixSocket.Lock()
+ mock.calls.HTTPUnixSocket = append(mock.calls.HTTPUnixSocket, callInfo)
+ mock.lockHTTPUnixSocket.Unlock()
+ return mock.HTTPUnixSocketFunc(s)
+}
+
+// HTTPUnixSocketCalls gets all the calls that were made to HTTPUnixSocket.
+// Check the length with:
+//
+// len(mockedConfig.HTTPUnixSocketCalls())
+func (mock *ConfigMock) HTTPUnixSocketCalls() []struct {
+ S string
+} {
+ var calls []struct {
+ S string
+ }
+ mock.lockHTTPUnixSocket.RLock()
+ calls = mock.calls.HTTPUnixSocket
+ mock.lockHTTPUnixSocket.RUnlock()
+ return calls
+}
+
+// Migrate calls MigrateFunc.
+func (mock *ConfigMock) Migrate(migration Migration) error {
+ if mock.MigrateFunc == nil {
+ panic("ConfigMock.MigrateFunc: method is nil but Config.Migrate was just called")
+ }
+ callInfo := struct {
+ Migration Migration
+ }{
+ Migration: migration,
+ }
+ mock.lockMigrate.Lock()
+ mock.calls.Migrate = append(mock.calls.Migrate, callInfo)
+ mock.lockMigrate.Unlock()
+ return mock.MigrateFunc(migration)
+}
+
+// MigrateCalls gets all the calls that were made to Migrate.
+// Check the length with:
+//
+// len(mockedConfig.MigrateCalls())
+func (mock *ConfigMock) MigrateCalls() []struct {
+ Migration Migration
+} {
+ var calls []struct {
+ Migration Migration
+ }
+ mock.lockMigrate.RLock()
+ calls = mock.calls.Migrate
+ mock.lockMigrate.RUnlock()
+ return calls
+}
+
+// Pager calls PagerFunc.
+func (mock *ConfigMock) Pager(s string) string {
+ if mock.PagerFunc == nil {
+ panic("ConfigMock.PagerFunc: method is nil but Config.Pager was just called")
+ }
+ callInfo := struct {
+ S string
+ }{
+ S: s,
+ }
+ mock.lockPager.Lock()
+ mock.calls.Pager = append(mock.calls.Pager, callInfo)
+ mock.lockPager.Unlock()
+ return mock.PagerFunc(s)
+}
+
+// PagerCalls gets all the calls that were made to Pager.
+// Check the length with:
+//
+// len(mockedConfig.PagerCalls())
+func (mock *ConfigMock) PagerCalls() []struct {
+ S string
+} {
+ var calls []struct {
+ S string
+ }
+ mock.lockPager.RLock()
+ calls = mock.calls.Pager
+ mock.lockPager.RUnlock()
+ return calls
+}
+
+// Prompt calls PromptFunc.
+func (mock *ConfigMock) Prompt(s string) string {
+ if mock.PromptFunc == nil {
+ panic("ConfigMock.PromptFunc: method is nil but Config.Prompt was just called")
+ }
+ callInfo := struct {
+ S string
+ }{
+ S: s,
+ }
+ mock.lockPrompt.Lock()
+ mock.calls.Prompt = append(mock.calls.Prompt, callInfo)
+ mock.lockPrompt.Unlock()
+ return mock.PromptFunc(s)
+}
+
+// PromptCalls gets all the calls that were made to Prompt.
+// Check the length with:
+//
+// len(mockedConfig.PromptCalls())
+func (mock *ConfigMock) PromptCalls() []struct {
+ S string
+} {
+ var calls []struct {
+ S string
+ }
+ mock.lockPrompt.RLock()
+ calls = mock.calls.Prompt
+ mock.lockPrompt.RUnlock()
+ return calls
+}
+
+// Set calls SetFunc.
+func (mock *ConfigMock) Set(s1 string, s2 string, s3 string) {
+ if mock.SetFunc == nil {
+ panic("ConfigMock.SetFunc: method is nil but Config.Set was just called")
+ }
+ callInfo := struct {
+ S1 string
+ S2 string
+ S3 string
+ }{
+ S1: s1,
+ S2: s2,
+ S3: s3,
+ }
+ mock.lockSet.Lock()
+ mock.calls.Set = append(mock.calls.Set, callInfo)
+ mock.lockSet.Unlock()
+ mock.SetFunc(s1, s2, s3)
+}
+
+// SetCalls gets all the calls that were made to Set.
+// Check the length with:
+//
+// len(mockedConfig.SetCalls())
+func (mock *ConfigMock) SetCalls() []struct {
+ S1 string
+ S2 string
+ S3 string
+} {
+ var calls []struct {
+ S1 string
+ S2 string
+ S3 string
+ }
+ mock.lockSet.RLock()
+ calls = mock.calls.Set
+ mock.lockSet.RUnlock()
+ return calls
+}
+
+// Version calls VersionFunc.
+func (mock *ConfigMock) Version() string {
+ if mock.VersionFunc == nil {
+ panic("ConfigMock.VersionFunc: method is nil but Config.Version was just called")
+ }
+ callInfo := struct {
+ }{}
+ mock.lockVersion.Lock()
+ mock.calls.Version = append(mock.calls.Version, callInfo)
+ mock.lockVersion.Unlock()
+ return mock.VersionFunc()
+}
+
+// VersionCalls gets all the calls that were made to Version.
+// Check the length with:
+//
+// len(mockedConfig.VersionCalls())
+func (mock *ConfigMock) VersionCalls() []struct {
+} {
+ var calls []struct {
+ }
+ mock.lockVersion.RLock()
+ calls = mock.calls.Version
+ mock.lockVersion.RUnlock()
+ return calls
+}
+
+// Write calls WriteFunc.
+func (mock *ConfigMock) Write() error {
+ if mock.WriteFunc == nil {
+ panic("ConfigMock.WriteFunc: method is nil but Config.Write was just called")
+ }
+ callInfo := struct {
+ }{}
+ mock.lockWrite.Lock()
+ mock.calls.Write = append(mock.calls.Write, callInfo)
+ mock.lockWrite.Unlock()
+ return mock.WriteFunc()
+}
+
+// WriteCalls gets all the calls that were made to Write.
+// Check the length with:
+//
+// len(mockedConfig.WriteCalls())
+func (mock *ConfigMock) WriteCalls() []struct {
+} {
+ var calls []struct {
+ }
+ mock.lockWrite.RLock()
+ calls = mock.calls.Write
+ mock.lockWrite.RUnlock()
+ return calls
+}
diff --git a/vendor/github.com/cli/cli/v2/internal/config/migration_mock.go b/vendor/github.com/cli/cli/v2/internal/config/migration_mock.go
new file mode 100644
index 000000000..bf8133fb4
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/internal/config/migration_mock.go
@@ -0,0 +1,149 @@
+// Code generated by moq; DO NOT EDIT.
+// github.com/matryer/moq
+
+package config
+
+import (
+ ghConfig "github.com/cli/go-gh/v2/pkg/config"
+ "sync"
+)
+
+// Ensure, that MigrationMock does implement Migration.
+// If this is not the case, regenerate this file with moq.
+var _ Migration = &MigrationMock{}
+
+// MigrationMock is a mock implementation of Migration.
+//
+// func TestSomethingThatUsesMigration(t *testing.T) {
+//
+// // make and configure a mocked Migration
+// mockedMigration := &MigrationMock{
+// DoFunc: func(config *ghConfig.Config) error {
+// panic("mock out the Do method")
+// },
+// PostVersionFunc: func() string {
+// panic("mock out the PostVersion method")
+// },
+// PreVersionFunc: func() string {
+// panic("mock out the PreVersion method")
+// },
+// }
+//
+// // use mockedMigration in code that requires Migration
+// // and then make assertions.
+//
+// }
+type MigrationMock struct {
+ // DoFunc mocks the Do method.
+ DoFunc func(config *ghConfig.Config) error
+
+ // PostVersionFunc mocks the PostVersion method.
+ PostVersionFunc func() string
+
+ // PreVersionFunc mocks the PreVersion method.
+ PreVersionFunc func() string
+
+ // calls tracks calls to the methods.
+ calls struct {
+ // Do holds details about calls to the Do method.
+ Do []struct {
+ // Config is the config argument value.
+ Config *ghConfig.Config
+ }
+ // PostVersion holds details about calls to the PostVersion method.
+ PostVersion []struct {
+ }
+ // PreVersion holds details about calls to the PreVersion method.
+ PreVersion []struct {
+ }
+ }
+ lockDo sync.RWMutex
+ lockPostVersion sync.RWMutex
+ lockPreVersion sync.RWMutex
+}
+
+// Do calls DoFunc.
+func (mock *MigrationMock) Do(config *ghConfig.Config) error {
+ if mock.DoFunc == nil {
+ panic("MigrationMock.DoFunc: method is nil but Migration.Do was just called")
+ }
+ callInfo := struct {
+ Config *ghConfig.Config
+ }{
+ Config: config,
+ }
+ mock.lockDo.Lock()
+ mock.calls.Do = append(mock.calls.Do, callInfo)
+ mock.lockDo.Unlock()
+ return mock.DoFunc(config)
+}
+
+// DoCalls gets all the calls that were made to Do.
+// Check the length with:
+//
+// len(mockedMigration.DoCalls())
+func (mock *MigrationMock) DoCalls() []struct {
+ Config *ghConfig.Config
+} {
+ var calls []struct {
+ Config *ghConfig.Config
+ }
+ mock.lockDo.RLock()
+ calls = mock.calls.Do
+ mock.lockDo.RUnlock()
+ return calls
+}
+
+// PostVersion calls PostVersionFunc.
+func (mock *MigrationMock) PostVersion() string {
+ if mock.PostVersionFunc == nil {
+ panic("MigrationMock.PostVersionFunc: method is nil but Migration.PostVersion was just called")
+ }
+ callInfo := struct {
+ }{}
+ mock.lockPostVersion.Lock()
+ mock.calls.PostVersion = append(mock.calls.PostVersion, callInfo)
+ mock.lockPostVersion.Unlock()
+ return mock.PostVersionFunc()
+}
+
+// PostVersionCalls gets all the calls that were made to PostVersion.
+// Check the length with:
+//
+// len(mockedMigration.PostVersionCalls())
+func (mock *MigrationMock) PostVersionCalls() []struct {
+} {
+ var calls []struct {
+ }
+ mock.lockPostVersion.RLock()
+ calls = mock.calls.PostVersion
+ mock.lockPostVersion.RUnlock()
+ return calls
+}
+
+// PreVersion calls PreVersionFunc.
+func (mock *MigrationMock) PreVersion() string {
+ if mock.PreVersionFunc == nil {
+ panic("MigrationMock.PreVersionFunc: method is nil but Migration.PreVersion was just called")
+ }
+ callInfo := struct {
+ }{}
+ mock.lockPreVersion.Lock()
+ mock.calls.PreVersion = append(mock.calls.PreVersion, callInfo)
+ mock.lockPreVersion.Unlock()
+ return mock.PreVersionFunc()
+}
+
+// PreVersionCalls gets all the calls that were made to PreVersion.
+// Check the length with:
+//
+// len(mockedMigration.PreVersionCalls())
+func (mock *MigrationMock) PreVersionCalls() []struct {
+} {
+ var calls []struct {
+ }
+ mock.lockPreVersion.RLock()
+ calls = mock.calls.PreVersion
+ mock.lockPreVersion.RUnlock()
+ return calls
+}
diff --git a/vendor/github.com/cli/cli/v2/internal/config/stub.go b/vendor/github.com/cli/cli/v2/internal/config/stub.go
new file mode 100644
index 000000000..98c1ceaba
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/internal/config/stub.go
@@ -0,0 +1,150 @@
+package config
+
+import (
+ "io"
+ "os"
+ "path/filepath"
+ "testing"
+
+ "github.com/cli/cli/v2/internal/keyring"
+ ghConfig "github.com/cli/go-gh/v2/pkg/config"
+)
+
+func NewBlankConfig() *ConfigMock {
+ return NewFromString(defaultConfigStr)
+}
+
+func NewFromString(cfgStr string) *ConfigMock {
+ c := ghConfig.ReadFromString(cfgStr)
+ cfg := cfg{c}
+ mock := &ConfigMock{}
+ mock.GetOrDefaultFunc = func(host, key string) (string, error) {
+ return cfg.GetOrDefault(host, key)
+ }
+ mock.SetFunc = func(host, key, value string) {
+ cfg.Set(host, key, value)
+ }
+ mock.WriteFunc = func() error {
+ return cfg.Write()
+ }
+ mock.MigrateFunc = func(m Migration) error {
+ return cfg.Migrate(m)
+ }
+ mock.AliasesFunc = func() *AliasConfig {
+ return &AliasConfig{cfg: c}
+ }
+ mock.AuthenticationFunc = func() *AuthConfig {
+ return &AuthConfig{
+ cfg: c,
+ defaultHostOverride: func() (string, string) {
+ return "github.com", "default"
+ },
+ hostsOverride: func() []string {
+ keys, _ := c.Keys([]string{hostsKey})
+ return keys
+ },
+ tokenOverride: func(hostname string) (string, string) {
+ token, _ := c.Get([]string{hostsKey, hostname, oauthTokenKey})
+ return token, oauthTokenKey
+ },
+ }
+ }
+ mock.BrowserFunc = func(hostname string) string {
+ val, _ := cfg.GetOrDefault(hostname, browserKey)
+ return val
+ }
+ mock.EditorFunc = func(hostname string) string {
+ val, _ := cfg.GetOrDefault(hostname, editorKey)
+ return val
+ }
+ mock.GitProtocolFunc = func(hostname string) string {
+ val, _ := cfg.GetOrDefault(hostname, gitProtocolKey)
+ return val
+ }
+ mock.HTTPUnixSocketFunc = func(hostname string) string {
+ val, _ := cfg.GetOrDefault(hostname, httpUnixSocketKey)
+ return val
+ }
+ mock.PagerFunc = func(hostname string) string {
+ val, _ := cfg.GetOrDefault(hostname, pagerKey)
+ return val
+ }
+ mock.PromptFunc = func(hostname string) string {
+ val, _ := cfg.GetOrDefault(hostname, promptKey)
+ return val
+ }
+ mock.VersionFunc = func() string {
+ val, _ := cfg.GetOrDefault("", versionKey)
+ return val
+ }
+ return mock
+}
+
+// NewIsolatedTestConfig sets up a Mock keyring, creates a blank config
+// overwrites the ghConfig.Read function that returns a singleton config
+// in the real implementation, sets the GH_CONFIG_DIR env var so that
+// any call to Write goes to a different location on disk, and then returns
+// the blank config and a function that reads any data written to disk.
+func NewIsolatedTestConfig(t *testing.T) (Config, func(io.Writer, io.Writer)) {
+ keyring.MockInit()
+
+ c := ghConfig.ReadFromString("")
+ cfg := cfg{c}
+
+ // The real implementation of config.Read uses a sync.Once
+ // to read config files and initialise package level variables
+ // that are used from then on.
+ //
+ // This means that tests can't be isolated from each other, so
+ // we swap out the function here to return a new config each time.
+ ghConfig.Read = func(_ *ghConfig.Config) (*ghConfig.Config, error) {
+ return c, nil
+ }
+
+ // The config.Write method isn't defined in the same way as Read to allow
+ // the function to be swapped out and it does try to write to disk.
+ //
+ // We should consider whether it makes sense to change that but in the meantime
+ // we can use GH_CONFIG_DIR env var to ensure the tests remain isolated.
+ readConfigs := StubWriteConfig(t)
+
+ return &cfg, readConfigs
+}
+
+// StubWriteConfig stubs out the filesystem where config file are written.
+// It then returns a function that will read in the config files into io.Writers.
+// It automatically cleans up environment variables and written files.
+func StubWriteConfig(t *testing.T) func(io.Writer, io.Writer) {
+ t.Helper()
+ tempDir := t.TempDir()
+ t.Setenv("GH_CONFIG_DIR", tempDir)
+ return func(wc io.Writer, wh io.Writer) {
+ config, err := os.Open(filepath.Join(tempDir, "config.yml"))
+ if err != nil {
+ return
+ }
+ defer config.Close()
+ configData, err := io.ReadAll(config)
+ if err != nil {
+ return
+ }
+ _, err = wc.Write(configData)
+ if err != nil {
+ return
+ }
+
+ hosts, err := os.Open(filepath.Join(tempDir, "hosts.yml"))
+ if err != nil {
+ return
+ }
+ defer hosts.Close()
+ hostsData, err := io.ReadAll(hosts)
+ if err != nil {
+ return
+ }
+ _, err = wh.Write(hostsData)
+ if err != nil {
+ return
+ }
+ }
+}
diff --git a/vendor/github.com/cli/cli/v2/internal/ghinstance/host.go b/vendor/github.com/cli/cli/v2/internal/ghinstance/host.go
new file mode 100644
index 000000000..729d47f31
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/internal/ghinstance/host.go
@@ -0,0 +1,132 @@
+package ghinstance
+
+import (
+ "errors"
+ "fmt"
+ "strings"
+)
+
+// DefaultHostname is the domain name of the default GitHub instance.
+const defaultHostname = "github.com"
+
+// Localhost is the domain name of a local GitHub instance.
+const localhost = "github.localhost"
+
+// TenancyHost is the domain name of a tenancy GitHub instance.
+const tenancyHost = "ghe.com"
+
+// Default returns the host name of the default GitHub instance.
+func Default() string {
+ return defaultHostname
+}
+
+// IsEnterprise reports whether a non-normalized host name looks like a GHE instance.
+func IsEnterprise(h string) bool {
+ normalizedHostName := NormalizeHostname(h)
+ return normalizedHostName != defaultHostname && normalizedHostName != localhost
+}
+
+// IsTenancy reports whether a non-normalized host name looks like a tenancy instance.
+func IsTenancy(h string) bool {
+ normalizedHostName := NormalizeHostname(h)
+ return strings.HasSuffix(normalizedHostName, "."+tenancyHost)
+}
+
+// TenantName extracts the tenant name from tenancy host name and
+// reports whether it found the tenant name.
+func TenantName(h string) (string, bool) {
+ normalizedHostName := NormalizeHostname(h)
+ return cutSuffix(normalizedHostName, "."+tenancyHost)
+}
+
+func isGarage(h string) bool {
+ return strings.EqualFold(h, "garage.github.com")
+}
+
+// NormalizeHostname returns the canonical host name of a GitHub instance.
+func NormalizeHostname(h string) string {
+ hostname := strings.ToLower(h)
+ if strings.HasSuffix(hostname, "."+defaultHostname) {
+ return defaultHostname
+ }
+ if strings.HasSuffix(hostname, "."+localhost) {
+ return localhost
+ }
+ if before, found := cutSuffix(hostname, "."+tenancyHost); found {
+ idx := strings.LastIndex(before, ".")
+ return fmt.Sprintf("%s.%s", before[idx+1:], tenancyHost)
+ }
+ return hostname
+}
+
+func HostnameValidator(hostname string) error {
+ if len(strings.TrimSpace(hostname)) < 1 {
+ return errors.New("a value is required")
+ }
+ if strings.ContainsRune(hostname, '/') || strings.ContainsRune(hostname, ':') {
+ return errors.New("invalid hostname")
+ }
+ return nil
+}
+
+func GraphQLEndpoint(hostname string) string {
+ if isGarage(hostname) {
+ return fmt.Sprintf("https://%s/api/graphql", hostname)
+ }
+ if IsEnterprise(hostname) {
+ return fmt.Sprintf("https://%s/api/graphql", hostname)
+ }
+ if strings.EqualFold(hostname, localhost) {
+ return fmt.Sprintf("http://api.%s/graphql", hostname)
+ }
+ return fmt.Sprintf("https://api.%s/graphql", hostname)
+}
+
+func RESTPrefix(hostname string) string {
+ if isGarage(hostname) {
+ return fmt.Sprintf("https://%s/api/v3/", hostname)
+ }
+ if IsEnterprise(hostname) {
+ return fmt.Sprintf("https://%s/api/v3/", hostname)
+ }
+ if strings.EqualFold(hostname, localhost) {
+ return fmt.Sprintf("http://api.%s/", hostname)
+ }
+ return fmt.Sprintf("https://api.%s/", hostname)
+}
+
+func GistPrefix(hostname string) string {
+ prefix := "https://"
+ if strings.EqualFold(hostname, localhost) {
+ prefix = "http://"
+ }
+ return prefix + GistHost(hostname)
+}
+
+func GistHost(hostname string) string {
+ if isGarage(hostname) {
+ return fmt.Sprintf("%s/gist/", hostname)
+ }
+ if IsEnterprise(hostname) {
+ return fmt.Sprintf("%s/gist/", hostname)
+ }
+ if strings.EqualFold(hostname, localhost) {
+ return fmt.Sprintf("%s/gist/", hostname)
+ }
+ return fmt.Sprintf("gist.%s/", hostname)
+}
+
+func HostPrefix(hostname string) string {
+ if strings.EqualFold(hostname, localhost) {
+ return fmt.Sprintf("http://%s/", hostname)
+ }
+ return fmt.Sprintf("https://%s/", hostname)
+}
+
+// Backport strings.CutSuffix from Go 1.20.
+func cutSuffix(s, suffix string) (string, bool) {
+ if !strings.HasSuffix(s, suffix) {
+ return s, false
+ }
+ return s[:len(s)-len(suffix)], true
+}
diff --git a/vendor/github.com/cli/cli/v2/internal/ghrepo/repo.go b/vendor/github.com/cli/cli/v2/internal/ghrepo/repo.go
new file mode 100644
index 000000000..4f0328e99
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/internal/ghrepo/repo.go
@@ -0,0 +1,121 @@
+package ghrepo
+
+import (
+ "fmt"
+ "net/url"
+ "strings"
+
+ "github.com/cli/cli/v2/internal/ghinstance"
+ ghAuth "github.com/cli/go-gh/v2/pkg/auth"
+ "github.com/cli/go-gh/v2/pkg/repository"
+)
+
+// Interface describes an object that represents a GitHub repository
+type Interface interface {
+ RepoName() string
+ RepoOwner() string
+ RepoHost() string
+}
+
+// New instantiates a GitHub repository from owner and name arguments
+func New(owner, repo string) Interface {
+ return NewWithHost(owner, repo, ghinstance.Default())
+}
+
+// NewWithHost is like New with an explicit host name
+func NewWithHost(owner, repo, hostname string) Interface {
+ return &ghRepo{
+ owner: owner,
+ name: repo,
+ hostname: normalizeHostname(hostname),
+ }
+}
+
+// FullName serializes a GitHub repository into an "OWNER/REPO" string
+func FullName(r Interface) string {
+ return fmt.Sprintf("%s/%s", r.RepoOwner(), r.RepoName())
+}
+
+func defaultHost() string {
+ host, _ := ghAuth.DefaultHost()
+ return host
+}
+
+// FromFullName extracts the GitHub repository information from the following
+// formats: "OWNER/REPO", "HOST/OWNER/REPO", and a full URL.
+func FromFullName(nwo string) (Interface, error) {
+ return FromFullNameWithHost(nwo, defaultHost())
+}
+
+// FromFullNameWithHost is like FromFullName that defaults to a specific host for values that don't
+// explicitly include a hostname.
+func FromFullNameWithHost(nwo, fallbackHost string) (Interface, error) {
+ repo, err := repository.ParseWithHost(nwo, fallbackHost)
+ if err != nil {
+ return nil, err
+ }
+ return NewWithHost(repo.Owner, repo.Name, repo.Host), nil
+}
+
+// FromURL extracts the GitHub repository information from a git remote URL
+func FromURL(u *url.URL) (Interface, error) {
+ if u.Hostname() == "" {
+ return nil, fmt.Errorf("no hostname detected")
+ }
+
+ parts := strings.SplitN(strings.Trim(u.Path, "/"), "/", 3)
+ if len(parts) != 2 {
+ return nil, fmt.Errorf("invalid path: %s", u.Path)
+ }
+
+ return NewWithHost(parts[0], strings.TrimSuffix(parts[1], ".git"), u.Hostname()), nil
+}
+
+func normalizeHostname(h string) string {
+ return strings.ToLower(strings.TrimPrefix(h, "www."))
+}
+
+// IsSame compares two GitHub repositories
+func IsSame(a, b Interface) bool {
+ return strings.EqualFold(a.RepoOwner(), b.RepoOwner()) &&
+ strings.EqualFold(a.RepoName(), b.RepoName()) &&
+ normalizeHostname(a.RepoHost()) == normalizeHostname(b.RepoHost())
+}
+
+func GenerateRepoURL(repo Interface, p string, args ...interface{}) string {
+ baseURL := fmt.Sprintf("%s%s/%s", ghinstance.HostPrefix(repo.RepoHost()), repo.RepoOwner(), repo.RepoName())
+ if p != "" {
+ if path := fmt.Sprintf(p, args...); path != "" {
+ return baseURL + "/" + path
+ }
+ }
+ return baseURL
+}
+
+func FormatRemoteURL(repo Interface, protocol string) string {
+ if protocol == "ssh" {
+ if tenant, found := ghinstance.TenantName(repo.RepoHost()); found {
+ return fmt.Sprintf("%s@%s:%s/%s.git", tenant, repo.RepoHost(), repo.RepoOwner(), repo.RepoName())
+ }
+ return fmt.Sprintf("git@%s:%s/%s.git", repo.RepoHost(), repo.RepoOwner(), repo.RepoName())
+ }
+ return fmt.Sprintf("%s%s/%s.git", ghinstance.HostPrefix(repo.RepoHost()), repo.RepoOwner(), repo.RepoName())
+}
+
+type ghRepo struct {
+ owner string
+ name string
+ hostname string
+}
+
+func (r ghRepo) RepoOwner() string {
+ return r.owner
+}
+
+func (r ghRepo) RepoName() string {
+ return r.name
+}
+
+func (r ghRepo) RepoHost() string {
+ return r.hostname
+}
diff --git a/vendor/github.com/cli/cli/v2/internal/keyring/keyring.go b/vendor/github.com/cli/cli/v2/internal/keyring/keyring.go
new file mode 100644
index 000000000..f873c6436
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/internal/keyring/keyring.go
@@ -0,0 +1,82 @@
+// Package keyring is a simple wrapper that adds timeouts to the zalando/go-keyring package.
+package keyring
+
+import (
+ "errors"
+ "time"
+
+ "github.com/zalando/go-keyring"
+)
+
+var ErrNotFound = errors.New("secret not found in keyring")
+
+type TimeoutError struct {
+ message string
+}
+
+func (e *TimeoutError) Error() string {
+ return e.message
+}
+
+// Set secret in keyring for user.
+func Set(service, user, secret string) error {
+ ch := make(chan error, 1)
+ go func() {
+ defer close(ch)
+ ch <- keyring.Set(service, user, secret)
+ }()
+ select {
+ case err := <-ch:
+ return err
+ case <-time.After(3 * time.Second):
+ return &TimeoutError{"timeout while trying to set secret in keyring"}
+ }
+}
+
+// Get secret from keyring given service and user name.
+func Get(service, user string) (string, error) {
+ ch := make(chan struct {
+ val string
+ err error
+ }, 1)
+ go func() {
+ defer close(ch)
+ val, err := keyring.Get(service, user)
+ ch <- struct {
+ val string
+ err error
+ }{val, err}
+ }()
+ select {
+ case res := <-ch:
+ if errors.Is(res.err, keyring.ErrNotFound) {
+ return "", ErrNotFound
+ }
+ return res.val, res.err
+ case <-time.After(3 * time.Second):
+ return "", &TimeoutError{"timeout while trying to get secret from keyring"}
+ }
+}
+
+// Delete secret from keyring.
+func Delete(service, user string) error {
+ ch := make(chan error, 1)
+ go func() {
+ defer close(ch)
+ ch <- keyring.Delete(service, user)
+ }()
+ select {
+ case err := <-ch:
+ return err
+ case <-time.After(3 * time.Second):
+ return &TimeoutError{"timeout while trying to delete secret from keyring"}
+ }
+}
+
+func MockInit() {
+ keyring.MockInit()
+}
+
+func MockInitWithError(err error) {
+ keyring.MockInitWithError(err)
+}
diff --git a/vendor/github.com/cli/cli/v2/internal/prompter/prompter.go b/vendor/github.com/cli/cli/v2/internal/prompter/prompter.go
new file mode 100644
index 000000000..44579b189
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/internal/prompter/prompter.go
@@ -0,0 +1,125 @@
+package prompter
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/AlecAivazis/survey/v2"
+ "github.com/cli/cli/v2/internal/ghinstance"
+ "github.com/cli/cli/v2/pkg/surveyext"
+ ghPrompter "github.com/cli/go-gh/v2/pkg/prompter"
+)
+
+//go:generate moq -rm -out prompter_mock.go . Prompter
+type Prompter interface {
+ // generic prompts from go-gh
+ Select(string, string, []string) (int, error)
+ MultiSelect(prompt string, defaults []string, options []string) ([]int, error)
+ Input(string, string) (string, error)
+ Password(string) (string, error)
+ Confirm(string, bool) (bool, error)
+
+ // gh specific prompts
+ AuthToken() (string, error)
+ ConfirmDeletion(string) error
+ InputHostname() (string, error)
+ MarkdownEditor(string, string, bool) (string, error)
+}
+
+func New(editorCmd string, stdin ghPrompter.FileReader, stdout ghPrompter.FileWriter, stderr ghPrompter.FileWriter) Prompter {
+ return &surveyPrompter{
+ prompter: ghPrompter.New(stdin, stdout, stderr),
+ stdin: stdin,
+ stdout: stdout,
+ stderr: stderr,
+ editorCmd: editorCmd,
+ }
+}
+
+type surveyPrompter struct {
+ prompter *ghPrompter.Prompter
+ stdin ghPrompter.FileReader
+ stdout ghPrompter.FileWriter
+ stderr ghPrompter.FileWriter
+ editorCmd string
+}
+
+func (p *surveyPrompter) Select(prompt, defaultValue string, options []string) (int, error) {
+ return p.prompter.Select(prompt, defaultValue, options)
+}
+
+func (p *surveyPrompter) MultiSelect(prompt string, defaultValues, options []string) ([]int, error) {
+ return p.prompter.MultiSelect(prompt, defaultValues, options)
+}
+
+func (p *surveyPrompter) Input(prompt, defaultValue string) (string, error) {
+ return p.prompter.Input(prompt, defaultValue)
+}
+
+func (p *surveyPrompter) Password(prompt string) (string, error) {
+ return p.prompter.Password(prompt)
+}
+
+func (p *surveyPrompter) Confirm(prompt string, defaultValue bool) (bool, error) {
+ return p.prompter.Confirm(prompt, defaultValue)
+}
+
+func (p *surveyPrompter) AuthToken() (string, error) {
+ var result string
+ err := p.ask(&survey.Password{
+ Message: "Paste your authentication token:",
+ }, &result, survey.WithValidator(survey.Required))
+ return result, err
+}
+
+func (p *surveyPrompter) ConfirmDeletion(requiredValue string) error {
+ var result string
+ return p.ask(
+ &survey.Input{
+ Message: fmt.Sprintf("Type %s to confirm deletion:", requiredValue),
+ },
+ &result,
+ survey.WithValidator(
+ func(val interface{}) error {
+ if str := val.(string); !strings.EqualFold(str, requiredValue) {
+ return fmt.Errorf("You entered %s", str)
+ }
+ return nil
+ }))
+}
+
+func (p *surveyPrompter) InputHostname() (string, error) {
+ var result string
+ err := p.ask(
+ &survey.Input{
+ Message: "GHE hostname:",
+ }, &result, survey.WithValidator(func(v interface{}) error {
+ return ghinstance.HostnameValidator(v.(string))
+ }))
+ return result, err
+}
+
+func (p *surveyPrompter) MarkdownEditor(prompt, defaultValue string, blankAllowed bool) (string, error) {
+ var result string
+ err := p.ask(&surveyext.GhEditor{
+ BlankAllowed: blankAllowed,
+ EditorCommand: p.editorCmd,
+ Editor: &survey.Editor{
+ Message: prompt,
+ Default: defaultValue,
+ FileName: "*.md",
+ HideDefault: true,
+ AppendDefault: true,
+ },
+ }, &result)
+ return result, err
+}
+
+func (p *surveyPrompter) ask(q survey.Prompt, response interface{}, opts ...survey.AskOpt) error {
+ opts = append(opts, survey.WithStdio(p.stdin, p.stdout, p.stderr))
+ err := survey.AskOne(q, response, opts...)
+ if err == nil {
+ return nil
+ }
+ return fmt.Errorf("could not prompt: %w", err)
+}
diff --git a/vendor/github.com/cli/cli/v2/internal/prompter/prompter_mock.go b/vendor/github.com/cli/cli/v2/internal/prompter/prompter_mock.go
new file mode 100644
index 000000000..b817a491f
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/internal/prompter/prompter_mock.go
@@ -0,0 +1,460 @@
+// Code generated by moq; DO NOT EDIT.
+// github.com/matryer/moq
+
+package prompter
+
+import (
+ "sync"
+)
+
+// Ensure, that PrompterMock does implement Prompter.
+// If this is not the case, regenerate this file with moq.
+var _ Prompter = &PrompterMock{}
+
+// PrompterMock is a mock implementation of Prompter.
+//
+// func TestSomethingThatUsesPrompter(t *testing.T) {
+//
+// // make and configure a mocked Prompter
+// mockedPrompter := &PrompterMock{
+// AuthTokenFunc: func() (string, error) {
+// panic("mock out the AuthToken method")
+// },
+// ConfirmFunc: func(s string, b bool) (bool, error) {
+// panic("mock out the Confirm method")
+// },
+// ConfirmDeletionFunc: func(s string) error {
+// panic("mock out the ConfirmDeletion method")
+// },
+// InputFunc: func(s1 string, s2 string) (string, error) {
+// panic("mock out the Input method")
+// },
+// InputHostnameFunc: func() (string, error) {
+// panic("mock out the InputHostname method")
+// },
+// MarkdownEditorFunc: func(s1 string, s2 string, b bool) (string, error) {
+// panic("mock out the MarkdownEditor method")
+// },
+// MultiSelectFunc: func(prompt string, defaults []string, options []string) ([]int, error) {
+// panic("mock out the MultiSelect method")
+// },
+// PasswordFunc: func(s string) (string, error) {
+// panic("mock out the Password method")
+// },
+// SelectFunc: func(s1 string, s2 string, strings []string) (int, error) {
+// panic("mock out the Select method")
+// },
+// }
+//
+// // use mockedPrompter in code that requires Prompter
+// // and then make assertions.
+//
+// }
+type PrompterMock struct {
+ // AuthTokenFunc mocks the AuthToken method.
+ AuthTokenFunc func() (string, error)
+
+ // ConfirmFunc mocks the Confirm method.
+ ConfirmFunc func(s string, b bool) (bool, error)
+
+ // ConfirmDeletionFunc mocks the ConfirmDeletion method.
+ ConfirmDeletionFunc func(s string) error
+
+ // InputFunc mocks the Input method.
+ InputFunc func(s1 string, s2 string) (string, error)
+
+ // InputHostnameFunc mocks the InputHostname method.
+ InputHostnameFunc func() (string, error)
+
+ // MarkdownEditorFunc mocks the MarkdownEditor method.
+ MarkdownEditorFunc func(s1 string, s2 string, b bool) (string, error)
+
+ // MultiSelectFunc mocks the MultiSelect method.
+ MultiSelectFunc func(prompt string, defaults []string, options []string) ([]int, error)
+
+ // PasswordFunc mocks the Password method.
+ PasswordFunc func(s string) (string, error)
+
+ // SelectFunc mocks the Select method.
+ SelectFunc func(s1 string, s2 string, strings []string) (int, error)
+
+ // calls tracks calls to the methods.
+ calls struct {
+ // AuthToken holds details about calls to the AuthToken method.
+ AuthToken []struct {
+ }
+ // Confirm holds details about calls to the Confirm method.
+ Confirm []struct {
+ // S is the s argument value.
+ S string
+ // B is the b argument value.
+ B bool
+ }
+ // ConfirmDeletion holds details about calls to the ConfirmDeletion method.
+ ConfirmDeletion []struct {
+ // S is the s argument value.
+ S string
+ }
+ // Input holds details about calls to the Input method.
+ Input []struct {
+ // S1 is the s1 argument value.
+ S1 string
+ // S2 is the s2 argument value.
+ S2 string
+ }
+ // InputHostname holds details about calls to the InputHostname method.
+ InputHostname []struct {
+ }
+ // MarkdownEditor holds details about calls to the MarkdownEditor method.
+ MarkdownEditor []struct {
+ // S1 is the s1 argument value.
+ S1 string
+ // S2 is the s2 argument value.
+ S2 string
+ // B is the b argument value.
+ B bool
+ }
+ // MultiSelect holds details about calls to the MultiSelect method.
+ MultiSelect []struct {
+ // Prompt is the prompt argument value.
+ Prompt string
+ // Defaults is the defaults argument value.
+ Defaults []string
+ // Options is the options argument value.
+ Options []string
+ }
+ // Password holds details about calls to the Password method.
+ Password []struct {
+ // S is the s argument value.
+ S string
+ }
+ // Select holds details about calls to the Select method.
+ Select []struct {
+ // S1 is the s1 argument value.
+ S1 string
+ // S2 is the s2 argument value.
+ S2 string
+ // Strings is the strings argument value.
+ Strings []string
+ }
+ }
+ lockAuthToken sync.RWMutex
+ lockConfirm sync.RWMutex
+ lockConfirmDeletion sync.RWMutex
+ lockInput sync.RWMutex
+ lockInputHostname sync.RWMutex
+ lockMarkdownEditor sync.RWMutex
+ lockMultiSelect sync.RWMutex
+ lockPassword sync.RWMutex
+ lockSelect sync.RWMutex
+}
+
+// AuthToken calls AuthTokenFunc.
+func (mock *PrompterMock) AuthToken() (string, error) {
+ if mock.AuthTokenFunc == nil {
+ panic("PrompterMock.AuthTokenFunc: method is nil but Prompter.AuthToken was just called")
+ }
+ callInfo := struct {
+ }{}
+ mock.lockAuthToken.Lock()
+ mock.calls.AuthToken = append(mock.calls.AuthToken, callInfo)
+ mock.lockAuthToken.Unlock()
+ return mock.AuthTokenFunc()
+}
+
+// AuthTokenCalls gets all the calls that were made to AuthToken.
+// Check the length with:
+//
+// len(mockedPrompter.AuthTokenCalls())
+func (mock *PrompterMock) AuthTokenCalls() []struct {
+} {
+ var calls []struct {
+ }
+ mock.lockAuthToken.RLock()
+ calls = mock.calls.AuthToken
+ mock.lockAuthToken.RUnlock()
+ return calls
+}
+
+// Confirm calls ConfirmFunc.
+func (mock *PrompterMock) Confirm(s string, b bool) (bool, error) {
+ if mock.ConfirmFunc == nil {
+ panic("PrompterMock.ConfirmFunc: method is nil but Prompter.Confirm was just called")
+ }
+ callInfo := struct {
+ S string
+ B bool
+ }{
+ S: s,
+ B: b,
+ }
+ mock.lockConfirm.Lock()
+ mock.calls.Confirm = append(mock.calls.Confirm, callInfo)
+ mock.lockConfirm.Unlock()
+ return mock.ConfirmFunc(s, b)
+}
+
+// ConfirmCalls gets all the calls that were made to Confirm.
+// Check the length with:
+//
+// len(mockedPrompter.ConfirmCalls())
+func (mock *PrompterMock) ConfirmCalls() []struct {
+ S string
+ B bool
+} {
+ var calls []struct {
+ S string
+ B bool
+ }
+ mock.lockConfirm.RLock()
+ calls = mock.calls.Confirm
+ mock.lockConfirm.RUnlock()
+ return calls
+}
+
+// ConfirmDeletion calls ConfirmDeletionFunc.
+func (mock *PrompterMock) ConfirmDeletion(s string) error {
+ if mock.ConfirmDeletionFunc == nil {
+ panic("PrompterMock.ConfirmDeletionFunc: method is nil but Prompter.ConfirmDeletion was just called")
+ }
+ callInfo := struct {
+ S string
+ }{
+ S: s,
+ }
+ mock.lockConfirmDeletion.Lock()
+ mock.calls.ConfirmDeletion = append(mock.calls.ConfirmDeletion, callInfo)
+ mock.lockConfirmDeletion.Unlock()
+ return mock.ConfirmDeletionFunc(s)
+}
+
+// ConfirmDeletionCalls gets all the calls that were made to ConfirmDeletion.
+// Check the length with:
+//
+// len(mockedPrompter.ConfirmDeletionCalls())
+func (mock *PrompterMock) ConfirmDeletionCalls() []struct {
+ S string
+} {
+ var calls []struct {
+ S string
+ }
+ mock.lockConfirmDeletion.RLock()
+ calls = mock.calls.ConfirmDeletion
+ mock.lockConfirmDeletion.RUnlock()
+ return calls
+}
+
+// Input calls InputFunc.
+func (mock *PrompterMock) Input(s1 string, s2 string) (string, error) {
+ if mock.InputFunc == nil {
+ panic("PrompterMock.InputFunc: method is nil but Prompter.Input was just called")
+ }
+ callInfo := struct {
+ S1 string
+ S2 string
+ }{
+ S1: s1,
+ S2: s2,
+ }
+ mock.lockInput.Lock()
+ mock.calls.Input = append(mock.calls.Input, callInfo)
+ mock.lockInput.Unlock()
+ return mock.InputFunc(s1, s2)
+}
+
+// InputCalls gets all the calls that were made to Input.
+// Check the length with:
+//
+// len(mockedPrompter.InputCalls())
+func (mock *PrompterMock) InputCalls() []struct {
+ S1 string
+ S2 string
+} {
+ var calls []struct {
+ S1 string
+ S2 string
+ }
+ mock.lockInput.RLock()
+ calls = mock.calls.Input
+ mock.lockInput.RUnlock()
+ return calls
+}
+
+// InputHostname calls InputHostnameFunc.
+func (mock *PrompterMock) InputHostname() (string, error) {
+ if mock.InputHostnameFunc == nil {
+ panic("PrompterMock.InputHostnameFunc: method is nil but Prompter.InputHostname was just called")
+ }
+ callInfo := struct {
+ }{}
+ mock.lockInputHostname.Lock()
+ mock.calls.InputHostname = append(mock.calls.InputHostname, callInfo)
+ mock.lockInputHostname.Unlock()
+ return mock.InputHostnameFunc()
+}
+
+// InputHostnameCalls gets all the calls that were made to InputHostname.
+// Check the length with:
+//
+// len(mockedPrompter.InputHostnameCalls())
+func (mock *PrompterMock) InputHostnameCalls() []struct {
+} {
+ var calls []struct {
+ }
+ mock.lockInputHostname.RLock()
+ calls = mock.calls.InputHostname
+ mock.lockInputHostname.RUnlock()
+ return calls
+}
+
+// MarkdownEditor calls MarkdownEditorFunc.
+func (mock *PrompterMock) MarkdownEditor(s1 string, s2 string, b bool) (string, error) {
+ if mock.MarkdownEditorFunc == nil {
+ panic("PrompterMock.MarkdownEditorFunc: method is nil but Prompter.MarkdownEditor was just called")
+ }
+ callInfo := struct {
+ S1 string
+ S2 string
+ B bool
+ }{
+ S1: s1,
+ S2: s2,
+ B: b,
+ }
+ mock.lockMarkdownEditor.Lock()
+ mock.calls.MarkdownEditor = append(mock.calls.MarkdownEditor, callInfo)
+ mock.lockMarkdownEditor.Unlock()
+ return mock.MarkdownEditorFunc(s1, s2, b)
+}
+
+// MarkdownEditorCalls gets all the calls that were made to MarkdownEditor.
+// Check the length with:
+//
+// len(mockedPrompter.MarkdownEditorCalls())
+func (mock *PrompterMock) MarkdownEditorCalls() []struct {
+ S1 string
+ S2 string
+ B bool
+} {
+ var calls []struct {
+ S1 string
+ S2 string
+ B bool
+ }
+ mock.lockMarkdownEditor.RLock()
+ calls = mock.calls.MarkdownEditor
+ mock.lockMarkdownEditor.RUnlock()
+ return calls
+}
+
+// MultiSelect calls MultiSelectFunc.
+func (mock *PrompterMock) MultiSelect(prompt string, defaults []string, options []string) ([]int, error) {
+ if mock.MultiSelectFunc == nil {
+ panic("PrompterMock.MultiSelectFunc: method is nil but Prompter.MultiSelect was just called")
+ }
+ callInfo := struct {
+ Prompt string
+ Defaults []string
+ Options []string
+ }{
+ Prompt: prompt,
+ Defaults: defaults,
+ Options: options,
+ }
+ mock.lockMultiSelect.Lock()
+ mock.calls.MultiSelect = append(mock.calls.MultiSelect, callInfo)
+ mock.lockMultiSelect.Unlock()
+ return mock.MultiSelectFunc(prompt, defaults, options)
+}
+
+// MultiSelectCalls gets all the calls that were made to MultiSelect.
+// Check the length with:
+//
+// len(mockedPrompter.MultiSelectCalls())
+func (mock *PrompterMock) MultiSelectCalls() []struct {
+ Prompt string
+ Defaults []string
+ Options []string
+} {
+ var calls []struct {
+ Prompt string
+ Defaults []string
+ Options []string
+ }
+ mock.lockMultiSelect.RLock()
+ calls = mock.calls.MultiSelect
+ mock.lockMultiSelect.RUnlock()
+ return calls
+}
+
+// Password calls PasswordFunc.
+func (mock *PrompterMock) Password(s string) (string, error) {
+ if mock.PasswordFunc == nil {
+ panic("PrompterMock.PasswordFunc: method is nil but Prompter.Password was just called")
+ }
+ callInfo := struct {
+ S string
+ }{
+ S: s,
+ }
+ mock.lockPassword.Lock()
+ mock.calls.Password = append(mock.calls.Password, callInfo)
+ mock.lockPassword.Unlock()
+ return mock.PasswordFunc(s)
+}
+
+// PasswordCalls gets all the calls that were made to Password.
+// Check the length with:
+//
+// len(mockedPrompter.PasswordCalls())
+func (mock *PrompterMock) PasswordCalls() []struct {
+ S string
+} {
+ var calls []struct {
+ S string
+ }
+ mock.lockPassword.RLock()
+ calls = mock.calls.Password
+ mock.lockPassword.RUnlock()
+ return calls
+}
+
+// Select calls SelectFunc.
+func (mock *PrompterMock) Select(s1 string, s2 string, strings []string) (int, error) {
+ if mock.SelectFunc == nil {
+ panic("PrompterMock.SelectFunc: method is nil but Prompter.Select was just called")
+ }
+ callInfo := struct {
+ S1 string
+ S2 string
+ Strings []string
+ }{
+ S1: s1,
+ S2: s2,
+ Strings: strings,
+ }
+ mock.lockSelect.Lock()
+ mock.calls.Select = append(mock.calls.Select, callInfo)
+ mock.lockSelect.Unlock()
+ return mock.SelectFunc(s1, s2, strings)
+}
+
+// SelectCalls gets all the calls that were made to Select.
+// Check the length with:
+//
+// len(mockedPrompter.SelectCalls())
+func (mock *PrompterMock) SelectCalls() []struct {
+ S1 string
+ S2 string
+ Strings []string
+} {
+ var calls []struct {
+ S1 string
+ S2 string
+ Strings []string
+ }
+ mock.lockSelect.RLock()
+ calls = mock.calls.Select
+ mock.lockSelect.RUnlock()
+ return calls
+}
diff --git a/vendor/github.com/cli/cli/v2/internal/prompter/test.go b/vendor/github.com/cli/cli/v2/internal/prompter/test.go
new file mode 100644
index 000000000..04375ce76
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/internal/prompter/test.go
@@ -0,0 +1,150 @@
+package prompter
+
+import (
+ "fmt"
+ "strings"
+ "testing"
+
+ ghPrompter "github.com/cli/go-gh/v2/pkg/prompter"
+ "github.com/stretchr/testify/assert"
+)
+
+func NewMockPrompter(t *testing.T) *MockPrompter {
+ m := &MockPrompter{
+ t: t,
+ PrompterMock: *ghPrompter.NewMock(t),
+ authTokenStubs: []authTokenStub{},
+ confirmDeletionStubs: []confirmDeletionStub{},
+ inputHostnameStubs: []inputHostnameStub{},
+ markdownEditorStubs: []markdownEditorStub{},
+ }
+ t.Cleanup(m.Verify)
+ return m
+}
+
+type MockPrompter struct {
+ t *testing.T
+ ghPrompter.PrompterMock
+ authTokenStubs []authTokenStub
+ confirmDeletionStubs []confirmDeletionStub
+ inputHostnameStubs []inputHostnameStub
+ markdownEditorStubs []markdownEditorStub
+}
+
+type authTokenStub struct {
+ fn func() (string, error)
+}
+
+type confirmDeletionStub struct {
+ prompt string
+ fn func(string) error
+}
+
+type inputHostnameStub struct {
+ fn func() (string, error)
+}
+
+type markdownEditorStub struct {
+ prompt string
+ fn func(string, string, bool) (string, error)
+}
+
+func (m *MockPrompter) AuthToken() (string, error) {
+ var s authTokenStub
+ if len(m.authTokenStubs) == 0 {
+ return "", NoSuchPromptErr("AuthToken")
+ }
+ s = m.authTokenStubs[0]
+ m.authTokenStubs = m.authTokenStubs[1:len(m.authTokenStubs)]
+ return s.fn()
+}
+
+func (m *MockPrompter) ConfirmDeletion(prompt string) error {
+ var s confirmDeletionStub
+ if len(m.confirmDeletionStubs) == 0 {
+ return NoSuchPromptErr("ConfirmDeletion")
+ }
+ s = m.confirmDeletionStubs[0]
+ m.confirmDeletionStubs = m.confirmDeletionStubs[1:len(m.confirmDeletionStubs)]
+ return s.fn(prompt)
+}
+
+func (m *MockPrompter) InputHostname() (string, error) {
+ var s inputHostnameStub
+ if len(m.inputHostnameStubs) == 0 {
+ return "", NoSuchPromptErr("InputHostname")
+ }
+ s = m.inputHostnameStubs[0]
+ m.inputHostnameStubs = m.inputHostnameStubs[1:len(m.inputHostnameStubs)]
+ return s.fn()
+}
+
+func (m *MockPrompter) MarkdownEditor(prompt, defaultValue string, blankAllowed bool) (string, error) {
+ var s markdownEditorStub
+ if len(m.markdownEditorStubs) == 0 {
+ return "", NoSuchPromptErr(prompt)
+ }
+ s = m.markdownEditorStubs[0]
+ m.markdownEditorStubs = m.markdownEditorStubs[1:len(m.markdownEditorStubs)]
+ if s.prompt != prompt {
+ return "", NoSuchPromptErr(prompt)
+ }
+ return s.fn(prompt, defaultValue, blankAllowed)
+}
+
+func (m *MockPrompter) RegisterAuthToken(stub func() (string, error)) {
+ m.authTokenStubs = append(m.authTokenStubs, authTokenStub{fn: stub})
+}
+
+func (m *MockPrompter) RegisterConfirmDeletion(prompt string, stub func(string) error) {
+ m.confirmDeletionStubs = append(m.confirmDeletionStubs, confirmDeletionStub{prompt: prompt, fn: stub})
+}
+
+func (m *MockPrompter) RegisterInputHostname(stub func() (string, error)) {
+ m.inputHostnameStubs = append(m.inputHostnameStubs, inputHostnameStub{fn: stub})
+}
+
+func (m *MockPrompter) RegisterMarkdownEditor(prompt string, stub func(string, string, bool) (string, error)) {
+ m.markdownEditorStubs = append(m.markdownEditorStubs, markdownEditorStub{prompt: prompt, fn: stub})
+}
+
+func (m *MockPrompter) Verify() {
+ errs := []string{}
+ if len(m.authTokenStubs) > 0 {
+ errs = append(errs, "AuthToken")
+ }
+ if len(m.confirmDeletionStubs) > 0 {
+ errs = append(errs, "ConfirmDeletion")
+ }
+ if len(m.inputHostnameStubs) > 0 {
+ errs = append(errs, "inputHostname")
+ }
+ if len(m.markdownEditorStubs) > 0 {
+ errs = append(errs, "markdownEditorStubs")
+ }
+ if len(errs) > 0 {
+ m.t.Helper()
+ m.t.Errorf("%d unmatched calls to %s", len(errs), strings.Join(errs, ","))
+ }
+}
+
+func AssertOptions(t *testing.T, expected, actual []string) {
+ assert.Equal(t, expected, actual)
+}
+
+func IndexFor(options []string, answer string) (int, error) {
+ for ix, a := range options {
+ if a == answer {
+ return ix, nil
+ }
+ }
+ return -1, NoSuchAnswerErr(answer, options)
+}
+
+func NoSuchPromptErr(prompt string) error {
+ return fmt.Errorf("no such prompt '%s'", prompt)
+}
+
+func NoSuchAnswerErr(answer string, options []string) error {
+ return fmt.Errorf("no such answer '%s' in [%s]", answer, strings.Join(options, ", "))
+}
diff --git a/vendor/github.com/cli/cli/v2/internal/run/run.go b/vendor/github.com/cli/cli/v2/internal/run/run.go
new file mode 100644
index 000000000..3a166e7ba
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/internal/run/run.go
@@ -0,0 +1,98 @@
+package run
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strings"
+
+ "github.com/cli/cli/v2/utils"
+)
+
+// Runnable is typically an exec.Cmd or its stub in tests
+type Runnable interface {
+ Output() ([]byte, error)
+ Run() error
+}
+
+// PrepareCmd extends exec.Cmd with extra error reporting features and provides a
+// hook to stub command execution in tests
+var PrepareCmd = func(cmd *exec.Cmd) Runnable {
+ return &cmdWithStderr{cmd}
+}
+
+// cmdWithStderr augments exec.Cmd by adding stderr to the error message
+type cmdWithStderr struct {
+ *exec.Cmd
+}
+
+func (c cmdWithStderr) Output() ([]byte, error) {
+ if isVerbose, _ := utils.IsDebugEnabled(); isVerbose {
+ _ = printArgs(os.Stderr, c.Cmd.Args)
+ }
+ out, err := c.Cmd.Output()
+ if c.Cmd.Stderr != nil || err == nil {
+ return out, err
+ }
+ cmdErr := &CmdError{
+ Args: c.Cmd.Args,
+ Err: err,
+ }
+ var exitError *exec.ExitError
+ if errors.As(err, &exitError) {
+ cmdErr.Stderr = bytes.NewBuffer(exitError.Stderr)
+ }
+ return out, cmdErr
+}
+
+func (c cmdWithStderr) Run() error {
+ if isVerbose, _ := utils.IsDebugEnabled(); isVerbose {
+ _ = printArgs(os.Stderr, c.Cmd.Args)
+ }
+ if c.Cmd.Stderr != nil {
+ return c.Cmd.Run()
+ }
+ errStream := &bytes.Buffer{}
+ c.Cmd.Stderr = errStream
+ err := c.Cmd.Run()
+ if err != nil {
+ err = &CmdError{
+ Args: c.Cmd.Args,
+ Err: err,
+ Stderr: errStream,
+ }
+ }
+ return err
+}
+
+// CmdError provides more visibility into why an exec.Cmd had failed
+type CmdError struct {
+ Args []string
+ Err error
+ Stderr *bytes.Buffer
+}
+
+func (e CmdError) Error() string {
+ msg := e.Stderr.String()
+ if msg != "" && !strings.HasSuffix(msg, "\n") {
+ msg += "\n"
+ }
+ return fmt.Sprintf("%s%s: %s", msg, e.Args[0], e.Err)
+}
+
+func (e CmdError) Unwrap() error {
+ return e.Err
+}
+
+func printArgs(w io.Writer, args []string) error {
+ if len(args) > 0 {
+ // print commands, but omit the full path to an executable
+ args = append([]string{filepath.Base(args[0])}, args[1:]...)
+ }
+ _, err := fmt.Fprintf(w, "%v\n", args)
+ return err
+}
diff --git a/vendor/github.com/cli/cli/v2/internal/run/stub.go b/vendor/github.com/cli/cli/v2/internal/run/stub.go
new file mode 100644
index 000000000..49bf62d29
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/internal/run/stub.go
@@ -0,0 +1,151 @@
+package run
+
+import (
+ "fmt"
+ "os/exec"
+ "path/filepath"
+ "regexp"
+ "strings"
+)
+
+const (
+ gitAuthRE = `-c credential.helper= -c credential.helper=!"[^"]+" auth git-credential `
+)
+
+type T interface {
+ Helper()
+ Errorf(string, ...interface{})
+}
+
+// Stub installs a catch-all for all external commands invoked from gh. It returns a restore func that, when
+// invoked from tests, fails the current test if some stubs that were registered were never matched.
+func Stub() (*CommandStubber, func(T)) {
+ cs := &CommandStubber{}
+ teardown := setPrepareCmd(func(cmd *exec.Cmd) Runnable {
+ s := cs.find(cmd.Args)
+ if s == nil {
+ panic(fmt.Sprintf("no exec stub for `%s`", strings.Join(cmd.Args, " ")))
+ }
+ for _, c := range s.callbacks {
+ c(cmd.Args)
+ }
+ s.matched = true
+ return s
+ })
+
+ return cs, func(t T) {
+ defer teardown()
+ var unmatched []string
+ for _, s := range cs.stubs {
+ if s.matched {
+ continue
+ }
+ unmatched = append(unmatched, s.pattern.String())
+ }
+ if len(unmatched) == 0 {
+ return
+ }
+ t.Helper()
+ t.Errorf("unmatched stubs (%d): %s", len(unmatched), strings.Join(unmatched, ", "))
+ }
+}
+
+func setPrepareCmd(fn func(*exec.Cmd) Runnable) func() {
+ origPrepare := PrepareCmd
+ PrepareCmd = func(cmd *exec.Cmd) Runnable {
+ // normalize git executable name for consistency in tests
+ if baseName := filepath.Base(cmd.Args[0]); baseName == "git" || baseName == "git.exe" {
+ cmd.Args[0] = "git"
+ }
+ return fn(cmd)
+ }
+ return func() {
+ PrepareCmd = origPrepare
+ }
+}
+
+// CommandStubber stubs out invocations to external commands.
+type CommandStubber struct {
+ stubs []*commandStub
+}
+
+// Register a stub for an external command. Pattern is a regular expression, output is the standard output
+// from a command. Pass callbacks to inspect raw arguments that the command was invoked with.
+func (cs *CommandStubber) Register(pattern string, exitStatus int, output string, callbacks ...CommandCallback) {
+ if len(pattern) < 1 {
+ panic("cannot use empty regexp pattern")
+ }
+ if strings.HasPrefix(pattern, "git") {
+ pattern = addGitAuthentication(pattern)
+ }
+ cs.stubs = append(cs.stubs, &commandStub{
+ pattern: regexp.MustCompile(pattern),
+ exitStatus: exitStatus,
+ stdout: output,
+ callbacks: callbacks,
+ })
+}
+
+func (cs *CommandStubber) find(args []string) *commandStub {
+ line := strings.Join(args, " ")
+ for _, s := range cs.stubs {
+ if !s.matched && s.pattern.MatchString(line) {
+ return s
+ }
+ }
+ return nil
+}
+
+type CommandCallback func([]string)
+
+type commandStub struct {
+ pattern *regexp.Regexp
+ matched bool
+ exitStatus int
+ stdout string
+ callbacks []CommandCallback
+}
+
+type errWithExitCode struct {
+ message string
+ exitCode int
+}
+
+func (e errWithExitCode) Error() string {
+ return e.message
+}
+
+func (e errWithExitCode) ExitCode() int {
+ return e.exitCode
+}
+
+// Run satisfies Runnable
+func (s *commandStub) Run() error {
+ if s.exitStatus != 0 {
+ // It's nontrivial to construct a fake `exec.ExitError` instance, so we return an error type
+ // that has the `ExitCode() int` method.
+ return errWithExitCode{
+ message: fmt.Sprintf("%s exited with status %d", s.pattern, s.exitStatus),
+ exitCode: s.exitStatus,
+ }
+ }
+ return nil
+}
+
+// Output satisfies Runnable
+func (s *commandStub) Output() ([]byte, error) {
+ if err := s.Run(); err != nil {
+ return []byte(nil), err
+ }
+ return []byte(s.stdout), nil
+}
+
+// Inject git authentication string for specific git commands.
+func addGitAuthentication(s string) string {
+ pattern := regexp.MustCompile(`( fetch | pull | push | clone | remote add.+-f | submodule )`)
+ loc := pattern.FindStringIndex(s)
+ if loc == nil {
+ return s
+ }
+ return s[:loc[0]+1] + gitAuthRE + s[loc[0]+1:]
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/cmd/auth/shared/git_credential.go b/vendor/github.com/cli/cli/v2/pkg/cmd/auth/shared/git_credential.go
new file mode 100644
index 000000000..8624cf00b
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/cmd/auth/shared/git_credential.go
@@ -0,0 +1,187 @@
+package shared
+
+import (
+ "bytes"
+ "context"
+ "errors"
+ "fmt"
+ "path/filepath"
+ "strings"
+
+ "github.com/MakeNowJust/heredoc"
+ "github.com/cli/cli/v2/git"
+ "github.com/cli/cli/v2/internal/ghinstance"
+ "github.com/google/shlex"
+)
+
+type GitCredentialFlow struct {
+ Executable string
+ Prompter Prompt
+ GitClient *git.Client
+
+ shouldSetup bool
+ helper string
+ scopes []string
+}
+
+func (flow *GitCredentialFlow) Prompt(hostname string) error {
+ var gitErr error
+ flow.helper, gitErr = gitCredentialHelper(flow.GitClient, hostname)
+ if isOurCredentialHelper(flow.helper) {
+ flow.scopes = append(flow.scopes, "workflow")
+ return nil
+ }
+
+ result, err := flow.Prompter.Confirm("Authenticate Git with your GitHub credentials?", true)
+ if err != nil {
+ return err
+ }
+ flow.shouldSetup = result
+
+ if flow.shouldSetup {
+ if isGitMissing(gitErr) {
+ return gitErr
+ }
+ flow.scopes = append(flow.scopes, "workflow")
+ }
+
+ return nil
+}
+
+func (flow *GitCredentialFlow) Scopes() []string {
+ return flow.scopes
+}
+
+func (flow *GitCredentialFlow) ShouldSetup() bool {
+ return flow.shouldSetup
+}
+
+func (flow *GitCredentialFlow) Setup(hostname, username, authToken string) error {
+ return flow.gitCredentialSetup(hostname, username, authToken)
+}
+
+func (flow *GitCredentialFlow) gitCredentialSetup(hostname, username, password string) error {
+ gitClient := flow.GitClient
+ ctx := context.Background()
+
+ if flow.helper == "" {
+ credHelperKeys := []string{
+ gitCredentialHelperKey(hostname),
+ }
+
+ gistHost := strings.TrimSuffix(ghinstance.GistHost(hostname), "/")
+ if strings.HasPrefix(gistHost, "gist.") {
+ credHelperKeys = append(credHelperKeys, gitCredentialHelperKey(gistHost))
+ }
+
+ var configErr error
+
+ for _, credHelperKey := range credHelperKeys {
+ if configErr != nil {
+ break
+ }
+ // first use a blank value to indicate to git we want to sever the chain of credential helpers
+ preConfigureCmd, err := gitClient.Command(ctx, "config", "--global", "--replace-all", credHelperKey, "")
+ if err != nil {
+ configErr = err
+ break
+ }
+ if _, err = preConfigureCmd.Output(); err != nil {
+ configErr = err
+ break
+ }
+
+ // second configure the actual helper for this host
+ configureCmd, err := gitClient.Command(ctx,
+ "config", "--global", "--add",
+ credHelperKey,
+ fmt.Sprintf("!%s auth git-credential", shellQuote(flow.Executable)),
+ )
+ if err != nil {
+ configErr = err
+ } else {
+ _, configErr = configureCmd.Output()
+ }
+ }
+
+ return configErr
+ }
+
+ // clear previous cached credentials
+ rejectCmd, err := gitClient.Command(ctx, "credential", "reject")
+ if err != nil {
+ return err
+ }
+
+ rejectCmd.Stdin = bytes.NewBufferString(heredoc.Docf(`
+ protocol=https
+ host=%s
+ `, hostname))
+
+ _, err = rejectCmd.Output()
+ if err != nil {
+ return err
+ }
+
+ approveCmd, err := gitClient.Command(ctx, "credential", "approve")
+ if err != nil {
+ return err
+ }
+
+ approveCmd.Stdin = bytes.NewBufferString(heredoc.Docf(`
+ protocol=https
+ host=%s
+ username=%s
+ password=%s
+ `, hostname, username, password))
+
+ _, err = approveCmd.Output()
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func gitCredentialHelperKey(hostname string) string {
+ host := strings.TrimSuffix(ghinstance.HostPrefix(hostname), "/")
+ return fmt.Sprintf("credential.%s.helper", host)
+}
+
+func gitCredentialHelper(gitClient *git.Client, hostname string) (helper string, err error) {
+ ctx := context.Background()
+ helper, err = gitClient.Config(ctx, gitCredentialHelperKey(hostname))
+ if helper != "" {
+ return
+ }
+ helper, err = gitClient.Config(ctx, "credential.helper")
+ return
+}
+
+func isOurCredentialHelper(cmd string) bool {
+ if !strings.HasPrefix(cmd, "!") {
+ return false
+ }
+
+ args, err := shlex.Split(cmd[1:])
+ if err != nil || len(args) == 0 {
+ return false
+ }
+
+ return strings.TrimSuffix(filepath.Base(args[0]), ".exe") == "gh"
+}
+
+func isGitMissing(err error) bool {
+ if err == nil {
+ return false
+ }
+ var errNotInstalled *git.NotInstalled
+ return errors.As(err, &errNotInstalled)
+}
+
+func shellQuote(s string) string {
+ if strings.ContainsAny(s, " $\\") {
+ return "'" + s + "'"
+ }
+ return s
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/cmd/auth/shared/login_flow.go b/vendor/github.com/cli/cli/v2/pkg/cmd/auth/shared/login_flow.go
new file mode 100644
index 000000000..7bb974547
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/cmd/auth/shared/login_flow.go
@@ -0,0 +1,285 @@
+package shared
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "net/http"
+ "os"
+ "slices"
+ "strings"
+
+ "github.com/MakeNowJust/heredoc"
+ "github.com/cli/cli/v2/api"
+ "github.com/cli/cli/v2/git"
+ "github.com/cli/cli/v2/internal/authflow"
+ "github.com/cli/cli/v2/internal/browser"
+ "github.com/cli/cli/v2/internal/ghinstance"
+ "github.com/cli/cli/v2/pkg/cmd/ssh-key/add"
+ "github.com/cli/cli/v2/pkg/iostreams"
+ "github.com/cli/cli/v2/pkg/ssh"
+)
+
+const defaultSSHKeyTitle = "GitHub CLI"
+
+type iconfig interface {
+ Login(string, string, string, string, bool) (bool, error)
+ UsersForHost(string) []string
+}
+
+type LoginOptions struct {
+ IO *iostreams.IOStreams
+ Config iconfig
+ HTTPClient *http.Client
+ GitClient *git.Client
+ Hostname string
+ Interactive bool
+ Web bool
+ Scopes []string
+ Executable string
+ GitProtocol string
+ Prompter Prompt
+ Browser browser.Browser
+ SecureStorage bool
+
+ sshContext ssh.Context
+}
+
+func Login(opts *LoginOptions) error {
+ cfg := opts.Config
+ hostname := opts.Hostname
+ httpClient := opts.HTTPClient
+ cs := opts.IO.ColorScheme()
+
+ gitProtocol := strings.ToLower(opts.GitProtocol)
+ if opts.Interactive && gitProtocol == "" {
+ options := []string{
+ "HTTPS",
+ "SSH",
+ }
+ result, err := opts.Prompter.Select(
+ "What is your preferred protocol for Git operations on this host?",
+ options[0],
+ options)
+ if err != nil {
+ return err
+ }
+ proto := options[result]
+ gitProtocol = strings.ToLower(proto)
+ }
+
+ var additionalScopes []string
+
+ credentialFlow := &GitCredentialFlow{
+ Executable: opts.Executable,
+ Prompter: opts.Prompter,
+ GitClient: opts.GitClient,
+ }
+ if opts.Interactive && gitProtocol == "https" {
+ if err := credentialFlow.Prompt(hostname); err != nil {
+ return err
+ }
+ additionalScopes = append(additionalScopes, credentialFlow.Scopes()...)
+ }
+
+ var keyToUpload string
+ keyTitle := defaultSSHKeyTitle
+ if opts.Interactive && gitProtocol == "ssh" {
+ pubKeys, err := opts.sshContext.LocalPublicKeys()
+ if err != nil {
+ return err
+ }
+
+ if len(pubKeys) > 0 {
+ options := append(pubKeys, "Skip")
+ keyChoice, err := opts.Prompter.Select(
+ "Upload your SSH public key to your GitHub account?",
+ options[0],
+ options)
+ if err != nil {
+ return err
+ }
+ if keyChoice < len(pubKeys) {
+ keyToUpload = pubKeys[keyChoice]
+ }
+ } else if opts.sshContext.HasKeygen() {
+ sshChoice, err := opts.Prompter.Confirm("Generate a new SSH key to add to your GitHub account?", true)
+ if err != nil {
+ return err
+ }
+
+ if sshChoice {
+ passphrase, err := opts.Prompter.Password(
+ "Enter a passphrase for your new SSH key (Optional)")
+ if err != nil {
+ return err
+ }
+ keyPair, err := opts.sshContext.GenerateSSHKey("id_ed25519", passphrase)
+ if err != nil {
+ return err
+ }
+ keyToUpload = keyPair.PublicKeyPath
+ }
+ }
+
+ if keyToUpload != "" {
+ var err error
+ keyTitle, err = opts.Prompter.Input(
+ "Title for your SSH key:", defaultSSHKeyTitle)
+ if err != nil {
+ return err
+ }
+
+ additionalScopes = append(additionalScopes, "admin:public_key")
+ }
+ }
+
+ var authMode int
+ if opts.Web {
+ authMode = 0
+ } else if opts.Interactive {
+ options := []string{"Login with a web browser", "Paste an authentication token"}
+ var err error
+ authMode, err = opts.Prompter.Select(
+ "How would you like to authenticate GitHub CLI?",
+ options[0],
+ options)
+ if err != nil {
+ return err
+ }
+ }
+
+ var authToken string
+ var username string
+
+ if authMode == 0 {
+ var err error
+ authToken, username, err = authflow.AuthFlow(hostname, opts.IO, "", append(opts.Scopes, additionalScopes...), opts.Interactive, opts.Browser)
+ if err != nil {
+ return fmt.Errorf("failed to authenticate via web browser: %w", err)
+ }
+ fmt.Fprintf(opts.IO.ErrOut, "%s Authentication complete.\n", cs.SuccessIcon())
+ } else {
+ minimumScopes := append([]string{"repo", "read:org"}, additionalScopes...)
+ fmt.Fprint(opts.IO.ErrOut, heredoc.Docf(`
+ Tip: you can generate a Personal Access Token here https://%s/settings/tokens
+ The minimum required scopes are %s.
+ `, hostname, scopesSentence(minimumScopes)))
+
+ var err error
+ authToken, err = opts.Prompter.AuthToken()
+ if err != nil {
+ return err
+ }
+
+ if err := HasMinimumScopes(httpClient, hostname, authToken); err != nil {
+ return fmt.Errorf("error validating token: %w", err)
+ }
+ }
+
+ if username == "" {
+ var err error
+ username, err = GetCurrentLogin(httpClient, hostname, authToken)
+ if err != nil {
+ return fmt.Errorf("error retrieving current user: %w", err)
+ }
+ }
+
+ // Get these users before adding the new one, so that we can
+ // check whether the user was already logged in later.
+ //
+ // In this case we ignore the error if the host doesn't exist
+ // because that can occur when the user is logging into a host
+ // for the first time.
+ usersForHost := cfg.UsersForHost(hostname)
+ userWasAlreadyLoggedIn := slices.Contains(usersForHost, username)
+
+ if gitProtocol != "" {
+ fmt.Fprintf(opts.IO.ErrOut, "- gh config set -h %s git_protocol %s\n", hostname, gitProtocol)
+ fmt.Fprintf(opts.IO.ErrOut, "%s Configured git protocol\n", cs.SuccessIcon())
+ }
+
+ insecureStorageUsed, err := cfg.Login(hostname, username, authToken, gitProtocol, opts.SecureStorage)
+ if err != nil {
+ return err
+ }
+ if insecureStorageUsed {
+ fmt.Fprintf(opts.IO.ErrOut, "%s Authentication credentials saved in plain text\n", cs.Yellow("!"))
+ }
+
+ if credentialFlow.ShouldSetup() {
+ err := credentialFlow.Setup(hostname, username, authToken)
+ if err != nil {
+ return err
+ }
+ }
+
+ if keyToUpload != "" {
+ uploaded, err := sshKeyUpload(httpClient, hostname, keyToUpload, keyTitle)
+ if err != nil {
+ return err
+ }
+
+ if uploaded {
+ fmt.Fprintf(opts.IO.ErrOut, "%s Uploaded the SSH key to your GitHub account: %s\n", cs.SuccessIcon(), cs.Bold(keyToUpload))
+ } else {
+ fmt.Fprintf(opts.IO.ErrOut, "%s SSH key already existed on your GitHub account: %s\n", cs.SuccessIcon(), cs.Bold(keyToUpload))
+ }
+ }
+
+ fmt.Fprintf(opts.IO.ErrOut, "%s Logged in as %s\n", cs.SuccessIcon(), cs.Bold(username))
+ if userWasAlreadyLoggedIn {
+ fmt.Fprintf(opts.IO.ErrOut, "%s You were already logged in to this account\n", cs.WarningIcon())
+ }
+
+ return nil
+}
+
+func scopesSentence(scopes []string) string {
+ quoted := make([]string, len(scopes))
+ for i, s := range scopes {
+ quoted[i] = fmt.Sprintf("'%s'", s)
+ }
+ return strings.Join(quoted, ", ")
+}
+
+func sshKeyUpload(httpClient *http.Client, hostname, keyFile string, title string) (bool, error) {
+ f, err := os.Open(keyFile)
+ if err != nil {
+ return false, err
+ }
+ defer f.Close()
+
+ return add.SSHKeyUpload(httpClient, hostname, f, title)
+}
+
+func GetCurrentLogin(httpClient httpClient, hostname, authToken string) (string, error) {
+ query := `query UserCurrent{viewer{login}}`
+ reqBody, err := json.Marshal(map[string]interface{}{"query": query})
+ if err != nil {
+ return "", err
+ }
+ result := struct {
+ Data struct{ Viewer struct{ Login string } }
+ }{}
+ apiEndpoint := ghinstance.GraphQLEndpoint(hostname)
+ req, err := http.NewRequest("POST", apiEndpoint, bytes.NewBuffer(reqBody))
+ if err != nil {
+ return "", err
+ }
+ req.Header.Set("Authorization", "token "+authToken)
+ res, err := httpClient.Do(req)
+ if err != nil {
+ return "", err
+ }
+ defer res.Body.Close()
+ if res.StatusCode > 299 {
+ return "", api.HandleHTTPError(res)
+ }
+ decoder := json.NewDecoder(res.Body)
+ err = decoder.Decode(&result)
+ if err != nil {
+ return "", err
+ }
+ return result.Data.Viewer.Login, nil
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/cmd/auth/shared/oauth_scopes.go b/vendor/github.com/cli/cli/v2/pkg/cmd/auth/shared/oauth_scopes.go
new file mode 100644
index 000000000..8d9996019
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/cmd/auth/shared/oauth_scopes.go
@@ -0,0 +1,106 @@
+package shared
+
+import (
+ "fmt"
+ "io"
+ "net/http"
+ "strings"
+
+ "github.com/cli/cli/v2/api"
+ "github.com/cli/cli/v2/internal/ghinstance"
+)
+
+type MissingScopesError struct {
+ MissingScopes []string
+}
+
+func (e MissingScopesError) Error() string {
+ var missing []string
+ for _, s := range e.MissingScopes {
+ missing = append(missing, fmt.Sprintf("'%s'", s))
+ }
+ scopes := strings.Join(missing, ", ")
+
+ if len(e.MissingScopes) == 1 {
+ return "missing required scope " + scopes
+ }
+ return "missing required scopes " + scopes
+}
+
+type httpClient interface {
+ Do(*http.Request) (*http.Response, error)
+}
+
+// GetScopes performs a GitHub API request and returns the value of the X-Oauth-Scopes header.
+func GetScopes(httpClient httpClient, hostname, authToken string) (string, error) {
+ apiEndpoint := ghinstance.RESTPrefix(hostname)
+
+ req, err := http.NewRequest("GET", apiEndpoint, nil)
+ if err != nil {
+ return "", err
+ }
+
+ req.Header.Set("Authorization", "token "+authToken)
+
+ res, err := httpClient.Do(req)
+ if err != nil {
+ return "", err
+ }
+
+ defer func() {
+ // Ensure the response body is fully read and closed
+ // before we reconnect, so that we reuse the same TCPconnection.
+ _, _ = io.Copy(io.Discard, res.Body)
+ res.Body.Close()
+ }()
+
+ if res.StatusCode != 200 {
+ return "", api.HandleHTTPError(res)
+ }
+
+ return res.Header.Get("X-Oauth-Scopes"), nil
+}
+
+// HasMinimumScopes performs a GitHub API request and returns an error if the token used in the request
+// lacks the minimum required scopes for performing API operations with gh.
+func HasMinimumScopes(httpClient httpClient, hostname, authToken string) error {
+ scopesHeader, err := GetScopes(httpClient, hostname, authToken)
+ if err != nil {
+ return err
+ }
+
+ return HeaderHasMinimumScopes(scopesHeader)
+}
+
+// HeaderHasMinimumScopes parses the comma separated scopesHeader string and returns an error
+// if it lacks the minimum required scopes for performing API operations with gh.
+func HeaderHasMinimumScopes(scopesHeader string) error {
+ if scopesHeader == "" {
+ // if the token reports no scopes, assume that it's an integration token and give up on
+ // detecting its capabilities
+ return nil
+ }
+
+ search := map[string]bool{
+ "repo": false,
+ "read:org": false,
+ "admin:org": false,
+ }
+ for _, s := range strings.Split(scopesHeader, ",") {
+ search[strings.TrimSpace(s)] = true
+ }
+
+ var missingScopes []string
+ if !search["repo"] {
+ missingScopes = append(missingScopes, "repo")
+ }
+
+ if !search["read:org"] && !search["write:org"] && !search["admin:org"] {
+ missingScopes = append(missingScopes, "read:org")
+ }
+
+ if len(missingScopes) > 0 {
+ return &MissingScopesError{MissingScopes: missingScopes}
+ }
+ return nil
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/cmd/auth/shared/prompt.go b/vendor/github.com/cli/cli/v2/pkg/cmd/auth/shared/prompt.go
new file mode 100644
index 000000000..c0d47372c
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/cmd/auth/shared/prompt.go
@@ -0,0 +1,10 @@
+package shared
+
+type Prompt interface {
+ Select(string, string, []string) (int, error)
+ Confirm(string, bool) (bool, error)
+ InputHostname() (string, error)
+ AuthToken() (string, error)
+ Input(string, string) (string, error)
+ Password(string) (string, error)
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/cmd/auth/shared/writeable.go b/vendor/github.com/cli/cli/v2/pkg/cmd/auth/shared/writeable.go
new file mode 100644
index 000000000..e5ae91469
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/cmd/auth/shared/writeable.go
@@ -0,0 +1,12 @@
+package shared
+
+import (
+ "strings"
+
+ "github.com/cli/cli/v2/internal/config"
+)
+
+func AuthTokenWriteable(authCfg *config.AuthConfig, hostname string) (string, bool) {
+ token, src := authCfg.ActiveToken(hostname)
+ return src, (token == "" || !strings.HasSuffix(src, "_TOKEN"))
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/cmd/ssh-key/add/add.go b/vendor/github.com/cli/cli/v2/pkg/cmd/ssh-key/add/add.go
new file mode 100644
index 000000000..553c35985
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/cmd/ssh-key/add/add.go
@@ -0,0 +1,107 @@
+package add
+
+import (
+ "fmt"
+ "io"
+ "net/http"
+ "os"
+
+ "github.com/cli/cli/v2/internal/config"
+ "github.com/cli/cli/v2/pkg/cmd/ssh-key/shared"
+ "github.com/cli/cli/v2/pkg/cmdutil"
+ "github.com/cli/cli/v2/pkg/iostreams"
+ "github.com/spf13/cobra"
+)
+
+type AddOptions struct {
+ IO *iostreams.IOStreams
+ Config func() (config.Config, error)
+ HTTPClient func() (*http.Client, error)
+
+ KeyFile string
+ Title string
+ Type string
+}
+
+func NewCmdAdd(f *cmdutil.Factory, runF func(*AddOptions) error) *cobra.Command {
+ opts := &AddOptions{
+ HTTPClient: f.HttpClient,
+ Config: f.Config,
+ IO: f.IOStreams,
+ }
+
+ cmd := &cobra.Command{
+ Use: "add []",
+ Short: "Add an SSH key to your GitHub account",
+ Args: cobra.MaximumNArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ if len(args) == 0 {
+ if opts.IO.IsStdoutTTY() && opts.IO.IsStdinTTY() {
+ return cmdutil.FlagErrorf("public key file missing")
+ }
+ opts.KeyFile = "-"
+ } else {
+ opts.KeyFile = args[0]
+ }
+
+ if runF != nil {
+ return runF(opts)
+ }
+ return runAdd(opts)
+ },
+ }
+
+ typeEnums := []string{shared.AuthenticationKey, shared.SigningKey}
+ cmdutil.StringEnumFlag(cmd, &opts.Type, "type", "", shared.AuthenticationKey, typeEnums, "Type of the ssh key")
+ cmd.Flags().StringVarP(&opts.Title, "title", "t", "", "Title for the new key")
+ return cmd
+}
+
+func runAdd(opts *AddOptions) error {
+ httpClient, err := opts.HTTPClient()
+ if err != nil {
+ return err
+ }
+
+ var keyReader io.Reader
+ if opts.KeyFile == "-" {
+ keyReader = opts.IO.In
+ defer opts.IO.In.Close()
+ } else {
+ f, err := os.Open(opts.KeyFile)
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+ keyReader = f
+ }
+
+ cfg, err := opts.Config()
+ if err != nil {
+ return err
+ }
+
+ hostname, _ := cfg.Authentication().DefaultHost()
+
+ var uploaded bool
+
+ if opts.Type == shared.SigningKey {
+ uploaded, err = SSHSigningKeyUpload(httpClient, hostname, keyReader, opts.Title)
+ } else {
+ uploaded, err = SSHKeyUpload(httpClient, hostname, keyReader, opts.Title)
+ }
+
+ if err != nil {
+ return err
+ }
+
+ cs := opts.IO.ColorScheme()
+
+ if uploaded {
+ fmt.Fprintf(opts.IO.ErrOut, "%s Public key added to your account\n", cs.SuccessIcon())
+ } else {
+ fmt.Fprintf(opts.IO.ErrOut, "%s Public key already exists on your account\n", cs.SuccessIcon())
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/cmd/ssh-key/add/http.go b/vendor/github.com/cli/cli/v2/pkg/cmd/ssh-key/add/http.go
new file mode 100644
index 000000000..83aa77bdc
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/cmd/ssh-key/add/http.go
@@ -0,0 +1,127 @@
+package add
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "io"
+ "net/http"
+ "strings"
+
+ "github.com/cli/cli/v2/api"
+ "github.com/cli/cli/v2/internal/ghinstance"
+ "github.com/cli/cli/v2/pkg/cmd/ssh-key/shared"
+)
+
+// Uploads the provided SSH key. Returns true if the key was uploaded, false if it was not.
+func SSHKeyUpload(httpClient *http.Client, hostname string, keyFile io.Reader, title string) (bool, error) {
+ url := ghinstance.RESTPrefix(hostname) + "user/keys"
+
+ keyBytes, err := io.ReadAll(keyFile)
+ if err != nil {
+ return false, err
+ }
+
+ fullUserKey := string(keyBytes)
+ splitKey := strings.Fields(fullUserKey)
+ if len(splitKey) < 2 {
+ return false, errors.New("provided key is not in a valid format")
+ }
+
+ keyToCompare := splitKey[0] + " " + splitKey[1]
+
+ keys, err := shared.UserKeys(httpClient, hostname, "")
+ if err != nil {
+ return false, err
+ }
+
+ for _, k := range keys {
+ if k.Key == keyToCompare {
+ return false, nil
+ }
+ }
+
+ payload := map[string]string{
+ "title": title,
+ "key": fullUserKey,
+ }
+
+ err = keyUpload(httpClient, url, payload)
+
+ if err != nil {
+ return false, err
+ }
+
+ return true, nil
+}
+
+// Uploads the provided SSH Signing key. Returns true if the key was uploaded, false if it was not.
+func SSHSigningKeyUpload(httpClient *http.Client, hostname string, keyFile io.Reader, title string) (bool, error) {
+ url := ghinstance.RESTPrefix(hostname) + "user/ssh_signing_keys"
+
+ keyBytes, err := io.ReadAll(keyFile)
+ if err != nil {
+ return false, err
+ }
+
+ fullUserKey := string(keyBytes)
+ splitKey := strings.Fields(fullUserKey)
+ if len(splitKey) < 2 {
+ return false, errors.New("provided key is not in a valid format")
+ }
+
+ keyToCompare := splitKey[0] + " " + splitKey[1]
+
+ keys, err := shared.UserSigningKeys(httpClient, hostname, "")
+ if err != nil {
+ return false, err
+ }
+
+ for _, k := range keys {
+ if k.Key == keyToCompare {
+ return false, nil
+ }
+ }
+
+ payload := map[string]string{
+ "title": title,
+ "key": fullUserKey,
+ }
+
+ err = keyUpload(httpClient, url, payload)
+
+ if err != nil {
+ return false, err
+ }
+
+ return true, nil
+}
+
+func keyUpload(httpClient *http.Client, url string, payload map[string]string) error {
+ payloadBytes, err := json.Marshal(payload)
+ if err != nil {
+ return err
+ }
+
+ req, err := http.NewRequest("POST", url, bytes.NewBuffer(payloadBytes))
+ if err != nil {
+ return err
+ }
+
+ resp, err := httpClient.Do(req)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+
+ if resp.StatusCode > 299 {
+ return api.HandleHTTPError(resp)
+ }
+
+ _, err = io.Copy(io.Discard, resp.Body)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/cmd/ssh-key/shared/user_keys.go b/vendor/github.com/cli/cli/v2/pkg/cmd/ssh-key/shared/user_keys.go
new file mode 100644
index 000000000..035d00244
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/cmd/ssh-key/shared/user_keys.go
@@ -0,0 +1,95 @@
+package shared
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "time"
+
+ "github.com/cli/cli/v2/api"
+ "github.com/cli/cli/v2/internal/ghinstance"
+)
+
+const (
+ AuthenticationKey = "authentication"
+ SigningKey = "signing"
+)
+
+type sshKey struct {
+ ID int
+ Key string
+ Title string
+ Type string
+ CreatedAt time.Time `json:"created_at"`
+}
+
+func UserKeys(httpClient *http.Client, host, userHandle string) ([]sshKey, error) {
+ resource := "user/keys"
+ if userHandle != "" {
+ resource = fmt.Sprintf("users/%s/keys", userHandle)
+ }
+ url := fmt.Sprintf("%s%s?per_page=%d", ghinstance.RESTPrefix(host), resource, 100)
+
+ keys, err := getUserKeys(httpClient, url)
+
+ if err != nil {
+ return nil, err
+ }
+
+ for i := 0; i < len(keys); i++ {
+ keys[i].Type = AuthenticationKey
+ }
+
+ return keys, nil
+}
+
+func UserSigningKeys(httpClient *http.Client, host, userHandle string) ([]sshKey, error) {
+ resource := "user/ssh_signing_keys"
+ if userHandle != "" {
+ resource = fmt.Sprintf("users/%s/ssh_signing_keys", userHandle)
+ }
+ url := fmt.Sprintf("%s%s?per_page=%d", ghinstance.RESTPrefix(host), resource, 100)
+
+ keys, err := getUserKeys(httpClient, url)
+
+ if err != nil {
+ return nil, err
+ }
+
+ for i := 0; i < len(keys); i++ {
+ keys[i].Type = SigningKey
+ }
+
+ return keys, nil
+}
+
+func getUserKeys(httpClient *http.Client, url string) ([]sshKey, error) {
+ req, err := http.NewRequest("GET", url, nil)
+ if err != nil {
+ return nil, err
+ }
+
+ resp, err := httpClient.Do(req)
+ if err != nil {
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ if resp.StatusCode > 299 {
+ return nil, api.HandleHTTPError(resp)
+ }
+
+ b, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return nil, err
+ }
+
+ var keys []sshKey
+ err = json.Unmarshal(b, &keys)
+ if err != nil {
+ return nil, err
+ }
+
+ return keys, nil
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/cmdutil/args.go b/vendor/github.com/cli/cli/v2/pkg/cmdutil/args.go
new file mode 100644
index 000000000..0f03a07bd
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/cmdutil/args.go
@@ -0,0 +1,59 @@
+package cmdutil
+
+import (
+ "fmt"
+
+ "github.com/spf13/cobra"
+ "github.com/spf13/pflag"
+)
+
+func MinimumArgs(n int, msg string) cobra.PositionalArgs {
+ if msg == "" {
+ return cobra.MinimumNArgs(1)
+ }
+
+ return func(cmd *cobra.Command, args []string) error {
+ if len(args) < n {
+ return FlagErrorf("%s", msg)
+ }
+ return nil
+ }
+}
+
+func ExactArgs(n int, msg string) cobra.PositionalArgs {
+ return func(cmd *cobra.Command, args []string) error {
+ if len(args) > n {
+ return FlagErrorf("too many arguments")
+ }
+
+ if len(args) < n {
+ return FlagErrorf("%s", msg)
+ }
+
+ return nil
+ }
+}
+
+func NoArgsQuoteReminder(cmd *cobra.Command, args []string) error {
+ if len(args) < 1 {
+ return nil
+ }
+
+ errMsg := fmt.Sprintf("unknown argument %q", args[0])
+ if len(args) > 1 {
+ errMsg = fmt.Sprintf("unknown arguments %q", args)
+ }
+
+ hasValueFlag := false
+ cmd.Flags().Visit(func(f *pflag.Flag) {
+ if f.Value.Type() != "bool" {
+ hasValueFlag = true
+ }
+ })
+
+ if hasValueFlag {
+ errMsg += "; please quote all values that have spaces"
+ }
+
+ return FlagErrorf("%s", errMsg)
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/cmdutil/auth_check.go b/vendor/github.com/cli/cli/v2/pkg/cmdutil/auth_check.go
new file mode 100644
index 000000000..56ebb0c4d
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/cmdutil/auth_check.go
@@ -0,0 +1,41 @@
+package cmdutil
+
+import (
+ "github.com/cli/cli/v2/internal/config"
+ "github.com/spf13/cobra"
+)
+
+func DisableAuthCheck(cmd *cobra.Command) {
+ if cmd.Annotations == nil {
+ cmd.Annotations = map[string]string{}
+ }
+
+ cmd.Annotations["skipAuthCheck"] = "true"
+}
+
+func CheckAuth(cfg config.Config) bool {
+ if cfg.Authentication().HasEnvToken() {
+ return true
+ }
+
+ if len(cfg.Authentication().Hosts()) > 0 {
+ return true
+ }
+
+ return false
+}
+
+func IsAuthCheckEnabled(cmd *cobra.Command) bool {
+ switch cmd.Name() {
+ case "help", cobra.ShellCompRequestCmd, cobra.ShellCompNoDescRequestCmd:
+ return false
+ }
+
+ for c := cmd; c.Parent() != nil; c = c.Parent() {
+ if c.Annotations != nil && c.Annotations["skipAuthCheck"] == "true" {
+ return false
+ }
+ }
+
+ return true
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/cmdutil/cmdgroup.go b/vendor/github.com/cli/cli/v2/pkg/cmdutil/cmdgroup.go
new file mode 100644
index 000000000..e1b7b2362
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/cmdutil/cmdgroup.go
@@ -0,0 +1,15 @@
+package cmdutil
+
+import "github.com/spf13/cobra"
+
+func AddGroup(parent *cobra.Command, title string, cmds ...*cobra.Command) {
+ g := &cobra.Group{
+ Title: title,
+ ID: title,
+ }
+ parent.AddGroup(g)
+ for _, c := range cmds {
+ c.GroupID = g.ID
+ parent.AddCommand(c)
+ }
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/cmdutil/errors.go b/vendor/github.com/cli/cli/v2/pkg/cmdutil/errors.go
new file mode 100644
index 000000000..26a059d25
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/cmdutil/errors.go
@@ -0,0 +1,70 @@
+package cmdutil
+
+import (
+ "errors"
+ "fmt"
+
+ "github.com/AlecAivazis/survey/v2/terminal"
+)
+
+// FlagErrorf returns a new FlagError that wraps an error produced by
+// fmt.Errorf(format, args...).
+func FlagErrorf(format string, args ...interface{}) error {
+ return FlagErrorWrap(fmt.Errorf(format, args...))
+}
+
+// FlagError returns a new FlagError that wraps the specified error.
+func FlagErrorWrap(err error) error { return &FlagError{err} }
+
+// A *FlagError indicates an error processing command-line flags or other arguments.
+// Such errors cause the application to display the usage message.
+type FlagError struct {
+ // Note: not struct{error}: only *FlagError should satisfy error.
+ err error
+}
+
+func (fe *FlagError) Error() string {
+ return fe.err.Error()
+}
+
+func (fe *FlagError) Unwrap() error {
+ return fe.err
+}
+
+// SilentError is an error that triggers exit code 1 without any error messaging
+var SilentError = errors.New("SilentError")
+
+// CancelError signals user-initiated cancellation
+var CancelError = errors.New("CancelError")
+
+// PendingError signals nothing failed but something is pending
+var PendingError = errors.New("PendingError")
+
+func IsUserCancellation(err error) bool {
+ return errors.Is(err, CancelError) || errors.Is(err, terminal.InterruptErr)
+}
+
+func MutuallyExclusive(message string, conditions ...bool) error {
+ numTrue := 0
+ for _, ok := range conditions {
+ if ok {
+ numTrue++
+ }
+ }
+ if numTrue > 1 {
+ return FlagErrorf("%s", message)
+ }
+ return nil
+}
+
+type NoResultsError struct {
+ message string
+}
+
+func (e NoResultsError) Error() string {
+ return e.message
+}
+
+func NewNoResultsError(message string) NoResultsError {
+ return NoResultsError{message: message}
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/cmdutil/factory.go b/vendor/github.com/cli/cli/v2/pkg/cmdutil/factory.go
new file mode 100644
index 000000000..b48dceed3
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/cmdutil/factory.go
@@ -0,0 +1,100 @@
+package cmdutil
+
+import (
+ "net/http"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/cli/cli/v2/context"
+ "github.com/cli/cli/v2/git"
+ "github.com/cli/cli/v2/internal/browser"
+ "github.com/cli/cli/v2/internal/config"
+ "github.com/cli/cli/v2/internal/ghrepo"
+ "github.com/cli/cli/v2/internal/prompter"
+ "github.com/cli/cli/v2/pkg/extensions"
+ "github.com/cli/cli/v2/pkg/iostreams"
+)
+
+type Factory struct {
+ AppVersion string
+ ExecutableName string
+
+ Browser browser.Browser
+ ExtensionManager extensions.ExtensionManager
+ GitClient *git.Client
+ IOStreams *iostreams.IOStreams
+ Prompter prompter.Prompter
+
+ BaseRepo func() (ghrepo.Interface, error)
+ Branch func() (string, error)
+ Config func() (config.Config, error)
+ HttpClient func() (*http.Client, error)
+ Remotes func() (context.Remotes, error)
+}
+
+// Executable is the path to the currently invoked binary
+func (f *Factory) Executable() string {
+ ghPath := os.Getenv("GH_PATH")
+ if ghPath != "" {
+ return ghPath
+ }
+ if !strings.ContainsRune(f.ExecutableName, os.PathSeparator) {
+ f.ExecutableName = executable(f.ExecutableName)
+ }
+ return f.ExecutableName
+}
+
+// Finds the location of the executable for the current process as it's found in PATH, respecting symlinks.
+// If the process couldn't determine its location, return fallbackName. If the executable wasn't found in
+// PATH, return the absolute location to the program.
+//
+// The idea is that the result of this function is callable in the future and refers to the same
+// installation of gh, even across upgrades. This is needed primarily for Homebrew, which installs software
+// under a location such as `/usr/local/Cellar/gh/1.13.1/bin/gh` and symlinks it from `/usr/local/bin/gh`.
+// When the version is upgraded, Homebrew will often delete older versions, but keep the symlink. Because of
+// this, we want to refer to the `gh` binary as `/usr/local/bin/gh` and not as its internal Homebrew
+// location.
+//
+// None of this would be needed if we could just refer to GitHub CLI as `gh`, i.e. without using an absolute
+// path. However, for some reason Homebrew does not include `/usr/local/bin` in PATH when it invokes git
+// commands to update its taps. If `gh` (no path) is being used as git credential helper, as set up by `gh
+// auth login`, running `brew update` will print out authentication errors as git is unable to locate
+// Homebrew-installed `gh`.
+func executable(fallbackName string) string {
+ exe, err := os.Executable()
+ if err != nil {
+ return fallbackName
+ }
+
+ base := filepath.Base(exe)
+ path := os.Getenv("PATH")
+ for _, dir := range filepath.SplitList(path) {
+ p, err := filepath.Abs(filepath.Join(dir, base))
+ if err != nil {
+ continue
+ }
+ f, err := os.Lstat(p)
+ if err != nil {
+ continue
+ }
+
+ if p == exe {
+ return p
+ } else if f.Mode()&os.ModeSymlink != 0 {
+ realP, err := filepath.EvalSymlinks(p)
+ if err != nil {
+ continue
+ }
+ realExe, err := filepath.EvalSymlinks(exe)
+ if err != nil {
+ continue
+ }
+ if realP == realExe {
+ return p
+ }
+ }
+ }
+
+ return exe
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/cmdutil/file_input.go b/vendor/github.com/cli/cli/v2/pkg/cmdutil/file_input.go
new file mode 100644
index 000000000..e4cfd218a
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/cmdutil/file_input.go
@@ -0,0 +1,16 @@
+package cmdutil
+
+import (
+ "io"
+ "os"
+)
+
+func ReadFile(filename string, stdin io.ReadCloser) ([]byte, error) {
+ if filename == "-" {
+ b, err := io.ReadAll(stdin)
+ _ = stdin.Close()
+ return b, err
+ }
+
+ return os.ReadFile(filename)
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/cmdutil/flags.go b/vendor/github.com/cli/cli/v2/pkg/cmdutil/flags.go
new file mode 100644
index 000000000..c0064099c
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/cmdutil/flags.go
@@ -0,0 +1,182 @@
+package cmdutil
+
+import (
+ "context"
+ "fmt"
+ "strconv"
+ "strings"
+
+ "github.com/spf13/cobra"
+ "github.com/spf13/pflag"
+)
+
+// NilStringFlag defines a new flag with a string pointer receiver. This is useful for differentiating
+// between the flag being set to a blank value and the flag not being passed at all.
+func NilStringFlag(cmd *cobra.Command, p **string, name string, shorthand string, usage string) *pflag.Flag {
+ return cmd.Flags().VarPF(newStringValue(p), name, shorthand, usage)
+}
+
+// NilBoolFlag defines a new flag with a bool pointer receiver. This is useful for differentiating
+// between the flag being explicitly set to a false value and the flag not being passed at all.
+func NilBoolFlag(cmd *cobra.Command, p **bool, name string, shorthand string, usage string) *pflag.Flag {
+ f := cmd.Flags().VarPF(newBoolValue(p), name, shorthand, usage)
+ f.NoOptDefVal = "true"
+ return f
+}
+
+// StringEnumFlag defines a new string flag that only allows values listed in options.
+func StringEnumFlag(cmd *cobra.Command, p *string, name, shorthand, defaultValue string, options []string, usage string) *pflag.Flag {
+ *p = defaultValue
+ val := &enumValue{string: p, options: options}
+ f := cmd.Flags().VarPF(val, name, shorthand, fmt.Sprintf("%s: %s", usage, formatValuesForUsageDocs(options)))
+ _ = cmd.RegisterFlagCompletionFunc(name, func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+ return options, cobra.ShellCompDirectiveNoFileComp
+ })
+ return f
+}
+
+func StringSliceEnumFlag(cmd *cobra.Command, p *[]string, name, shorthand string, defaultValues, options []string, usage string) *pflag.Flag {
+ *p = defaultValues
+ val := &enumMultiValue{value: p, options: options}
+ f := cmd.Flags().VarPF(val, name, shorthand, fmt.Sprintf("%s: %s", usage, formatValuesForUsageDocs(options)))
+ _ = cmd.RegisterFlagCompletionFunc(name, func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+ return options, cobra.ShellCompDirectiveNoFileComp
+ })
+ return f
+}
+
+type gitClient interface {
+ TrackingBranchNames(context.Context, string) []string
+}
+
+// RegisterBranchCompletionFlags suggests and autocompletes known remote git branches for flags passed
+func RegisterBranchCompletionFlags(gitc gitClient, cmd *cobra.Command, flags ...string) error {
+ for _, flag := range flags {
+ err := cmd.RegisterFlagCompletionFunc(flag, func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+ if repoFlag := cmd.Flag("repo"); repoFlag != nil && repoFlag.Changed {
+ return nil, cobra.ShellCompDirectiveNoFileComp
+ }
+ return gitc.TrackingBranchNames(context.TODO(), toComplete), cobra.ShellCompDirectiveNoFileComp
+ })
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func formatValuesForUsageDocs(values []string) string {
+ return fmt.Sprintf("{%s}", strings.Join(values, "|"))
+}
+
+type stringValue struct {
+ string **string
+}
+
+func newStringValue(p **string) *stringValue {
+ return &stringValue{p}
+}
+
+func (s *stringValue) Set(value string) error {
+ *s.string = &value
+ return nil
+}
+
+func (s *stringValue) String() string {
+ if s.string == nil || *s.string == nil {
+ return ""
+ }
+ return **s.string
+}
+
+func (s *stringValue) Type() string {
+ return "string"
+}
+
+type boolValue struct {
+ bool **bool
+}
+
+func newBoolValue(p **bool) *boolValue {
+ return &boolValue{p}
+}
+
+func (b *boolValue) Set(value string) error {
+ v, err := strconv.ParseBool(value)
+ *b.bool = &v
+ return err
+}
+
+func (b *boolValue) String() string {
+ if b.bool == nil || *b.bool == nil {
+ return "false"
+ } else if **b.bool {
+ return "true"
+ }
+ return "false"
+}
+
+func (b *boolValue) Type() string {
+ return "bool"
+}
+
+func (b *boolValue) IsBoolFlag() bool {
+ return true
+}
+
+type enumValue struct {
+ string *string
+ options []string
+}
+
+func (e *enumValue) Set(value string) error {
+ if !isIncluded(value, e.options) {
+ return fmt.Errorf("valid values are %s", formatValuesForUsageDocs(e.options))
+ }
+ *e.string = value
+ return nil
+}
+
+func (e *enumValue) String() string {
+ return *e.string
+}
+
+func (e *enumValue) Type() string {
+ return "string"
+}
+
+type enumMultiValue struct {
+ value *[]string
+ options []string
+}
+
+func (e *enumMultiValue) Set(value string) error {
+ items := strings.Split(value, ",")
+ for _, item := range items {
+ if !isIncluded(item, e.options) {
+ return fmt.Errorf("valid values are %s", formatValuesForUsageDocs(e.options))
+ }
+ }
+ *e.value = append(*e.value, items...)
+ return nil
+}
+
+func (e *enumMultiValue) String() string {
+ if len(*e.value) == 0 {
+ return ""
+ }
+ return fmt.Sprintf("{%s}", strings.Join(*e.value, ", "))
+}
+
+func (e *enumMultiValue) Type() string {
+ return "stringSlice"
+}
+
+func isIncluded(value string, opts []string) bool {
+ for _, opt := range opts {
+ if strings.EqualFold(opt, value) {
+ return true
+ }
+ }
+ return false
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/cmdutil/json_flags.go b/vendor/github.com/cli/cli/v2/pkg/cmdutil/json_flags.go
new file mode 100644
index 000000000..bc3c242fe
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/cmdutil/json_flags.go
@@ -0,0 +1,297 @@
+package cmdutil
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "reflect"
+ "sort"
+ "strings"
+
+ "github.com/cli/cli/v2/pkg/iostreams"
+ "github.com/cli/cli/v2/pkg/jsoncolor"
+ "github.com/cli/cli/v2/pkg/set"
+ "github.com/cli/go-gh/v2/pkg/jq"
+ "github.com/cli/go-gh/v2/pkg/template"
+ "github.com/spf13/cobra"
+ "github.com/spf13/pflag"
+)
+
+type JSONFlagError struct {
+ error
+}
+
+func AddJSONFlags(cmd *cobra.Command, exportTarget *Exporter, fields []string) {
+ f := cmd.Flags()
+ f.StringSlice("json", nil, "Output JSON with the specified `fields`")
+ f.StringP("jq", "q", "", "Filter JSON output using a jq `expression`")
+ f.StringP("template", "t", "", "Format JSON output using a Go template; see \"gh help formatting\"")
+
+ _ = cmd.RegisterFlagCompletionFunc("json", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+ var results []string
+ var prefix string
+ if idx := strings.LastIndexByte(toComplete, ','); idx >= 0 {
+ prefix = toComplete[:idx+1]
+ toComplete = toComplete[idx+1:]
+ }
+ toComplete = strings.ToLower(toComplete)
+ for _, f := range fields {
+ if strings.HasPrefix(strings.ToLower(f), toComplete) {
+ results = append(results, prefix+f)
+ }
+ }
+ sort.Strings(results)
+ return results, cobra.ShellCompDirectiveNoSpace
+ })
+
+ oldPreRun := cmd.PreRunE
+ cmd.PreRunE = func(c *cobra.Command, args []string) error {
+ if oldPreRun != nil {
+ if err := oldPreRun(c, args); err != nil {
+ return err
+ }
+ }
+ if export, err := checkJSONFlags(c); err == nil {
+ if export == nil {
+ *exportTarget = nil
+ } else {
+ allowedFields := set.NewStringSet()
+ allowedFields.AddValues(fields)
+ for _, f := range export.fields {
+ if !allowedFields.Contains(f) {
+ sort.Strings(fields)
+ return JSONFlagError{fmt.Errorf("Unknown JSON field: %q\nAvailable fields:\n %s", f, strings.Join(fields, "\n "))}
+ }
+ }
+ *exportTarget = export
+ }
+ } else {
+ return err
+ }
+ return nil
+ }
+
+ cmd.SetFlagErrorFunc(func(c *cobra.Command, e error) error {
+ if c == cmd && e.Error() == "flag needs an argument: --json" {
+ sort.Strings(fields)
+ return JSONFlagError{fmt.Errorf("Specify one or more comma-separated fields for `--json`:\n %s", strings.Join(fields, "\n "))}
+ }
+ if cmd.HasParent() {
+ return cmd.Parent().FlagErrorFunc()(c, e)
+ }
+ return e
+ })
+}
+
+func checkJSONFlags(cmd *cobra.Command) (*jsonExporter, error) {
+ f := cmd.Flags()
+ jsonFlag := f.Lookup("json")
+ jqFlag := f.Lookup("jq")
+ tplFlag := f.Lookup("template")
+ webFlag := f.Lookup("web")
+
+ if jsonFlag.Changed {
+ if webFlag != nil && webFlag.Changed {
+ return nil, errors.New("cannot use `--web` with `--json`")
+ }
+ jv := jsonFlag.Value.(pflag.SliceValue)
+ return &jsonExporter{
+ fields: jv.GetSlice(),
+ filter: jqFlag.Value.String(),
+ template: tplFlag.Value.String(),
+ }, nil
+ } else if jqFlag.Changed {
+ return nil, errors.New("cannot use `--jq` without specifying `--json`")
+ } else if tplFlag.Changed {
+ return nil, errors.New("cannot use `--template` without specifying `--json`")
+ }
+ return nil, nil
+}
+
+func AddFormatFlags(cmd *cobra.Command, exportTarget *Exporter) {
+ var format string
+ StringEnumFlag(cmd, &format, "format", "", "", []string{"json"}, "Output format")
+ f := cmd.Flags()
+ f.StringP("jq", "q", "", "Filter JSON output using a jq `expression`")
+ f.StringP("template", "t", "", "Format JSON output using a Go template; see \"gh help formatting\"")
+
+ oldPreRun := cmd.PreRunE
+ cmd.PreRunE = func(c *cobra.Command, args []string) error {
+ if oldPreRun != nil {
+ if err := oldPreRun(c, args); err != nil {
+ return err
+ }
+ }
+
+ if export, err := checkFormatFlags(c); err == nil {
+ if export == nil {
+ *exportTarget = nil
+ } else {
+ *exportTarget = export
+ }
+ } else {
+ return err
+ }
+ return nil
+ }
+}
+
+func checkFormatFlags(cmd *cobra.Command) (*jsonExporter, error) {
+ f := cmd.Flags()
+ formatFlag := f.Lookup("format")
+ formatValue := formatFlag.Value.String()
+ jqFlag := f.Lookup("jq")
+ tplFlag := f.Lookup("template")
+ webFlag := f.Lookup("web")
+
+ if formatFlag.Changed {
+ if webFlag != nil && webFlag.Changed {
+ return nil, errors.New("cannot use `--web` with `--format`")
+ }
+ return &jsonExporter{
+ filter: jqFlag.Value.String(),
+ template: tplFlag.Value.String(),
+ }, nil
+ } else if jqFlag.Changed && formatValue != "json" {
+ return nil, errors.New("cannot use `--jq` without specifying `--format json`")
+ } else if tplFlag.Changed && formatValue != "json" {
+ return nil, errors.New("cannot use `--template` without specifying `--format json`")
+ }
+ return nil, nil
+}
+
+type Exporter interface {
+ Fields() []string
+ Write(io *iostreams.IOStreams, data interface{}) error
+}
+
+type jsonExporter struct {
+ fields []string
+ filter string
+ template string
+}
+
+// NewJSONExporter returns an Exporter to emit JSON.
+func NewJSONExporter() *jsonExporter {
+ return &jsonExporter{}
+}
+
+func (e *jsonExporter) Fields() []string {
+ return e.fields
+}
+
+func (e *jsonExporter) SetFields(fields []string) {
+ e.fields = fields
+}
+
+// Write serializes data into JSON output written to w. If the object passed as data implements exportable,
+// or if data is a map or slice of exportable object, ExportData() will be called on each object to obtain
+// raw data for serialization.
+func (e *jsonExporter) Write(ios *iostreams.IOStreams, data interface{}) error {
+ buf := bytes.Buffer{}
+ encoder := json.NewEncoder(&buf)
+ encoder.SetEscapeHTML(false)
+ if err := encoder.Encode(e.exportData(reflect.ValueOf(data))); err != nil {
+ return err
+ }
+
+ w := ios.Out
+ if e.filter != "" {
+ indent := ""
+ if ios.IsStdoutTTY() {
+ indent = " "
+ }
+ if err := jq.EvaluateFormatted(&buf, w, e.filter, indent, ios.ColorEnabled()); err != nil {
+ return err
+ }
+ } else if e.template != "" {
+ t := template.New(w, ios.TerminalWidth(), ios.ColorEnabled())
+ if err := t.Parse(e.template); err != nil {
+ return err
+ }
+ if err := t.Execute(&buf); err != nil {
+ return err
+ }
+ return t.Flush()
+ } else if ios.ColorEnabled() {
+ return jsoncolor.Write(w, &buf, " ")
+ }
+
+ _, err := io.Copy(w, &buf)
+ return err
+}
+
+func (e *jsonExporter) exportData(v reflect.Value) interface{} {
+ switch v.Kind() {
+ case reflect.Ptr, reflect.Interface:
+ if !v.IsNil() {
+ return e.exportData(v.Elem())
+ }
+ case reflect.Slice:
+ a := make([]interface{}, v.Len())
+ for i := 0; i < v.Len(); i++ {
+ a[i] = e.exportData(v.Index(i))
+ }
+ return a
+ case reflect.Map:
+ t := reflect.MapOf(v.Type().Key(), emptyInterfaceType)
+ m := reflect.MakeMapWithSize(t, v.Len())
+ iter := v.MapRange()
+ for iter.Next() {
+ ve := reflect.ValueOf(e.exportData(iter.Value()))
+ m.SetMapIndex(iter.Key(), ve)
+ }
+ return m.Interface()
+ case reflect.Struct:
+ if v.CanAddr() && reflect.PtrTo(v.Type()).Implements(exportableType) {
+ ve := v.Addr().Interface().(exportable)
+ return ve.ExportData(e.fields)
+ } else if v.Type().Implements(exportableType) {
+ ve := v.Interface().(exportable)
+ return ve.ExportData(e.fields)
+ }
+ }
+ return v.Interface()
+}
+
+type exportable interface {
+ ExportData([]string) map[string]interface{}
+}
+
+var exportableType = reflect.TypeOf((*exportable)(nil)).Elem()
+var sliceOfEmptyInterface []interface{}
+var emptyInterfaceType = reflect.TypeOf(sliceOfEmptyInterface).Elem()
+
+// Basic function that can be used with structs that need to implement
+// the exportable interface. It has numerous limitations so verify
+// that it works as expected with the struct and fields you want to export.
+// If it does not, then implementing a custom ExportData method is necessary.
+// Perhaps this should be moved up into exportData for the case when
+// a struct does not implement the exportable interface, but for now it will
+// need to be explicitly used.
+func StructExportData(s interface{}, fields []string) map[string]interface{} {
+ v := reflect.ValueOf(s)
+ if v.Kind() == reflect.Ptr {
+ v = v.Elem()
+ }
+ if v.Kind() != reflect.Struct {
+ // If s is not a struct or pointer to a struct return nil.
+ return nil
+ }
+ data := make(map[string]interface{}, len(fields))
+ for _, f := range fields {
+ sf := fieldByName(v, f)
+ if sf.IsValid() && sf.CanInterface() {
+ data[f] = sf.Interface()
+ }
+ }
+ return data
+}
+
+func fieldByName(v reflect.Value, field string) reflect.Value {
+ return v.FieldByNameFunc(func(s string) bool {
+ return strings.EqualFold(field, s)
+ })
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/cmdutil/legacy.go b/vendor/github.com/cli/cli/v2/pkg/cmdutil/legacy.go
new file mode 100644
index 000000000..1f247d4e6
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/cmdutil/legacy.go
@@ -0,0 +1,23 @@
+package cmdutil
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/cli/cli/v2/internal/config"
+)
+
+// TODO: consider passing via Factory
+// TODO: support per-hostname settings
+func DetermineEditor(cf func() (config.Config, error)) (string, error) {
+ editorCommand := os.Getenv("GH_EDITOR")
+ if editorCommand == "" {
+ cfg, err := cf()
+ if err != nil {
+ return "", fmt.Errorf("could not read config: %w", err)
+ }
+ editorCommand = cfg.Editor("")
+ }
+
+ return editorCommand, nil
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/cmdutil/repo_override.go b/vendor/github.com/cli/cli/v2/pkg/cmdutil/repo_override.go
new file mode 100644
index 000000000..791dd919a
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/cmdutil/repo_override.go
@@ -0,0 +1,70 @@
+package cmdutil
+
+import (
+ "os"
+ "sort"
+ "strings"
+
+ "github.com/cli/cli/v2/internal/ghrepo"
+ "github.com/spf13/cobra"
+)
+
+func executeParentHooks(cmd *cobra.Command, args []string) error {
+ for cmd.HasParent() {
+ cmd = cmd.Parent()
+ if cmd.PersistentPreRunE != nil {
+ return cmd.PersistentPreRunE(cmd, args)
+ }
+ }
+ return nil
+}
+
+func EnableRepoOverride(cmd *cobra.Command, f *Factory) {
+ cmd.PersistentFlags().StringP("repo", "R", "", "Select another repository using the `[HOST/]OWNER/REPO` format")
+ _ = cmd.RegisterFlagCompletionFunc("repo", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+ remotes, err := f.Remotes()
+ if err != nil {
+ return nil, cobra.ShellCompDirectiveError
+ }
+
+ config, err := f.Config()
+ if err != nil {
+ return nil, cobra.ShellCompDirectiveError
+ }
+ defaultHost, _ := config.Authentication().DefaultHost()
+
+ var results []string
+ for _, remote := range remotes {
+ repo := remote.RepoOwner() + "/" + remote.RepoName()
+ if !strings.EqualFold(remote.RepoHost(), defaultHost) {
+ repo = remote.RepoHost() + "/" + repo
+ }
+ if strings.HasPrefix(repo, toComplete) {
+ results = append(results, repo)
+ }
+ }
+ sort.Strings(results)
+ return results, cobra.ShellCompDirectiveNoFileComp
+ })
+
+ cmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
+ if err := executeParentHooks(cmd, args); err != nil {
+ return err
+ }
+ repoOverride, _ := cmd.Flags().GetString("repo")
+ f.BaseRepo = OverrideBaseRepoFunc(f, repoOverride)
+ return nil
+ }
+}
+
+func OverrideBaseRepoFunc(f *Factory, override string) func() (ghrepo.Interface, error) {
+ if override == "" {
+ override = os.Getenv("GH_REPO")
+ }
+ if override != "" {
+ return func() (ghrepo.Interface, error) {
+ return ghrepo.FromFullName(override)
+ }
+ }
+ return f.BaseRepo
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/extensions/extension.go b/vendor/github.com/cli/cli/v2/pkg/extensions/extension.go
new file mode 100644
index 000000000..0b94032df
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/extensions/extension.go
@@ -0,0 +1,41 @@
+package extensions
+
+import (
+ "io"
+
+ "github.com/cli/cli/v2/internal/ghrepo"
+)
+
+type ExtTemplateType int
+
+const (
+ GitTemplateType ExtTemplateType = 0
+ GoBinTemplateType ExtTemplateType = 1
+ OtherBinTemplateType ExtTemplateType = 2
+)
+
+//go:generate moq -rm -out extension_mock.go . Extension
+type Extension interface {
+ Name() string // Extension Name without gh-
+ Path() string // Path to executable
+ URL() string
+ CurrentVersion() string
+ LatestVersion() string
+ IsPinned() bool
+ UpdateAvailable() bool
+ IsBinary() bool
+ IsLocal() bool
+ Owner() string
+}
+
+//go:generate moq -rm -out manager_mock.go . ExtensionManager
+type ExtensionManager interface {
+ List() []Extension
+ Install(ghrepo.Interface, string) error
+ InstallLocal(dir string) error
+ Upgrade(name string, force bool) error
+ Remove(name string) error
+ Dispatch(args []string, stdin io.Reader, stdout, stderr io.Writer) (bool, error)
+ Create(name string, tmplType ExtTemplateType) error
+ EnableDryRunMode()
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/extensions/extension_mock.go b/vendor/github.com/cli/cli/v2/pkg/extensions/extension_mock.go
new file mode 100644
index 000000000..9b473e20a
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/extensions/extension_mock.go
@@ -0,0 +1,400 @@
+// Code generated by moq; DO NOT EDIT.
+// github.com/matryer/moq
+
+package extensions
+
+import (
+ "sync"
+)
+
+// Ensure, that ExtensionMock does implement Extension.
+// If this is not the case, regenerate this file with moq.
+var _ Extension = &ExtensionMock{}
+
+// ExtensionMock is a mock implementation of Extension.
+//
+// func TestSomethingThatUsesExtension(t *testing.T) {
+//
+// // make and configure a mocked Extension
+// mockedExtension := &ExtensionMock{
+// CurrentVersionFunc: func() string {
+// panic("mock out the CurrentVersion method")
+// },
+// IsBinaryFunc: func() bool {
+// panic("mock out the IsBinary method")
+// },
+// IsLocalFunc: func() bool {
+// panic("mock out the IsLocal method")
+// },
+// IsPinnedFunc: func() bool {
+// panic("mock out the IsPinned method")
+// },
+// LatestVersionFunc: func() string {
+// panic("mock out the LatestVersion method")
+// },
+// NameFunc: func() string {
+// panic("mock out the Name method")
+// },
+// OwnerFunc: func() string {
+// panic("mock out the Owner method")
+// },
+// PathFunc: func() string {
+// panic("mock out the Path method")
+// },
+// URLFunc: func() string {
+// panic("mock out the URL method")
+// },
+// UpdateAvailableFunc: func() bool {
+// panic("mock out the UpdateAvailable method")
+// },
+// }
+//
+// // use mockedExtension in code that requires Extension
+// // and then make assertions.
+//
+// }
+type ExtensionMock struct {
+ // CurrentVersionFunc mocks the CurrentVersion method.
+ CurrentVersionFunc func() string
+
+ // IsBinaryFunc mocks the IsBinary method.
+ IsBinaryFunc func() bool
+
+ // IsLocalFunc mocks the IsLocal method.
+ IsLocalFunc func() bool
+
+ // IsPinnedFunc mocks the IsPinned method.
+ IsPinnedFunc func() bool
+
+ // LatestVersionFunc mocks the LatestVersion method.
+ LatestVersionFunc func() string
+
+ // NameFunc mocks the Name method.
+ NameFunc func() string
+
+ // OwnerFunc mocks the Owner method.
+ OwnerFunc func() string
+
+ // PathFunc mocks the Path method.
+ PathFunc func() string
+
+ // URLFunc mocks the URL method.
+ URLFunc func() string
+
+ // UpdateAvailableFunc mocks the UpdateAvailable method.
+ UpdateAvailableFunc func() bool
+
+ // calls tracks calls to the methods.
+ calls struct {
+ // CurrentVersion holds details about calls to the CurrentVersion method.
+ CurrentVersion []struct {
+ }
+ // IsBinary holds details about calls to the IsBinary method.
+ IsBinary []struct {
+ }
+ // IsLocal holds details about calls to the IsLocal method.
+ IsLocal []struct {
+ }
+ // IsPinned holds details about calls to the IsPinned method.
+ IsPinned []struct {
+ }
+ // LatestVersion holds details about calls to the LatestVersion method.
+ LatestVersion []struct {
+ }
+ // Name holds details about calls to the Name method.
+ Name []struct {
+ }
+ // Owner holds details about calls to the Owner method.
+ Owner []struct {
+ }
+ // Path holds details about calls to the Path method.
+ Path []struct {
+ }
+ // URL holds details about calls to the URL method.
+ URL []struct {
+ }
+ // UpdateAvailable holds details about calls to the UpdateAvailable method.
+ UpdateAvailable []struct {
+ }
+ }
+ lockCurrentVersion sync.RWMutex
+ lockIsBinary sync.RWMutex
+ lockIsLocal sync.RWMutex
+ lockIsPinned sync.RWMutex
+ lockLatestVersion sync.RWMutex
+ lockName sync.RWMutex
+ lockOwner sync.RWMutex
+ lockPath sync.RWMutex
+ lockURL sync.RWMutex
+ lockUpdateAvailable sync.RWMutex
+}
+
+// CurrentVersion calls CurrentVersionFunc.
+func (mock *ExtensionMock) CurrentVersion() string {
+ if mock.CurrentVersionFunc == nil {
+ panic("ExtensionMock.CurrentVersionFunc: method is nil but Extension.CurrentVersion was just called")
+ }
+ callInfo := struct {
+ }{}
+ mock.lockCurrentVersion.Lock()
+ mock.calls.CurrentVersion = append(mock.calls.CurrentVersion, callInfo)
+ mock.lockCurrentVersion.Unlock()
+ return mock.CurrentVersionFunc()
+}
+
+// CurrentVersionCalls gets all the calls that were made to CurrentVersion.
+// Check the length with:
+//
+// len(mockedExtension.CurrentVersionCalls())
+func (mock *ExtensionMock) CurrentVersionCalls() []struct {
+} {
+ var calls []struct {
+ }
+ mock.lockCurrentVersion.RLock()
+ calls = mock.calls.CurrentVersion
+ mock.lockCurrentVersion.RUnlock()
+ return calls
+}
+
+// IsBinary calls IsBinaryFunc.
+func (mock *ExtensionMock) IsBinary() bool {
+ if mock.IsBinaryFunc == nil {
+ panic("ExtensionMock.IsBinaryFunc: method is nil but Extension.IsBinary was just called")
+ }
+ callInfo := struct {
+ }{}
+ mock.lockIsBinary.Lock()
+ mock.calls.IsBinary = append(mock.calls.IsBinary, callInfo)
+ mock.lockIsBinary.Unlock()
+ return mock.IsBinaryFunc()
+}
+
+// IsBinaryCalls gets all the calls that were made to IsBinary.
+// Check the length with:
+//
+// len(mockedExtension.IsBinaryCalls())
+func (mock *ExtensionMock) IsBinaryCalls() []struct {
+} {
+ var calls []struct {
+ }
+ mock.lockIsBinary.RLock()
+ calls = mock.calls.IsBinary
+ mock.lockIsBinary.RUnlock()
+ return calls
+}
+
+// IsLocal calls IsLocalFunc.
+func (mock *ExtensionMock) IsLocal() bool {
+ if mock.IsLocalFunc == nil {
+ panic("ExtensionMock.IsLocalFunc: method is nil but Extension.IsLocal was just called")
+ }
+ callInfo := struct {
+ }{}
+ mock.lockIsLocal.Lock()
+ mock.calls.IsLocal = append(mock.calls.IsLocal, callInfo)
+ mock.lockIsLocal.Unlock()
+ return mock.IsLocalFunc()
+}
+
+// IsLocalCalls gets all the calls that were made to IsLocal.
+// Check the length with:
+//
+// len(mockedExtension.IsLocalCalls())
+func (mock *ExtensionMock) IsLocalCalls() []struct {
+} {
+ var calls []struct {
+ }
+ mock.lockIsLocal.RLock()
+ calls = mock.calls.IsLocal
+ mock.lockIsLocal.RUnlock()
+ return calls
+}
+
+// IsPinned calls IsPinnedFunc.
+func (mock *ExtensionMock) IsPinned() bool {
+ if mock.IsPinnedFunc == nil {
+ panic("ExtensionMock.IsPinnedFunc: method is nil but Extension.IsPinned was just called")
+ }
+ callInfo := struct {
+ }{}
+ mock.lockIsPinned.Lock()
+ mock.calls.IsPinned = append(mock.calls.IsPinned, callInfo)
+ mock.lockIsPinned.Unlock()
+ return mock.IsPinnedFunc()
+}
+
+// IsPinnedCalls gets all the calls that were made to IsPinned.
+// Check the length with:
+//
+// len(mockedExtension.IsPinnedCalls())
+func (mock *ExtensionMock) IsPinnedCalls() []struct {
+} {
+ var calls []struct {
+ }
+ mock.lockIsPinned.RLock()
+ calls = mock.calls.IsPinned
+ mock.lockIsPinned.RUnlock()
+ return calls
+}
+
+// LatestVersion calls LatestVersionFunc.
+func (mock *ExtensionMock) LatestVersion() string {
+ if mock.LatestVersionFunc == nil {
+ panic("ExtensionMock.LatestVersionFunc: method is nil but Extension.LatestVersion was just called")
+ }
+ callInfo := struct {
+ }{}
+ mock.lockLatestVersion.Lock()
+ mock.calls.LatestVersion = append(mock.calls.LatestVersion, callInfo)
+ mock.lockLatestVersion.Unlock()
+ return mock.LatestVersionFunc()
+}
+
+// LatestVersionCalls gets all the calls that were made to LatestVersion.
+// Check the length with:
+//
+// len(mockedExtension.LatestVersionCalls())
+func (mock *ExtensionMock) LatestVersionCalls() []struct {
+} {
+ var calls []struct {
+ }
+ mock.lockLatestVersion.RLock()
+ calls = mock.calls.LatestVersion
+ mock.lockLatestVersion.RUnlock()
+ return calls
+}
+
+// Name calls NameFunc.
+func (mock *ExtensionMock) Name() string {
+ if mock.NameFunc == nil {
+ panic("ExtensionMock.NameFunc: method is nil but Extension.Name was just called")
+ }
+ callInfo := struct {
+ }{}
+ mock.lockName.Lock()
+ mock.calls.Name = append(mock.calls.Name, callInfo)
+ mock.lockName.Unlock()
+ return mock.NameFunc()
+}
+
+// NameCalls gets all the calls that were made to Name.
+// Check the length with:
+//
+// len(mockedExtension.NameCalls())
+func (mock *ExtensionMock) NameCalls() []struct {
+} {
+ var calls []struct {
+ }
+ mock.lockName.RLock()
+ calls = mock.calls.Name
+ mock.lockName.RUnlock()
+ return calls
+}
+
+// Owner calls OwnerFunc.
+func (mock *ExtensionMock) Owner() string {
+ if mock.OwnerFunc == nil {
+ panic("ExtensionMock.OwnerFunc: method is nil but Extension.Owner was just called")
+ }
+ callInfo := struct {
+ }{}
+ mock.lockOwner.Lock()
+ mock.calls.Owner = append(mock.calls.Owner, callInfo)
+ mock.lockOwner.Unlock()
+ return mock.OwnerFunc()
+}
+
+// OwnerCalls gets all the calls that were made to Owner.
+// Check the length with:
+//
+// len(mockedExtension.OwnerCalls())
+func (mock *ExtensionMock) OwnerCalls() []struct {
+} {
+ var calls []struct {
+ }
+ mock.lockOwner.RLock()
+ calls = mock.calls.Owner
+ mock.lockOwner.RUnlock()
+ return calls
+}
+
+// Path calls PathFunc.
+func (mock *ExtensionMock) Path() string {
+ if mock.PathFunc == nil {
+ panic("ExtensionMock.PathFunc: method is nil but Extension.Path was just called")
+ }
+ callInfo := struct {
+ }{}
+ mock.lockPath.Lock()
+ mock.calls.Path = append(mock.calls.Path, callInfo)
+ mock.lockPath.Unlock()
+ return mock.PathFunc()
+}
+
+// PathCalls gets all the calls that were made to Path.
+// Check the length with:
+//
+// len(mockedExtension.PathCalls())
+func (mock *ExtensionMock) PathCalls() []struct {
+} {
+ var calls []struct {
+ }
+ mock.lockPath.RLock()
+ calls = mock.calls.Path
+ mock.lockPath.RUnlock()
+ return calls
+}
+
+// URL calls URLFunc.
+func (mock *ExtensionMock) URL() string {
+ if mock.URLFunc == nil {
+ panic("ExtensionMock.URLFunc: method is nil but Extension.URL was just called")
+ }
+ callInfo := struct {
+ }{}
+ mock.lockURL.Lock()
+ mock.calls.URL = append(mock.calls.URL, callInfo)
+ mock.lockURL.Unlock()
+ return mock.URLFunc()
+}
+
+// URLCalls gets all the calls that were made to URL.
+// Check the length with:
+//
+// len(mockedExtension.URLCalls())
+func (mock *ExtensionMock) URLCalls() []struct {
+} {
+ var calls []struct {
+ }
+ mock.lockURL.RLock()
+ calls = mock.calls.URL
+ mock.lockURL.RUnlock()
+ return calls
+}
+
+// UpdateAvailable calls UpdateAvailableFunc.
+func (mock *ExtensionMock) UpdateAvailable() bool {
+ if mock.UpdateAvailableFunc == nil {
+ panic("ExtensionMock.UpdateAvailableFunc: method is nil but Extension.UpdateAvailable was just called")
+ }
+ callInfo := struct {
+ }{}
+ mock.lockUpdateAvailable.Lock()
+ mock.calls.UpdateAvailable = append(mock.calls.UpdateAvailable, callInfo)
+ mock.lockUpdateAvailable.Unlock()
+ return mock.UpdateAvailableFunc()
+}
+
+// UpdateAvailableCalls gets all the calls that were made to UpdateAvailable.
+// Check the length with:
+//
+// len(mockedExtension.UpdateAvailableCalls())
+func (mock *ExtensionMock) UpdateAvailableCalls() []struct {
+} {
+ var calls []struct {
+ }
+ mock.lockUpdateAvailable.RLock()
+ calls = mock.calls.UpdateAvailable
+ mock.lockUpdateAvailable.RUnlock()
+ return calls
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/extensions/manager_mock.go b/vendor/github.com/cli/cli/v2/pkg/extensions/manager_mock.go
new file mode 100644
index 000000000..962444f2b
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/extensions/manager_mock.go
@@ -0,0 +1,406 @@
+// Code generated by moq; DO NOT EDIT.
+// github.com/matryer/moq
+
+package extensions
+
+import (
+ "github.com/cli/cli/v2/internal/ghrepo"
+ "io"
+ "sync"
+)
+
+// Ensure, that ExtensionManagerMock does implement ExtensionManager.
+// If this is not the case, regenerate this file with moq.
+var _ ExtensionManager = &ExtensionManagerMock{}
+
+// ExtensionManagerMock is a mock implementation of ExtensionManager.
+//
+// func TestSomethingThatUsesExtensionManager(t *testing.T) {
+//
+// // make and configure a mocked ExtensionManager
+// mockedExtensionManager := &ExtensionManagerMock{
+// CreateFunc: func(name string, tmplType ExtTemplateType) error {
+// panic("mock out the Create method")
+// },
+// DispatchFunc: func(args []string, stdin io.Reader, stdout io.Writer, stderr io.Writer) (bool, error) {
+// panic("mock out the Dispatch method")
+// },
+// EnableDryRunModeFunc: func() {
+// panic("mock out the EnableDryRunMode method")
+// },
+// InstallFunc: func(interfaceMoqParam ghrepo.Interface, s string) error {
+// panic("mock out the Install method")
+// },
+// InstallLocalFunc: func(dir string) error {
+// panic("mock out the InstallLocal method")
+// },
+// ListFunc: func() []Extension {
+// panic("mock out the List method")
+// },
+// RemoveFunc: func(name string) error {
+// panic("mock out the Remove method")
+// },
+// UpgradeFunc: func(name string, force bool) error {
+// panic("mock out the Upgrade method")
+// },
+// }
+//
+// // use mockedExtensionManager in code that requires ExtensionManager
+// // and then make assertions.
+//
+// }
+type ExtensionManagerMock struct {
+ // CreateFunc mocks the Create method.
+ CreateFunc func(name string, tmplType ExtTemplateType) error
+
+ // DispatchFunc mocks the Dispatch method.
+ DispatchFunc func(args []string, stdin io.Reader, stdout io.Writer, stderr io.Writer) (bool, error)
+
+ // EnableDryRunModeFunc mocks the EnableDryRunMode method.
+ EnableDryRunModeFunc func()
+
+ // InstallFunc mocks the Install method.
+ InstallFunc func(interfaceMoqParam ghrepo.Interface, s string) error
+
+ // InstallLocalFunc mocks the InstallLocal method.
+ InstallLocalFunc func(dir string) error
+
+ // ListFunc mocks the List method.
+ ListFunc func() []Extension
+
+ // RemoveFunc mocks the Remove method.
+ RemoveFunc func(name string) error
+
+ // UpgradeFunc mocks the Upgrade method.
+ UpgradeFunc func(name string, force bool) error
+
+ // calls tracks calls to the methods.
+ calls struct {
+ // Create holds details about calls to the Create method.
+ Create []struct {
+ // Name is the name argument value.
+ Name string
+ // TmplType is the tmplType argument value.
+ TmplType ExtTemplateType
+ }
+ // Dispatch holds details about calls to the Dispatch method.
+ Dispatch []struct {
+ // Args is the args argument value.
+ Args []string
+ // Stdin is the stdin argument value.
+ Stdin io.Reader
+ // Stdout is the stdout argument value.
+ Stdout io.Writer
+ // Stderr is the stderr argument value.
+ Stderr io.Writer
+ }
+ // EnableDryRunMode holds details about calls to the EnableDryRunMode method.
+ EnableDryRunMode []struct {
+ }
+ // Install holds details about calls to the Install method.
+ Install []struct {
+ // InterfaceMoqParam is the interfaceMoqParam argument value.
+ InterfaceMoqParam ghrepo.Interface
+ // S is the s argument value.
+ S string
+ }
+ // InstallLocal holds details about calls to the InstallLocal method.
+ InstallLocal []struct {
+ // Dir is the dir argument value.
+ Dir string
+ }
+ // List holds details about calls to the List method.
+ List []struct {
+ }
+ // Remove holds details about calls to the Remove method.
+ Remove []struct {
+ // Name is the name argument value.
+ Name string
+ }
+ // Upgrade holds details about calls to the Upgrade method.
+ Upgrade []struct {
+ // Name is the name argument value.
+ Name string
+ // Force is the force argument value.
+ Force bool
+ }
+ }
+ lockCreate sync.RWMutex
+ lockDispatch sync.RWMutex
+ lockEnableDryRunMode sync.RWMutex
+ lockInstall sync.RWMutex
+ lockInstallLocal sync.RWMutex
+ lockList sync.RWMutex
+ lockRemove sync.RWMutex
+ lockUpgrade sync.RWMutex
+}
+
+// Create calls CreateFunc.
+func (mock *ExtensionManagerMock) Create(name string, tmplType ExtTemplateType) error {
+ if mock.CreateFunc == nil {
+ panic("ExtensionManagerMock.CreateFunc: method is nil but ExtensionManager.Create was just called")
+ }
+ callInfo := struct {
+ Name string
+ TmplType ExtTemplateType
+ }{
+ Name: name,
+ TmplType: tmplType,
+ }
+ mock.lockCreate.Lock()
+ mock.calls.Create = append(mock.calls.Create, callInfo)
+ mock.lockCreate.Unlock()
+ return mock.CreateFunc(name, tmplType)
+}
+
+// CreateCalls gets all the calls that were made to Create.
+// Check the length with:
+//
+// len(mockedExtensionManager.CreateCalls())
+func (mock *ExtensionManagerMock) CreateCalls() []struct {
+ Name string
+ TmplType ExtTemplateType
+} {
+ var calls []struct {
+ Name string
+ TmplType ExtTemplateType
+ }
+ mock.lockCreate.RLock()
+ calls = mock.calls.Create
+ mock.lockCreate.RUnlock()
+ return calls
+}
+
+// Dispatch calls DispatchFunc.
+func (mock *ExtensionManagerMock) Dispatch(args []string, stdin io.Reader, stdout io.Writer, stderr io.Writer) (bool, error) {
+ if mock.DispatchFunc == nil {
+ panic("ExtensionManagerMock.DispatchFunc: method is nil but ExtensionManager.Dispatch was just called")
+ }
+ callInfo := struct {
+ Args []string
+ Stdin io.Reader
+ Stdout io.Writer
+ Stderr io.Writer
+ }{
+ Args: args,
+ Stdin: stdin,
+ Stdout: stdout,
+ Stderr: stderr,
+ }
+ mock.lockDispatch.Lock()
+ mock.calls.Dispatch = append(mock.calls.Dispatch, callInfo)
+ mock.lockDispatch.Unlock()
+ return mock.DispatchFunc(args, stdin, stdout, stderr)
+}
+
+// DispatchCalls gets all the calls that were made to Dispatch.
+// Check the length with:
+//
+// len(mockedExtensionManager.DispatchCalls())
+func (mock *ExtensionManagerMock) DispatchCalls() []struct {
+ Args []string
+ Stdin io.Reader
+ Stdout io.Writer
+ Stderr io.Writer
+} {
+ var calls []struct {
+ Args []string
+ Stdin io.Reader
+ Stdout io.Writer
+ Stderr io.Writer
+ }
+ mock.lockDispatch.RLock()
+ calls = mock.calls.Dispatch
+ mock.lockDispatch.RUnlock()
+ return calls
+}
+
+// EnableDryRunMode calls EnableDryRunModeFunc.
+func (mock *ExtensionManagerMock) EnableDryRunMode() {
+ if mock.EnableDryRunModeFunc == nil {
+ panic("ExtensionManagerMock.EnableDryRunModeFunc: method is nil but ExtensionManager.EnableDryRunMode was just called")
+ }
+ callInfo := struct {
+ }{}
+ mock.lockEnableDryRunMode.Lock()
+ mock.calls.EnableDryRunMode = append(mock.calls.EnableDryRunMode, callInfo)
+ mock.lockEnableDryRunMode.Unlock()
+ mock.EnableDryRunModeFunc()
+}
+
+// EnableDryRunModeCalls gets all the calls that were made to EnableDryRunMode.
+// Check the length with:
+//
+// len(mockedExtensionManager.EnableDryRunModeCalls())
+func (mock *ExtensionManagerMock) EnableDryRunModeCalls() []struct {
+} {
+ var calls []struct {
+ }
+ mock.lockEnableDryRunMode.RLock()
+ calls = mock.calls.EnableDryRunMode
+ mock.lockEnableDryRunMode.RUnlock()
+ return calls
+}
+
+// Install calls InstallFunc.
+func (mock *ExtensionManagerMock) Install(interfaceMoqParam ghrepo.Interface, s string) error {
+ if mock.InstallFunc == nil {
+ panic("ExtensionManagerMock.InstallFunc: method is nil but ExtensionManager.Install was just called")
+ }
+ callInfo := struct {
+ InterfaceMoqParam ghrepo.Interface
+ S string
+ }{
+ InterfaceMoqParam: interfaceMoqParam,
+ S: s,
+ }
+ mock.lockInstall.Lock()
+ mock.calls.Install = append(mock.calls.Install, callInfo)
+ mock.lockInstall.Unlock()
+ return mock.InstallFunc(interfaceMoqParam, s)
+}
+
+// InstallCalls gets all the calls that were made to Install.
+// Check the length with:
+//
+// len(mockedExtensionManager.InstallCalls())
+func (mock *ExtensionManagerMock) InstallCalls() []struct {
+ InterfaceMoqParam ghrepo.Interface
+ S string
+} {
+ var calls []struct {
+ InterfaceMoqParam ghrepo.Interface
+ S string
+ }
+ mock.lockInstall.RLock()
+ calls = mock.calls.Install
+ mock.lockInstall.RUnlock()
+ return calls
+}
+
+// InstallLocal calls InstallLocalFunc.
+func (mock *ExtensionManagerMock) InstallLocal(dir string) error {
+ if mock.InstallLocalFunc == nil {
+ panic("ExtensionManagerMock.InstallLocalFunc: method is nil but ExtensionManager.InstallLocal was just called")
+ }
+ callInfo := struct {
+ Dir string
+ }{
+ Dir: dir,
+ }
+ mock.lockInstallLocal.Lock()
+ mock.calls.InstallLocal = append(mock.calls.InstallLocal, callInfo)
+ mock.lockInstallLocal.Unlock()
+ return mock.InstallLocalFunc(dir)
+}
+
+// InstallLocalCalls gets all the calls that were made to InstallLocal.
+// Check the length with:
+//
+// len(mockedExtensionManager.InstallLocalCalls())
+func (mock *ExtensionManagerMock) InstallLocalCalls() []struct {
+ Dir string
+} {
+ var calls []struct {
+ Dir string
+ }
+ mock.lockInstallLocal.RLock()
+ calls = mock.calls.InstallLocal
+ mock.lockInstallLocal.RUnlock()
+ return calls
+}
+
+// List calls ListFunc.
+func (mock *ExtensionManagerMock) List() []Extension {
+ if mock.ListFunc == nil {
+ panic("ExtensionManagerMock.ListFunc: method is nil but ExtensionManager.List was just called")
+ }
+ callInfo := struct {
+ }{}
+ mock.lockList.Lock()
+ mock.calls.List = append(mock.calls.List, callInfo)
+ mock.lockList.Unlock()
+ return mock.ListFunc()
+}
+
+// ListCalls gets all the calls that were made to List.
+// Check the length with:
+//
+// len(mockedExtensionManager.ListCalls())
+func (mock *ExtensionManagerMock) ListCalls() []struct {
+} {
+ var calls []struct {
+ }
+ mock.lockList.RLock()
+ calls = mock.calls.List
+ mock.lockList.RUnlock()
+ return calls
+}
+
+// Remove calls RemoveFunc.
+func (mock *ExtensionManagerMock) Remove(name string) error {
+ if mock.RemoveFunc == nil {
+ panic("ExtensionManagerMock.RemoveFunc: method is nil but ExtensionManager.Remove was just called")
+ }
+ callInfo := struct {
+ Name string
+ }{
+ Name: name,
+ }
+ mock.lockRemove.Lock()
+ mock.calls.Remove = append(mock.calls.Remove, callInfo)
+ mock.lockRemove.Unlock()
+ return mock.RemoveFunc(name)
+}
+
+// RemoveCalls gets all the calls that were made to Remove.
+// Check the length with:
+//
+// len(mockedExtensionManager.RemoveCalls())
+func (mock *ExtensionManagerMock) RemoveCalls() []struct {
+ Name string
+} {
+ var calls []struct {
+ Name string
+ }
+ mock.lockRemove.RLock()
+ calls = mock.calls.Remove
+ mock.lockRemove.RUnlock()
+ return calls
+}
+
+// Upgrade calls UpgradeFunc.
+func (mock *ExtensionManagerMock) Upgrade(name string, force bool) error {
+ if mock.UpgradeFunc == nil {
+ panic("ExtensionManagerMock.UpgradeFunc: method is nil but ExtensionManager.Upgrade was just called")
+ }
+ callInfo := struct {
+ Name string
+ Force bool
+ }{
+ Name: name,
+ Force: force,
+ }
+ mock.lockUpgrade.Lock()
+ mock.calls.Upgrade = append(mock.calls.Upgrade, callInfo)
+ mock.lockUpgrade.Unlock()
+ return mock.UpgradeFunc(name, force)
+}
+
+// UpgradeCalls gets all the calls that were made to Upgrade.
+// Check the length with:
+//
+// len(mockedExtensionManager.UpgradeCalls())
+func (mock *ExtensionManagerMock) UpgradeCalls() []struct {
+ Name string
+ Force bool
+} {
+ var calls []struct {
+ Name string
+ Force bool
+ }
+ mock.lockUpgrade.RLock()
+ calls = mock.calls.Upgrade
+ mock.lockUpgrade.RUnlock()
+ return calls
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/iostreams/color.go b/vendor/github.com/cli/cli/v2/pkg/iostreams/color.go
new file mode 100644
index 000000000..804b9a275
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/iostreams/color.go
@@ -0,0 +1,226 @@
+package iostreams
+
+import (
+ "fmt"
+ "strconv"
+ "strings"
+
+ "github.com/mgutz/ansi"
+)
+
+var (
+ magenta = ansi.ColorFunc("magenta")
+ cyan = ansi.ColorFunc("cyan")
+ red = ansi.ColorFunc("red")
+ yellow = ansi.ColorFunc("yellow")
+ blue = ansi.ColorFunc("blue")
+ green = ansi.ColorFunc("green")
+ gray = ansi.ColorFunc("black+h")
+ lightGrayUnderline = ansi.ColorFunc("white+du")
+ bold = ansi.ColorFunc("default+b")
+ cyanBold = ansi.ColorFunc("cyan+b")
+ greenBold = ansi.ColorFunc("green+b")
+
+ gray256 = func(t string) string {
+ return fmt.Sprintf("\x1b[%d;5;%dm%s\x1b[m", 38, 242, t)
+ }
+)
+
+func NewColorScheme(enabled, is256enabled bool, trueColor bool) *ColorScheme {
+ return &ColorScheme{
+ enabled: enabled,
+ is256enabled: is256enabled,
+ hasTrueColor: trueColor,
+ }
+}
+
+type ColorScheme struct {
+ enabled bool
+ is256enabled bool
+ hasTrueColor bool
+}
+
+func (c *ColorScheme) Enabled() bool {
+ return c.enabled
+}
+
+func (c *ColorScheme) Bold(t string) string {
+ if !c.enabled {
+ return t
+ }
+ return bold(t)
+}
+
+func (c *ColorScheme) Boldf(t string, args ...interface{}) string {
+ return c.Bold(fmt.Sprintf(t, args...))
+}
+
+func (c *ColorScheme) Red(t string) string {
+ if !c.enabled {
+ return t
+ }
+ return red(t)
+}
+
+func (c *ColorScheme) Redf(t string, args ...interface{}) string {
+ return c.Red(fmt.Sprintf(t, args...))
+}
+
+func (c *ColorScheme) Yellow(t string) string {
+ if !c.enabled {
+ return t
+ }
+ return yellow(t)
+}
+
+func (c *ColorScheme) Yellowf(t string, args ...interface{}) string {
+ return c.Yellow(fmt.Sprintf(t, args...))
+}
+
+func (c *ColorScheme) Green(t string) string {
+ if !c.enabled {
+ return t
+ }
+ return green(t)
+}
+
+func (c *ColorScheme) Greenf(t string, args ...interface{}) string {
+ return c.Green(fmt.Sprintf(t, args...))
+}
+
+func (c *ColorScheme) GreenBold(t string) string {
+ if !c.enabled {
+ return t
+ }
+ return greenBold(t)
+}
+
+func (c *ColorScheme) Gray(t string) string {
+ if !c.enabled {
+ return t
+ }
+ if c.is256enabled {
+ return gray256(t)
+ }
+ return gray(t)
+}
+
+func (c *ColorScheme) Grayf(t string, args ...interface{}) string {
+ return c.Gray(fmt.Sprintf(t, args...))
+}
+
+func (c *ColorScheme) LightGrayUnderline(t string) string {
+ if !c.enabled {
+ return t
+ }
+ return lightGrayUnderline(t)
+}
+
+func (c *ColorScheme) Magenta(t string) string {
+ if !c.enabled {
+ return t
+ }
+ return magenta(t)
+}
+
+func (c *ColorScheme) Magentaf(t string, args ...interface{}) string {
+ return c.Magenta(fmt.Sprintf(t, args...))
+}
+
+func (c *ColorScheme) Cyan(t string) string {
+ if !c.enabled {
+ return t
+ }
+ return cyan(t)
+}
+
+func (c *ColorScheme) Cyanf(t string, args ...interface{}) string {
+ return c.Cyan(fmt.Sprintf(t, args...))
+}
+
+func (c *ColorScheme) CyanBold(t string) string {
+ if !c.enabled {
+ return t
+ }
+ return cyanBold(t)
+}
+
+func (c *ColorScheme) Blue(t string) string {
+ if !c.enabled {
+ return t
+ }
+ return blue(t)
+}
+
+func (c *ColorScheme) Bluef(t string, args ...interface{}) string {
+ return c.Blue(fmt.Sprintf(t, args...))
+}
+
+func (c *ColorScheme) SuccessIcon() string {
+ return c.SuccessIconWithColor(c.Green)
+}
+
+func (c *ColorScheme) SuccessIconWithColor(colo func(string) string) string {
+ return colo("✓")
+}
+
+func (c *ColorScheme) WarningIcon() string {
+ return c.Yellow("!")
+}
+
+func (c *ColorScheme) FailureIcon() string {
+ return c.FailureIconWithColor(c.Red)
+}
+
+func (c *ColorScheme) FailureIconWithColor(colo func(string) string) string {
+ return colo("X")
+}
+
+func (c *ColorScheme) ColorFromString(s string) func(string) string {
+ s = strings.ToLower(s)
+ var fn func(string) string
+ switch s {
+ case "bold":
+ fn = c.Bold
+ case "red":
+ fn = c.Red
+ case "yellow":
+ fn = c.Yellow
+ case "green":
+ fn = c.Green
+ case "gray":
+ fn = c.Gray
+ case "magenta":
+ fn = c.Magenta
+ case "cyan":
+ fn = c.Cyan
+ case "blue":
+ fn = c.Blue
+ default:
+ fn = func(s string) string {
+ return s
+ }
+ }
+
+ return fn
+}
+
+// ColorFromRGB returns a function suitable for TablePrinter.AddField
+// that calls HexToRGB, coloring text if supported by the terminal.
+func (c *ColorScheme) ColorFromRGB(hex string) func(string) string {
+ return func(s string) string {
+ return c.HexToRGB(hex, s)
+ }
+}
+
+// HexToRGB uses the given hex to color x if supported by the terminal.
+func (c *ColorScheme) HexToRGB(hex string, x string) string {
+ if !c.enabled || !c.hasTrueColor || len(hex) != 6 {
+ return x
+ }
+
+ r, _ := strconv.ParseInt(hex[0:2], 16, 64)
+ g, _ := strconv.ParseInt(hex[2:4], 16, 64)
+ b, _ := strconv.ParseInt(hex[4:6], 16, 64)
+ return fmt.Sprintf("\033[38;2;%d;%d;%dm%s\033[0m", r, g, b, x)
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/iostreams/console.go b/vendor/github.com/cli/cli/v2/pkg/iostreams/console.go
new file mode 100644
index 000000000..89bdd1daa
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/iostreams/console.go
@@ -0,0 +1,11 @@
+//go:build !windows
+// +build !windows
+
+package iostreams
+
+import "os"
+
+func hasAlternateScreenBuffer(hasTrueColor bool) bool {
+ // on non-Windows, we just assume that alternate screen buffer is supported in most cases
+ return os.Getenv("TERM") != "dumb"
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/iostreams/console_windows.go b/vendor/github.com/cli/cli/v2/pkg/iostreams/console_windows.go
new file mode 100644
index 000000000..ee0238e49
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/iostreams/console_windows.go
@@ -0,0 +1,10 @@
+//go:build windows
+// +build windows
+
+package iostreams
+
+func hasAlternateScreenBuffer(hasTrueColor bool) bool {
+ // on Windows we just assume that alternate screen buffer is supported if we
+ // enabled virtual terminal processing, which in turn enables truecolor
+ return hasTrueColor
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/iostreams/epipe_other.go b/vendor/github.com/cli/cli/v2/pkg/iostreams/epipe_other.go
new file mode 100644
index 000000000..a8a4e0476
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/iostreams/epipe_other.go
@@ -0,0 +1,13 @@
+//go:build !windows
+// +build !windows
+
+package iostreams
+
+import (
+ "errors"
+ "syscall"
+)
+
+func isEpipeError(err error) bool {
+ return errors.Is(err, syscall.EPIPE)
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/iostreams/epipe_windows.go b/vendor/github.com/cli/cli/v2/pkg/iostreams/epipe_windows.go
new file mode 100644
index 000000000..69815cb15
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/iostreams/epipe_windows.go
@@ -0,0 +1,11 @@
+package iostreams
+
+import (
+ "errors"
+ "syscall"
+)
+
+func isEpipeError(err error) bool {
+ // 232 is Windows error code ERROR_NO_DATA, "The pipe is being closed".
+ return errors.Is(err, syscall.Errno(232))
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/iostreams/iostreams.go b/vendor/github.com/cli/cli/v2/pkg/iostreams/iostreams.go
new file mode 100644
index 000000000..be057c494
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/iostreams/iostreams.go
@@ -0,0 +1,535 @@
+package iostreams
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "os/exec"
+ "os/signal"
+ "strings"
+ "sync"
+ "time"
+
+ "github.com/briandowns/spinner"
+ ghTerm "github.com/cli/go-gh/v2/pkg/term"
+ "github.com/cli/safeexec"
+ "github.com/google/shlex"
+ "github.com/mattn/go-colorable"
+ "github.com/mattn/go-isatty"
+)
+
+const DefaultWidth = 80
+
+// ErrClosedPagerPipe is the error returned when writing to a pager that has been closed.
+type ErrClosedPagerPipe struct {
+ error
+}
+
+type fileWriter interface {
+ io.Writer
+ Fd() uintptr
+}
+
+type fileReader interface {
+ io.ReadCloser
+ Fd() uintptr
+}
+
+type term interface {
+ IsTerminalOutput() bool
+ IsColorEnabled() bool
+ Is256ColorSupported() bool
+ IsTrueColorSupported() bool
+ Theme() string
+ Size() (int, int, error)
+}
+
+type IOStreams struct {
+ term term
+
+ In fileReader
+ Out fileWriter
+ ErrOut fileWriter
+
+ terminalTheme string
+
+ progressIndicatorEnabled bool
+ progressIndicator *spinner.Spinner
+ progressIndicatorMu sync.Mutex
+
+ alternateScreenBufferEnabled bool
+ alternateScreenBufferActive bool
+ alternateScreenBufferMu sync.Mutex
+
+ stdinTTYOverride bool
+ stdinIsTTY bool
+ stdoutTTYOverride bool
+ stdoutIsTTY bool
+ stderrTTYOverride bool
+ stderrIsTTY bool
+
+ colorOverride bool
+ colorEnabled bool
+
+ pagerCommand string
+ pagerProcess *os.Process
+
+ neverPrompt bool
+
+ TempFileOverride *os.File
+}
+
+func (s *IOStreams) ColorEnabled() bool {
+ if s.colorOverride {
+ return s.colorEnabled
+ }
+ return s.term.IsColorEnabled()
+}
+
+func (s *IOStreams) ColorSupport256() bool {
+ if s.colorOverride {
+ return s.colorEnabled
+ }
+ return s.term.Is256ColorSupported()
+}
+
+func (s *IOStreams) HasTrueColor() bool {
+ if s.colorOverride {
+ return s.colorEnabled
+ }
+ return s.term.IsTrueColorSupported()
+}
+
+// DetectTerminalTheme is a utility to call before starting the output pager so that the terminal background
+// can be reliably detected.
+func (s *IOStreams) DetectTerminalTheme() {
+ if !s.ColorEnabled() || s.pagerProcess != nil {
+ s.terminalTheme = "none"
+ return
+ }
+
+ style := os.Getenv("GLAMOUR_STYLE")
+ if style != "" && style != "auto" {
+ // ensure GLAMOUR_STYLE takes precedence over "light" and "dark" themes
+ s.terminalTheme = "none"
+ return
+ }
+
+ s.terminalTheme = s.term.Theme()
+}
+
+// TerminalTheme returns "light", "dark", or "none" depending on the background color of the terminal.
+func (s *IOStreams) TerminalTheme() string {
+ if s.terminalTheme == "" {
+ s.DetectTerminalTheme()
+ }
+
+ return s.terminalTheme
+}
+
+func (s *IOStreams) SetColorEnabled(colorEnabled bool) {
+ s.colorOverride = true
+ s.colorEnabled = colorEnabled
+}
+
+func (s *IOStreams) SetStdinTTY(isTTY bool) {
+ s.stdinTTYOverride = true
+ s.stdinIsTTY = isTTY
+}
+
+func (s *IOStreams) IsStdinTTY() bool {
+ if s.stdinTTYOverride {
+ return s.stdinIsTTY
+ }
+ if stdin, ok := s.In.(*os.File); ok {
+ return isTerminal(stdin)
+ }
+ return false
+}
+
+func (s *IOStreams) SetStdoutTTY(isTTY bool) {
+ s.stdoutTTYOverride = true
+ s.stdoutIsTTY = isTTY
+}
+
+func (s *IOStreams) IsStdoutTTY() bool {
+ if s.stdoutTTYOverride {
+ return s.stdoutIsTTY
+ }
+ // support GH_FORCE_TTY
+ if s.term.IsTerminalOutput() {
+ return true
+ }
+ stdout, ok := s.Out.(*os.File)
+ return ok && isCygwinTerminal(stdout.Fd())
+}
+
+func (s *IOStreams) SetStderrTTY(isTTY bool) {
+ s.stderrTTYOverride = true
+ s.stderrIsTTY = isTTY
+}
+
+func (s *IOStreams) IsStderrTTY() bool {
+ if s.stderrTTYOverride {
+ return s.stderrIsTTY
+ }
+ if stderr, ok := s.ErrOut.(*os.File); ok {
+ return isTerminal(stderr)
+ }
+ return false
+}
+
+func (s *IOStreams) SetPager(cmd string) {
+ s.pagerCommand = cmd
+}
+
+func (s *IOStreams) GetPager() string {
+ return s.pagerCommand
+}
+
+func (s *IOStreams) StartPager() error {
+ if s.pagerCommand == "" || s.pagerCommand == "cat" || !s.IsStdoutTTY() {
+ return nil
+ }
+
+ pagerArgs, err := shlex.Split(s.pagerCommand)
+ if err != nil {
+ return err
+ }
+
+ pagerEnv := os.Environ()
+ for i := len(pagerEnv) - 1; i >= 0; i-- {
+ if strings.HasPrefix(pagerEnv[i], "PAGER=") {
+ pagerEnv = append(pagerEnv[0:i], pagerEnv[i+1:]...)
+ }
+ }
+ if _, ok := os.LookupEnv("LESS"); !ok {
+ pagerEnv = append(pagerEnv, "LESS=FRX")
+ }
+ if _, ok := os.LookupEnv("LV"); !ok {
+ pagerEnv = append(pagerEnv, "LV=-c")
+ }
+
+ pagerExe, err := safeexec.LookPath(pagerArgs[0])
+ if err != nil {
+ return err
+ }
+ pagerCmd := exec.Command(pagerExe, pagerArgs[1:]...)
+ pagerCmd.Env = pagerEnv
+ pagerCmd.Stdout = s.Out
+ pagerCmd.Stderr = s.ErrOut
+ pagedOut, err := pagerCmd.StdinPipe()
+ if err != nil {
+ return err
+ }
+ s.Out = &fdWriteCloser{
+ fd: s.Out.Fd(),
+ WriteCloser: &pagerWriter{pagedOut},
+ }
+ err = pagerCmd.Start()
+ if err != nil {
+ return err
+ }
+ s.pagerProcess = pagerCmd.Process
+ return nil
+}
+
+func (s *IOStreams) StopPager() {
+ if s.pagerProcess == nil {
+ return
+ }
+
+ // if a pager was started, we're guaranteed to have a WriteCloser
+ _ = s.Out.(io.WriteCloser).Close()
+ _, _ = s.pagerProcess.Wait()
+ s.pagerProcess = nil
+}
+
+func (s *IOStreams) CanPrompt() bool {
+ if s.neverPrompt {
+ return false
+ }
+
+ return s.IsStdinTTY() && s.IsStdoutTTY()
+}
+
+func (s *IOStreams) GetNeverPrompt() bool {
+ return s.neverPrompt
+}
+
+func (s *IOStreams) SetNeverPrompt(v bool) {
+ s.neverPrompt = v
+}
+
+func (s *IOStreams) StartProgressIndicator() {
+ s.StartProgressIndicatorWithLabel("")
+}
+
+func (s *IOStreams) StartProgressIndicatorWithLabel(label string) {
+ if !s.progressIndicatorEnabled {
+ return
+ }
+
+ s.progressIndicatorMu.Lock()
+ defer s.progressIndicatorMu.Unlock()
+
+ if s.progressIndicator != nil {
+ if label == "" {
+ s.progressIndicator.Prefix = ""
+ } else {
+ s.progressIndicator.Prefix = label + " "
+ }
+ return
+ }
+
+ // https://github.com/briandowns/spinner#available-character-sets
+ dotStyle := spinner.CharSets[11]
+ sp := spinner.New(dotStyle, 120*time.Millisecond, spinner.WithWriter(s.ErrOut), spinner.WithColor("fgCyan"))
+ if label != "" {
+ sp.Prefix = label + " "
+ }
+
+ sp.Start()
+ s.progressIndicator = sp
+}
+
+func (s *IOStreams) StopProgressIndicator() {
+ s.progressIndicatorMu.Lock()
+ defer s.progressIndicatorMu.Unlock()
+ if s.progressIndicator == nil {
+ return
+ }
+ s.progressIndicator.Stop()
+ s.progressIndicator = nil
+}
+
+func (s *IOStreams) RunWithProgress(label string, run func() error) error {
+ s.StartProgressIndicatorWithLabel(label)
+ defer s.StopProgressIndicator()
+
+ return run()
+}
+
+func (s *IOStreams) StartAlternateScreenBuffer() {
+ if s.alternateScreenBufferEnabled {
+ s.alternateScreenBufferMu.Lock()
+ defer s.alternateScreenBufferMu.Unlock()
+
+ if _, err := fmt.Fprint(s.Out, "\x1b[?1049h"); err == nil {
+ s.alternateScreenBufferActive = true
+
+ ch := make(chan os.Signal, 1)
+ signal.Notify(ch, os.Interrupt)
+
+ go func() {
+ <-ch
+ s.StopAlternateScreenBuffer()
+
+ os.Exit(1)
+ }()
+ }
+ }
+}
+
+func (s *IOStreams) StopAlternateScreenBuffer() {
+ s.alternateScreenBufferMu.Lock()
+ defer s.alternateScreenBufferMu.Unlock()
+
+ if s.alternateScreenBufferActive {
+ fmt.Fprint(s.Out, "\x1b[?1049l")
+ s.alternateScreenBufferActive = false
+ }
+}
+
+func (s *IOStreams) SetAlternateScreenBufferEnabled(enabled bool) {
+ s.alternateScreenBufferEnabled = enabled
+}
+
+func (s *IOStreams) RefreshScreen() {
+ if s.IsStdoutTTY() {
+ // Move cursor to 0,0
+ fmt.Fprint(s.Out, "\x1b[0;0H")
+ // Clear from cursor to bottom of screen
+ fmt.Fprint(s.Out, "\x1b[J")
+ }
+}
+
+// TerminalWidth returns the width of the terminal that controls the process
+func (s *IOStreams) TerminalWidth() int {
+ w, _, err := s.term.Size()
+ if err == nil && w > 0 {
+ return w
+ }
+ return DefaultWidth
+}
+
+func (s *IOStreams) ColorScheme() *ColorScheme {
+ return NewColorScheme(s.ColorEnabled(), s.ColorSupport256(), s.HasTrueColor())
+}
+
+func (s *IOStreams) ReadUserFile(fn string) ([]byte, error) {
+ var r io.ReadCloser
+ if fn == "-" {
+ r = s.In
+ } else {
+ var err error
+ r, err = os.Open(fn)
+ if err != nil {
+ return nil, err
+ }
+ }
+ defer r.Close()
+ return io.ReadAll(r)
+}
+
+func (s *IOStreams) TempFile(dir, pattern string) (*os.File, error) {
+ if s.TempFileOverride != nil {
+ return s.TempFileOverride, nil
+ }
+ return os.CreateTemp(dir, pattern)
+}
+
+func System() *IOStreams {
+ terminal := ghTerm.FromEnv()
+
+ var stdout fileWriter = os.Stdout
+ // On Windows with no virtual terminal processing support, translate ANSI escape
+ // sequences to console syscalls.
+ if colorableStdout := colorable.NewColorable(os.Stdout); colorableStdout != os.Stdout {
+ // Ensure that the file descriptor of the original stdout is preserved.
+ stdout = &fdWriter{
+ fd: os.Stdout.Fd(),
+ Writer: colorableStdout,
+ }
+ }
+
+ var stderr fileWriter = os.Stderr
+ // On Windows with no virtual terminal processing support, translate ANSI escape
+ // sequences to console syscalls.
+ if colorableStderr := colorable.NewColorable(os.Stderr); colorableStderr != os.Stderr {
+ // Ensure that the file descriptor of the original stderr is preserved.
+ stderr = &fdWriter{
+ fd: os.Stderr.Fd(),
+ Writer: colorableStderr,
+ }
+ }
+
+ io := &IOStreams{
+ In: os.Stdin,
+ Out: stdout,
+ ErrOut: stderr,
+ pagerCommand: os.Getenv("PAGER"),
+ term: &terminal,
+ }
+
+ stdoutIsTTY := io.IsStdoutTTY()
+ stderrIsTTY := io.IsStderrTTY()
+
+ if stdoutIsTTY && stderrIsTTY {
+ io.progressIndicatorEnabled = true
+ }
+
+ if stdoutIsTTY && hasAlternateScreenBuffer(terminal.IsTrueColorSupported()) {
+ io.alternateScreenBufferEnabled = true
+ }
+
+ return io
+}
+
+type fakeTerm struct{}
+
+func (t fakeTerm) IsTerminalOutput() bool {
+ return false
+}
+
+func (t fakeTerm) IsColorEnabled() bool {
+ return false
+}
+
+func (t fakeTerm) Is256ColorSupported() bool {
+ return false
+}
+
+func (t fakeTerm) IsTrueColorSupported() bool {
+ return false
+}
+
+func (t fakeTerm) Theme() string {
+ return ""
+}
+
+func (t fakeTerm) Size() (int, int, error) {
+ return 80, -1, nil
+}
+
+func Test() (*IOStreams, *bytes.Buffer, *bytes.Buffer, *bytes.Buffer) {
+ in := &bytes.Buffer{}
+ out := &bytes.Buffer{}
+ errOut := &bytes.Buffer{}
+ io := &IOStreams{
+ In: &fdReader{
+ fd: 0,
+ ReadCloser: io.NopCloser(in),
+ },
+ Out: &fdWriter{fd: 1, Writer: out},
+ ErrOut: &fdWriter{fd: 2, Writer: errOut},
+ term: &fakeTerm{},
+ }
+ io.SetStdinTTY(false)
+ io.SetStdoutTTY(false)
+ io.SetStderrTTY(false)
+ return io, in, out, errOut
+}
+
+func isTerminal(f *os.File) bool {
+ return ghTerm.IsTerminal(f) || isCygwinTerminal(f.Fd())
+}
+
+func isCygwinTerminal(fd uintptr) bool {
+ return isatty.IsCygwinTerminal(fd)
+}
+
+// pagerWriter implements a WriteCloser that wraps all EPIPE errors in an ErrClosedPagerPipe type.
+type pagerWriter struct {
+ io.WriteCloser
+}
+
+func (w *pagerWriter) Write(d []byte) (int, error) {
+ n, err := w.WriteCloser.Write(d)
+ if err != nil && (errors.Is(err, io.ErrClosedPipe) || isEpipeError(err)) {
+ return n, &ErrClosedPagerPipe{err}
+ }
+ return n, err
+}
+
+// fdWriter represents a wrapped stdout Writer that preserves the original file descriptor
+type fdWriter struct {
+ io.Writer
+ fd uintptr
+}
+
+func (w *fdWriter) Fd() uintptr {
+ return w.fd
+}
+
+// fdWriteCloser represents a wrapped stdout Writer that preserves the original file descriptor
+type fdWriteCloser struct {
+ io.WriteCloser
+ fd uintptr
+}
+
+func (w *fdWriteCloser) Fd() uintptr {
+ return w.fd
+}
+
+// fdWriter represents a wrapped stdin ReadCloser that preserves the original file descriptor
+type fdReader struct {
+ io.ReadCloser
+ fd uintptr
+}
+
+func (r *fdReader) Fd() uintptr {
+ return r.fd
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/jsoncolor/jsoncolor.go b/vendor/github.com/cli/cli/v2/pkg/jsoncolor/jsoncolor.go
new file mode 100644
index 000000000..dbe3d9a4b
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/jsoncolor/jsoncolor.go
@@ -0,0 +1,113 @@
+package jsoncolor
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "io"
+ "strings"
+)
+
+const (
+ colorDelim = "1;38" // bright white
+ colorKey = "1;34" // bright blue
+ colorNull = "36" // cyan
+ colorString = "32" // green
+ colorBool = "33" // yellow
+)
+
+// Write colorized JSON output parsed from reader
+func Write(w io.Writer, r io.Reader, indent string) error {
+ dec := json.NewDecoder(r)
+ dec.UseNumber()
+
+ var idx int
+ var stack []json.Delim
+
+ for {
+ t, err := dec.Token()
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ return err
+ }
+
+ switch tt := t.(type) {
+ case json.Delim:
+ switch tt {
+ case '{', '[':
+ stack = append(stack, tt)
+ idx = 0
+ fmt.Fprintf(w, "\x1b[%sm%s\x1b[m", colorDelim, tt)
+ if dec.More() {
+ fmt.Fprint(w, "\n", strings.Repeat(indent, len(stack)))
+ }
+ continue
+ case '}', ']':
+ stack = stack[:len(stack)-1]
+ idx = 0
+ fmt.Fprintf(w, "\x1b[%sm%s\x1b[m", colorDelim, tt)
+ }
+ default:
+ b, err := marshalJSON(tt)
+ if err != nil {
+ return err
+ }
+
+ isKey := len(stack) > 0 && stack[len(stack)-1] == '{' && idx%2 == 0
+ idx++
+
+ var color string
+ if isKey {
+ color = colorKey
+ } else if tt == nil {
+ color = colorNull
+ } else {
+ switch t.(type) {
+ case string:
+ color = colorString
+ case bool:
+ color = colorBool
+ }
+ }
+
+ if color == "" {
+ _, _ = w.Write(b)
+ } else {
+ fmt.Fprintf(w, "\x1b[%sm%s\x1b[m", color, b)
+ }
+
+ if isKey {
+ fmt.Fprintf(w, "\x1b[%sm:\x1b[m ", colorDelim)
+ continue
+ }
+ }
+
+ if dec.More() {
+ fmt.Fprintf(w, "\x1b[%sm,\x1b[m\n%s", colorDelim, strings.Repeat(indent, len(stack)))
+ } else if len(stack) > 0 {
+ fmt.Fprint(w, "\n", strings.Repeat(indent, len(stack)-1))
+ } else {
+ fmt.Fprint(w, "\n")
+ }
+ }
+
+ return nil
+}
+
+// marshalJSON works like json.Marshal but with HTML-escaping disabled
+func marshalJSON(v interface{}) ([]byte, error) {
+ buf := bytes.Buffer{}
+ enc := json.NewEncoder(&buf)
+ enc.SetEscapeHTML(false)
+ if err := enc.Encode(v); err != nil {
+ return nil, err
+ }
+ bb := buf.Bytes()
+ // omit trailing newline added by json.Encoder
+ if len(bb) > 0 && bb[len(bb)-1] == '\n' {
+ return bb[:len(bb)-1], nil
+ }
+ return bb, nil
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/set/string_set.go b/vendor/github.com/cli/cli/v2/pkg/set/string_set.go
new file mode 100644
index 000000000..0bd679a8d
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/set/string_set.go
@@ -0,0 +1,84 @@
+package set
+
+var exists = struct{}{}
+
+type stringSet struct {
+ v []string
+ m map[string]struct{}
+}
+
+func NewStringSet() *stringSet {
+ s := &stringSet{}
+ s.m = make(map[string]struct{})
+ s.v = []string{}
+ return s
+}
+
+func (s *stringSet) Add(value string) {
+ if s.Contains(value) {
+ return
+ }
+ s.m[value] = exists
+ s.v = append(s.v, value)
+}
+
+func (s *stringSet) AddValues(values []string) {
+ for _, v := range values {
+ s.Add(v)
+ }
+}
+
+func (s *stringSet) Remove(value string) {
+ if !s.Contains(value) {
+ return
+ }
+ delete(s.m, value)
+ s.v = sliceWithout(s.v, value)
+}
+
+func sliceWithout(s []string, v string) []string {
+ idx := -1
+ for i, item := range s {
+ if item == v {
+ idx = i
+ break
+ }
+ }
+ if idx < 0 {
+ return s
+ }
+ return append(s[:idx], s[idx+1:]...)
+}
+
+func (s *stringSet) RemoveValues(values []string) {
+ for _, v := range values {
+ s.Remove(v)
+ }
+}
+
+func (s *stringSet) Contains(value string) bool {
+ _, c := s.m[value]
+ return c
+}
+
+func (s *stringSet) Len() int {
+ return len(s.m)
+}
+
+func (s *stringSet) ToSlice() []string {
+ return s.v
+}
+
+func (s1 *stringSet) Equal(s2 *stringSet) bool {
+ if s1.Len() != s2.Len() {
+ return false
+ }
+ isEqual := true
+ for _, v := range s1.v {
+ if !s2.Contains(v) {
+ isEqual = false
+ break
+ }
+ }
+ return isEqual
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/ssh/ssh_keys.go b/vendor/github.com/cli/cli/v2/pkg/ssh/ssh_keys.go
new file mode 100644
index 000000000..c750b608a
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/ssh/ssh_keys.go
@@ -0,0 +1,113 @@
+package ssh
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "runtime"
+
+ "github.com/cli/cli/v2/internal/config"
+ "github.com/cli/cli/v2/internal/run"
+ "github.com/cli/safeexec"
+)
+
+type Context struct {
+ ConfigDir string
+ KeygenExe string
+}
+
+type KeyPair struct {
+ PublicKeyPath string
+ PrivateKeyPath string
+}
+
+var ErrKeyAlreadyExists = errors.New("SSH key already exists")
+
+func (c *Context) LocalPublicKeys() ([]string, error) {
+ sshDir, err := c.sshDir()
+ if err != nil {
+ return nil, err
+ }
+
+ return filepath.Glob(filepath.Join(sshDir, "*.pub"))
+}
+
+func (c *Context) HasKeygen() bool {
+ _, err := c.findKeygen()
+ return err == nil
+}
+
+func (c *Context) GenerateSSHKey(keyName string, passphrase string) (*KeyPair, error) {
+ keygenExe, err := c.findKeygen()
+ if err != nil {
+ return nil, err
+ }
+
+ sshDir, err := c.sshDir()
+ if err != nil {
+ return nil, err
+ }
+
+ err = os.MkdirAll(sshDir, 0700)
+ if err != nil {
+ return nil, fmt.Errorf("could not create .ssh directory: %w", err)
+ }
+
+ keyFile := filepath.Join(sshDir, keyName)
+ keyPair := KeyPair{
+ PublicKeyPath: keyFile + ".pub",
+ PrivateKeyPath: keyFile,
+ }
+
+ if _, err := os.Stat(keyFile); err == nil {
+ // Still return keyPair because the caller might be OK with this - they can check the error with errors.Is(err, ErrKeyAlreadyExists)
+ return &keyPair, ErrKeyAlreadyExists
+ }
+
+ if err := os.MkdirAll(filepath.Dir(keyFile), 0711); err != nil {
+ return nil, err
+ }
+
+ keygenCmd := exec.Command(keygenExe, "-t", "ed25519", "-C", "", "-N", passphrase, "-f", keyFile)
+ err = run.PrepareCmd(keygenCmd).Run()
+ if err != nil {
+ return nil, err
+ }
+
+ return &keyPair, nil
+}
+
+func (c *Context) sshDir() (string, error) {
+ if c.ConfigDir != "" {
+ return c.ConfigDir, nil
+ }
+ dir, err := config.HomeDirPath(".ssh")
+ if err == nil {
+ c.ConfigDir = dir
+ }
+ return dir, err
+}
+
+func (c *Context) findKeygen() (string, error) {
+ if c.KeygenExe != "" {
+ return c.KeygenExe, nil
+ }
+
+ keygenExe, err := safeexec.LookPath("ssh-keygen")
+ if err != nil && runtime.GOOS == "windows" {
+ // We can try and find ssh-keygen in a Git for Windows install
+ if gitPath, err := safeexec.LookPath("git"); err == nil {
+ gitKeygen := filepath.Join(filepath.Dir(gitPath), "..", "usr", "bin", "ssh-keygen.exe")
+ if _, err = os.Stat(gitKeygen); err == nil {
+ return gitKeygen, nil
+ }
+ }
+ }
+
+ if err == nil {
+ c.KeygenExe = keygenExe
+ }
+ return keygenExe, err
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/surveyext/editor.go b/vendor/github.com/cli/cli/v2/pkg/surveyext/editor.go
new file mode 100644
index 000000000..420ecc4e5
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/surveyext/editor.go
@@ -0,0 +1,170 @@
+package surveyext
+
+// This file extends survey.Editor to give it more flexible behavior. For more context, read
+// https://github.com/cli/cli/issues/70
+// To see what we extended, search through for EXTENDED comments.
+
+import (
+ "os"
+ "path/filepath"
+ "runtime"
+
+ "github.com/AlecAivazis/survey/v2"
+ "github.com/AlecAivazis/survey/v2/terminal"
+ shellquote "github.com/kballard/go-shellquote"
+)
+
+var (
+ bom = []byte{0xef, 0xbb, 0xbf}
+ defaultEditor = "nano" // EXTENDED to switch from vim as a default editor
+)
+
+func init() {
+ if g := os.Getenv("GIT_EDITOR"); g != "" {
+ defaultEditor = g
+ } else if v := os.Getenv("VISUAL"); v != "" {
+ defaultEditor = v
+ } else if e := os.Getenv("EDITOR"); e != "" {
+ defaultEditor = e
+ } else if runtime.GOOS == "windows" {
+ defaultEditor = "notepad"
+ }
+}
+
+// EXTENDED to enable different prompting behavior
+type GhEditor struct {
+ *survey.Editor
+ EditorCommand string
+ BlankAllowed bool
+
+ lookPath func(string) ([]string, []string, error)
+}
+
+// EXTENDED to change prompt text
+var EditorQuestionTemplate = `
+{{- if .ShowHelp }}{{- color .Config.Icons.Help.Format }}{{ .Config.Icons.Help.Text }} {{ .Help }}{{color "reset"}}{{"\n"}}{{end}}
+{{- color .Config.Icons.Question.Format }}{{ .Config.Icons.Question.Text }} {{color "reset"}}
+{{- color "default+hb"}}{{ .Message }} {{color "reset"}}
+{{- if .ShowAnswer}}
+ {{- color "cyan"}}{{.Answer}}{{color "reset"}}{{"\n"}}
+{{- else }}
+ {{- if and .Help (not .ShowHelp)}}{{color "cyan"}}[{{ .Config.HelpInput }} for help]{{color "reset"}} {{end}}
+ {{- if and .Default (not .HideDefault)}}{{color "white"}}({{.Default}}) {{color "reset"}}{{end}}
+ {{- color "cyan"}}[(e) to launch {{ .EditorCommand }}{{- if .BlankAllowed }}, enter to skip{{ end }}] {{color "reset"}}
+{{- end}}`
+
+// EXTENDED to pass editor name (to use in prompt)
+type EditorTemplateData struct {
+ survey.Editor
+ EditorCommand string
+ BlankAllowed bool
+ Answer string
+ ShowAnswer bool
+ ShowHelp bool
+ Config *survey.PromptConfig
+}
+
+// EXTENDED to augment prompt text and keypress handling
+func (e *GhEditor) prompt(initialValue string, config *survey.PromptConfig) (interface{}, error) {
+ err := e.Render(
+ EditorQuestionTemplate,
+ // EXTENDED to support printing editor in prompt and BlankAllowed
+ EditorTemplateData{
+ Editor: *e.Editor,
+ BlankAllowed: e.BlankAllowed,
+ EditorCommand: EditorName(e.EditorCommand),
+ Config: config,
+ },
+ )
+ if err != nil {
+ return "", err
+ }
+
+ // start reading runes from the standard in
+ rr := e.NewRuneReader()
+ _ = rr.SetTermMode()
+ defer func() { _ = rr.RestoreTermMode() }()
+
+ cursor := e.NewCursor()
+ _ = cursor.Hide()
+ defer func() {
+ _ = cursor.Show()
+ }()
+
+ for {
+ // EXTENDED to handle the e to edit / enter to skip behavior + BlankAllowed
+ r, _, err := rr.ReadRune()
+ if err != nil {
+ return "", err
+ }
+ if r == 'e' {
+ break
+ }
+ if r == '\r' || r == '\n' {
+ if e.BlankAllowed {
+ return initialValue, nil
+ } else {
+ continue
+ }
+ }
+ if r == terminal.KeyInterrupt {
+ return "", terminal.InterruptErr
+ }
+ if r == terminal.KeyEndTransmission {
+ break
+ }
+ if string(r) == config.HelpInput && e.Help != "" {
+ err = e.Render(
+ EditorQuestionTemplate,
+ EditorTemplateData{
+ // EXTENDED to support printing editor in prompt, BlankAllowed
+ Editor: *e.Editor,
+ BlankAllowed: e.BlankAllowed,
+ EditorCommand: EditorName(e.EditorCommand),
+ ShowHelp: true,
+ Config: config,
+ },
+ )
+ if err != nil {
+ return "", err
+ }
+ }
+ continue
+ }
+
+ stdio := e.Stdio()
+ lookPath := e.lookPath
+ if lookPath == nil {
+ lookPath = defaultLookPath
+ }
+ text, err := edit(e.EditorCommand, e.FileName, initialValue, stdio.In, stdio.Out, stdio.Err, cursor, lookPath)
+ if err != nil {
+ return "", err
+ }
+
+ // check length, return default value on empty
+ if len(text) == 0 && !e.AppendDefault {
+ return e.Default, nil
+ }
+
+ return text, nil
+}
+
+// EXTENDED This is straight copypasta from survey to get our overridden prompt called.;
+func (e *GhEditor) Prompt(config *survey.PromptConfig) (interface{}, error) {
+ initialValue := ""
+ if e.Default != "" && e.AppendDefault {
+ initialValue = e.Default
+ }
+ return e.prompt(initialValue, config)
+}
+
+func EditorName(editorCommand string) string {
+ if editorCommand == "" {
+ editorCommand = defaultEditor
+ }
+ if args, err := shellquote.Split(editorCommand); err == nil {
+ editorCommand = args[0]
+ }
+ return filepath.Base(editorCommand)
+}
diff --git a/vendor/github.com/cli/cli/v2/pkg/surveyext/editor_manual.go b/vendor/github.com/cli/cli/v2/pkg/surveyext/editor_manual.go
new file mode 100644
index 000000000..5ea493774
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/pkg/surveyext/editor_manual.go
@@ -0,0 +1,110 @@
+package surveyext
+
+import (
+ "bytes"
+ "io"
+ "os"
+ "os/exec"
+ "runtime"
+
+ "github.com/cli/safeexec"
+ shellquote "github.com/kballard/go-shellquote"
+)
+
+type showable interface {
+ Show() error
+}
+
+func Edit(editorCommand, fn, initialValue string, stdin io.Reader, stdout io.Writer, stderr io.Writer) (string, error) {
+ return edit(editorCommand, fn, initialValue, stdin, stdout, stderr, nil, defaultLookPath)
+}
+
+func defaultLookPath(name string) ([]string, []string, error) {
+ exe, err := safeexec.LookPath(name)
+ if err != nil {
+ return nil, nil, err
+ }
+ return []string{exe}, nil, nil
+}
+
+func needsBom() bool {
+ // The reason why we do this is because notepad.exe on Windows determines the
+ // encoding of an "empty" text file by the locale, for example, GBK in China,
+ // while golang string only handles utf8 well. However, a text file with utf8
+ // BOM header is not considered "empty" on Windows, and the encoding will then
+ // be determined utf8 by notepad.exe, instead of GBK or other encodings.
+
+ // This could be enhanced in the future by doing this only when a non-utf8
+ // locale is in use, and possibly doing that for any OS, not just windows.
+
+ return runtime.GOOS == "windows"
+}
+
+func edit(editorCommand, fn, initialValue string, stdin io.Reader, stdout io.Writer, stderr io.Writer, cursor showable, lookPath func(string) ([]string, []string, error)) (string, error) {
+ // prepare the temp file
+ pattern := fn
+ if pattern == "" {
+ pattern = "survey*.txt"
+ }
+ f, err := os.CreateTemp("", pattern)
+ if err != nil {
+ return "", err
+ }
+ defer os.Remove(f.Name())
+
+ // write utf8 BOM header if necessary for the current platform and/or locale
+ if needsBom() {
+ if _, err := f.Write(bom); err != nil {
+ return "", err
+ }
+ }
+
+ // write initial value
+ if _, err := f.WriteString(initialValue); err != nil {
+ return "", err
+ }
+
+ // close the fd to prevent the editor unable to save file
+ if err := f.Close(); err != nil {
+ return "", err
+ }
+
+ if editorCommand == "" {
+ editorCommand = defaultEditor
+ }
+ args, err := shellquote.Split(editorCommand)
+ if err != nil {
+ return "", err
+ }
+ args = append(args, f.Name())
+
+ editorExe, env, err := lookPath(args[0])
+ if err != nil {
+ return "", err
+ }
+ args = append(editorExe, args[1:]...)
+
+ cmd := exec.Command(args[0], args[1:]...)
+ cmd.Env = env
+ cmd.Stdin = stdin
+ cmd.Stdout = stdout
+ cmd.Stderr = stderr
+
+ if cursor != nil {
+ _ = cursor.Show()
+ }
+
+ // open the editor
+ if err := cmd.Run(); err != nil {
+ return "", err
+ }
+
+ // raw is a BOM-unstripped UTF8 byte slice
+ raw, err := os.ReadFile(f.Name())
+ if err != nil {
+ return "", err
+ }
+
+ // strip BOM header
+ return string(bytes.TrimPrefix(raw, bom)), nil
+}
diff --git a/vendor/github.com/cli/cli/v2/utils/utils.go b/vendor/github.com/cli/cli/v2/utils/utils.go
new file mode 100644
index 000000000..58894ba4f
--- /dev/null
+++ b/vendor/github.com/cli/cli/v2/utils/utils.go
@@ -0,0 +1,37 @@
+package utils
+
+import (
+ "fmt"
+ "os"
+
+ "golang.org/x/term"
+)
+
+func IsDebugEnabled() (bool, string) {
+ debugValue, isDebugSet := os.LookupEnv("GH_DEBUG")
+ legacyDebugValue := os.Getenv("DEBUG")
+
+ if !isDebugSet {
+ switch legacyDebugValue {
+ case "true", "1", "yes", "api":
+ return true, legacyDebugValue
+ default:
+ return false, legacyDebugValue
+ }
+ }
+
+ switch debugValue {
+ case "false", "0", "no", "":
+ return false, debugValue
+ default:
+ return true, debugValue
+ }
+}
+
+var TerminalSize = func(w interface{}) (int, int, error) {
+ if f, isFile := w.(*os.File); isFile {
+ return term.GetSize(int(f.Fd()))
+ }
+
+ return 0, 0, fmt.Errorf("%v is not a file", w)
+}
diff --git a/vendor/github.com/cli/go-gh/v2/LICENSE b/vendor/github.com/cli/go-gh/v2/LICENSE
new file mode 100644
index 000000000..af732f027
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 GitHub 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/cli/go-gh/v2/internal/git/git.go b/vendor/github.com/cli/go-gh/v2/internal/git/git.go
new file mode 100644
index 000000000..fd79f8da5
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/internal/git/git.go
@@ -0,0 +1,37 @@
+package git
+
+import (
+ "bytes"
+ "fmt"
+ "os/exec"
+
+ "github.com/cli/safeexec"
+)
+
+func Exec(args ...string) (stdOut, stdErr bytes.Buffer, err error) {
+ path, err := path()
+ if err != nil {
+ err = fmt.Errorf("could not find git executable in PATH. error: %w", err)
+ return
+ }
+ return run(path, nil, args...)
+}
+
+func path() (string, error) {
+ return safeexec.LookPath("git")
+}
+
+func run(path string, env []string, args ...string) (stdOut, stdErr bytes.Buffer, err error) {
+ cmd := exec.Command(path, args...)
+ cmd.Stdout = &stdOut
+ cmd.Stderr = &stdErr
+ if env != nil {
+ cmd.Env = env
+ }
+ err = cmd.Run()
+ if err != nil {
+ err = fmt.Errorf("failed to run git: %s. error: %w", stdErr.String(), err)
+ return
+ }
+ return
+}
diff --git a/vendor/github.com/cli/go-gh/v2/internal/git/remote.go b/vendor/github.com/cli/go-gh/v2/internal/git/remote.go
new file mode 100644
index 000000000..917440b8c
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/internal/git/remote.go
@@ -0,0 +1,154 @@
+package git
+
+import (
+ "net/url"
+ "regexp"
+ "sort"
+ "strings"
+)
+
+var remoteRE = regexp.MustCompile(`(.+)\s+(.+)\s+\((push|fetch)\)`)
+
+type RemoteSet []*Remote
+
+type Remote struct {
+ Name string
+ FetchURL *url.URL
+ PushURL *url.URL
+ Resolved string
+ Host string
+ Owner string
+ Repo string
+}
+
+func (r RemoteSet) Len() int { return len(r) }
+func (r RemoteSet) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
+func (r RemoteSet) Less(i, j int) bool {
+ return remoteNameSortScore(r[i].Name) > remoteNameSortScore(r[j].Name)
+}
+
+func remoteNameSortScore(name string) int {
+ switch strings.ToLower(name) {
+ case "upstream":
+ return 3
+ case "github":
+ return 2
+ case "origin":
+ return 1
+ default:
+ return 0
+ }
+}
+
+func Remotes() (RemoteSet, error) {
+ list, err := listRemotes()
+ if err != nil {
+ return nil, err
+ }
+ remotes := parseRemotes(list)
+ setResolvedRemotes(remotes)
+ sort.Sort(remotes)
+ return remotes, nil
+}
+
+// Filter remotes by given hostnames, maintains original order.
+func (rs RemoteSet) FilterByHosts(hosts []string) RemoteSet {
+ filtered := make(RemoteSet, 0)
+ for _, remote := range rs {
+ for _, host := range hosts {
+ if strings.EqualFold(remote.Host, host) {
+ filtered = append(filtered, remote)
+ break
+ }
+ }
+ }
+ return filtered
+}
+
+func listRemotes() ([]string, error) {
+ stdOut, _, err := Exec("remote", "-v")
+ if err != nil {
+ return nil, err
+ }
+ return toLines(stdOut.String()), nil
+}
+
+func parseRemotes(gitRemotes []string) RemoteSet {
+ remotes := RemoteSet{}
+ for _, r := range gitRemotes {
+ match := remoteRE.FindStringSubmatch(r)
+ if match == nil {
+ continue
+ }
+ name := strings.TrimSpace(match[1])
+ urlStr := strings.TrimSpace(match[2])
+ urlType := strings.TrimSpace(match[3])
+
+ url, err := ParseURL(urlStr)
+ if err != nil {
+ continue
+ }
+ host, owner, repo, _ := RepoInfoFromURL(url)
+
+ var rem *Remote
+ if len(remotes) > 0 {
+ rem = remotes[len(remotes)-1]
+ if name != rem.Name {
+ rem = nil
+ }
+ }
+ if rem == nil {
+ rem = &Remote{Name: name}
+ remotes = append(remotes, rem)
+ }
+
+ switch urlType {
+ case "fetch":
+ rem.FetchURL = url
+ rem.Host = host
+ rem.Owner = owner
+ rem.Repo = repo
+ case "push":
+ rem.PushURL = url
+ if rem.Host == "" {
+ rem.Host = host
+ }
+ if rem.Owner == "" {
+ rem.Owner = owner
+ }
+ if rem.Repo == "" {
+ rem.Repo = repo
+ }
+ }
+ }
+ return remotes
+}
+
+func setResolvedRemotes(remotes RemoteSet) {
+ stdOut, _, err := Exec("config", "--get-regexp", `^remote\..*\.gh-resolved$`)
+ if err != nil {
+ return
+ }
+ for _, l := range toLines(stdOut.String()) {
+ parts := strings.SplitN(l, " ", 2)
+ if len(parts) < 2 {
+ continue
+ }
+ rp := strings.SplitN(parts[0], ".", 3)
+ if len(rp) < 2 {
+ continue
+ }
+ name := rp[1]
+ for _, r := range remotes {
+ if r.Name == name {
+ r.Resolved = parts[1]
+ break
+ }
+ }
+ }
+}
+
+func toLines(output string) []string {
+ lines := strings.TrimSuffix(output, "\n")
+ return strings.Split(lines, "\n")
+}
diff --git a/vendor/github.com/cli/go-gh/v2/internal/git/url.go b/vendor/github.com/cli/go-gh/v2/internal/git/url.go
new file mode 100644
index 000000000..8e503c6f9
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/internal/git/url.go
@@ -0,0 +1,83 @@
+package git
+
+import (
+ "fmt"
+ "net/url"
+ "strings"
+)
+
+func IsURL(u string) bool {
+ return strings.HasPrefix(u, "git@") || isSupportedProtocol(u)
+}
+
+func isSupportedProtocol(u string) bool {
+ return strings.HasPrefix(u, "ssh:") ||
+ strings.HasPrefix(u, "git+ssh:") ||
+ strings.HasPrefix(u, "git:") ||
+ strings.HasPrefix(u, "http:") ||
+ strings.HasPrefix(u, "git+https:") ||
+ strings.HasPrefix(u, "https:")
+}
+
+func isPossibleProtocol(u string) bool {
+ return isSupportedProtocol(u) ||
+ strings.HasPrefix(u, "ftp:") ||
+ strings.HasPrefix(u, "ftps:") ||
+ strings.HasPrefix(u, "file:")
+}
+
+// ParseURL normalizes git remote urls.
+func ParseURL(rawURL string) (u *url.URL, err error) {
+ if !isPossibleProtocol(rawURL) &&
+ strings.ContainsRune(rawURL, ':') &&
+ // Not a Windows path.
+ !strings.ContainsRune(rawURL, '\\') {
+ // Support scp-like syntax for ssh protocol.
+ rawURL = "ssh://" + strings.Replace(rawURL, ":", "/", 1)
+ }
+
+ u, err = url.Parse(rawURL)
+ if err != nil {
+ return
+ }
+
+ if u.Scheme == "git+ssh" {
+ u.Scheme = "ssh"
+ }
+
+ if u.Scheme == "git+https" {
+ u.Scheme = "https"
+ }
+
+ if u.Scheme != "ssh" {
+ return
+ }
+
+ if strings.HasPrefix(u.Path, "//") {
+ u.Path = strings.TrimPrefix(u.Path, "/")
+ }
+
+ if idx := strings.Index(u.Host, ":"); idx >= 0 {
+ u.Host = u.Host[0:idx]
+ }
+
+ return
+}
+
+// Extract GitHub repository information from a git remote URL.
+func RepoInfoFromURL(u *url.URL) (host string, owner string, name string, err error) {
+ if u.Hostname() == "" {
+ return "", "", "", fmt.Errorf("no hostname detected")
+ }
+
+ parts := strings.SplitN(strings.Trim(u.Path, "/"), "/", 3)
+ if len(parts) != 2 {
+ return "", "", "", fmt.Errorf("invalid path: %s", u.Path)
+ }
+
+ return normalizeHostname(u.Hostname()), parts[0], strings.TrimSuffix(parts[1], ".git"), nil
+}
+
+func normalizeHostname(h string) string {
+ return strings.ToLower(strings.TrimPrefix(h, "www."))
+}
diff --git a/vendor/github.com/cli/go-gh/v2/internal/set/string_set.go b/vendor/github.com/cli/go-gh/v2/internal/set/string_set.go
new file mode 100644
index 000000000..8be4492f1
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/internal/set/string_set.go
@@ -0,0 +1,70 @@
+package set
+
+var exists = struct{}{}
+
+type stringSet struct {
+ v []string
+ m map[string]struct{}
+}
+
+func NewStringSet() *stringSet {
+ s := &stringSet{}
+ s.m = make(map[string]struct{})
+ s.v = []string{}
+ return s
+}
+
+func (s *stringSet) Add(value string) {
+ if s.Contains(value) {
+ return
+ }
+ s.m[value] = exists
+ s.v = append(s.v, value)
+}
+
+func (s *stringSet) AddValues(values []string) {
+ for _, v := range values {
+ s.Add(v)
+ }
+}
+
+func (s *stringSet) Remove(value string) {
+ if !s.Contains(value) {
+ return
+ }
+ delete(s.m, value)
+ s.v = sliceWithout(s.v, value)
+}
+
+func sliceWithout(s []string, v string) []string {
+ idx := -1
+ for i, item := range s {
+ if item == v {
+ idx = i
+ break
+ }
+ }
+ if idx < 0 {
+ return s
+ }
+ return append(s[:idx], s[idx+1:]...)
+}
+
+func (s *stringSet) RemoveValues(values []string) {
+ for _, v := range values {
+ s.Remove(v)
+ }
+}
+
+func (s *stringSet) Contains(value string) bool {
+ _, c := s.m[value]
+ return c
+}
+
+func (s *stringSet) Len() int {
+ return len(s.m)
+}
+
+func (s *stringSet) ToSlice() []string {
+ return s.v
+}
diff --git a/vendor/github.com/cli/go-gh/v2/internal/yamlmap/yaml_map.go b/vendor/github.com/cli/go-gh/v2/internal/yamlmap/yaml_map.go
new file mode 100644
index 000000000..78d09911b
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/internal/yamlmap/yaml_map.go
@@ -0,0 +1,214 @@
+// Package yamlmap is a wrapper of gopkg.in/yaml.v3 for interacting
+// with yaml data as if it were a map.
+package yamlmap
+
+import (
+ "errors"
+
+ "gopkg.in/yaml.v3"
+)
+
+const (
+ modified = "modifed"
+)
+
+type Map struct {
+ *yaml.Node
+}
+
+var ErrNotFound = errors.New("not found")
+var ErrInvalidYaml = errors.New("invalid yaml")
+var ErrInvalidFormat = errors.New("invalid format")
+
+func StringValue(value string) *Map {
+ return &Map{&yaml.Node{
+ Kind: yaml.ScalarNode,
+ Tag: "!!str",
+ Value: value,
+ }}
+}
+
+func MapValue() *Map {
+ return &Map{&yaml.Node{
+ Kind: yaml.MappingNode,
+ Tag: "!!map",
+ }}
+}
+
+func NullValue() *Map {
+ return &Map{&yaml.Node{
+ Kind: yaml.ScalarNode,
+ Tag: "!!null",
+ }}
+}
+
+func Unmarshal(data []byte) (*Map, error) {
+ var root yaml.Node
+ err := yaml.Unmarshal(data, &root)
+ if err != nil {
+ return nil, ErrInvalidYaml
+ }
+ if len(root.Content) == 0 {
+ return MapValue(), nil
+ }
+ if root.Content[0].Kind != yaml.MappingNode {
+ return nil, ErrInvalidFormat
+ }
+ return &Map{root.Content[0]}, nil
+}
+
+func Marshal(m *Map) ([]byte, error) {
+ return yaml.Marshal(m.Node)
+}
+
+func (m *Map) AddEntry(key string, value *Map) {
+ keyNode := &yaml.Node{
+ Kind: yaml.ScalarNode,
+ Tag: "!!str",
+ Value: key,
+ }
+ m.Content = append(m.Content, keyNode, value.Node)
+ m.SetModified()
+}
+
+func (m *Map) Empty() bool {
+ return m.Content == nil || len(m.Content) == 0
+}
+
+func (m *Map) FindEntry(key string) (*Map, error) {
+ // Note: The content slice of a yamlMap looks like [key1, value1, key2, value2, ...].
+ // When iterating over the content slice we only want to compare the keys of the yamlMap.
+ for i, v := range m.Content {
+ if i%2 != 0 {
+ continue
+ }
+ if v.Value == key {
+ if i+1 < len(m.Content) {
+ return &Map{m.Content[i+1]}, nil
+ }
+ }
+ }
+ return nil, ErrNotFound
+}
+
+func (m *Map) Keys() []string {
+ // Note: The content slice of a yamlMap looks like [key1, value1, key2, value2, ...].
+ // When iterating over the content slice we only want to select the keys of the yamlMap.
+ keys := []string{}
+ for i, v := range m.Content {
+ if i%2 != 0 {
+ continue
+ }
+ keys = append(keys, v.Value)
+ }
+ return keys
+}
+
+func (m *Map) RemoveEntry(key string) error {
+ // Note: The content slice of a yamlMap looks like [key1, value1, key2, value2, ...].
+ // When iterating over the content slice we only want to compare the keys of the yamlMap.
+ // If we find they key to remove, remove the key and its value from the content slice.
+ found, skipNext := false, false
+ newContent := []*yaml.Node{}
+ for i, v := range m.Content {
+ if skipNext {
+ skipNext = false
+ continue
+ }
+ if i%2 != 0 || v.Value != key {
+ newContent = append(newContent, v)
+ } else {
+ found = true
+ skipNext = true
+ m.SetModified()
+ }
+ }
+ if !found {
+ return ErrNotFound
+ }
+ m.Content = newContent
+ return nil
+}
+
+func (m *Map) SetEntry(key string, value *Map) {
+ // Note: The content slice of a yamlMap looks like [key1, value1, key2, value2, ...].
+ // When iterating over the content slice we only want to compare the keys of the yamlMap.
+ // If we find they key to set, set the next item in the content slice to the new value.
+ m.SetModified()
+ for i, v := range m.Content {
+ if i%2 != 0 || v.Value != key {
+ continue
+ }
+ if v.Value == key {
+ if i+1 < len(m.Content) {
+ m.Content[i+1] = value.Node
+ return
+ }
+ }
+ }
+ m.AddEntry(key, value)
+}
+
+// Note: This is a hack to introduce the concept of modified/unmodified
+// on top of gopkg.in/yaml.v3. This works by setting the Value property
+// of a MappingNode to a specific value and then later checking if the
+// node's Value property is that specific value. When a MappingNode gets
+// output as a string the Value property is not used, thus changing it
+// has no impact for our purposes.
+func (m *Map) SetModified() {
+ // Can not mark a non-mapping node as modified
+ if m.Node.Kind != yaml.MappingNode && m.Node.Tag == "!!null" {
+ m.Node.Kind = yaml.MappingNode
+ m.Node.Tag = "!!map"
+ }
+ if m.Node.Kind == yaml.MappingNode {
+ m.Node.Value = modified
+ }
+}
+
+// Traverse map using BFS to set all nodes as unmodified.
+func (m *Map) SetUnmodified() {
+ i := 0
+ queue := []*yaml.Node{m.Node}
+ for {
+ if i > (len(queue) - 1) {
+ break
+ }
+ q := queue[i]
+ i = i + 1
+ if q.Kind != yaml.MappingNode {
+ continue
+ }
+ q.Value = ""
+ queue = append(queue, q.Content...)
+ }
+}
+
+// Traverse map using BFS to searach for any nodes that have been modified.
+func (m *Map) IsModified() bool {
+ i := 0
+ queue := []*yaml.Node{m.Node}
+ for {
+ if i > (len(queue) - 1) {
+ break
+ }
+ q := queue[i]
+ i = i + 1
+ if q.Kind != yaml.MappingNode {
+ continue
+ }
+ if q.Value == modified {
+ return true
+ }
+ queue = append(queue, q.Content...)
+ }
+ return false
+}
+
+func (m *Map) String() string {
+ data, err := Marshal(m)
+ if err != nil {
+ return ""
+ }
+ return string(data)
+}
diff --git a/vendor/github.com/cli/go-gh/v2/pkg/api/cache.go b/vendor/github.com/cli/go-gh/v2/pkg/api/cache.go
new file mode 100644
index 000000000..7085d0525
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/pkg/api/cache.go
@@ -0,0 +1,215 @@
+package api
+
+import (
+ "bufio"
+ "bytes"
+ "crypto/sha256"
+ "errors"
+ "fmt"
+ "io"
+ "net/http"
+ "os"
+ "path/filepath"
+ "strings"
+ "sync"
+ "time"
+)
+
+type cache struct {
+ dir string
+ ttl time.Duration
+}
+
+type cacheRoundTripper struct {
+ fs fileStorage
+ rt http.RoundTripper
+}
+
+type fileStorage struct {
+ dir string
+ ttl time.Duration
+ mu *sync.RWMutex
+}
+
+type readCloser struct {
+ io.Reader
+ io.Closer
+}
+
+func isCacheableRequest(req *http.Request) bool {
+ if strings.EqualFold(req.Method, "GET") || strings.EqualFold(req.Method, "HEAD") {
+ return true
+ }
+
+ if strings.EqualFold(req.Method, "POST") && (req.URL.Path == "/graphql" || req.URL.Path == "/api/graphql") {
+ return true
+ }
+
+ return false
+}
+
+func isCacheableResponse(res *http.Response) bool {
+ return res.StatusCode < 500 && res.StatusCode != 403
+}
+
+func cacheKey(req *http.Request) (string, error) {
+ h := sha256.New()
+ fmt.Fprintf(h, "%s:", req.Method)
+ fmt.Fprintf(h, "%s:", req.URL.String())
+ fmt.Fprintf(h, "%s:", req.Header.Get("Accept"))
+ fmt.Fprintf(h, "%s:", req.Header.Get("Authorization"))
+
+ if req.Body != nil {
+ var bodyCopy io.ReadCloser
+ req.Body, bodyCopy = copyStream(req.Body)
+ defer bodyCopy.Close()
+ if _, err := io.Copy(h, bodyCopy); err != nil {
+ return "", err
+ }
+ }
+
+ digest := h.Sum(nil)
+ return fmt.Sprintf("%x", digest), nil
+}
+
+func (c cache) RoundTripper(rt http.RoundTripper) http.RoundTripper {
+ fs := fileStorage{
+ dir: c.dir,
+ ttl: c.ttl,
+ mu: &sync.RWMutex{},
+ }
+ return cacheRoundTripper{fs: fs, rt: rt}
+}
+
+func (crt cacheRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
+ reqDir, reqTTL := requestCacheOptions(req)
+
+ if crt.fs.ttl == 0 && reqTTL == 0 {
+ return crt.rt.RoundTrip(req)
+ }
+
+ if !isCacheableRequest(req) {
+ return crt.rt.RoundTrip(req)
+ }
+
+ origDir := crt.fs.dir
+ if reqDir != "" {
+ crt.fs.dir = reqDir
+ }
+ origTTL := crt.fs.ttl
+ if reqTTL != 0 {
+ crt.fs.ttl = reqTTL
+ }
+
+ key, keyErr := cacheKey(req)
+ if keyErr == nil {
+ if res, err := crt.fs.read(key); err == nil {
+ res.Request = req
+ return res, nil
+ }
+ }
+
+ res, err := crt.rt.RoundTrip(req)
+ if err == nil && keyErr == nil && isCacheableResponse(res) {
+ _ = crt.fs.store(key, res)
+ }
+
+ crt.fs.dir = origDir
+ crt.fs.ttl = origTTL
+
+ return res, err
+}
+
+// Allow an individual request to override cache options.
+func requestCacheOptions(req *http.Request) (string, time.Duration) {
+ var dur time.Duration
+ dir := req.Header.Get("X-GH-CACHE-DIR")
+ ttl := req.Header.Get("X-GH-CACHE-TTL")
+ if ttl != "" {
+ dur, _ = time.ParseDuration(ttl)
+ }
+ return dir, dur
+}
+
+func (fs *fileStorage) filePath(key string) string {
+ if len(key) >= 6 {
+ return filepath.Join(fs.dir, key[0:2], key[2:4], key[4:])
+ }
+ return filepath.Join(fs.dir, key)
+}
+
+func (fs *fileStorage) read(key string) (*http.Response, error) {
+ cacheFile := fs.filePath(key)
+
+ fs.mu.RLock()
+ defer fs.mu.RUnlock()
+
+ f, err := os.Open(cacheFile)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+
+ stat, err := f.Stat()
+ if err != nil {
+ return nil, err
+ }
+
+ age := time.Since(stat.ModTime())
+ if age > fs.ttl {
+ return nil, errors.New("cache expired")
+ }
+
+ body := &bytes.Buffer{}
+ _, err = io.Copy(body, f)
+ if err != nil {
+ return nil, err
+ }
+
+ res, err := http.ReadResponse(bufio.NewReader(body), nil)
+ return res, err
+}
+
+func (fs *fileStorage) store(key string, res *http.Response) (storeErr error) {
+ cacheFile := fs.filePath(key)
+
+ fs.mu.Lock()
+ defer fs.mu.Unlock()
+
+ if storeErr = os.MkdirAll(filepath.Dir(cacheFile), 0755); storeErr != nil {
+ return
+ }
+
+ var f *os.File
+ if f, storeErr = os.OpenFile(cacheFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600); storeErr != nil {
+ return
+ }
+
+ defer func() {
+ if err := f.Close(); storeErr == nil && err != nil {
+ storeErr = err
+ }
+ }()
+
+ var origBody io.ReadCloser
+ if res.Body != nil {
+ origBody, res.Body = copyStream(res.Body)
+ defer res.Body.Close()
+ }
+
+ storeErr = res.Write(f)
+ if origBody != nil {
+ res.Body = origBody
+ }
+
+ return
+}
+
+func copyStream(r io.ReadCloser) (io.ReadCloser, io.ReadCloser) {
+ b := &bytes.Buffer{}
+ nr := io.TeeReader(r, b)
+ return io.NopCloser(b), &readCloser{
+ Reader: nr,
+ Closer: r,
+ }
+}
diff --git a/vendor/github.com/cli/go-gh/v2/pkg/api/client_options.go b/vendor/github.com/cli/go-gh/v2/pkg/api/client_options.go
new file mode 100644
index 000000000..3464aacc0
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/pkg/api/client_options.go
@@ -0,0 +1,106 @@
+// Package api is a set of types for interacting with the GitHub API.
+package api
+
+import (
+ "fmt"
+ "io"
+ "net/http"
+ "time"
+
+ "github.com/cli/go-gh/v2/pkg/auth"
+ "github.com/cli/go-gh/v2/pkg/config"
+)
+
+// ClientOptions holds available options to configure API clients.
+type ClientOptions struct {
+ // AuthToken is the authorization token that will be used
+ // to authenticate against API endpoints.
+ AuthToken string
+
+ // CacheDir is the directory to use for cached API requests.
+ // Default is the same directory that gh uses for caching.
+ CacheDir string
+
+ // CacheTTL is the time that cached API requests are valid for.
+ // Default is 24 hours.
+ CacheTTL time.Duration
+
+ // EnableCache specifies if API requests will be cached or not.
+ // Default is no caching.
+ EnableCache bool
+
+ // Headers are the headers that will be sent with every API request.
+ // Default headers set are Accept, Content-Type, Time-Zone, and User-Agent.
+ // Default headers will be overridden by keys specified in Headers.
+ Headers map[string]string
+
+ // Host is the default host that API requests will be sent to.
+ Host string
+
+ // Log specifies a writer to write API request logs to. Default is to respect the GH_DEBUG environment
+ // variable, and no logging otherwise.
+ Log io.Writer
+
+ // LogIgnoreEnv disables respecting the GH_DEBUG environment variable. This can be useful in test mode
+ // or when the extension already offers its own controls for logging to the user.
+ LogIgnoreEnv bool
+
+ // LogColorize enables colorized logging to Log for display in a terminal.
+ // Default is no coloring.
+ LogColorize bool
+
+ // LogVerboseHTTP enables logging HTTP headers and bodies to Log.
+ // Default is only logging request URLs and response statuses.
+ LogVerboseHTTP bool
+
+ // SkipDefaultHeaders disables setting of the default headers.
+ SkipDefaultHeaders bool
+
+ // Timeout specifies a time limit for each API request.
+ // Default is no timeout.
+ Timeout time.Duration
+
+ // Transport specifies the mechanism by which individual API requests are made.
+ // If both Transport and UnixDomainSocket are specified then Transport takes
+ // precedence. Due to this behavior any value set for Transport needs to manually
+ // handle routing to UnixDomainSocket if necessary. Generally, setting Transport
+ // should be reserved for testing purposes.
+ // Default is http.DefaultTransport.
+ Transport http.RoundTripper
+
+ // UnixDomainSocket specifies the Unix domain socket address by which individual
+ // API requests will be routed. If specifed, this will form the base of the API
+ // request transport chain.
+ // Default is no socket address.
+ UnixDomainSocket string
+}
+
+func optionsNeedResolution(opts ClientOptions) bool {
+ if opts.Host == "" {
+ return true
+ }
+ if opts.AuthToken == "" {
+ return true
+ }
+ if opts.UnixDomainSocket == "" && opts.Transport == nil {
+ return true
+ }
+ return false
+}
+
+func resolveOptions(opts ClientOptions) (ClientOptions, error) {
+ cfg, _ := config.Read(nil)
+ if opts.Host == "" {
+ opts.Host, _ = auth.DefaultHost()
+ }
+ if opts.AuthToken == "" {
+ opts.AuthToken, _ = auth.TokenForHost(opts.Host)
+ if opts.AuthToken == "" {
+ return ClientOptions{}, fmt.Errorf("authentication token not found for host %s", opts.Host)
+ }
+ }
+ if opts.UnixDomainSocket == "" && cfg != nil {
+ opts.UnixDomainSocket, _ = cfg.Get([]string{"http_unix_socket"})
+ }
+ return opts, nil
+}
diff --git a/vendor/github.com/cli/go-gh/v2/pkg/api/errors.go b/vendor/github.com/cli/go-gh/v2/pkg/api/errors.go
new file mode 100644
index 000000000..e8fb93fb1
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/pkg/api/errors.go
@@ -0,0 +1,169 @@
+package api
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "net/url"
+ "strings"
+)
+
+// HTTPError represents an error response from the GitHub API.
+type HTTPError struct {
+ Errors []HTTPErrorItem
+ Headers http.Header
+ Message string
+ RequestURL *url.URL
+ StatusCode int
+}
+
+// HTTPErrorItem stores additional information about an error response
+// returned from the GitHub API.
+type HTTPErrorItem struct {
+ Code string
+ Field string
+ Message string
+ Resource string
+}
+
+// Allow HTTPError to satisfy error interface.
+func (err *HTTPError) Error() string {
+ if msgs := strings.SplitN(err.Message, "\n", 2); len(msgs) > 1 {
+ return fmt.Sprintf("HTTP %d: %s (%s)\n%s", err.StatusCode, msgs[0], err.RequestURL, msgs[1])
+ } else if err.Message != "" {
+ return fmt.Sprintf("HTTP %d: %s (%s)", err.StatusCode, err.Message, err.RequestURL)
+ }
+ return fmt.Sprintf("HTTP %d (%s)", err.StatusCode, err.RequestURL)
+}
+
+// GraphQLError represents an error response from GitHub GraphQL API.
+type GraphQLError struct {
+ Errors []GraphQLErrorItem
+}
+
+// GraphQLErrorItem stores additional information about an error response
+// returned from the GitHub GraphQL API.
+type GraphQLErrorItem struct {
+ Message string
+ Locations []struct {
+ Line int
+ Column int
+ }
+ Path []interface{}
+ Extensions map[string]interface{}
+ Type string
+}
+
+// Allow GraphQLError to satisfy error interface.
+func (gr *GraphQLError) Error() string {
+ errorMessages := make([]string, 0, len(gr.Errors))
+ for _, e := range gr.Errors {
+ msg := e.Message
+ if p := e.pathString(); p != "" {
+ msg = fmt.Sprintf("%s (%s)", msg, p)
+ }
+ errorMessages = append(errorMessages, msg)
+ }
+ return fmt.Sprintf("GraphQL: %s", strings.Join(errorMessages, ", "))
+}
+
+// Match determines if the GraphQLError is about a specific type on a specific path.
+// If the path argument ends with a ".", it will match all its subpaths.
+func (gr *GraphQLError) Match(expectType, expectPath string) bool {
+ for _, e := range gr.Errors {
+ if e.Type != expectType || !matchPath(e.pathString(), expectPath) {
+ return false
+ }
+ }
+ return true
+}
+
+func (ge GraphQLErrorItem) pathString() string {
+ var res strings.Builder
+ for i, v := range ge.Path {
+ if i > 0 {
+ res.WriteRune('.')
+ }
+ fmt.Fprintf(&res, "%v", v)
+ }
+ return res.String()
+}
+
+func matchPath(p, expect string) bool {
+ if strings.HasSuffix(expect, ".") {
+ return strings.HasPrefix(p, expect) || p == strings.TrimSuffix(expect, ".")
+ }
+ return p == expect
+}
+
+// HandleHTTPError parses a http.Response into a HTTPError.
+func HandleHTTPError(resp *http.Response) error {
+ httpError := &HTTPError{
+ Headers: resp.Header,
+ RequestURL: resp.Request.URL,
+ StatusCode: resp.StatusCode,
+ }
+
+ if !jsonTypeRE.MatchString(resp.Header.Get(contentType)) {
+ httpError.Message = resp.Status
+ return httpError
+ }
+
+ body, err := io.ReadAll(resp.Body)
+ if err != nil {
+ httpError.Message = err.Error()
+ return httpError
+ }
+
+ var parsedBody struct {
+ Message string `json:"message"`
+ Errors []json.RawMessage
+ }
+ if err := json.Unmarshal(body, &parsedBody); err != nil {
+ return httpError
+ }
+
+ var messages []string
+ if parsedBody.Message != "" {
+ messages = append(messages, parsedBody.Message)
+ }
+ for _, raw := range parsedBody.Errors {
+ switch raw[0] {
+ case '"':
+ var errString string
+ _ = json.Unmarshal(raw, &errString)
+ messages = append(messages, errString)
+ httpError.Errors = append(httpError.Errors, HTTPErrorItem{Message: errString})
+ case '{':
+ var errInfo HTTPErrorItem
+ _ = json.Unmarshal(raw, &errInfo)
+ msg := errInfo.Message
+ if errInfo.Code != "" && errInfo.Code != "custom" {
+ msg = fmt.Sprintf("%s.%s %s", errInfo.Resource, errInfo.Field, errorCodeToMessage(errInfo.Code))
+ }
+ if msg != "" {
+ messages = append(messages, msg)
+ }
+ httpError.Errors = append(httpError.Errors, errInfo)
+ }
+ }
+ httpError.Message = strings.Join(messages, "\n")
+
+ return httpError
+}
+
+// Convert common error codes to human readable messages
+// See https://docs.github.com/en/rest/overview/resources-in-the-rest-api#client-errors for more details.
+func errorCodeToMessage(code string) string {
+ switch code {
+ case "missing", "missing_field":
+ return "is missing"
+ case "invalid", "unprocessable":
+ return "is invalid"
+ case "already_exists":
+ return "already exists"
+ default:
+ return code
+ }
+}
diff --git a/vendor/github.com/cli/go-gh/v2/pkg/api/graphql_client.go b/vendor/github.com/cli/go-gh/v2/pkg/api/graphql_client.go
new file mode 100644
index 000000000..405b10f31
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/pkg/api/graphql_client.go
@@ -0,0 +1,182 @@
+package api
+
+import (
+ "bytes"
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "net/http"
+ "strings"
+
+ graphql "github.com/cli/shurcooL-graphql"
+)
+
+// GraphQLClient wraps methods for the different types of
+// API requests that are supported by the server.
+type GraphQLClient struct {
+ client *graphql.Client
+ host string
+ httpClient *http.Client
+}
+
+func DefaultGraphQLClient() (*GraphQLClient, error) {
+ return NewGraphQLClient(ClientOptions{})
+}
+
+// GraphQLClient builds a client to send requests to GitHub GraphQL API endpoints.
+// As part of the configuration a hostname, auth token, default set of headers,
+// and unix domain socket are resolved from the gh environment configuration.
+// These behaviors can be overridden using the opts argument.
+func NewGraphQLClient(opts ClientOptions) (*GraphQLClient, error) {
+ if optionsNeedResolution(opts) {
+ var err error
+ opts, err = resolveOptions(opts)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ httpClient, err := NewHTTPClient(opts)
+ if err != nil {
+ return nil, err
+ }
+
+ endpoint := graphQLEndpoint(opts.Host)
+
+ return &GraphQLClient{
+ client: graphql.NewClient(endpoint, httpClient),
+ host: endpoint,
+ httpClient: httpClient,
+ }, nil
+}
+
+// DoWithContext executes a GraphQL query request.
+// The response is populated into the response argument.
+func (c *GraphQLClient) DoWithContext(ctx context.Context, query string, variables map[string]interface{}, response interface{}) error {
+ reqBody, err := json.Marshal(map[string]interface{}{"query": query, "variables": variables})
+ if err != nil {
+ return err
+ }
+
+ req, err := http.NewRequestWithContext(ctx, "POST", c.host, bytes.NewBuffer(reqBody))
+ if err != nil {
+ return err
+ }
+
+ resp, err := c.httpClient.Do(req)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+
+ success := resp.StatusCode >= 200 && resp.StatusCode < 300
+ if !success {
+ return HandleHTTPError(resp)
+ }
+
+ if resp.StatusCode == http.StatusNoContent {
+ return nil
+ }
+
+ body, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return err
+ }
+
+ gr := graphQLResponse{Data: response}
+ err = json.Unmarshal(body, &gr)
+ if err != nil {
+ return err
+ }
+
+ if len(gr.Errors) > 0 {
+ return &GraphQLError{Errors: gr.Errors}
+ }
+
+ return nil
+}
+
+// Do wraps DoWithContext using context.Background.
+func (c *GraphQLClient) Do(query string, variables map[string]interface{}, response interface{}) error {
+ return c.DoWithContext(context.Background(), query, variables, response)
+}
+
+// MutateWithContext executes a GraphQL mutation request.
+// The mutation string is derived from the mutation argument, and the
+// response is populated into it.
+// The mutation argument should be a pointer to struct that corresponds
+// to the GitHub GraphQL schema.
+// Provided input will be set as a variable named input.
+func (c *GraphQLClient) MutateWithContext(ctx context.Context, name string, m interface{}, variables map[string]interface{}) error {
+ err := c.client.MutateNamed(ctx, name, m, variables)
+ var graphQLErrs graphql.Errors
+ if err != nil && errors.As(err, &graphQLErrs) {
+ items := make([]GraphQLErrorItem, len(graphQLErrs))
+ for i, e := range graphQLErrs {
+ items[i] = GraphQLErrorItem{
+ Message: e.Message,
+ Locations: e.Locations,
+ Path: e.Path,
+ Extensions: e.Extensions,
+ Type: e.Type,
+ }
+ }
+ err = &GraphQLError{items}
+ }
+ return err
+}
+
+// Mutate wraps MutateWithContext using context.Background.
+func (c *GraphQLClient) Mutate(name string, m interface{}, variables map[string]interface{}) error {
+ return c.MutateWithContext(context.Background(), name, m, variables)
+}
+
+// QueryWithContext executes a GraphQL query request,
+// The query string is derived from the query argument, and the
+// response is populated into it.
+// The query argument should be a pointer to struct that corresponds
+// to the GitHub GraphQL schema.
+func (c *GraphQLClient) QueryWithContext(ctx context.Context, name string, q interface{}, variables map[string]interface{}) error {
+ err := c.client.QueryNamed(ctx, name, q, variables)
+ var graphQLErrs graphql.Errors
+ if err != nil && errors.As(err, &graphQLErrs) {
+ items := make([]GraphQLErrorItem, len(graphQLErrs))
+ for i, e := range graphQLErrs {
+ items[i] = GraphQLErrorItem{
+ Message: e.Message,
+ Locations: e.Locations,
+ Path: e.Path,
+ Extensions: e.Extensions,
+ Type: e.Type,
+ }
+ }
+ err = &GraphQLError{items}
+ }
+ return err
+}
+
+// Query wraps QueryWithContext using context.Background.
+func (c *GraphQLClient) Query(name string, q interface{}, variables map[string]interface{}) error {
+ return c.QueryWithContext(context.Background(), name, q, variables)
+}
+
+type graphQLResponse struct {
+ Data interface{}
+ Errors []GraphQLErrorItem
+}
+
+func graphQLEndpoint(host string) string {
+ if isGarage(host) {
+ return fmt.Sprintf("https://%s/api/graphql", host)
+ }
+ host = normalizeHostname(host)
+ if isEnterprise(host) {
+ return fmt.Sprintf("https://%s/api/graphql", host)
+ }
+ if strings.EqualFold(host, localhost) {
+ return fmt.Sprintf("http://api.%s/graphql", host)
+ }
+ return fmt.Sprintf("https://api.%s/graphql", host)
+}
diff --git a/vendor/github.com/cli/go-gh/v2/pkg/api/http_client.go b/vendor/github.com/cli/go-gh/v2/pkg/api/http_client.go
new file mode 100644
index 000000000..589de91ae
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/pkg/api/http_client.go
@@ -0,0 +1,259 @@
+package api
+
+import (
+ "fmt"
+ "io"
+ "net"
+ "net/http"
+ "os"
+ "regexp"
+ "runtime/debug"
+ "strings"
+ "time"
+
+ "github.com/cli/go-gh/v2/pkg/asciisanitizer"
+ "github.com/cli/go-gh/v2/pkg/config"
+ "github.com/cli/go-gh/v2/pkg/term"
+ "github.com/henvic/httpretty"
+ "github.com/thlib/go-timezone-local/tzlocal"
+ "golang.org/x/text/transform"
+)
+
+const (
+ accept = "Accept"
+ authorization = "Authorization"
+ contentType = "Content-Type"
+ github = "github.com"
+ jsonContentType = "application/json; charset=utf-8"
+ localhost = "github.localhost"
+ modulePath = "github.com/cli/go-gh"
+ timeZone = "Time-Zone"
+ userAgent = "User-Agent"
+)
+
+var jsonTypeRE = regexp.MustCompile(`[/+]json($|;)`)
+
+func DefaultHTTPClient() (*http.Client, error) {
+ return NewHTTPClient(ClientOptions{})
+}
+
+// HTTPClient builds a client that can be passed to another library.
+// As part of the configuration a hostname, auth token, default set of headers,
+// and unix domain socket are resolved from the gh environment configuration.
+// These behaviors can be overridden using the opts argument. In this instance
+// providing opts.Host will not change the destination of your request as it is
+// the responsibility of the consumer to configure this. However, if opts.Host
+// does not match the request host, the auth token will not be added to the headers.
+// This is to protect against the case where tokens could be sent to an arbitrary
+// host.
+func NewHTTPClient(opts ClientOptions) (*http.Client, error) {
+ if optionsNeedResolution(opts) {
+ var err error
+ opts, err = resolveOptions(opts)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ transport := http.DefaultTransport
+
+ if opts.UnixDomainSocket != "" {
+ transport = newUnixDomainSocketRoundTripper(opts.UnixDomainSocket)
+ }
+
+ if opts.Transport != nil {
+ transport = opts.Transport
+ }
+
+ transport = newSanitizerRoundTripper(transport)
+
+ if opts.CacheDir == "" {
+ opts.CacheDir = config.CacheDir()
+ }
+ if opts.EnableCache && opts.CacheTTL == 0 {
+ opts.CacheTTL = time.Hour * 24
+ }
+ c := cache{dir: opts.CacheDir, ttl: opts.CacheTTL}
+ transport = c.RoundTripper(transport)
+
+ if opts.Log == nil && !opts.LogIgnoreEnv {
+ ghDebug := os.Getenv("GH_DEBUG")
+ switch ghDebug {
+ case "", "0", "false", "no":
+ // no logging
+ default:
+ opts.Log = os.Stderr
+ opts.LogColorize = !term.IsColorDisabled() && term.IsTerminal(os.Stderr)
+ opts.LogVerboseHTTP = strings.Contains(ghDebug, "api")
+ }
+ }
+
+ if opts.Log != nil {
+ logger := &httpretty.Logger{
+ Time: true,
+ TLS: false,
+ Colors: opts.LogColorize,
+ RequestHeader: opts.LogVerboseHTTP,
+ RequestBody: opts.LogVerboseHTTP,
+ ResponseHeader: opts.LogVerboseHTTP,
+ ResponseBody: opts.LogVerboseHTTP,
+ Formatters: []httpretty.Formatter{&jsonFormatter{colorize: opts.LogColorize}},
+ MaxResponseBody: 100000,
+ }
+ logger.SetOutput(opts.Log)
+ logger.SetBodyFilter(func(h http.Header) (skip bool, err error) {
+ return !inspectableMIMEType(h.Get(contentType)), nil
+ })
+ transport = logger.RoundTripper(transport)
+ }
+
+ if opts.Headers == nil {
+ opts.Headers = map[string]string{}
+ }
+ if !opts.SkipDefaultHeaders {
+ resolveHeaders(opts.Headers)
+ }
+ transport = newHeaderRoundTripper(opts.Host, opts.AuthToken, opts.Headers, transport)
+
+ return &http.Client{Transport: transport, Timeout: opts.Timeout}, nil
+}
+
+func inspectableMIMEType(t string) bool {
+ return strings.HasPrefix(t, "text/") ||
+ strings.HasPrefix(t, "application/x-www-form-urlencoded") ||
+ jsonTypeRE.MatchString(t)
+}
+
+func isSameDomain(requestHost, domain string) bool {
+ requestHost = strings.ToLower(requestHost)
+ domain = strings.ToLower(domain)
+ return (requestHost == domain) || strings.HasSuffix(requestHost, "."+domain)
+}
+
+func isGarage(host string) bool {
+ return strings.EqualFold(host, "garage.github.com")
+}
+
+func isEnterprise(host string) bool {
+ return host != github && host != localhost
+}
+
+func normalizeHostname(hostname string) string {
+ hostname = strings.ToLower(hostname)
+ if strings.HasSuffix(hostname, "."+github) {
+ return github
+ }
+ if strings.HasSuffix(hostname, "."+localhost) {
+ return localhost
+ }
+ return hostname
+}
+
+type headerRoundTripper struct {
+ headers map[string]string
+ host string
+ rt http.RoundTripper
+}
+
+func resolveHeaders(headers map[string]string) {
+ if _, ok := headers[contentType]; !ok {
+ headers[contentType] = jsonContentType
+ }
+ if _, ok := headers[userAgent]; !ok {
+ headers[userAgent] = "go-gh"
+ info, ok := debug.ReadBuildInfo()
+ if ok {
+ for _, dep := range info.Deps {
+ if dep.Path == modulePath {
+ headers[userAgent] += fmt.Sprintf(" %s", dep.Version)
+ break
+ }
+ }
+ }
+ }
+ if _, ok := headers[timeZone]; !ok {
+ tz := currentTimeZone()
+ if tz != "" {
+ headers[timeZone] = tz
+ }
+ }
+ if _, ok := headers[accept]; !ok {
+ // Preview for PullRequest.mergeStateStatus.
+ a := "application/vnd.github.merge-info-preview+json"
+ // Preview for visibility when RESTing repos into an org.
+ a += ", application/vnd.github.nebula-preview"
+ headers[accept] = a
+ }
+}
+
+func newHeaderRoundTripper(host string, authToken string, headers map[string]string, rt http.RoundTripper) http.RoundTripper {
+ if _, ok := headers[authorization]; !ok && authToken != "" {
+ headers[authorization] = fmt.Sprintf("token %s", authToken)
+ }
+ if len(headers) == 0 {
+ return rt
+ }
+ return headerRoundTripper{host: host, headers: headers, rt: rt}
+}
+
+func (hrt headerRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
+ for k, v := range hrt.headers {
+ // If the authorization header has been set and the request
+ // host is not in the same domain that was specified in the ClientOptions
+ // then do not add the authorization header to the request.
+ if k == authorization && !isSameDomain(req.URL.Hostname(), hrt.host) {
+ continue
+ }
+
+ // If the header is already set in the request, don't overwrite it.
+ if req.Header.Get(k) == "" {
+ req.Header.Set(k, v)
+ }
+ }
+
+ return hrt.rt.RoundTrip(req)
+}
+
+func newUnixDomainSocketRoundTripper(socketPath string) http.RoundTripper {
+ dial := func(network, addr string) (net.Conn, error) {
+ return net.Dial("unix", socketPath)
+ }
+
+ return &http.Transport{
+ Dial: dial,
+ DialTLS: dial,
+ DisableKeepAlives: true,
+ }
+}
+
+type sanitizerRoundTripper struct {
+ rt http.RoundTripper
+}
+
+func newSanitizerRoundTripper(rt http.RoundTripper) http.RoundTripper {
+ return sanitizerRoundTripper{rt: rt}
+}
+
+func (srt sanitizerRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
+ resp, err := srt.rt.RoundTrip(req)
+ if err != nil || !jsonTypeRE.MatchString(resp.Header.Get(contentType)) {
+ return resp, err
+ }
+ sanitizedReadCloser := struct {
+ io.Reader
+ io.Closer
+ }{
+ Reader: transform.NewReader(resp.Body, &asciisanitizer.Sanitizer{JSON: true}),
+ Closer: resp.Body,
+ }
+ resp.Body = sanitizedReadCloser
+ return resp, err
+}
+
+func currentTimeZone() string {
+ tz, err := tzlocal.RuntimeTZ()
+ if err != nil {
+ return ""
+ }
+ return tz
+}
diff --git a/vendor/github.com/cli/go-gh/v2/pkg/api/log_formatter.go b/vendor/github.com/cli/go-gh/v2/pkg/api/log_formatter.go
new file mode 100644
index 000000000..e3a85f043
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/pkg/api/log_formatter.go
@@ -0,0 +1,47 @@
+package api
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "io"
+ "strings"
+
+ "github.com/cli/go-gh/v2/pkg/jsonpretty"
+)
+
+type graphqlBody struct {
+ Query string `json:"query"`
+ OperationName string `json:"operationName"`
+ Variables json.RawMessage `json:"variables"`
+}
+
+// jsonFormatter is a httpretty.Formatter that prettifies JSON payloads and GraphQL queries.
+type jsonFormatter struct {
+ colorize bool
+}
+
+func (f *jsonFormatter) Format(w io.Writer, src []byte) error {
+ var graphqlQuery graphqlBody
+ // TODO: find more precise way to detect a GraphQL query from the JSON payload alone
+ if err := json.Unmarshal(src, &graphqlQuery); err == nil && graphqlQuery.Query != "" && len(graphqlQuery.Variables) > 0 {
+ colorHighlight := "\x1b[35;1m"
+ colorReset := "\x1b[m"
+ if !f.colorize {
+ colorHighlight = ""
+ colorReset = ""
+ }
+ if _, err := fmt.Fprintf(w, "%sGraphQL query:%s\n%s\n", colorHighlight, colorReset, strings.ReplaceAll(strings.TrimSpace(graphqlQuery.Query), "\t", " ")); err != nil {
+ return err
+ }
+ if _, err := fmt.Fprintf(w, "%sGraphQL variables:%s %s\n", colorHighlight, colorReset, string(graphqlQuery.Variables)); err != nil {
+ return err
+ }
+ return nil
+ }
+ return jsonpretty.Format(w, bytes.NewReader(src), " ", f.colorize)
+}
+
+func (f *jsonFormatter) Match(t string) bool {
+ return jsonTypeRE.MatchString(t)
+}
diff --git a/vendor/github.com/cli/go-gh/v2/pkg/api/rest_client.go b/vendor/github.com/cli/go-gh/v2/pkg/api/rest_client.go
new file mode 100644
index 000000000..2d91f707d
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/pkg/api/rest_client.go
@@ -0,0 +1,170 @@
+package api
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "strings"
+)
+
+// RESTClient wraps methods for the different types of
+// API requests that are supported by the server.
+type RESTClient struct {
+ client *http.Client
+ host string
+}
+
+func DefaultRESTClient() (*RESTClient, error) {
+ return NewRESTClient(ClientOptions{})
+}
+
+// RESTClient builds a client to send requests to GitHub REST API endpoints.
+// As part of the configuration a hostname, auth token, default set of headers,
+// and unix domain socket are resolved from the gh environment configuration.
+// These behaviors can be overridden using the opts argument.
+func NewRESTClient(opts ClientOptions) (*RESTClient, error) {
+ if optionsNeedResolution(opts) {
+ var err error
+ opts, err = resolveOptions(opts)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ client, err := NewHTTPClient(opts)
+ if err != nil {
+ return nil, err
+ }
+
+ return &RESTClient{
+ client: client,
+ host: opts.Host,
+ }, nil
+}
+
+// RequestWithContext issues a request with type specified by method to the
+// specified path with the specified body.
+// The response is returned rather than being populated
+// into a response argument.
+func (c *RESTClient) RequestWithContext(ctx context.Context, method string, path string, body io.Reader) (*http.Response, error) {
+ url := restURL(c.host, path)
+ req, err := http.NewRequestWithContext(ctx, method, url, body)
+ if err != nil {
+ return nil, err
+ }
+
+ resp, err := c.client.Do(req)
+ if err != nil {
+ return nil, err
+ }
+
+ success := resp.StatusCode >= 200 && resp.StatusCode < 300
+ if !success {
+ defer resp.Body.Close()
+ return nil, HandleHTTPError(resp)
+ }
+
+ return resp, err
+}
+
+// Request wraps RequestWithContext with context.Background.
+func (c *RESTClient) Request(method string, path string, body io.Reader) (*http.Response, error) {
+ return c.RequestWithContext(context.Background(), method, path, body)
+}
+
+// DoWithContext issues a request with type specified by method to the
+// specified path with the specified body.
+// The response is populated into the response argument.
+func (c *RESTClient) DoWithContext(ctx context.Context, method string, path string, body io.Reader, response interface{}) error {
+ url := restURL(c.host, path)
+ req, err := http.NewRequestWithContext(ctx, method, url, body)
+ if err != nil {
+ return err
+ }
+
+ resp, err := c.client.Do(req)
+ if err != nil {
+ return err
+ }
+
+ success := resp.StatusCode >= 200 && resp.StatusCode < 300
+ if !success {
+ defer resp.Body.Close()
+ return HandleHTTPError(resp)
+ }
+
+ if resp.StatusCode == http.StatusNoContent {
+ return nil
+ }
+ defer resp.Body.Close()
+
+ b, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return err
+ }
+
+ err = json.Unmarshal(b, &response)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// Do wraps DoWithContext with context.Background.
+func (c *RESTClient) Do(method string, path string, body io.Reader, response interface{}) error {
+ return c.DoWithContext(context.Background(), method, path, body, response)
+}
+
+// Delete issues a DELETE request to the specified path.
+// The response is populated into the response argument.
+func (c *RESTClient) Delete(path string, resp interface{}) error {
+ return c.Do(http.MethodDelete, path, nil, resp)
+}
+
+// Get issues a GET request to the specified path.
+// The response is populated into the response argument.
+func (c *RESTClient) Get(path string, resp interface{}) error {
+ return c.Do(http.MethodGet, path, nil, resp)
+}
+
+// Patch issues a PATCH request to the specified path with the specified body.
+// The response is populated into the response argument.
+func (c *RESTClient) Patch(path string, body io.Reader, resp interface{}) error {
+ return c.Do(http.MethodPatch, path, body, resp)
+}
+
+// Post issues a POST request to the specified path with the specified body.
+// The response is populated into the response argument.
+func (c *RESTClient) Post(path string, body io.Reader, resp interface{}) error {
+ return c.Do(http.MethodPost, path, body, resp)
+}
+
+// Put issues a PUT request to the specified path with the specified body.
+// The response is populated into the response argument.
+func (c *RESTClient) Put(path string, body io.Reader, resp interface{}) error {
+ return c.Do(http.MethodPut, path, body, resp)
+}
+
+func restURL(hostname string, pathOrURL string) string {
+ if strings.HasPrefix(pathOrURL, "https://") || strings.HasPrefix(pathOrURL, "http://") {
+ return pathOrURL
+ }
+ return restPrefix(hostname) + pathOrURL
+}
+
+func restPrefix(hostname string) string {
+ if isGarage(hostname) {
+ return fmt.Sprintf("https://%s/api/v3/", hostname)
+ }
+ hostname = normalizeHostname(hostname)
+ if isEnterprise(hostname) {
+ return fmt.Sprintf("https://%s/api/v3/", hostname)
+ }
+ if strings.EqualFold(hostname, localhost) {
+ return fmt.Sprintf("http://api.%s/", hostname)
+ }
+ return fmt.Sprintf("https://api.%s/", hostname)
+}
diff --git a/vendor/github.com/cli/go-gh/v2/pkg/asciisanitizer/sanitizer.go b/vendor/github.com/cli/go-gh/v2/pkg/asciisanitizer/sanitizer.go
new file mode 100644
index 000000000..0292bec4b
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/pkg/asciisanitizer/sanitizer.go
@@ -0,0 +1,253 @@
+// Package asciisanitizer implements an ASCII control character sanitizer for UTF-8 strings.
+// It will transform ASCII control codes into equivalent inert characters that are safe for display in the terminal.
+// Without sanitization these ASCII control characters will be interpreted by the terminal.
+// This behaviour can be used maliciously as an attack vector, especially the ASCII control characters \x1B and \x9B.
+package asciisanitizer
+
+import (
+ "bytes"
+ "errors"
+ "strings"
+ "unicode"
+ "unicode/utf8"
+
+ "golang.org/x/text/transform"
+)
+
+// Sanitizer implements transform.Transformer interface.
+type Sanitizer struct {
+ // JSON tells the Sanitizer to replace strings that will be transformed
+ // into control characters when the string is marshaled to JSON. Set to
+ // true if the string being sanitized represents JSON formatted data.
+ JSON bool
+ addEscape bool
+}
+
+// Transform uses a sliding window algorithm to detect C0 and C1 control characters as they are read and replaces
+// them with equivalent inert characters. Bytes that are not part of a control character are not modified.
+func (t *Sanitizer) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
+ transfer := func(write, read []byte) error {
+ readLength := len(read)
+ writeLength := len(write)
+ if writeLength > len(dst) {
+ return transform.ErrShortDst
+ }
+ copy(dst, write)
+ nDst += writeLength
+ dst = dst[writeLength:]
+ nSrc += readLength
+ src = src[readLength:]
+ return nil
+ }
+
+ for len(src) > 0 {
+ // When sanitizing JSON strings make sure that we have 6 bytes if available.
+ if t.JSON && len(src) < 6 && !atEOF {
+ err = transform.ErrShortSrc
+ return
+ }
+ r, size := utf8.DecodeRune(src)
+ if r == utf8.RuneError && size < 2 {
+ if !atEOF {
+ err = transform.ErrShortSrc
+ return
+ } else {
+ err = errors.New("invalid UTF-8 string")
+ return
+ }
+ }
+ // Replace C0 and C1 control characters.
+ if unicode.IsControl(r) {
+ if repl, found := mapControlToCaret(r); found {
+ err = transfer(repl, src[:size])
+ if err != nil {
+ return
+ }
+ continue
+ }
+ }
+ // Replace JSON C0 and C1 control characters.
+ if t.JSON && len(src) >= 6 {
+ if repl, found := mapJSONControlToCaret(src[:6]); found {
+ if t.addEscape {
+ // Add an escape character when necessary to prevent creating
+ // invalid JSON with our replacements.
+ repl = append([]byte{'\\'}, repl...)
+ t.addEscape = false
+ }
+ err = transfer(repl, src[:6])
+ if err != nil {
+ return
+ }
+ continue
+ }
+ }
+ err = transfer(src[:size], src[:size])
+ if err != nil {
+ return
+ }
+ if t.JSON {
+ if r == '\\' {
+ t.addEscape = !t.addEscape
+ } else {
+ t.addEscape = false
+ }
+ }
+ }
+ return
+}
+
+// Reset resets the state and allows the Sanitizer to be reused.
+func (t *Sanitizer) Reset() {
+ t.addEscape = false
+}
+
+// mapControlToCaret maps C0 and C1 control characters to their caret notation.
+func mapControlToCaret(r rune) ([]byte, bool) {
+ //\t (09), \n (10), \v (11), \r (13) are safe C0 characters and are not sanitized.
+ m := map[rune]string{
+ 0: `^@`,
+ 1: `^A`,
+ 2: `^B`,
+ 3: `^C`,
+ 4: `^D`,
+ 5: `^E`,
+ 6: `^F`,
+ 7: `^G`,
+ 8: `^H`,
+ 12: `^L`,
+ 14: `^N`,
+ 15: `^O`,
+ 16: `^P`,
+ 17: `^Q`,
+ 18: `^R`,
+ 19: `^S`,
+ 20: `^T`,
+ 21: `^U`,
+ 22: `^V`,
+ 23: `^W`,
+ 24: `^X`,
+ 25: `^Y`,
+ 26: `^Z`,
+ 27: `^[`,
+ 28: `^\\`,
+ 29: `^]`,
+ 30: `^^`,
+ 31: `^_`,
+ 128: `^@`,
+ 129: `^A`,
+ 130: `^B`,
+ 131: `^C`,
+ 132: `^D`,
+ 133: `^E`,
+ 134: `^F`,
+ 135: `^G`,
+ 136: `^H`,
+ 137: `^I`,
+ 138: `^J`,
+ 139: `^K`,
+ 140: `^L`,
+ 141: `^M`,
+ 142: `^N`,
+ 143: `^O`,
+ 144: `^P`,
+ 145: `^Q`,
+ 146: `^R`,
+ 147: `^S`,
+ 148: `^T`,
+ 149: `^U`,
+ 150: `^V`,
+ 151: `^W`,
+ 152: `^X`,
+ 153: `^Y`,
+ 154: `^Z`,
+ 155: `^[`,
+ 156: `^\\`,
+ 157: `^]`,
+ 158: `^^`,
+ 159: `^_`,
+ }
+ if c, ok := m[r]; ok {
+ return []byte(c), true
+ }
+ return nil, false
+}
+
+// mapJSONControlToCaret maps JSON C0 and C1 control characters to their caret notation.
+// JSON control characters are six byte strings, representing a unicode code point,
+// ranging from \u0000 to \u001F and \u0080 to \u009F.
+func mapJSONControlToCaret(b []byte) ([]byte, bool) {
+ if len(b) != 6 {
+ return nil, false
+ }
+ if !bytes.HasPrefix(b, []byte(`\u00`)) {
+ return nil, false
+ }
+ //\t (\u0009), \n (\u000a), \v (\u000b), \r (\u000d) are safe C0 characters and are not sanitized.
+ m := map[string]string{
+ `\u0000`: `^@`,
+ `\u0001`: `^A`,
+ `\u0002`: `^B`,
+ `\u0003`: `^C`,
+ `\u0004`: `^D`,
+ `\u0005`: `^E`,
+ `\u0006`: `^F`,
+ `\u0007`: `^G`,
+ `\u0008`: `^H`,
+ `\u000c`: `^L`,
+ `\u000e`: `^N`,
+ `\u000f`: `^O`,
+ `\u0010`: `^P`,
+ `\u0011`: `^Q`,
+ `\u0012`: `^R`,
+ `\u0013`: `^S`,
+ `\u0014`: `^T`,
+ `\u0015`: `^U`,
+ `\u0016`: `^V`,
+ `\u0017`: `^W`,
+ `\u0018`: `^X`,
+ `\u0019`: `^Y`,
+ `\u001a`: `^Z`,
+ `\u001b`: `^[`,
+ `\u001c`: `^\\`,
+ `\u001d`: `^]`,
+ `\u001e`: `^^`,
+ `\u001f`: `^_`,
+ `\u0080`: `^@`,
+ `\u0081`: `^A`,
+ `\u0082`: `^B`,
+ `\u0083`: `^C`,
+ `\u0084`: `^D`,
+ `\u0085`: `^E`,
+ `\u0086`: `^F`,
+ `\u0087`: `^G`,
+ `\u0088`: `^H`,
+ `\u0089`: `^I`,
+ `\u008a`: `^J`,
+ `\u008b`: `^K`,
+ `\u008c`: `^L`,
+ `\u008d`: `^M`,
+ `\u008e`: `^N`,
+ `\u008f`: `^O`,
+ `\u0090`: `^P`,
+ `\u0091`: `^Q`,
+ `\u0092`: `^R`,
+ `\u0093`: `^S`,
+ `\u0094`: `^T`,
+ `\u0095`: `^U`,
+ `\u0096`: `^V`,
+ `\u0097`: `^W`,
+ `\u0098`: `^X`,
+ `\u0099`: `^Y`,
+ `\u009a`: `^Z`,
+ `\u009b`: `^[`,
+ `\u009c`: `^\\`,
+ `\u009d`: `^]`,
+ `\u009e`: `^^`,
+ `\u009f`: `^_`,
+ }
+ if c, ok := m[strings.ToLower(string(b))]; ok {
+ return []byte(c), true
+ }
+ return nil, false
+}
diff --git a/vendor/github.com/cli/go-gh/v2/pkg/auth/auth.go b/vendor/github.com/cli/go-gh/v2/pkg/auth/auth.go
new file mode 100644
index 000000000..6ab996f81
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/pkg/auth/auth.go
@@ -0,0 +1,194 @@
+// Package auth is a set of functions for retrieving authentication tokens
+// and authenticated hosts.
+package auth
+
+import (
+ "fmt"
+ "os"
+ "os/exec"
+ "strconv"
+ "strings"
+
+ "github.com/cli/go-gh/v2/internal/set"
+ "github.com/cli/go-gh/v2/pkg/config"
+ "github.com/cli/safeexec"
+)
+
+const (
+ codespaces = "CODESPACES"
+ defaultSource = "default"
+ ghEnterpriseToken = "GH_ENTERPRISE_TOKEN"
+ ghHost = "GH_HOST"
+ ghToken = "GH_TOKEN"
+ github = "github.com"
+ githubEnterpriseToken = "GITHUB_ENTERPRISE_TOKEN"
+ githubToken = "GITHUB_TOKEN"
+ hostsKey = "hosts"
+ localhost = "github.localhost"
+ oauthToken = "oauth_token"
+)
+
+// TokenForHost retrieves an authentication token and the source of that token for the specified
+// host. The source can be either an environment variable, configuration file, or the system
+// keyring. In the latter case, this shells out to "gh auth token" to obtain the token.
+//
+// Returns "", "default" if no applicable token is found.
+func TokenForHost(host string) (string, string) {
+ if token, source := TokenFromEnvOrConfig(host); token != "" {
+ return token, source
+ }
+
+ ghExe := os.Getenv("GH_PATH")
+ if ghExe == "" {
+ ghExe, _ = safeexec.LookPath("gh")
+ }
+
+ if ghExe != "" {
+ if token, source := tokenFromGh(ghExe, host); token != "" {
+ return token, source
+ }
+ }
+
+ return "", defaultSource
+}
+
+// TokenFromEnvOrConfig retrieves an authentication token from environment variables or the config
+// file as fallback, but does not support reading the token from system keyring. Most consumers
+// should use TokenForHost.
+func TokenFromEnvOrConfig(host string) (string, string) {
+ cfg, _ := config.Read(nil)
+ return tokenForHost(cfg, host)
+}
+
+func tokenForHost(cfg *config.Config, host string) (string, string) {
+ host = normalizeHostname(host)
+ if IsEnterprise(host) {
+ if token := os.Getenv(ghEnterpriseToken); token != "" {
+ return token, ghEnterpriseToken
+ }
+ if token := os.Getenv(githubEnterpriseToken); token != "" {
+ return token, githubEnterpriseToken
+ }
+ if isCodespaces, _ := strconv.ParseBool(os.Getenv(codespaces)); isCodespaces {
+ if token := os.Getenv(githubToken); token != "" {
+ return token, githubToken
+ }
+ }
+ if cfg != nil {
+ token, _ := cfg.Get([]string{hostsKey, host, oauthToken})
+ return token, oauthToken
+ }
+ }
+ if token := os.Getenv(ghToken); token != "" {
+ return token, ghToken
+ }
+ if token := os.Getenv(githubToken); token != "" {
+ return token, githubToken
+ }
+ if cfg != nil {
+ token, _ := cfg.Get([]string{hostsKey, host, oauthToken})
+ return token, oauthToken
+ }
+ return "", defaultSource
+}
+
+func tokenFromGh(path string, host string) (string, string) {
+ cmd := exec.Command(path, "auth", "token", "--secure-storage", "--hostname", host)
+ result, err := cmd.Output()
+ if err != nil {
+ return "", "gh"
+ }
+ return strings.TrimSpace(string(result)), "gh"
+}
+
+// KnownHosts retrieves a list of hosts that have corresponding
+// authentication tokens, either from environment variables
+// or from the configuration file.
+// Returns an empty string slice if no hosts are found.
+func KnownHosts() []string {
+ cfg, _ := config.Read(nil)
+ return knownHosts(cfg)
+}
+
+func knownHosts(cfg *config.Config) []string {
+ hosts := set.NewStringSet()
+ if host := os.Getenv(ghHost); host != "" {
+ hosts.Add(host)
+ }
+ if token, _ := tokenForHost(cfg, github); token != "" {
+ hosts.Add(github)
+ }
+ if cfg != nil {
+ keys, err := cfg.Keys([]string{hostsKey})
+ if err == nil {
+ hosts.AddValues(keys)
+ }
+ }
+ return hosts.ToSlice()
+}
+
+// DefaultHost retrieves an authenticated host and the source of host.
+// The source can be either an environment variable or from the
+// configuration file.
+// Returns "github.com", "default" if no viable host is found.
+func DefaultHost() (string, string) {
+ cfg, _ := config.Read(nil)
+ return defaultHost(cfg)
+}
+
+func defaultHost(cfg *config.Config) (string, string) {
+ if host := os.Getenv(ghHost); host != "" {
+ return host, ghHost
+ }
+ if cfg != nil {
+ keys, err := cfg.Keys([]string{hostsKey})
+ if err == nil && len(keys) == 1 {
+ return keys[0], hostsKey
+ }
+ }
+ return github, defaultSource
+}
+
+// TenancyHost is the domain name of a tenancy GitHub instance.
+const tenancyHost = "ghe.com"
+
+// IsEnterprise determines if a provided host is a GitHub Enterprise Server instance,
+// rather than GitHub.com or a tenancy GitHub instance.
+func IsEnterprise(host string) bool {
+ normalizedHost := normalizeHostname(host)
+ return normalizedHost != github && normalizedHost != localhost && !IsTenancy(normalizedHost)
+}
+
+// IsTenancy determines if a provided host is a tenancy GitHub instance,
+// rather than GitHub.com or a GitHub Enterprise Server instance.
+func IsTenancy(host string) bool {
+ normalizedHost := normalizeHostname(host)
+ return strings.HasSuffix(normalizedHost, "."+tenancyHost)
+}
+
+func normalizeHostname(host string) string {
+ hostname := strings.ToLower(host)
+ if strings.HasSuffix(hostname, "."+github) {
+ return github
+ }
+ if strings.HasSuffix(hostname, "."+localhost) {
+ return localhost
+ }
+ // This has been copied over from the cli/cli NormalizeHostname function
+ // to ensure compatible behaviour but we don't fully understand when or
+ // why it would be useful here. We can't see what harm will come of
+ // duplicating the logic.
+ if before, found := cutSuffix(hostname, "."+tenancyHost); found {
+ idx := strings.LastIndex(before, ".")
+ return fmt.Sprintf("%s.%s", before[idx+1:], tenancyHost)
+ }
+ return hostname
+}
+
+// Backport strings.CutSuffix from Go 1.20.
+func cutSuffix(s, suffix string) (string, bool) {
+ if !strings.HasSuffix(s, suffix) {
+ return s, false
+ }
+ return s[:len(s)-len(suffix)], true
+}
diff --git a/vendor/github.com/cli/go-gh/v2/pkg/browser/browser.go b/vendor/github.com/cli/go-gh/v2/pkg/browser/browser.go
new file mode 100644
index 000000000..4d567106d
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/pkg/browser/browser.go
@@ -0,0 +1,80 @@
+// Package browser facilitates opening of URLs in a web browser.
+package browser
+
+import (
+ "io"
+ "os"
+ "os/exec"
+
+ cliBrowser "github.com/cli/browser"
+ "github.com/cli/go-gh/v2/pkg/config"
+ "github.com/cli/safeexec"
+ "github.com/google/shlex"
+)
+
+// Browser represents a web browser that can be used to open up URLs.
+type Browser struct {
+ launcher string
+ stderr io.Writer
+ stdout io.Writer
+}
+
+// New initializes a Browser. If a launcher is not specified
+// one is determined based on environment variables or from the
+// configuration file.
+// The order of precedence for determining a launcher is:
+// - Specified launcher;
+// - GH_BROWSER environment variable;
+// - browser option from configuration file;
+// - BROWSER environment variable.
+func New(launcher string, stdout, stderr io.Writer) *Browser {
+ if launcher == "" {
+ launcher = resolveLauncher()
+ }
+ b := &Browser{
+ launcher: launcher,
+ stderr: stderr,
+ stdout: stdout,
+ }
+ return b
+}
+
+// Browse opens the launcher and navigates to the specified URL.
+func (b *Browser) Browse(url string) error {
+ return b.browse(url, nil)
+}
+
+func (b *Browser) browse(url string, env []string) error {
+ if b.launcher == "" {
+ return cliBrowser.OpenURL(url)
+ }
+ launcherArgs, err := shlex.Split(b.launcher)
+ if err != nil {
+ return err
+ }
+ launcherExe, err := safeexec.LookPath(launcherArgs[0])
+ if err != nil {
+ return err
+ }
+ args := append(launcherArgs[1:], url)
+ cmd := exec.Command(launcherExe, args...)
+ cmd.Stdout = b.stdout
+ cmd.Stderr = b.stderr
+ if env != nil {
+ cmd.Env = env
+ }
+ return cmd.Run()
+}
+
+func resolveLauncher() string {
+ if ghBrowser := os.Getenv("GH_BROWSER"); ghBrowser != "" {
+ return ghBrowser
+ }
+ cfg, err := config.Read(nil)
+ if err == nil {
+ if cfgBrowser, _ := cfg.Get([]string{"browser"}); cfgBrowser != "" {
+ return cfgBrowser
+ }
+ }
+ return os.Getenv("BROWSER")
+}
diff --git a/vendor/github.com/cli/go-gh/v2/pkg/config/config.go b/vendor/github.com/cli/go-gh/v2/pkg/config/config.go
new file mode 100644
index 000000000..0de46fe79
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/pkg/config/config.go
@@ -0,0 +1,336 @@
+// Package config is a set of types for interacting with the gh configuration files.
+// Note: This package is intended for use only in gh, any other use cases are subject
+// to breakage and non-backwards compatible updates.
+package config
+
+import (
+ "errors"
+ "io"
+ "os"
+ "path/filepath"
+ "runtime"
+ "sync"
+
+ "github.com/cli/go-gh/v2/internal/yamlmap"
+)
+
+const (
+ appData = "AppData"
+ ghConfigDir = "GH_CONFIG_DIR"
+ localAppData = "LocalAppData"
+ xdgConfigHome = "XDG_CONFIG_HOME"
+ xdgDataHome = "XDG_DATA_HOME"
+ xdgStateHome = "XDG_STATE_HOME"
+ xdgCacheHome = "XDG_CACHE_HOME"
+)
+
+var (
+ cfg *Config
+ once sync.Once
+ loadErr error
+)
+
+// Config is a in memory representation of the gh configuration files.
+// It can be thought of as map where entries consist of a key that
+// correspond to either a string value or a map value, allowing for
+// multi-level maps.
+type Config struct {
+ entries *yamlmap.Map
+ mu sync.RWMutex
+}
+
+// Get a string value from a Config.
+// The keys argument is a sequence of key values so that nested
+// entries can be retrieved. A undefined string will be returned
+// if trying to retrieve a key that corresponds to a map value.
+// Returns "", KeyNotFoundError if any of the keys can not be found.
+func (c *Config) Get(keys []string) (string, error) {
+ c.mu.RLock()
+ defer c.mu.RUnlock()
+ m := c.entries
+ for _, key := range keys {
+ var err error
+ m, err = m.FindEntry(key)
+ if err != nil {
+ return "", &KeyNotFoundError{key}
+ }
+ }
+ return m.Value, nil
+}
+
+// Keys enumerates a Config's keys.
+// The keys argument is a sequence of key values so that nested
+// map values can be have their keys enumerated.
+// Returns nil, KeyNotFoundError if any of the keys can not be found.
+func (c *Config) Keys(keys []string) ([]string, error) {
+ c.mu.RLock()
+ defer c.mu.RUnlock()
+ m := c.entries
+ for _, key := range keys {
+ var err error
+ m, err = m.FindEntry(key)
+ if err != nil {
+ return nil, &KeyNotFoundError{key}
+ }
+ }
+ return m.Keys(), nil
+}
+
+// Remove an entry from a Config.
+// The keys argument is a sequence of key values so that nested
+// entries can be removed. Removing an entry that has nested
+// entries removes those also.
+// Returns KeyNotFoundError if any of the keys can not be found.
+func (c *Config) Remove(keys []string) error {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ m := c.entries
+ for i := 0; i < len(keys)-1; i++ {
+ var err error
+ key := keys[i]
+ m, err = m.FindEntry(key)
+ if err != nil {
+ return &KeyNotFoundError{key}
+ }
+ }
+ err := m.RemoveEntry(keys[len(keys)-1])
+ if err != nil {
+ return &KeyNotFoundError{keys[len(keys)-1]}
+ }
+ return nil
+}
+
+// Set a string value in a Config.
+// The keys argument is a sequence of key values so that nested
+// entries can be set. If any of the keys do not exist they will
+// be created. If the string value to be set is empty it will be
+// represented as null not an empty string when written.
+//
+// var c *Config
+// c.Set([]string{"key"}, "")
+// Write(c) // writes `key: ` not `key: ""`
+func (c *Config) Set(keys []string, value string) {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ m := c.entries
+ for i := 0; i < len(keys)-1; i++ {
+ key := keys[i]
+ entry, err := m.FindEntry(key)
+ if err != nil {
+ entry = yamlmap.MapValue()
+ m.AddEntry(key, entry)
+ }
+ m = entry
+ }
+ val := yamlmap.StringValue(value)
+ if value == "" {
+ val = yamlmap.NullValue()
+ }
+ m.SetEntry(keys[len(keys)-1], val)
+}
+
+func (c *Config) deepCopy() *Config {
+ return ReadFromString(c.entries.String())
+}
+
+// Read gh configuration files from the local file system and
+// returns a Config. A copy of the fallback configuration will
+// be returned when there are no configuration files to load.
+// If there are no configuration files and no fallback configuration
+// an empty configuration will be returned.
+var Read = func(fallback *Config) (*Config, error) {
+ once.Do(func() {
+ cfg, loadErr = load(generalConfigFile(), hostsConfigFile(), fallback)
+ })
+ return cfg, loadErr
+}
+
+// ReadFromString takes a yaml string and returns a Config.
+func ReadFromString(str string) *Config {
+ m, _ := mapFromString(str)
+ if m == nil {
+ m = yamlmap.MapValue()
+ }
+ return &Config{entries: m}
+}
+
+// Write gh configuration files to the local file system.
+// It will only write gh configuration files that have been modified
+// since last being read.
+func Write(c *Config) error {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ hosts, err := c.entries.FindEntry("hosts")
+ if err == nil && hosts.IsModified() {
+ err := writeFile(hostsConfigFile(), []byte(hosts.String()))
+ if err != nil {
+ return err
+ }
+ hosts.SetUnmodified()
+ }
+
+ if c.entries.IsModified() {
+ // Hosts gets written to a different file above so remove it
+ // before writing and add it back in after writing.
+ hostsMap, hostsErr := c.entries.FindEntry("hosts")
+ if hostsErr == nil {
+ _ = c.entries.RemoveEntry("hosts")
+ }
+ err := writeFile(generalConfigFile(), []byte(c.entries.String()))
+ if err != nil {
+ return err
+ }
+ c.entries.SetUnmodified()
+ if hostsErr == nil {
+ c.entries.AddEntry("hosts", hostsMap)
+ }
+ }
+
+ return nil
+}
+
+func load(generalFilePath, hostsFilePath string, fallback *Config) (*Config, error) {
+ generalMap, err := mapFromFile(generalFilePath)
+ if err != nil && !os.IsNotExist(err) {
+ if errors.Is(err, yamlmap.ErrInvalidYaml) ||
+ errors.Is(err, yamlmap.ErrInvalidFormat) {
+ return nil, &InvalidConfigFileError{Path: generalFilePath, Err: err}
+ }
+ return nil, err
+ }
+
+ if generalMap == nil {
+ generalMap = yamlmap.MapValue()
+ }
+
+ hostsMap, err := mapFromFile(hostsFilePath)
+ if err != nil && !os.IsNotExist(err) {
+ if errors.Is(err, yamlmap.ErrInvalidYaml) ||
+ errors.Is(err, yamlmap.ErrInvalidFormat) {
+ return nil, &InvalidConfigFileError{Path: hostsFilePath, Err: err}
+ }
+ return nil, err
+ }
+
+ if hostsMap != nil && !hostsMap.Empty() {
+ generalMap.AddEntry("hosts", hostsMap)
+ generalMap.SetUnmodified()
+ }
+
+ if generalMap.Empty() && fallback != nil {
+ return fallback.deepCopy(), nil
+ }
+
+ return &Config{entries: generalMap}, nil
+}
+
+func generalConfigFile() string {
+ return filepath.Join(ConfigDir(), "config.yml")
+}
+
+func hostsConfigFile() string {
+ return filepath.Join(ConfigDir(), "hosts.yml")
+}
+
+func mapFromFile(filename string) (*yamlmap.Map, error) {
+ data, err := readFile(filename)
+ if err != nil {
+ return nil, err
+ }
+ return yamlmap.Unmarshal(data)
+}
+
+func mapFromString(str string) (*yamlmap.Map, error) {
+ return yamlmap.Unmarshal([]byte(str))
+}
+
+// Config path precedence: GH_CONFIG_DIR, XDG_CONFIG_HOME, AppData (windows only), HOME.
+func ConfigDir() string {
+ var path string
+ if a := os.Getenv(ghConfigDir); a != "" {
+ path = a
+ } else if b := os.Getenv(xdgConfigHome); b != "" {
+ path = filepath.Join(b, "gh")
+ } else if c := os.Getenv(appData); runtime.GOOS == "windows" && c != "" {
+ path = filepath.Join(c, "GitHub CLI")
+ } else {
+ d, _ := os.UserHomeDir()
+ path = filepath.Join(d, ".config", "gh")
+ }
+ return path
+}
+
+// State path precedence: XDG_STATE_HOME, LocalAppData (windows only), HOME.
+func StateDir() string {
+ var path string
+ if a := os.Getenv(xdgStateHome); a != "" {
+ path = filepath.Join(a, "gh")
+ } else if b := os.Getenv(localAppData); runtime.GOOS == "windows" && b != "" {
+ path = filepath.Join(b, "GitHub CLI")
+ } else {
+ c, _ := os.UserHomeDir()
+ path = filepath.Join(c, ".local", "state", "gh")
+ }
+ return path
+}
+
+// Data path precedence: XDG_DATA_HOME, LocalAppData (windows only), HOME.
+func DataDir() string {
+ var path string
+ if a := os.Getenv(xdgDataHome); a != "" {
+ path = filepath.Join(a, "gh")
+ } else if b := os.Getenv(localAppData); runtime.GOOS == "windows" && b != "" {
+ path = filepath.Join(b, "GitHub CLI")
+ } else {
+ c, _ := os.UserHomeDir()
+ path = filepath.Join(c, ".local", "share", "gh")
+ }
+ return path
+}
+
+// Cache path precedence: XDG_CACHE_HOME, LocalAppData (windows only), HOME, legacy gh-cli-cache.
+func CacheDir() string {
+ if a := os.Getenv(xdgCacheHome); a != "" {
+ return filepath.Join(a, "gh")
+ } else if b := os.Getenv(localAppData); runtime.GOOS == "windows" && b != "" {
+ return filepath.Join(b, "GitHub CLI")
+ } else if c, err := os.UserHomeDir(); err == nil {
+ return filepath.Join(c, ".cache", "gh")
+ } else {
+ // Note that this has a minor security issue because /tmp is world-writeable.
+ // As such, it is possible for other users on a shared system to overwrite cached data.
+ // The practical risk of this is low, but it's worth calling out as a risk.
+ // I've included this here for backwards compatibility but we should consider removing it.
+ return filepath.Join(os.TempDir(), "gh-cli-cache")
+ }
+}
+
+func readFile(filename string) ([]byte, error) {
+ f, err := os.Open(filename)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+ data, err := io.ReadAll(f)
+ if err != nil {
+ return nil, err
+ }
+ return data, nil
+}
+
+func writeFile(filename string, data []byte) (writeErr error) {
+ if writeErr = os.MkdirAll(filepath.Dir(filename), 0771); writeErr != nil {
+ return
+ }
+ var file *os.File
+ if file, writeErr = os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600); writeErr != nil {
+ return
+ }
+ defer func() {
+ if err := file.Close(); writeErr == nil && err != nil {
+ writeErr = err
+ }
+ }()
+ _, writeErr = file.Write(data)
+ return
+}
diff --git a/vendor/github.com/cli/go-gh/v2/pkg/config/errors.go b/vendor/github.com/cli/go-gh/v2/pkg/config/errors.go
new file mode 100644
index 000000000..1aefd1922
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/pkg/config/errors.go
@@ -0,0 +1,32 @@
+package config
+
+import (
+ "fmt"
+)
+
+// InvalidConfigFileError represents an error when trying to read a config file.
+type InvalidConfigFileError struct {
+ Path string
+ Err error
+}
+
+// Allow InvalidConfigFileError to satisfy error interface.
+func (e *InvalidConfigFileError) Error() string {
+ return fmt.Sprintf("invalid config file %s: %s", e.Path, e.Err)
+}
+
+// Allow InvalidConfigFileError to be unwrapped.
+func (e *InvalidConfigFileError) Unwrap() error {
+ return e.Err
+}
+
+// KeyNotFoundError represents an error when trying to find a config key
+// that does not exist.
+type KeyNotFoundError struct {
+ Key string
+}
+
+// Allow KeyNotFoundError to satisfy error interface.
+func (e *KeyNotFoundError) Error() string {
+ return fmt.Sprintf("could not find key %q", e.Key)
+}
diff --git a/vendor/github.com/cli/go-gh/v2/pkg/jq/jq.go b/vendor/github.com/cli/go-gh/v2/pkg/jq/jq.go
new file mode 100644
index 000000000..ade2308be
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/pkg/jq/jq.go
@@ -0,0 +1,159 @@
+// Package jq facilitates processing of JSON strings using jq expressions.
+package jq
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "math"
+ "os"
+ "strconv"
+ "strings"
+
+ "github.com/cli/go-gh/v2/pkg/jsonpretty"
+ "github.com/itchyny/gojq"
+)
+
+// Evaluate a jq expression against an input and write it to an output.
+// Any top-level scalar values produced by the jq expression are written out
+// directly, as raw values and not as JSON scalars, similar to how jq --raw
+// works.
+func Evaluate(input io.Reader, output io.Writer, expr string) error {
+ return EvaluateFormatted(input, output, expr, "", false)
+}
+
+// Evaluate a jq expression against an input and write it to an output,
+// optionally with indentation and colorization. Any top-level scalar values
+// produced by the jq expression are written out directly, as raw values and not
+// as JSON scalars, similar to how jq --raw works.
+func EvaluateFormatted(input io.Reader, output io.Writer, expr string, indent string, colorize bool) error {
+ query, err := gojq.Parse(expr)
+ if err != nil {
+ var e *gojq.ParseError
+ if errors.As(err, &e) {
+ str, line, column := getLineColumn(expr, e.Offset-len(e.Token))
+ return fmt.Errorf(
+ "failed to parse jq expression (line %d, column %d)\n %s\n %*c %w",
+ line, column, str, column, '^', err,
+ )
+ }
+ return err
+ }
+
+ code, err := gojq.Compile(
+ query,
+ gojq.WithEnvironLoader(func() []string {
+ return os.Environ()
+ }))
+ if err != nil {
+ return err
+ }
+
+ jsonData, err := io.ReadAll(input)
+ if err != nil {
+ return err
+ }
+
+ var responseData interface{}
+ err = json.Unmarshal(jsonData, &responseData)
+ if err != nil {
+ return err
+ }
+
+ enc := prettyEncoder{
+ w: output,
+ indent: indent,
+ colorize: colorize,
+ }
+
+ iter := code.Run(responseData)
+ for {
+ v, ok := iter.Next()
+ if !ok {
+ break
+ }
+ if err, isErr := v.(error); isErr {
+ var e *gojq.HaltError
+ if errors.As(err, &e) && e.Value() == nil {
+ break
+ }
+ return err
+ }
+ if text, e := jsonScalarToString(v); e == nil {
+ _, err := fmt.Fprintln(output, text)
+ if err != nil {
+ return err
+ }
+ } else {
+ if err = enc.Encode(v); err != nil {
+ return err
+ }
+ }
+ }
+
+ return nil
+}
+
+func jsonScalarToString(input interface{}) (string, error) {
+ switch tt := input.(type) {
+ case string:
+ return tt, nil
+ case float64:
+ if math.Trunc(tt) == tt {
+ return strconv.FormatFloat(tt, 'f', 0, 64), nil
+ } else {
+ return strconv.FormatFloat(tt, 'f', 2, 64), nil
+ }
+ case nil:
+ return "", nil
+ case bool:
+ return fmt.Sprintf("%v", tt), nil
+ default:
+ return "", fmt.Errorf("cannot convert type to string: %v", tt)
+ }
+}
+
+type prettyEncoder struct {
+ w io.Writer
+ indent string
+ colorize bool
+}
+
+func (p prettyEncoder) Encode(v any) error {
+ var b []byte
+ var err error
+ if p.indent == "" {
+ b, err = json.Marshal(v)
+ } else {
+ b, err = json.MarshalIndent(v, "", p.indent)
+ }
+ if err != nil {
+ return err
+ }
+ if !p.colorize {
+ if _, err := p.w.Write(b); err != nil {
+ return err
+ }
+ if _, err := p.w.Write([]byte{'\n'}); err != nil {
+ return err
+ }
+ return nil
+ }
+ return jsonpretty.Format(p.w, bytes.NewReader(b), p.indent, true)
+}
+
+func getLineColumn(expr string, offset int) (string, int, int) {
+ for line := 1; ; line++ {
+ index := strings.Index(expr, "\n")
+ if index < 0 {
+ return expr, line, offset + 1
+ }
+ if index >= offset {
+ return expr[:index], line, offset + 1
+ }
+ expr = expr[index+1:]
+ offset -= index + 1
+ }
+}
diff --git a/vendor/github.com/cli/go-gh/v2/pkg/jsonpretty/format.go b/vendor/github.com/cli/go-gh/v2/pkg/jsonpretty/format.go
new file mode 100644
index 000000000..63ac972fc
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/pkg/jsonpretty/format.go
@@ -0,0 +1,144 @@
+// Package jsonpretty implements a terminal pretty-printer for JSON.
+package jsonpretty
+
+import (
+ "bytes"
+ "encoding/json"
+ "fmt"
+ "io"
+ "strings"
+)
+
+const (
+ colorDelim = "\x1b[1;38m" // bright white
+ colorKey = "\x1b[1;34m" // bright blue
+ colorNull = "\x1b[36m" // cyan
+ colorString = "\x1b[32m" // green
+ colorBool = "\x1b[33m" // yellow
+ colorReset = "\x1b[m"
+)
+
+// Format reads JSON from r and writes a prettified version of it to w.
+func Format(w io.Writer, r io.Reader, indent string, colorize bool) error {
+ dec := json.NewDecoder(r)
+ dec.UseNumber()
+
+ c := func(ansi string) string {
+ if !colorize {
+ return ""
+ }
+ return ansi
+ }
+
+ var idx int
+ var stack []json.Delim
+
+ for {
+ t, err := dec.Token()
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ return err
+ }
+
+ switch tt := t.(type) {
+ case json.Delim:
+ switch tt {
+ case '{', '[':
+ stack = append(stack, tt)
+ idx = 0
+ if _, err := fmt.Fprint(w, c(colorDelim), tt, c(colorReset)); err != nil {
+ return err
+ }
+ if dec.More() {
+ if _, err := fmt.Fprint(w, "\n", strings.Repeat(indent, len(stack))); err != nil {
+ return err
+ }
+ }
+ continue
+ case '}', ']':
+ stack = stack[:len(stack)-1]
+ idx = 0
+ if _, err := fmt.Fprint(w, c(colorDelim), tt, c(colorReset)); err != nil {
+ return err
+ }
+ }
+ default:
+ b, err := marshalJSON(tt)
+ if err != nil {
+ return err
+ }
+
+ isKey := len(stack) > 0 && stack[len(stack)-1] == '{' && idx%2 == 0
+ idx++
+
+ var color string
+ if isKey {
+ color = colorKey
+ } else if tt == nil {
+ color = colorNull
+ } else {
+ switch t.(type) {
+ case string:
+ color = colorString
+ case bool:
+ color = colorBool
+ }
+ }
+
+ if color != "" {
+ if _, err := fmt.Fprint(w, c(color)); err != nil {
+ return err
+ }
+ }
+ if _, err := w.Write(b); err != nil {
+ return err
+ }
+ if color != "" {
+ if _, err := fmt.Fprint(w, c(colorReset)); err != nil {
+ return err
+ }
+ }
+
+ if isKey {
+ if _, err := fmt.Fprint(w, c(colorDelim), ":", c(colorReset), " "); err != nil {
+ return err
+ }
+ continue
+ }
+ }
+
+ if dec.More() {
+ if _, err := fmt.Fprint(w, c(colorDelim), ",", c(colorReset), "\n", strings.Repeat(indent, len(stack))); err != nil {
+ return err
+ }
+ } else if len(stack) > 0 {
+ if _, err := fmt.Fprint(w, "\n", strings.Repeat(indent, len(stack)-1)); err != nil {
+ return err
+ }
+ } else {
+ if _, err := fmt.Fprint(w, "\n"); err != nil {
+ return err
+ }
+ }
+ }
+
+ return nil
+}
+
+// marshalJSON works like json.Marshal, but with HTML-escaping disabled.
+func marshalJSON(v interface{}) ([]byte, error) {
+ buf := bytes.Buffer{}
+ enc := json.NewEncoder(&buf)
+ enc.SetEscapeHTML(false)
+ if err := enc.Encode(v); err != nil {
+ return nil, err
+ }
+ bb := buf.Bytes()
+ // omit trailing newline added by json.Encoder
+ if len(bb) > 0 && bb[len(bb)-1] == '\n' {
+ return bb[:len(bb)-1], nil
+ }
+ return bb, nil
+}
diff --git a/vendor/github.com/cli/go-gh/v2/pkg/prompter/mock.go b/vendor/github.com/cli/go-gh/v2/pkg/prompter/mock.go
new file mode 100644
index 000000000..c5694239c
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/pkg/prompter/mock.go
@@ -0,0 +1,228 @@
+package prompter
+
+import (
+ "fmt"
+ "strings"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+// PrompterMock provides stubbed out methods for prompting the user for
+// use in tests. PrompterMock has a superset of the methods on Prompter
+// so they both can satisfy the same interface.
+//
+// A basic example of how PrompterMock can be used:
+//
+// type ConfirmPrompter interface {
+// Confirm(string, bool) (bool, error)
+// }
+//
+// func PlayGame(prompter ConfirmPrompter) (int, error) {
+// confirm, err := prompter.Confirm("Shall we play a game", true)
+// if err != nil {
+// return 0, err
+// }
+// if confirm {
+// return 1, nil
+// }
+// return 2, nil
+// }
+//
+// func TestPlayGame(t *testing.T) {
+// expectedOutcome := 1
+// mock := NewMock(t)
+// mock.RegisterConfirm("Shall we play a game", func(prompt string, defaultValue bool) (bool, error) {
+// return true, nil
+// })
+// outcome, err := PlayGame(mock)
+// if err != nil {
+// t.Fatalf("unexpected error: %v", err)
+// }
+// if outcome != expectedOutcome {
+// t.Errorf("expected %q, got %q", expectedOutcome, outcome)
+// }
+// }
+type PrompterMock struct {
+ t *testing.T
+ selectStubs []selectStub
+ multiSelectStubs []multiSelectStub
+ inputStubs []inputStub
+ passwordStubs []passwordStub
+ confirmStubs []confirmStub
+}
+
+type selectStub struct {
+ prompt string
+ expectedOptions []string
+ fn func(string, string, []string) (int, error)
+}
+
+type multiSelectStub struct {
+ prompt string
+ expectedOptions []string
+ fn func(string, []string, []string) ([]int, error)
+}
+
+type inputStub struct {
+ prompt string
+ fn func(string, string) (string, error)
+}
+
+type passwordStub struct {
+ prompt string
+ fn func(string) (string, error)
+}
+
+type confirmStub struct {
+ Prompt string
+ Fn func(string, bool) (bool, error)
+}
+
+// NewMock instantiates a new PrompterMock.
+func NewMock(t *testing.T) *PrompterMock {
+ m := &PrompterMock{
+ t: t,
+ selectStubs: []selectStub{},
+ multiSelectStubs: []multiSelectStub{},
+ inputStubs: []inputStub{},
+ passwordStubs: []passwordStub{},
+ confirmStubs: []confirmStub{},
+ }
+ t.Cleanup(m.verify)
+ return m
+}
+
+// Select prompts the user to select an option from a list of options.
+func (m *PrompterMock) Select(prompt, defaultValue string, options []string) (int, error) {
+ var s selectStub
+ if len(m.selectStubs) == 0 {
+ return -1, noSuchPromptErr(prompt)
+ }
+ s = m.selectStubs[0]
+ m.selectStubs = m.selectStubs[1:len(m.selectStubs)]
+ if s.prompt != prompt {
+ return -1, noSuchPromptErr(prompt)
+ }
+ assertOptions(m.t, s.expectedOptions, options)
+ return s.fn(prompt, defaultValue, options)
+}
+
+// MultiSelect prompts the user to select multiple options from a list of options.
+func (m *PrompterMock) MultiSelect(prompt string, defaultValues, options []string) ([]int, error) {
+ var s multiSelectStub
+ if len(m.multiSelectStubs) == 0 {
+ return []int{}, noSuchPromptErr(prompt)
+ }
+ s = m.multiSelectStubs[0]
+ m.multiSelectStubs = m.multiSelectStubs[1:len(m.multiSelectStubs)]
+ if s.prompt != prompt {
+ return []int{}, noSuchPromptErr(prompt)
+ }
+ assertOptions(m.t, s.expectedOptions, options)
+ return s.fn(prompt, defaultValues, options)
+}
+
+// Input prompts the user to input a single-line string.
+func (m *PrompterMock) Input(prompt, defaultValue string) (string, error) {
+ var s inputStub
+ if len(m.inputStubs) == 0 {
+ return "", noSuchPromptErr(prompt)
+ }
+ s = m.inputStubs[0]
+ m.inputStubs = m.inputStubs[1:len(m.inputStubs)]
+ if s.prompt != prompt {
+ return "", noSuchPromptErr(prompt)
+ }
+ return s.fn(prompt, defaultValue)
+}
+
+// Password prompts the user to input a single-line string without echoing the input.
+func (m *PrompterMock) Password(prompt string) (string, error) {
+ var s passwordStub
+ if len(m.passwordStubs) == 0 {
+ return "", noSuchPromptErr(prompt)
+ }
+ s = m.passwordStubs[0]
+ m.passwordStubs = m.passwordStubs[1:len(m.passwordStubs)]
+ if s.prompt != prompt {
+ return "", noSuchPromptErr(prompt)
+ }
+ return s.fn(prompt)
+}
+
+// Confirm prompts the user to confirm a yes/no question.
+func (m *PrompterMock) Confirm(prompt string, defaultValue bool) (bool, error) {
+ var s confirmStub
+ if len(m.confirmStubs) == 0 {
+ return false, noSuchPromptErr(prompt)
+ }
+ s = m.confirmStubs[0]
+ m.confirmStubs = m.confirmStubs[1:len(m.confirmStubs)]
+ if s.Prompt != prompt {
+ return false, noSuchPromptErr(prompt)
+ }
+ return s.Fn(prompt, defaultValue)
+}
+
+// RegisterSelect records that a Select prompt should be called.
+func (m *PrompterMock) RegisterSelect(prompt string, opts []string, stub func(_, _ string, _ []string) (int, error)) {
+ m.selectStubs = append(m.selectStubs, selectStub{
+ prompt: prompt,
+ expectedOptions: opts,
+ fn: stub})
+}
+
+// RegisterMultiSelect records that a MultiSelect prompt should be called.
+func (m *PrompterMock) RegisterMultiSelect(prompt string, d, opts []string, stub func(_ string, _, _ []string) ([]int, error)) {
+ m.multiSelectStubs = append(m.multiSelectStubs, multiSelectStub{
+ prompt: prompt,
+ expectedOptions: opts,
+ fn: stub})
+}
+
+// RegisterInput records that an Input prompt should be called.
+func (m *PrompterMock) RegisterInput(prompt string, stub func(_, _ string) (string, error)) {
+ m.inputStubs = append(m.inputStubs, inputStub{prompt: prompt, fn: stub})
+}
+
+// RegisterPassword records that a Password prompt should be called.
+func (m *PrompterMock) RegisterPassword(prompt string, stub func(string) (string, error)) {
+ m.passwordStubs = append(m.passwordStubs, passwordStub{prompt: prompt, fn: stub})
+}
+
+// RegisterConfirm records that a Confirm prompt should be called.
+func (m *PrompterMock) RegisterConfirm(prompt string, stub func(_ string, _ bool) (bool, error)) {
+ m.confirmStubs = append(m.confirmStubs, confirmStub{Prompt: prompt, Fn: stub})
+}
+
+func (m *PrompterMock) verify() {
+ errs := []string{}
+ if len(m.selectStubs) > 0 {
+ errs = append(errs, "MultiSelect")
+ }
+ if len(m.multiSelectStubs) > 0 {
+ errs = append(errs, "Select")
+ }
+ if len(m.inputStubs) > 0 {
+ errs = append(errs, "Input")
+ }
+ if len(m.passwordStubs) > 0 {
+ errs = append(errs, "Password")
+ }
+ if len(m.confirmStubs) > 0 {
+ errs = append(errs, "Confirm")
+ }
+ if len(errs) > 0 {
+ m.t.Helper()
+ m.t.Errorf("%d unmatched calls to %s", len(errs), strings.Join(errs, ","))
+ }
+}
+
+func noSuchPromptErr(prompt string) error {
+ return fmt.Errorf("no such prompt '%s'", prompt)
+}
+
+func assertOptions(t *testing.T, expected, actual []string) {
+ assert.Equal(t, expected, actual)
+}
diff --git a/vendor/github.com/cli/go-gh/v2/pkg/prompter/prompter.go b/vendor/github.com/cli/go-gh/v2/pkg/prompter/prompter.go
new file mode 100644
index 000000000..1cc184916
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/pkg/prompter/prompter.go
@@ -0,0 +1,134 @@
+// Package prompter provides various methods for prompting the user with
+// questions for input.
+package prompter
+
+import (
+ "fmt"
+ "io"
+ "strings"
+
+ "github.com/AlecAivazis/survey/v2"
+ "github.com/cli/go-gh/v2/pkg/text"
+)
+
+// Prompter provides methods for prompting the user.
+type Prompter struct {
+ stdin FileReader
+ stdout FileWriter
+ stderr FileWriter
+}
+
+// FileWriter provides a minimal writable interface for stdout and stderr.
+type FileWriter interface {
+ io.Writer
+ Fd() uintptr
+}
+
+// FileReader provides a minimal readable interface for stdin.
+type FileReader interface {
+ io.Reader
+ Fd() uintptr
+}
+
+// New instantiates a new Prompter.
+func New(stdin FileReader, stdout FileWriter, stderr FileWriter) *Prompter {
+ return &Prompter{
+ stdin: stdin,
+ stdout: stdout,
+ stderr: stderr,
+ }
+}
+
+// Select prompts the user to select an option from a list of options.
+func (p *Prompter) Select(prompt, defaultValue string, options []string) (int, error) {
+ var result int
+ q := &survey.Select{
+ Message: prompt,
+ Options: options,
+ PageSize: 20,
+ Filter: latinMatchingFilter,
+ }
+ if defaultValue != "" {
+ for _, o := range options {
+ if o == defaultValue {
+ q.Default = defaultValue
+ break
+ }
+ }
+ }
+ err := p.ask(q, &result)
+ return result, err
+}
+
+// MultiSelect prompts the user to select multiple options from a list of options.
+func (p *Prompter) MultiSelect(prompt string, defaultValues, options []string) ([]int, error) {
+ var result []int
+ q := &survey.MultiSelect{
+ Message: prompt,
+ Options: options,
+ PageSize: 20,
+ Filter: latinMatchingFilter,
+ }
+ if len(defaultValues) > 0 {
+ validatedDefault := []string{}
+ for _, x := range defaultValues {
+ for _, y := range options {
+ if x == y {
+ validatedDefault = append(validatedDefault, x)
+ }
+ }
+ }
+ q.Default = validatedDefault
+ }
+ err := p.ask(q, &result)
+ return result, err
+}
+
+// Input prompts the user to input a single-line string.
+func (p *Prompter) Input(prompt, defaultValue string) (string, error) {
+ var result string
+ err := p.ask(&survey.Input{
+ Message: prompt,
+ Default: defaultValue,
+ }, &result)
+ return result, err
+}
+
+// Password prompts the user to input a single-line string without echoing the input.
+func (p *Prompter) Password(prompt string) (string, error) {
+ var result string
+ err := p.ask(&survey.Password{
+ Message: prompt,
+ }, &result)
+ return result, err
+}
+
+// Confirm prompts the user to confirm a yes/no question.
+func (p *Prompter) Confirm(prompt string, defaultValue bool) (bool, error) {
+ var result bool
+ err := p.ask(&survey.Confirm{
+ Message: prompt,
+ Default: defaultValue,
+ }, &result)
+ return result, err
+}
+
+func (p *Prompter) ask(q survey.Prompt, response interface{}, opts ...survey.AskOpt) error {
+ opts = append(opts, survey.WithStdio(p.stdin, p.stdout, p.stderr))
+ err := survey.AskOne(q, response, opts...)
+ if err == nil {
+ return nil
+ }
+ return fmt.Errorf("could not prompt: %w", err)
+}
+
+// latinMatchingFilter returns whether the value matches the input filter.
+// The strings are compared normalized in case.
+// The filter's diactritics are kept as-is, but the value's are normalized,
+// so that a missing diactritic in the filter still returns a result.
+func latinMatchingFilter(filter, value string, index int) bool {
+ filter = strings.ToLower(filter)
+ value = strings.ToLower(value)
+ // include this option if it matches.
+ return strings.Contains(value, filter) || strings.Contains(text.RemoveDiacritics(value), filter)
+}
diff --git a/vendor/github.com/cli/go-gh/v2/pkg/repository/repository.go b/vendor/github.com/cli/go-gh/v2/pkg/repository/repository.go
new file mode 100644
index 000000000..2d3400b53
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/pkg/repository/repository.go
@@ -0,0 +1,158 @@
+// Package repository is a set of types and functions for modeling and
+// interacting with GitHub repositories.
+package repository
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "strings"
+
+ "github.com/cli/go-gh/v2/internal/git"
+ "github.com/cli/go-gh/v2/pkg/auth"
+ "github.com/cli/go-gh/v2/pkg/ssh"
+)
+
+// Repository holds information representing a GitHub repository.
+type Repository struct {
+ Host string
+ Name string
+ Owner string
+}
+
+// Parse extracts the repository information from the following
+// string formats: "OWNER/REPO", "HOST/OWNER/REPO", and a full URL.
+// If the format does not specify a host, use the config to determine a host.
+func Parse(s string) (Repository, error) {
+ var r Repository
+
+ if git.IsURL(s) {
+ u, err := git.ParseURL(s)
+ if err != nil {
+ return r, err
+ }
+
+ host, owner, name, err := git.RepoInfoFromURL(u)
+ if err != nil {
+ return r, err
+ }
+
+ r.Host = host
+ r.Name = name
+ r.Owner = owner
+
+ return r, nil
+ }
+
+ parts := strings.SplitN(s, "/", 4)
+ for _, p := range parts {
+ if len(p) == 0 {
+ return r, fmt.Errorf(`expected the "[HOST/]OWNER/REPO" format, got %q`, s)
+ }
+ }
+
+ switch len(parts) {
+ case 3:
+ r.Host = parts[0]
+ r.Owner = parts[1]
+ r.Name = parts[2]
+ return r, nil
+ case 2:
+ r.Host, _ = auth.DefaultHost()
+ r.Owner = parts[0]
+ r.Name = parts[1]
+ return r, nil
+ default:
+ return r, fmt.Errorf(`expected the "[HOST/]OWNER/REPO" format, got %q`, s)
+ }
+}
+
+// Parse extracts the repository information from the following
+// string formats: "OWNER/REPO", "HOST/OWNER/REPO", and a full URL.
+// If the format does not specify a host, use the host provided.
+func ParseWithHost(s, host string) (Repository, error) {
+ var r Repository
+
+ if git.IsURL(s) {
+ u, err := git.ParseURL(s)
+ if err != nil {
+ return r, err
+ }
+
+ host, owner, name, err := git.RepoInfoFromURL(u)
+ if err != nil {
+ return r, err
+ }
+
+ r.Host = host
+ r.Owner = owner
+ r.Name = name
+
+ return r, nil
+ }
+
+ parts := strings.SplitN(s, "/", 4)
+ for _, p := range parts {
+ if len(p) == 0 {
+ return r, fmt.Errorf(`expected the "[HOST/]OWNER/REPO" format, got %q`, s)
+ }
+ }
+
+ switch len(parts) {
+ case 3:
+ r.Host = parts[0]
+ r.Owner = parts[1]
+ r.Name = parts[2]
+ return r, nil
+ case 2:
+ r.Host = host
+ r.Owner = parts[0]
+ r.Name = parts[1]
+ return r, nil
+ default:
+ return r, fmt.Errorf(`expected the "[HOST/]OWNER/REPO" format, got %q`, s)
+ }
+}
+
+// Current uses git remotes to determine the GitHub repository
+// the current directory is tracking.
+func Current() (Repository, error) {
+ var r Repository
+
+ override := os.Getenv("GH_REPO")
+ if override != "" {
+ return Parse(override)
+ }
+
+ remotes, err := git.Remotes()
+ if err != nil {
+ return r, err
+ }
+ if len(remotes) == 0 {
+ return r, errors.New("unable to determine current repository, no git remotes configured for this repository")
+ }
+
+ translator := ssh.NewTranslator()
+ for _, r := range remotes {
+ if r.FetchURL != nil {
+ r.FetchURL = translator.Translate(r.FetchURL)
+ }
+ if r.PushURL != nil {
+ r.PushURL = translator.Translate(r.PushURL)
+ }
+ }
+
+ hosts := auth.KnownHosts()
+
+ filteredRemotes := remotes.FilterByHosts(hosts)
+ if len(filteredRemotes) == 0 {
+ return r, errors.New("unable to determine current repository, none of the git remotes configured for this repository point to a known GitHub host")
+ }
+
+ rem := filteredRemotes[0]
+ r.Host = rem.Host
+ r.Owner = rem.Owner
+ r.Name = rem.Repo
+
+ return r, nil
+}
diff --git a/vendor/github.com/cli/go-gh/v2/pkg/ssh/ssh.go b/vendor/github.com/cli/go-gh/v2/pkg/ssh/ssh.go
new file mode 100644
index 000000000..4e5216e7d
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/pkg/ssh/ssh.go
@@ -0,0 +1,109 @@
+// Package ssh resolves local SSH hostname aliases.
+package ssh
+
+import (
+ "bufio"
+ "net/url"
+ "os/exec"
+ "strings"
+ "sync"
+
+ "github.com/cli/safeexec"
+)
+
+type Translator struct {
+ cacheMap map[string]string
+ cacheMu sync.RWMutex
+ sshPath string
+ sshPathErr error
+ sshPathMu sync.Mutex
+
+ lookPath func(string) (string, error)
+ newCommand func(string, ...string) *exec.Cmd
+}
+
+// NewTranslator initializes a new Translator instance.
+func NewTranslator() *Translator {
+ return &Translator{}
+}
+
+// Translate applies applicable SSH hostname aliases to the specified URL and returns the resulting URL.
+func (t *Translator) Translate(u *url.URL) *url.URL {
+ if u.Scheme != "ssh" {
+ return u
+ }
+ resolvedHost, err := t.resolve(u.Hostname())
+ if err != nil {
+ return u
+ }
+ if strings.EqualFold(resolvedHost, "ssh.github.com") {
+ resolvedHost = "github.com"
+ }
+ newURL, _ := url.Parse(u.String())
+ newURL.Host = resolvedHost
+ return newURL
+}
+
+func (t *Translator) resolve(hostname string) (string, error) {
+ t.cacheMu.RLock()
+ cached, cacheFound := t.cacheMap[strings.ToLower(hostname)]
+ t.cacheMu.RUnlock()
+ if cacheFound {
+ return cached, nil
+ }
+
+ var sshPath string
+ t.sshPathMu.Lock()
+ if t.sshPath == "" && t.sshPathErr == nil {
+ lookPath := t.lookPath
+ if lookPath == nil {
+ lookPath = safeexec.LookPath
+ }
+ t.sshPath, t.sshPathErr = lookPath("ssh")
+ }
+ if t.sshPathErr != nil {
+ defer t.sshPathMu.Unlock()
+ return t.sshPath, t.sshPathErr
+ }
+ sshPath = t.sshPath
+ t.sshPathMu.Unlock()
+
+ t.cacheMu.Lock()
+ defer t.cacheMu.Unlock()
+
+ newCommand := t.newCommand
+ if newCommand == nil {
+ newCommand = exec.Command
+ }
+ sshCmd := newCommand(sshPath, "-G", hostname)
+ stdout, err := sshCmd.StdoutPipe()
+ if err != nil {
+ return "", err
+ }
+
+ if err := sshCmd.Start(); err != nil {
+ return "", err
+ }
+
+ var resolvedHost string
+ s := bufio.NewScanner(stdout)
+ for s.Scan() {
+ line := s.Text()
+ parts := strings.SplitN(line, " ", 2)
+ if len(parts) == 2 && parts[0] == "hostname" {
+ resolvedHost = parts[1]
+ }
+ }
+
+ err = sshCmd.Wait()
+ if err != nil || resolvedHost == "" {
+ // handle failures by returning the original hostname unchanged
+ resolvedHost = hostname
+ }
+
+ if t.cacheMap == nil {
+ t.cacheMap = map[string]string{}
+ }
+ t.cacheMap[strings.ToLower(hostname)] = resolvedHost
+ return resolvedHost, nil
+}
diff --git a/vendor/github.com/cli/go-gh/v2/pkg/tableprinter/table.go b/vendor/github.com/cli/go-gh/v2/pkg/tableprinter/table.go
new file mode 100644
index 000000000..15217abdd
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/pkg/tableprinter/table.go
@@ -0,0 +1,259 @@
+// Package tableprinter facilitates rendering column-formatted data to a terminal and TSV-formatted data to
+// a script or a file. It is suitable for presenting tabular data in a human-readable format that is
+// guaranteed to fit within the given viewport, while at the same time offering the same data in a
+// machine-readable format for scripts.
+package tableprinter
+
+import (
+ "fmt"
+ "io"
+
+ "github.com/cli/go-gh/v2/pkg/text"
+)
+
+type fieldOption func(*tableField)
+
+type TablePrinter interface {
+ AddHeader([]string, ...fieldOption)
+ AddField(string, ...fieldOption)
+ EndRow()
+ Render() error
+}
+
+// WithTruncate overrides the truncation function for the field. The function should transform a string
+// argument into a string that fits within the given display width. The default behavior is to truncate the
+// value by adding "..." in the end. The truncation function will be called before padding and coloring.
+// Pass nil to disable truncation for this value.
+func WithTruncate(fn func(int, string) string) fieldOption {
+ return func(f *tableField) {
+ f.truncateFunc = fn
+ }
+}
+
+// WithPadding overrides the padding function for the field. The function should transform a string argument
+// into a string that is padded to fit within the given display width. The default behavior is to pad fields
+// with spaces except for the last field. The padding function will be called after truncation and before coloring.
+// Pass nil to disable padding for this value.
+func WithPadding(fn func(int, string) string) fieldOption {
+ return func(f *tableField) {
+ f.paddingFunc = fn
+ }
+}
+
+// WithColor sets the color function for the field. The function should transform a string value by wrapping
+// it in ANSI escape codes. The color function will not be used if the table was initialized in non-terminal mode.
+// The color function will be called before truncation and padding.
+func WithColor(fn func(string) string) fieldOption {
+ return func(f *tableField) {
+ f.colorFunc = fn
+ }
+}
+
+// New initializes a table printer with terminal mode and terminal width. When terminal mode is enabled, the
+// output will be human-readable, column-formatted to fit available width, and rendered with color support.
+// In non-terminal mode, the output is tab-separated and all truncation of values is disabled.
+func New(w io.Writer, isTTY bool, maxWidth int) TablePrinter {
+ if isTTY {
+ return &ttyTablePrinter{
+ out: w,
+ maxWidth: maxWidth,
+ }
+ }
+
+ return &tsvTablePrinter{
+ out: w,
+ }
+}
+
+type tableField struct {
+ text string
+ truncateFunc func(int, string) string
+ paddingFunc func(int, string) string
+ colorFunc func(string) string
+}
+
+type ttyTablePrinter struct {
+ out io.Writer
+ maxWidth int
+ hasHeaders bool
+ rows [][]tableField
+}
+
+func (t *ttyTablePrinter) AddHeader(columns []string, opts ...fieldOption) {
+ if t.hasHeaders {
+ return
+ }
+
+ t.hasHeaders = true
+ for _, column := range columns {
+ t.AddField(column, opts...)
+ }
+ t.EndRow()
+}
+
+func (t *ttyTablePrinter) AddField(s string, opts ...fieldOption) {
+ if t.rows == nil {
+ t.rows = make([][]tableField, 1)
+ }
+ rowI := len(t.rows) - 1
+ field := tableField{
+ text: s,
+ truncateFunc: text.Truncate,
+ }
+ for _, opt := range opts {
+ opt(&field)
+ }
+ t.rows[rowI] = append(t.rows[rowI], field)
+}
+
+func (t *ttyTablePrinter) EndRow() {
+ t.rows = append(t.rows, []tableField{})
+}
+
+func (t *ttyTablePrinter) Render() error {
+ if len(t.rows) == 0 {
+ return nil
+ }
+
+ delim := " "
+ numCols := len(t.rows[0])
+ colWidths := t.calculateColumnWidths(len(delim))
+
+ for _, row := range t.rows {
+ for col, field := range row {
+ if col > 0 {
+ _, err := fmt.Fprint(t.out, delim)
+ if err != nil {
+ return err
+ }
+ }
+ truncVal := field.text
+ if field.truncateFunc != nil {
+ truncVal = field.truncateFunc(colWidths[col], field.text)
+ }
+ if field.paddingFunc != nil {
+ truncVal = field.paddingFunc(colWidths[col], truncVal)
+ } else if col < numCols-1 {
+ truncVal = text.PadRight(colWidths[col], truncVal)
+ }
+ if field.colorFunc != nil {
+ truncVal = field.colorFunc(truncVal)
+ }
+ _, err := fmt.Fprint(t.out, truncVal)
+ if err != nil {
+ return err
+ }
+ }
+ if len(row) > 0 {
+ _, err := fmt.Fprint(t.out, "\n")
+ if err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+func (t *ttyTablePrinter) calculateColumnWidths(delimSize int) []int {
+ numCols := len(t.rows[0])
+ maxColWidths := make([]int, numCols)
+ colWidths := make([]int, numCols)
+
+ for _, row := range t.rows {
+ for col, field := range row {
+ w := text.DisplayWidth(field.text)
+ if w > maxColWidths[col] {
+ maxColWidths[col] = w
+ }
+ // if this field has disabled truncating, ensure that the column is wide enough
+ if field.truncateFunc == nil && w > colWidths[col] {
+ colWidths[col] = w
+ }
+ }
+ }
+
+ availWidth := func() int {
+ setWidths := 0
+ for col := 0; col < numCols; col++ {
+ setWidths += colWidths[col]
+ }
+ return t.maxWidth - delimSize*(numCols-1) - setWidths
+ }
+ numFixedCols := func() int {
+ fixedCols := 0
+ for col := 0; col < numCols; col++ {
+ if colWidths[col] > 0 {
+ fixedCols++
+ }
+ }
+ return fixedCols
+ }
+
+ // set the widths of short columns
+ if w := availWidth(); w > 0 {
+ if numFlexColumns := numCols - numFixedCols(); numFlexColumns > 0 {
+ perColumn := w / numFlexColumns
+ for col := 0; col < numCols; col++ {
+ if max := maxColWidths[col]; max < perColumn {
+ colWidths[col] = max
+ }
+ }
+ }
+ }
+
+ // truncate long columns to the remaining available width
+ if numFlexColumns := numCols - numFixedCols(); numFlexColumns > 0 {
+ perColumn := availWidth() / numFlexColumns
+ for col := 0; col < numCols; col++ {
+ if colWidths[col] == 0 {
+ if max := maxColWidths[col]; max < perColumn {
+ colWidths[col] = max
+ } else if perColumn > 0 {
+ colWidths[col] = perColumn
+ }
+ }
+ }
+ }
+
+ // add the remainder to truncated columns
+ if w := availWidth(); w > 0 {
+ for col := 0; col < numCols; col++ {
+ d := maxColWidths[col] - colWidths[col]
+ toAdd := w
+ if d < toAdd {
+ toAdd = d
+ }
+ colWidths[col] += toAdd
+ w -= toAdd
+ if w <= 0 {
+ break
+ }
+ }
+ }
+
+ return colWidths
+}
+
+type tsvTablePrinter struct {
+ out io.Writer
+ currentCol int
+}
+
+func (t *tsvTablePrinter) AddHeader(_ []string, _ ...fieldOption) {}
+
+func (t *tsvTablePrinter) AddField(text string, _ ...fieldOption) {
+ if t.currentCol > 0 {
+ fmt.Fprint(t.out, "\t")
+ }
+ fmt.Fprint(t.out, text)
+ t.currentCol++
+}
+
+func (t *tsvTablePrinter) EndRow() {
+ fmt.Fprint(t.out, "\n")
+ t.currentCol = 0
+}
+
+func (t *tsvTablePrinter) Render() error {
+ return nil
+}
diff --git a/vendor/github.com/cli/go-gh/v2/pkg/template/template.go b/vendor/github.com/cli/go-gh/v2/pkg/template/template.go
new file mode 100644
index 000000000..a561ebb65
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/pkg/template/template.go
@@ -0,0 +1,261 @@
+// Package template facilitates processing of JSON strings using Go templates.
+// Provides additional functions not available using basic Go templates, such as coloring,
+// and table rendering.
+package template
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "math"
+ "strconv"
+ "strings"
+ "text/template"
+ "time"
+
+ "github.com/cli/go-gh/v2/pkg/tableprinter"
+ "github.com/cli/go-gh/v2/pkg/text"
+ color "github.com/mgutz/ansi"
+)
+
+const (
+ ellipsis = "..."
+)
+
+// Template is the representation of a template.
+type Template struct {
+ colorEnabled bool
+ output io.Writer
+ tmpl *template.Template
+ tp tableprinter.TablePrinter
+ width int
+ funcs template.FuncMap
+}
+
+// New initializes a Template.
+func New(w io.Writer, width int, colorEnabled bool) *Template {
+ return &Template{
+ colorEnabled: colorEnabled,
+ output: w,
+ tp: tableprinter.New(w, true, width),
+ width: width,
+ funcs: template.FuncMap{},
+ }
+}
+
+// Funcs adds the elements of the argument map to the template's function map.
+// It must be called before the template is parsed.
+// It is legal to overwrite elements of the map including default functions.
+// The return value is the template, so calls can be chained.
+func (t *Template) Funcs(funcMap map[string]interface{}) *Template {
+ for name, f := range funcMap {
+ t.funcs[name] = f
+ }
+ return t
+}
+
+// Parse the given template string for use with Execute.
+func (t *Template) Parse(tmpl string) error {
+ now := time.Now()
+ templateFuncs := map[string]interface{}{
+ "autocolor": colorFunc,
+ "color": colorFunc,
+ "hyperlink": hyperlinkFunc,
+ "join": joinFunc,
+ "pluck": pluckFunc,
+ "tablerender": func() (string, error) {
+ // After rendering a table, prepare a new table printer incase user wants to output
+ // another table.
+ defer func() {
+ t.tp = tableprinter.New(t.output, true, t.width)
+ }()
+ return tableRenderFunc(t.tp)
+ },
+ "tablerow": func(fields ...interface{}) (string, error) {
+ return tableRowFunc(t.tp, fields...)
+ },
+ "timeago": func(input string) (string, error) {
+ return timeAgoFunc(now, input)
+ },
+ "timefmt": timeFormatFunc,
+ "truncate": truncateFunc,
+ }
+ if !t.colorEnabled {
+ templateFuncs["autocolor"] = autoColorFunc
+ }
+ for name, f := range t.funcs {
+ templateFuncs[name] = f
+ }
+ var err error
+ t.tmpl, err = template.New("").Funcs(templateFuncs).Parse(tmpl)
+ return err
+}
+
+// Execute applies the parsed template to the input and writes result to the writer
+// the template was initialized with.
+func (t *Template) Execute(input io.Reader) error {
+ jsonData, err := io.ReadAll(input)
+ if err != nil {
+ return err
+ }
+
+ var data interface{}
+ if err := json.Unmarshal(jsonData, &data); err != nil {
+ return err
+ }
+
+ return t.tmpl.Execute(t.output, data)
+}
+
+// Flush writes any remaining data to the writer. This is mostly useful
+// when a templates uses the tablerow function but does not include the
+// tablerender function at the end.
+// If a template did not use the table functionality this is a noop.
+func (t *Template) Flush() error {
+ if _, err := tableRenderFunc(t.tp); err != nil {
+ return err
+ }
+ return nil
+}
+
+func colorFunc(colorName string, input interface{}) (string, error) {
+ text, err := jsonScalarToString(input)
+ if err != nil {
+ return "", err
+ }
+ return color.Color(text, colorName), nil
+}
+
+func pluckFunc(field string, input []interface{}) []interface{} {
+ var results []interface{}
+ for _, item := range input {
+ obj := item.(map[string]interface{})
+ results = append(results, obj[field])
+ }
+ return results
+}
+
+func joinFunc(sep string, input []interface{}) (string, error) {
+ var results []string
+ for _, item := range input {
+ text, err := jsonScalarToString(item)
+ if err != nil {
+ return "", err
+ }
+ results = append(results, text)
+ }
+ return strings.Join(results, sep), nil
+}
+
+func timeFormatFunc(format, input string) (string, error) {
+ t, err := time.Parse(time.RFC3339, input)
+ if err != nil {
+ return "", err
+ }
+ return t.Format(format), nil
+}
+
+func timeAgoFunc(now time.Time, input string) (string, error) {
+ t, err := time.Parse(time.RFC3339, input)
+ if err != nil {
+ return "", err
+ }
+ return timeAgo(now.Sub(t)), nil
+}
+
+func truncateFunc(maxWidth int, v interface{}) (string, error) {
+ if v == nil {
+ return "", nil
+ }
+ if s, ok := v.(string); ok {
+ return text.Truncate(maxWidth, s), nil
+ }
+ return "", fmt.Errorf("invalid value; expected string, got %T", v)
+}
+
+func autoColorFunc(colorName string, input interface{}) (string, error) {
+ return jsonScalarToString(input)
+}
+
+func tableRowFunc(tp tableprinter.TablePrinter, fields ...interface{}) (string, error) {
+ if tp == nil {
+ return "", fmt.Errorf("failed to write table row: no table printer")
+ }
+ for _, e := range fields {
+ s, err := jsonScalarToString(e)
+ if err != nil {
+ return "", fmt.Errorf("failed to write table row: %v", err)
+ }
+ tp.AddField(s, tableprinter.WithTruncate(truncateMultiline))
+ }
+ tp.EndRow()
+ return "", nil
+}
+
+func tableRenderFunc(tp tableprinter.TablePrinter) (string, error) {
+ if tp == nil {
+ return "", fmt.Errorf("failed to render table: no table printer")
+ }
+ err := tp.Render()
+ if err != nil {
+ return "", fmt.Errorf("failed to render table: %v", err)
+ }
+ return "", nil
+}
+
+func jsonScalarToString(input interface{}) (string, error) {
+ switch tt := input.(type) {
+ case string:
+ return tt, nil
+ case float64:
+ if math.Trunc(tt) == tt {
+ return strconv.FormatFloat(tt, 'f', 0, 64), nil
+ } else {
+ return strconv.FormatFloat(tt, 'f', 2, 64), nil
+ }
+ case nil:
+ return "", nil
+ case bool:
+ return fmt.Sprintf("%v", tt), nil
+ default:
+ return "", fmt.Errorf("cannot convert type to string: %v", tt)
+ }
+}
+
+func timeAgo(ago time.Duration) string {
+ if ago < time.Minute {
+ return "just now"
+ }
+ if ago < time.Hour {
+ return text.Pluralize(int(ago.Minutes()), "minute") + " ago"
+ }
+ if ago < 24*time.Hour {
+ return text.Pluralize(int(ago.Hours()), "hour") + " ago"
+ }
+ if ago < 30*24*time.Hour {
+ return text.Pluralize(int(ago.Hours())/24, "day") + " ago"
+ }
+ if ago < 365*24*time.Hour {
+ return text.Pluralize(int(ago.Hours())/24/30, "month") + " ago"
+ }
+ return text.Pluralize(int(ago.Hours()/24/365), "year") + " ago"
+}
+
+// TruncateMultiline returns a copy of the string s that has been shortened to fit the maximum
+// display width. If string s has multiple lines the first line will be shortened and all others
+// removed.
+func truncateMultiline(maxWidth int, s string) string {
+ if i := strings.IndexAny(s, "\r\n"); i >= 0 {
+ s = s[:i] + ellipsis
+ }
+ return text.Truncate(maxWidth, s)
+}
+
+func hyperlinkFunc(link, text string) string {
+ if text == "" {
+ text = link
+ }
+
+ // See https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda
+ return fmt.Sprintf("\x1b]8;;%s\x1b\\%s\x1b]8;;\x1b\\", link, text)
+}
diff --git a/vendor/github.com/cli/go-gh/v2/pkg/term/console.go b/vendor/github.com/cli/go-gh/v2/pkg/term/console.go
new file mode 100644
index 000000000..4ff7e95d6
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/pkg/term/console.go
@@ -0,0 +1,17 @@
+//go:build !windows
+// +build !windows
+
+package term
+
+import (
+ "errors"
+ "os"
+)
+
+func enableVirtualTerminalProcessing(f *os.File) error {
+ return errors.New("not implemented")
+}
+
+func openTTY() (*os.File, error) {
+ return os.Open("/dev/tty")
+}
diff --git a/vendor/github.com/cli/go-gh/v2/pkg/term/console_windows.go b/vendor/github.com/cli/go-gh/v2/pkg/term/console_windows.go
new file mode 100644
index 000000000..55b1e42ae
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/pkg/term/console_windows.go
@@ -0,0 +1,22 @@
+//go:build windows
+// +build windows
+
+package term
+
+import (
+ "os"
+
+ "golang.org/x/sys/windows"
+)
+
+func enableVirtualTerminalProcessing(f *os.File) error {
+ stdout := windows.Handle(f.Fd())
+
+ var originalMode uint32
+ windows.GetConsoleMode(stdout, &originalMode)
+ return windows.SetConsoleMode(stdout, originalMode|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING)
+}
+
+func openTTY() (*os.File, error) {
+ return os.Open("CONOUT$")
+}
diff --git a/vendor/github.com/cli/go-gh/v2/pkg/term/env.go b/vendor/github.com/cli/go-gh/v2/pkg/term/env.go
new file mode 100644
index 000000000..c650cc228
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/pkg/term/env.go
@@ -0,0 +1,184 @@
+// Package term provides information about the terminal that the current process is connected to (if any),
+// for example measuring the dimensions of the terminal and inspecting whether it's safe to output color.
+package term
+
+import (
+ "io"
+ "os"
+ "strconv"
+ "strings"
+
+ "github.com/muesli/termenv"
+ "golang.org/x/term"
+)
+
+// Term represents information about the terminal that a process is connected to.
+type Term struct {
+ in *os.File
+ out *os.File
+ errOut *os.File
+ isTTY bool
+ colorEnabled bool
+ is256enabled bool
+ hasTrueColor bool
+ width int
+ widthPercent int
+}
+
+// FromEnv initializes a Term from [os.Stdout] and environment variables:
+// - GH_FORCE_TTY
+// - NO_COLOR
+// - CLICOLOR
+// - CLICOLOR_FORCE
+// - TERM
+// - COLORTERM
+func FromEnv() Term {
+ var stdoutIsTTY bool
+ var isColorEnabled bool
+ var termWidthOverride int
+ var termWidthPercentage int
+
+ spec := os.Getenv("GH_FORCE_TTY")
+ if spec != "" {
+ stdoutIsTTY = true
+ isColorEnabled = !IsColorDisabled()
+
+ if w, err := strconv.Atoi(spec); err == nil {
+ termWidthOverride = w
+ } else if strings.HasSuffix(spec, "%") {
+ if p, err := strconv.Atoi(spec[:len(spec)-1]); err == nil {
+ termWidthPercentage = p
+ }
+ }
+ } else {
+ stdoutIsTTY = IsTerminal(os.Stdout)
+ isColorEnabled = IsColorForced() || (!IsColorDisabled() && stdoutIsTTY)
+ }
+
+ isVirtualTerminal := false
+ if stdoutIsTTY {
+ if err := enableVirtualTerminalProcessing(os.Stdout); err == nil {
+ isVirtualTerminal = true
+ }
+ }
+
+ return Term{
+ in: os.Stdin,
+ out: os.Stdout,
+ errOut: os.Stderr,
+ isTTY: stdoutIsTTY,
+ colorEnabled: isColorEnabled,
+ is256enabled: isVirtualTerminal || is256ColorSupported(),
+ hasTrueColor: isVirtualTerminal || isTrueColorSupported(),
+ width: termWidthOverride,
+ widthPercent: termWidthPercentage,
+ }
+}
+
+// In is the reader reading from standard input.
+func (t Term) In() io.Reader {
+ return t.in
+}
+
+// Out is the writer writing to standard output.
+func (t Term) Out() io.Writer {
+ return t.out
+}
+
+// ErrOut is the writer writing to standard error.
+func (t Term) ErrOut() io.Writer {
+ return t.errOut
+}
+
+// IsTerminalOutput returns true if standard output is connected to a terminal.
+func (t Term) IsTerminalOutput() bool {
+ return t.isTTY
+}
+
+// IsColorEnabled reports whether it's safe to output ANSI color sequences, depending on IsTerminalOutput
+// and environment variables.
+func (t Term) IsColorEnabled() bool {
+ return t.colorEnabled
+}
+
+// Is256ColorSupported reports whether the terminal advertises ANSI 256 color codes.
+func (t Term) Is256ColorSupported() bool {
+ return t.is256enabled
+}
+
+// IsTrueColorSupported reports whether the terminal advertises support for ANSI true color sequences.
+func (t Term) IsTrueColorSupported() bool {
+ return t.hasTrueColor
+}
+
+// Size returns the width and height of the terminal that the current process is attached to.
+// In case of errors, the numeric values returned are -1.
+func (t Term) Size() (int, int, error) {
+ if t.width > 0 {
+ return t.width, -1, nil
+ }
+
+ ttyOut := t.out
+ if ttyOut == nil || !IsTerminal(ttyOut) {
+ if f, err := openTTY(); err == nil {
+ defer f.Close()
+ ttyOut = f
+ } else {
+ return -1, -1, err
+ }
+ }
+
+ width, height, err := terminalSize(ttyOut)
+ if err == nil && t.widthPercent > 0 {
+ return int(float64(width) * float64(t.widthPercent) / 100), height, nil
+ }
+
+ return width, height, err
+}
+
+// Theme returns the theme of the terminal by analyzing the background color of the terminal.
+func (t Term) Theme() string {
+ if !t.IsColorEnabled() {
+ return "none"
+ }
+ if termenv.HasDarkBackground() {
+ return "dark"
+ }
+ return "light"
+}
+
+// IsTerminal reports whether a file descriptor is connected to a terminal.
+func IsTerminal(f *os.File) bool {
+ return term.IsTerminal(int(f.Fd()))
+}
+
+func terminalSize(f *os.File) (int, int, error) {
+ return term.GetSize(int(f.Fd()))
+}
+
+// IsColorDisabled returns true if environment variables NO_COLOR or CLICOLOR prohibit usage of color codes
+// in terminal output.
+func IsColorDisabled() bool {
+ return os.Getenv("NO_COLOR") != "" || os.Getenv("CLICOLOR") == "0"
+}
+
+// IsColorForced returns true if environment variable CLICOLOR_FORCE is set to force colored terminal output.
+func IsColorForced() bool {
+ return os.Getenv("CLICOLOR_FORCE") != "" && os.Getenv("CLICOLOR_FORCE") != "0"
+}
+
+func is256ColorSupported() bool {
+ return isTrueColorSupported() ||
+ strings.Contains(os.Getenv("TERM"), "256") ||
+ strings.Contains(os.Getenv("COLORTERM"), "256")
+}
+
+func isTrueColorSupported() bool {
+ term := os.Getenv("TERM")
+ colorterm := os.Getenv("COLORTERM")
+
+ return strings.Contains(term, "24bit") ||
+ strings.Contains(term, "truecolor") ||
+ strings.Contains(colorterm, "24bit") ||
+ strings.Contains(colorterm, "truecolor")
+}
diff --git a/vendor/github.com/cli/go-gh/v2/pkg/text/text.go b/vendor/github.com/cli/go-gh/v2/pkg/text/text.go
new file mode 100644
index 000000000..687517f9d
--- /dev/null
+++ b/vendor/github.com/cli/go-gh/v2/pkg/text/text.go
@@ -0,0 +1,115 @@
+// Package text is a set of utility functions for text processing and outputting to the terminal.
+package text
+
+import (
+ "fmt"
+ "regexp"
+ "strings"
+ "time"
+ "unicode"
+
+ "github.com/charmbracelet/lipgloss"
+ "github.com/muesli/reflow/truncate"
+ "golang.org/x/text/runes"
+ "golang.org/x/text/transform"
+ "golang.org/x/text/unicode/norm"
+)
+
+const (
+ ellipsis = "..."
+ minWidthForEllipsis = len(ellipsis) + 2
+)
+
+var indentRE = regexp.MustCompile(`(?m)^`)
+
+// Indent returns a copy of the string s with indent prefixed to it, will apply indent
+// to each line of the string.
+func Indent(s, indent string) string {
+ if len(strings.TrimSpace(s)) == 0 {
+ return s
+ }
+ return indentRE.ReplaceAllLiteralString(s, indent)
+}
+
+// DisplayWidth calculates what the rendered width of string s will be.
+func DisplayWidth(s string) int {
+ return lipgloss.Width(s)
+}
+
+// Truncate returns a copy of the string s that has been shortened to fit the maximum display width.
+func Truncate(maxWidth int, s string) string {
+ w := DisplayWidth(s)
+ if w <= maxWidth {
+ return s
+ }
+ tail := ""
+ if maxWidth >= minWidthForEllipsis {
+ tail = ellipsis
+ }
+ r := truncate.StringWithTail(s, uint(maxWidth), tail)
+ if DisplayWidth(r) < maxWidth {
+ r += " "
+ }
+ return r
+}
+
+// PadRight returns a copy of the string s that has been padded on the right with whitespace to fit
+// the maximum display width.
+func PadRight(maxWidth int, s string) string {
+ if padWidth := maxWidth - DisplayWidth(s); padWidth > 0 {
+ s += strings.Repeat(" ", padWidth)
+ }
+ return s
+}
+
+// Pluralize returns a concatenated string with num and the plural form of thing if necessary.
+func Pluralize(num int, thing string) string {
+ if num == 1 {
+ return fmt.Sprintf("%d %s", num, thing)
+ }
+ return fmt.Sprintf("%d %ss", num, thing)
+}
+
+func fmtDuration(amount int, unit string) string {
+ return fmt.Sprintf("about %s ago", Pluralize(amount, unit))
+}
+
+// RelativeTimeAgo returns a human readable string of the time duration between a and b that is estimated
+// to the nearest unit of time.
+func RelativeTimeAgo(a, b time.Time) string {
+ ago := a.Sub(b)
+
+ if ago < time.Minute {
+ return "less than a minute ago"
+ }
+ if ago < time.Hour {
+ return fmtDuration(int(ago.Minutes()), "minute")
+ }
+ if ago < 24*time.Hour {
+ return fmtDuration(int(ago.Hours()), "hour")
+ }
+ if ago < 30*24*time.Hour {
+ return fmtDuration(int(ago.Hours())/24, "day")
+ }
+ if ago < 365*24*time.Hour {
+ return fmtDuration(int(ago.Hours())/24/30, "month")
+ }
+
+ return fmtDuration(int(ago.Hours()/24/365), "year")
+}
+
+// RemoveDiacritics returns the input value without "diacritics", or accent marks.
+func RemoveDiacritics(value string) string {
+ // Mn = "Mark, nonspacing" unicode character category
+ removeMnTransfomer := runes.Remove(runes.In(unicode.Mn))
+
+ // 1. Decompose the text into characters and diacritical marks
+ // 2. Remove the diacriticals marks
+ // 3. Recompose the text
+ t := transform.Chain(norm.NFD, removeMnTransfomer, norm.NFC)
+ normalized, _, err := transform.String(t, value)
+ if err != nil {
+ return value
+ }
+ return normalized
+}
diff --git a/vendor/github.com/cli/oauth/.golangci.yml b/vendor/github.com/cli/oauth/.golangci.yml
new file mode 100644
index 000000000..aa52e9842
--- /dev/null
+++ b/vendor/github.com/cli/oauth/.golangci.yml
@@ -0,0 +1,15 @@
+linters:
+ enable:
+ - gofmt
+ - godot
+ - revive
+
+linters-settings:
+ godot:
+ # comments to be checked: `declarations`, `toplevel`, or `all`
+ scope: declarations
+ # check that each sentence starts with a capital letter
+ capital: true
+
+issues:
+ exclude-use-default: false
diff --git a/vendor/github.com/cli/oauth/LICENSE b/vendor/github.com/cli/oauth/LICENSE
new file mode 100644
index 000000000..284b811ef
--- /dev/null
+++ b/vendor/github.com/cli/oauth/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 GitHub, 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/cli/oauth/README.md b/vendor/github.com/cli/oauth/README.md
new file mode 100644
index 000000000..41cb35c77
--- /dev/null
+++ b/vendor/github.com/cli/oauth/README.md
@@ -0,0 +1,28 @@
+# oauth
+
+A library for Go client applications that need to perform OAuth authorization against a server, typically GitHub.com.
+
+
+
+
+
+
+Traditionally, OAuth for web applications involves redirecting to a URI after the user authorizes an app. While web apps (and some native client apps) can receive a browser redirect, client apps such as CLI applications do not have such an option.
+
+To accommodate client apps, this library implements the [OAuth Device Authorization Grant][oauth-device] which [GitHub.com now supports][gh-device]. With Device flow, the user is presented with a one-time code that they will have to enter in a web browser while authorizing the app on the server. Device flow is suitable for cases where the web browser may be running on a separate device than the client app itself; for example a CLI application could run within a headless, containerized instance, but the user may complete authorization using a browser on their phone.
+
+To transparently enable OAuth authorization on _any GitHub host_ (e.g. GHES instances without OAuth “Device flow” support), this library also bundles an implementation of OAuth web application flow in which the client app starts a local server at `http://127.0.0.1:/` that acts as a receiver for the browser redirect. First, Device flow is attempted, and the localhost server is used as fallback. With the localhost server, the user's web browser must be running on the same machine as the client application itself.
+
+## Usage
+
+- [OAuth Device flow with fallback](./examples_test.go)
+- [manual OAuth Device flow](./device/examples_test.go)
+- [manual OAuth web application flow](./webapp/examples_test.go)
+
+Applications that need more control over the user experience around authentication should directly interface with `github.com/cli/oauth/device` and `github.com/cli/oauth/webapp` packages.
+
+In theory, these packages would enable authorization on any OAuth-enabled host. In practice, however, this was only tested for authorizing with GitHub.
+
+
+[oauth-device]: https://oauth.net/2/device-flow/
+[gh-device]: https://docs.github.com/en/free-pro-team@latest/developers/apps/authorizing-oauth-apps#device-flow
diff --git a/vendor/github.com/cli/oauth/api/access_token.go b/vendor/github.com/cli/oauth/api/access_token.go
new file mode 100644
index 000000000..718d69d50
--- /dev/null
+++ b/vendor/github.com/cli/oauth/api/access_token.go
@@ -0,0 +1,27 @@
+package api
+
+// AccessToken is an OAuth access token.
+type AccessToken struct {
+ // The token value, typically a 40-character random string.
+ Token string
+ // The refresh token value, associated with the access token.
+ RefreshToken string
+ // The token type, e.g. "bearer".
+ Type string
+ // Space-separated list of OAuth scopes that this token grants.
+ Scope string
+}
+
+// AccessToken extracts the access token information from a server response.
+func (f FormResponse) AccessToken() (*AccessToken, error) {
+ if accessToken := f.Get("access_token"); accessToken != "" {
+ return &AccessToken{
+ Token: accessToken,
+ RefreshToken: f.Get("refresh_token"),
+ Type: f.Get("token_type"),
+ Scope: f.Get("scope"),
+ }, nil
+ }
+
+ return nil, f.Err()
+}
diff --git a/vendor/github.com/cli/oauth/api/form.go b/vendor/github.com/cli/oauth/api/form.go
new file mode 100644
index 000000000..9b28484ed
--- /dev/null
+++ b/vendor/github.com/cli/oauth/api/form.go
@@ -0,0 +1,115 @@
+// Package api implements request and response parsing logic shared between different OAuth strategies.
+package api
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "mime"
+ "net/http"
+ "net/url"
+ "strconv"
+)
+
+type httpClient interface {
+ PostForm(string, url.Values) (*http.Response, error)
+}
+
+// FormResponse is the parsed "www-form-urlencoded" response from the server.
+type FormResponse struct {
+ StatusCode int
+
+ requestURI string
+ values url.Values
+}
+
+// Get the response value named k.
+func (f FormResponse) Get(k string) string {
+ return f.values.Get(k)
+}
+
+// Err returns an Error object extracted from the response.
+func (f FormResponse) Err() error {
+ return &Error{
+ RequestURI: f.requestURI,
+ ResponseCode: f.StatusCode,
+ Code: f.Get("error"),
+ message: f.Get("error_description"),
+ }
+}
+
+// Error is the result of an unexpected HTTP response from the server.
+type Error struct {
+ Code string
+ ResponseCode int
+ RequestURI string
+
+ message string
+}
+
+func (e Error) Error() string {
+ if e.message != "" {
+ return fmt.Sprintf("%s (%s)", e.message, e.Code)
+ }
+ if e.Code != "" {
+ return e.Code
+ }
+ return fmt.Sprintf("HTTP %d", e.ResponseCode)
+}
+
+// PostForm makes an POST request by serializing input parameters as a form and parsing the response
+// of the same type.
+func PostForm(c httpClient, u string, params url.Values) (*FormResponse, error) {
+ resp, err := c.PostForm(u, params)
+ if err != nil {
+ return nil, err
+ }
+ defer func() {
+ _ = resp.Body.Close()
+ }()
+
+ r := &FormResponse{
+ StatusCode: resp.StatusCode,
+ requestURI: u,
+ }
+
+ mediaType, _, _ := mime.ParseMediaType(resp.Header.Get("Content-Type"))
+ switch mediaType {
+ case "application/x-www-form-urlencoded":
+ var bb []byte
+ bb, err = ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return r, err
+ }
+
+ r.values, err = url.ParseQuery(string(bb))
+ if err != nil {
+ return r, err
+ }
+ case "application/json":
+ var values map[string]interface{}
+ if err := json.NewDecoder(resp.Body).Decode(&values); err != nil {
+ return r, err
+ }
+
+ r.values = make(url.Values)
+ for key, value := range values {
+ switch v := value.(type) {
+ case string:
+ r.values.Set(key, v)
+ case int64:
+ r.values.Set(key, strconv.FormatInt(v, 10))
+ case float64:
+ r.values.Set(key, strconv.FormatFloat(v, 'f', -1, 64))
+ }
+ }
+ default:
+ _, err = io.Copy(ioutil.Discard, resp.Body)
+ if err != nil {
+ return r, err
+ }
+ }
+
+ return r, nil
+}
diff --git a/vendor/github.com/cli/oauth/device/device_flow.go b/vendor/github.com/cli/oauth/device/device_flow.go
new file mode 100644
index 000000000..e6a6ee95c
--- /dev/null
+++ b/vendor/github.com/cli/oauth/device/device_flow.go
@@ -0,0 +1,175 @@
+// Package device facilitates performing OAuth Device Authorization Flow for client applications
+// such as CLIs that can not receive redirects from a web site.
+//
+// First, RequestCode should be used to obtain a CodeResponse.
+//
+// Next, the user will need to navigate to VerificationURI in their web browser on any device and fill
+// in the UserCode.
+//
+// While the user is completing the web flow, the application should invoke PollToken, which blocks
+// the goroutine until the user has authorized the app on the server.
+//
+// https://docs.github.com/en/free-pro-team@latest/developers/apps/authorizing-oauth-apps#device-flow
+package device
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "net/http"
+ "net/url"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/cli/oauth/api"
+)
+
+var (
+ // ErrUnsupported is thrown when the server does not implement Device flow.
+ ErrUnsupported = errors.New("device flow not supported")
+ // ErrTimeout is thrown when polling the server for the granted token has timed out.
+ ErrTimeout = errors.New("authentication timed out")
+)
+
+type httpClient interface {
+ PostForm(string, url.Values) (*http.Response, error)
+}
+
+// CodeResponse holds information about the authorization-in-progress.
+type CodeResponse struct {
+ // The user verification code is displayed on the device so the user can enter the code in a browser.
+ UserCode string
+ // The verification URL where users need to enter the UserCode.
+ VerificationURI string
+ // The optional verification URL that includes the UserCode.
+ VerificationURIComplete string
+
+ // The device verification code is 40 characters and used to verify the device.
+ DeviceCode string
+ // The number of seconds before the DeviceCode and UserCode expire.
+ ExpiresIn int
+ // The minimum number of seconds that must pass before you can make a new access token request to
+ // complete the device authorization.
+ Interval int
+}
+
+// RequestCode initiates the authorization flow by requesting a code from uri.
+func RequestCode(c httpClient, uri string, clientID string, scopes []string) (*CodeResponse, error) {
+ resp, err := api.PostForm(c, uri, url.Values{
+ "client_id": {clientID},
+ "scope": {strings.Join(scopes, " ")},
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ verificationURI := resp.Get("verification_uri")
+ if verificationURI == "" {
+ // Google's "OAuth 2.0 for TV and Limited-Input Device Applications" uses `verification_url`.
+ verificationURI = resp.Get("verification_url")
+ }
+
+ if resp.StatusCode == 401 || resp.StatusCode == 403 || resp.StatusCode == 404 || resp.StatusCode == 422 ||
+ (resp.StatusCode == 200 && verificationURI == "") ||
+ (resp.StatusCode == 400 && resp.Get("error") == "device_flow_disabled") ||
+ (resp.StatusCode == 400 && resp.Get("error") == "unauthorized_client") {
+ return nil, ErrUnsupported
+ }
+
+ if resp.StatusCode != 200 {
+ return nil, resp.Err()
+ }
+
+ intervalSeconds, err := strconv.Atoi(resp.Get("interval"))
+ if err != nil {
+ return nil, fmt.Errorf("could not parse interval=%q as integer: %w", resp.Get("interval"), err)
+ }
+
+ expiresIn, err := strconv.Atoi(resp.Get("expires_in"))
+ if err != nil {
+ return nil, fmt.Errorf("could not parse expires_in=%q as integer: %w", resp.Get("expires_in"), err)
+ }
+
+ return &CodeResponse{
+ DeviceCode: resp.Get("device_code"),
+ UserCode: resp.Get("user_code"),
+ VerificationURI: verificationURI,
+ VerificationURIComplete: resp.Get("verification_uri_complete"),
+ Interval: intervalSeconds,
+ ExpiresIn: expiresIn,
+ }, nil
+}
+
+const defaultGrantType = "urn:ietf:params:oauth:grant-type:device_code"
+
+// PollToken polls the server at pollURL until an access token is granted or denied.
+//
+// Deprecated: use Wait.
+func PollToken(c httpClient, pollURL string, clientID string, code *CodeResponse) (*api.AccessToken, error) {
+ return Wait(context.Background(), c, pollURL, WaitOptions{
+ ClientID: clientID,
+ DeviceCode: code,
+ })
+}
+
+// WaitOptions specifies parameters to poll the server with until authentication completes.
+type WaitOptions struct {
+ // ClientID is the app client ID value.
+ ClientID string
+ // ClientSecret is the app client secret value. Optional: only pass if the server requires it.
+ ClientSecret string
+ // DeviceCode is the value obtained from RequestCode.
+ DeviceCode *CodeResponse
+ // GrantType overrides the default value specified by OAuth 2.0 Device Code. Optional.
+ GrantType string
+
+ newPoller pollerFactory
+}
+
+// Wait polls the server at uri until authorization completes.
+func Wait(ctx context.Context, c httpClient, uri string, opts WaitOptions) (*api.AccessToken, error) {
+ checkInterval := time.Duration(opts.DeviceCode.Interval) * time.Second
+ expiresIn := time.Duration(opts.DeviceCode.ExpiresIn) * time.Second
+ grantType := opts.GrantType
+ if opts.GrantType == "" {
+ grantType = defaultGrantType
+ }
+
+ makePoller := opts.newPoller
+ if makePoller == nil {
+ makePoller = newPoller
+ }
+ _, poll := makePoller(ctx, checkInterval, expiresIn)
+
+ for {
+ if err := poll.Wait(); err != nil {
+ return nil, err
+ }
+
+ values := url.Values{
+ "client_id": {opts.ClientID},
+ "device_code": {opts.DeviceCode.DeviceCode},
+ "grant_type": {grantType},
+ }
+
+ // Google's "OAuth 2.0 for TV and Limited-Input Device Applications" requires `client_secret`.
+ if opts.ClientSecret != "" {
+ values.Add("client_secret", opts.ClientSecret)
+ }
+
+ // TODO: pass tctx down to the HTTP layer
+ resp, err := api.PostForm(c, uri, values)
+ if err != nil {
+ return nil, err
+ }
+
+ var apiError *api.Error
+ token, err := resp.AccessToken()
+ if err == nil {
+ return token, nil
+ } else if !(errors.As(err, &apiError) && apiError.Code == "authorization_pending") {
+ return nil, err
+ }
+ }
+}
diff --git a/vendor/github.com/cli/oauth/device/poller.go b/vendor/github.com/cli/oauth/device/poller.go
new file mode 100644
index 000000000..06a2e9d2c
--- /dev/null
+++ b/vendor/github.com/cli/oauth/device/poller.go
@@ -0,0 +1,43 @@
+package device
+
+import (
+ "context"
+ "time"
+)
+
+type poller interface {
+ Wait() error
+ Cancel()
+}
+
+type pollerFactory func(context.Context, time.Duration, time.Duration) (context.Context, poller)
+
+func newPoller(ctx context.Context, checkInteval, expiresIn time.Duration) (context.Context, poller) {
+ c, cancel := context.WithTimeout(ctx, expiresIn)
+ return c, &intervalPoller{
+ ctx: c,
+ interval: checkInteval,
+ cancelFunc: cancel,
+ }
+}
+
+type intervalPoller struct {
+ ctx context.Context
+ interval time.Duration
+ cancelFunc func()
+}
+
+func (p intervalPoller) Wait() error {
+ t := time.NewTimer(p.interval)
+ select {
+ case <-p.ctx.Done():
+ t.Stop()
+ return p.ctx.Err()
+ case <-t.C:
+ return nil
+ }
+}
+
+func (p intervalPoller) Cancel() {
+ p.cancelFunc()
+}
diff --git a/vendor/github.com/cli/oauth/oauth.go b/vendor/github.com/cli/oauth/oauth.go
new file mode 100644
index 000000000..643978212
--- /dev/null
+++ b/vendor/github.com/cli/oauth/oauth.go
@@ -0,0 +1,79 @@
+// Package oauth is a library for Go client applications that need to perform OAuth authorization
+// against a server, typically GitHub.com.
+package oauth
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "net/http"
+ "net/url"
+
+ "github.com/cli/oauth/api"
+ "github.com/cli/oauth/device"
+)
+
+type httpClient interface {
+ PostForm(string, url.Values) (*http.Response, error)
+}
+
+// Host defines the endpoints used to authorize against an OAuth server.
+type Host struct {
+ DeviceCodeURL string
+ AuthorizeURL string
+ TokenURL string
+}
+
+// GitHubHost constructs a Host from the given URL to a GitHub instance.
+func GitHubHost(hostURL string) *Host {
+ u, _ := url.Parse(hostURL)
+
+ return &Host{
+ DeviceCodeURL: fmt.Sprintf("%s://%s/login/device/code", u.Scheme, u.Host),
+ AuthorizeURL: fmt.Sprintf("%s://%s/login/oauth/authorize", u.Scheme, u.Host),
+ TokenURL: fmt.Sprintf("%s://%s/login/oauth/access_token", u.Scheme, u.Host),
+ }
+}
+
+// Flow facilitates a single OAuth authorization flow.
+type Flow struct {
+ // The hostname to authorize the app with.
+ //
+ // Deprecated: Use Host instead.
+ Hostname string
+ // Host configuration to authorize the app with.
+ Host *Host
+ // OAuth scopes to request from the user.
+ Scopes []string
+ // OAuth application ID.
+ ClientID string
+ // OAuth application secret. Only applicable in web application flow.
+ ClientSecret string
+ // The localhost URI for web application flow callback, e.g. "http://127.0.0.1/callback".
+ CallbackURI string
+
+ // Display a one-time code to the user. Receives the code and the browser URL as arguments. Defaults to printing the
+ // code to the user on Stdout with instructions to copy the code and to press Enter to continue in their browser.
+ DisplayCode func(string, string) error
+ // Open a web browser at a URL. Defaults to opening the default system browser.
+ BrowseURL func(string) error
+ // Render an HTML page to the user upon completion of web application flow. The default is to
+ // render a simple message that informs the user they can close the browser tab and return to the app.
+ WriteSuccessHTML func(io.Writer)
+
+ // The HTTP client to use for API POST requests. Defaults to http.DefaultClient.
+ HTTPClient httpClient
+ // The stream to listen to keyboard input on. Defaults to os.Stdin.
+ Stdin io.Reader
+ // The stream to print UI messages to. Defaults to os.Stdout.
+ Stdout io.Writer
+}
+
+// DetectFlow tries to perform Device flow first and falls back to Web application flow.
+func (oa *Flow) DetectFlow() (*api.AccessToken, error) {
+ accessToken, err := oa.DeviceFlow()
+ if errors.Is(err, device.ErrUnsupported) {
+ return oa.WebAppFlow()
+ }
+ return accessToken, err
+}
diff --git a/vendor/github.com/cli/oauth/oauth_device.go b/vendor/github.com/cli/oauth/oauth_device.go
new file mode 100644
index 000000000..d4615ef2a
--- /dev/null
+++ b/vendor/github.com/cli/oauth/oauth_device.go
@@ -0,0 +1,72 @@
+package oauth
+
+import (
+ "bufio"
+ "context"
+ "fmt"
+ "io"
+ "net/http"
+ "os"
+
+ "github.com/cli/browser"
+ "github.com/cli/oauth/api"
+ "github.com/cli/oauth/device"
+)
+
+// DeviceFlow captures the full OAuth Device flow, including prompting the user to copy a one-time
+// code and opening their web browser, and returns an access token upon completion.
+func (oa *Flow) DeviceFlow() (*api.AccessToken, error) {
+ httpClient := oa.HTTPClient
+ if httpClient == nil {
+ httpClient = http.DefaultClient
+ }
+
+ stdin := oa.Stdin
+ if stdin == nil {
+ stdin = os.Stdin
+ }
+ stdout := oa.Stdout
+ if stdout == nil {
+ stdout = os.Stdout
+ }
+ host := oa.Host
+ if host == nil {
+ host = GitHubHost("https://" + oa.Hostname)
+ }
+
+ code, err := device.RequestCode(httpClient, host.DeviceCodeURL, oa.ClientID, oa.Scopes)
+ if err != nil {
+ return nil, err
+ }
+
+ if oa.DisplayCode == nil {
+ fmt.Fprintf(stdout, "First, copy your one-time code: %s\n", code.UserCode)
+ fmt.Fprint(stdout, "Then press [Enter] to continue in the web browser... ")
+ _ = waitForEnter(stdin)
+ } else {
+ err := oa.DisplayCode(code.UserCode, code.VerificationURI)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ browseURL := oa.BrowseURL
+ if browseURL == nil {
+ browseURL = browser.OpenURL
+ }
+
+ if err = browseURL(code.VerificationURI); err != nil {
+ return nil, fmt.Errorf("error opening the web browser: %w", err)
+ }
+
+ return device.Wait(context.TODO(), httpClient, host.TokenURL, device.WaitOptions{
+ ClientID: oa.ClientID,
+ DeviceCode: code,
+ })
+}
+
+func waitForEnter(r io.Reader) error {
+ scanner := bufio.NewScanner(r)
+ scanner.Scan()
+ return scanner.Err()
+}
diff --git a/vendor/github.com/cli/oauth/oauth_webapp.go b/vendor/github.com/cli/oauth/oauth_webapp.go
new file mode 100644
index 000000000..e448715bc
--- /dev/null
+++ b/vendor/github.com/cli/oauth/oauth_webapp.go
@@ -0,0 +1,59 @@
+package oauth
+
+import (
+ "context"
+ "fmt"
+ "net/http"
+
+ "github.com/cli/browser"
+ "github.com/cli/oauth/api"
+ "github.com/cli/oauth/webapp"
+)
+
+// WebAppFlow starts a local HTTP server, opens the web browser to initiate the OAuth Web application
+// flow, blocks until the user completes authorization and is redirected back, and returns the access token.
+func (oa *Flow) WebAppFlow() (*api.AccessToken, error) {
+ host := oa.Host
+ if host == nil {
+ host = GitHubHost("https://" + oa.Hostname)
+ }
+
+ flow, err := webapp.InitFlow()
+ if err != nil {
+ return nil, err
+ }
+
+ params := webapp.BrowserParams{
+ ClientID: oa.ClientID,
+ RedirectURI: oa.CallbackURI,
+ Scopes: oa.Scopes,
+ AllowSignup: true,
+ }
+ browserURL, err := flow.BrowserURL(host.AuthorizeURL, params)
+ if err != nil {
+ return nil, err
+ }
+
+ go func() {
+ _ = flow.StartServer(oa.WriteSuccessHTML)
+ }()
+
+ browseURL := oa.BrowseURL
+ if browseURL == nil {
+ browseURL = browser.OpenURL
+ }
+
+ err = browseURL(browserURL)
+ if err != nil {
+ return nil, fmt.Errorf("error opening the web browser: %w", err)
+ }
+
+ httpClient := oa.HTTPClient
+ if httpClient == nil {
+ httpClient = http.DefaultClient
+ }
+
+ return flow.Wait(context.TODO(), httpClient, host.TokenURL, webapp.WaitOptions{
+ ClientSecret: oa.ClientSecret,
+ })
+}
diff --git a/vendor/github.com/cli/oauth/webapp/local_server.go b/vendor/github.com/cli/oauth/webapp/local_server.go
new file mode 100644
index 000000000..c895dfe02
--- /dev/null
+++ b/vendor/github.com/cli/oauth/webapp/local_server.go
@@ -0,0 +1,85 @@
+package webapp
+
+import (
+ "context"
+ "fmt"
+ "io"
+ "net"
+ "net/http"
+)
+
+// CodeResponse represents the code received by the local server's callback handler.
+type CodeResponse struct {
+ Code string
+ State string
+}
+
+// bindLocalServer initializes a LocalServer that will listen on a randomly available TCP port.
+func bindLocalServer() (*localServer, error) {
+ listener, err := net.Listen("tcp4", "127.0.0.1:0")
+ if err != nil {
+ return nil, err
+ }
+
+ return &localServer{
+ listener: listener,
+ resultChan: make(chan CodeResponse, 1),
+ }, nil
+}
+
+type localServer struct {
+ CallbackPath string
+ WriteSuccessHTML func(w io.Writer)
+
+ resultChan chan (CodeResponse)
+ listener net.Listener
+}
+
+func (s *localServer) Port() int {
+ return s.listener.Addr().(*net.TCPAddr).Port
+}
+
+func (s *localServer) Close() error {
+ return s.listener.Close()
+}
+
+func (s *localServer) Serve() error {
+ return http.Serve(s.listener, s)
+}
+
+func (s *localServer) WaitForCode(ctx context.Context) (CodeResponse, error) {
+ select {
+ case <-ctx.Done():
+ return CodeResponse{}, ctx.Err()
+ case code := <-s.resultChan:
+ return code, nil
+ }
+}
+
+// ServeHTTP implements http.Handler.
+func (s *localServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ if s.CallbackPath != "" && r.URL.Path != s.CallbackPath {
+ w.WriteHeader(404)
+ return
+ }
+ defer func() {
+ _ = s.Close()
+ }()
+
+ params := r.URL.Query()
+ s.resultChan <- CodeResponse{
+ Code: params.Get("code"),
+ State: params.Get("state"),
+ }
+
+ w.Header().Add("content-type", "text/html")
+ if s.WriteSuccessHTML != nil {
+ s.WriteSuccessHTML(w)
+ } else {
+ defaultSuccessHTML(w)
+ }
+}
+
+func defaultSuccessHTML(w io.Writer) {
+ fmt.Fprintf(w, "You may now close this page and return to the client app.
")
+}
diff --git a/vendor/github.com/cli/oauth/webapp/webapp_flow.go b/vendor/github.com/cli/oauth/webapp/webapp_flow.go
new file mode 100644
index 000000000..49c655106
--- /dev/null
+++ b/vendor/github.com/cli/oauth/webapp/webapp_flow.go
@@ -0,0 +1,132 @@
+// Package webapp implements the OAuth Web Application authorization flow for client applications by
+// starting a server at localhost to receive the web redirect after the user has authorized the application.
+package webapp
+
+import (
+ "context"
+ "crypto/rand"
+ "encoding/hex"
+ "errors"
+ "fmt"
+ "io"
+ "net/http"
+ "net/url"
+ "strings"
+
+ "github.com/cli/oauth/api"
+)
+
+type httpClient interface {
+ PostForm(string, url.Values) (*http.Response, error)
+}
+
+// Flow holds the state for the steps of OAuth Web Application flow.
+type Flow struct {
+ server *localServer
+ clientID string
+ state string
+}
+
+// InitFlow creates a new Flow instance by detecting a locally available port number.
+func InitFlow() (*Flow, error) {
+ server, err := bindLocalServer()
+ if err != nil {
+ return nil, err
+ }
+
+ state, _ := randomString(20)
+
+ return &Flow{
+ server: server,
+ state: state,
+ }, nil
+}
+
+// BrowserParams are GET query parameters for initiating the web flow.
+type BrowserParams struct {
+ ClientID string
+ RedirectURI string
+ Scopes []string
+ LoginHandle string
+ AllowSignup bool
+}
+
+// BrowserURL appends GET query parameters to baseURL and returns the url that the user should
+// navigate to in their web browser.
+func (flow *Flow) BrowserURL(baseURL string, params BrowserParams) (string, error) {
+ ru, err := url.Parse(params.RedirectURI)
+ if err != nil {
+ return "", err
+ }
+
+ ru.Host = fmt.Sprintf("%s:%d", ru.Hostname(), flow.server.Port())
+ flow.server.CallbackPath = ru.Path
+ flow.clientID = params.ClientID
+
+ q := url.Values{}
+ q.Set("client_id", params.ClientID)
+ q.Set("redirect_uri", ru.String())
+ q.Set("scope", strings.Join(params.Scopes, " "))
+ q.Set("state", flow.state)
+ if params.LoginHandle != "" {
+ q.Set("login", params.LoginHandle)
+ }
+ if !params.AllowSignup {
+ q.Set("allow_signup", "false")
+ }
+
+ return fmt.Sprintf("%s?%s", baseURL, q.Encode()), nil
+}
+
+// StartServer starts the localhost server and blocks until it has received the web redirect. The
+// writeSuccess function can be used to render a HTML page to the user upon completion.
+func (flow *Flow) StartServer(writeSuccess func(io.Writer)) error {
+ flow.server.WriteSuccessHTML = writeSuccess
+ return flow.server.Serve()
+}
+
+// AccessToken blocks until the browser flow has completed and returns the access token.
+//
+// Deprecated: use Wait.
+func (flow *Flow) AccessToken(c httpClient, tokenURL, clientSecret string) (*api.AccessToken, error) {
+ return flow.Wait(context.Background(), c, tokenURL, WaitOptions{ClientSecret: clientSecret})
+}
+
+// WaitOptions specifies parameters to exchange the access token for.
+type WaitOptions struct {
+ // ClientSecret is the app client secret value.
+ ClientSecret string
+}
+
+// Wait blocks until the browser flow has completed and returns the access token.
+func (flow *Flow) Wait(ctx context.Context, c httpClient, tokenURL string, opts WaitOptions) (*api.AccessToken, error) {
+ code, err := flow.server.WaitForCode(ctx)
+ if err != nil {
+ return nil, err
+ }
+ if code.State != flow.state {
+ return nil, errors.New("state mismatch")
+ }
+
+ resp, err := api.PostForm(c, tokenURL,
+ url.Values{
+ "client_id": {flow.clientID},
+ "client_secret": {opts.ClientSecret},
+ "code": {code.Code},
+ "state": {flow.state},
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ return resp.AccessToken()
+}
+
+func randomString(length int) (string, error) {
+ b := make([]byte, length/2)
+ _, err := rand.Read(b)
+ if err != nil {
+ return "", err
+ }
+ return hex.EncodeToString(b), nil
+}
diff --git a/vendor/github.com/cli/safeexec/LICENSE b/vendor/github.com/cli/safeexec/LICENSE
new file mode 100644
index 000000000..ca498575a
--- /dev/null
+++ b/vendor/github.com/cli/safeexec/LICENSE
@@ -0,0 +1,25 @@
+BSD 2-Clause License
+
+Copyright (c) 2020, GitHub Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. 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.
+
+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 HOLDER 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.
diff --git a/vendor/github.com/cli/safeexec/README.md b/vendor/github.com/cli/safeexec/README.md
new file mode 100644
index 000000000..4ff1c2aca
--- /dev/null
+++ b/vendor/github.com/cli/safeexec/README.md
@@ -0,0 +1,48 @@
+# safeexec
+
+A Go module that provides a stabler alternative to `exec.LookPath()` that:
+- Avoids a Windows security risk of executing commands found in the current directory; and
+- Allows executing commands found in PATH, even if they come from relative PATH entries.
+
+This is an alternative to [`golang.org/x/sys/execabs`](https://pkg.go.dev/golang.org/x/sys/execabs).
+
+## Usage
+```go
+import (
+ "os/exec"
+ "github.com/cli/safeexec"
+)
+
+func gitStatus() error {
+ gitBin, err := safeexec.LookPath("git")
+ if err != nil {
+ return err
+ }
+ cmd := exec.Command(gitBin, "status")
+ return cmd.Run()
+}
+```
+
+## Background
+### Windows security vulnerability with Go <= 1.18
+Go 1.18 (and older) standard library has a security vulnerability when executing programs:
+```go
+import "os/exec"
+
+func gitStatus() error {
+ // On Windows, this will result in `.\git.exe` or `.\git.bat` being executed
+ // if either were found in the current working directory.
+ cmd := exec.Command("git", "status")
+ return cmd.Run()
+}
+```
+
+For historic reasons, Go used to implicitly [include the current directory](https://github.com/golang/go/issues/38736) in the PATH resolution on Windows. The `safeexec` package avoids searching the current directory on Windows.
+
+### Relative PATH entries with Go 1.19+
+
+Go 1.19 (and newer) standard library [throws an error](https://github.com/golang/go/issues/43724) if `exec.LookPath("git")` resolved to an executable relative to the current directory. This can happen on other platforms if the PATH environment variable contains relative entries, e.g. `PATH=./bin:$PATH`. The `safeexec` package allows respecting relative PATH entries as it assumes that the responsibility for keeping PATH safe lies outside of the Go program.
+
+## TODO
+
+Ideally, this module would also provide `exec.Command()` and `exec.CommandContext()` equivalents that delegate to the patched version of `LookPath`. However, this doesn't seem possible since `LookPath` may return an error, while `exec.Command/CommandContext()` themselves do not return an error. In the standard library, the resulting `exec.Cmd` struct stores the LookPath error in a private field, but that functionality isn't available to us.
diff --git a/vendor/github.com/cli/safeexec/lookpath.go b/vendor/github.com/cli/safeexec/lookpath.go
new file mode 100644
index 000000000..e649ca7d1
--- /dev/null
+++ b/vendor/github.com/cli/safeexec/lookpath.go
@@ -0,0 +1,17 @@
+//go:build !windows && go1.19
+// +build !windows,go1.19
+
+package safeexec
+
+import (
+ "errors"
+ "os/exec"
+)
+
+func LookPath(file string) (string, error) {
+ path, err := exec.LookPath(file)
+ if errors.Is(err, exec.ErrDot) {
+ return path, nil
+ }
+ return path, err
+}
diff --git a/vendor/github.com/cli/safeexec/lookpath_1.18.go b/vendor/github.com/cli/safeexec/lookpath_1.18.go
new file mode 100644
index 000000000..bb4a27e4f
--- /dev/null
+++ b/vendor/github.com/cli/safeexec/lookpath_1.18.go
@@ -0,0 +1,10 @@
+//go:build !windows && !go1.19
+// +build !windows,!go1.19
+
+package safeexec
+
+import "os/exec"
+
+func LookPath(file string) (string, error) {
+ return exec.LookPath(file)
+}
diff --git a/vendor/github.com/cli/safeexec/lookpath_windows.go b/vendor/github.com/cli/safeexec/lookpath_windows.go
new file mode 100644
index 000000000..19b3e52f7
--- /dev/null
+++ b/vendor/github.com/cli/safeexec/lookpath_windows.go
@@ -0,0 +1,120 @@
+// 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.
+
+// Package safeexec provides alternatives for exec package functions to avoid
+// accidentally executing binaries found in the current working directory on
+// Windows.
+package safeexec
+
+import (
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strings"
+)
+
+func chkStat(file string) error {
+ d, err := os.Stat(file)
+ if err != nil {
+ return err
+ }
+ if d.IsDir() {
+ return os.ErrPermission
+ }
+ return nil
+}
+
+func hasExt(file string) bool {
+ i := strings.LastIndex(file, ".")
+ if i < 0 {
+ return false
+ }
+ return strings.LastIndexAny(file, `:\/`) < i
+}
+
+func findExecutable(file string, exts []string) (string, error) {
+ if len(exts) == 0 {
+ return file, chkStat(file)
+ }
+ if hasExt(file) {
+ if chkStat(file) == nil {
+ return file, nil
+ }
+ }
+ for _, e := range exts {
+ if f := file + e; chkStat(f) == nil {
+ return f, nil
+ }
+ }
+ return "", os.ErrNotExist
+}
+
+// LookPath searches for an executable named file in the
+// directories named by the PATH environment variable.
+// If file contains a slash, it is tried directly and the PATH is not consulted.
+// LookPath also uses PATHEXT environment variable to match
+// a suitable candidate.
+// The result may be an absolute path or a path relative to the current directory.
+func LookPath(file string) (string, error) {
+ var exts []string
+ x := os.Getenv(`PATHEXT`)
+ if x != "" {
+ for _, e := range strings.Split(strings.ToLower(x), `;`) {
+ if e == "" {
+ continue
+ }
+ if e[0] != '.' {
+ e = "." + e
+ }
+ exts = append(exts, e)
+ }
+ } else {
+ exts = []string{".com", ".exe", ".bat", ".cmd"}
+ }
+
+ if strings.ContainsAny(file, `:\/`) {
+ if f, err := findExecutable(file, exts); err == nil {
+ return f, nil
+ } else {
+ return "", &exec.Error{file, err}
+ }
+ }
+
+ // https://github.com/golang/go/issues/38736
+ // if f, err := findExecutable(filepath.Join(".", file), exts); err == nil {
+ // return f, nil
+ // }
+
+ path := os.Getenv("path")
+ for _, dir := range filepath.SplitList(path) {
+ if f, err := findExecutable(filepath.Join(dir, file), exts); err == nil {
+ return f, nil
+ }
+ }
+ return "", &exec.Error{file, exec.ErrNotFound}
+}
diff --git a/vendor/github.com/cli/shurcooL-graphql/.golangci.yml b/vendor/github.com/cli/shurcooL-graphql/.golangci.yml
new file mode 100644
index 000000000..2d5cc27b6
--- /dev/null
+++ b/vendor/github.com/cli/shurcooL-graphql/.golangci.yml
@@ -0,0 +1,11 @@
+linters:
+ enable:
+ - gofmt
+ - godot
+
+linters-settings:
+ godot:
+ # comments to be checked: `declarations`, `toplevel`, or `all`
+ scope: declarations
+ # check that each sentence starts with a capital letter
+ capital: true
diff --git a/vendor/github.com/cli/shurcooL-graphql/LICENSE b/vendor/github.com/cli/shurcooL-graphql/LICENSE
new file mode 100644
index 000000000..ca4c77642
--- /dev/null
+++ b/vendor/github.com/cli/shurcooL-graphql/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 Dmitri Shuralyov
+
+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/cli/shurcooL-graphql/README.md b/vendor/github.com/cli/shurcooL-graphql/README.md
new file mode 100644
index 000000000..a49c52474
--- /dev/null
+++ b/vendor/github.com/cli/shurcooL-graphql/README.md
@@ -0,0 +1,276 @@
+graphql
+=======
+
+Package `graphql` provides a GraphQL client implementation, and is forked from `https://github.com/shurcooL/graphql`.
+
+Installation
+------------
+
+```bash
+go get -u github.com/cli/shurcooL-graphql
+```
+
+Usage
+-----
+
+Construct a GraphQL client, specifying the GraphQL server URL. Then, you can use it to make GraphQL queries and mutations.
+
+```Go
+client := graphql.NewClient("https://example.com/graphql", nil)
+// Use client...
+```
+
+### Authentication
+
+Some GraphQL servers may require authentication. The `graphql` package does not directly handle authentication. Instead, when creating a new client, you're expected to pass an `http.Client` that performs authentication. The easiest and recommended way to do this is to use the [`golang.org/x/oauth2`](https://golang.org/x/oauth2) package. You'll need an OAuth token with the right scopes. Then:
+
+```Go
+import "golang.org/x/oauth2"
+
+func main() {
+ src := oauth2.StaticTokenSource(
+ &oauth2.Token{AccessToken: os.Getenv("GRAPHQL_TOKEN")},
+ )
+ httpClient := oauth2.NewClient(context.Background(), src)
+
+ client := graphql.NewClient("https://example.com/graphql", httpClient)
+ // Use client...
+```
+
+### Simple Query
+
+To make a GraphQL query, you need to define a corresponding Go type.
+
+For example, to make the following GraphQL query:
+
+```GraphQL
+query {
+ me {
+ name
+ }
+}
+```
+
+You can define this variable:
+
+```Go
+var query struct {
+ Me struct {
+ Name graphql.String
+ }
+}
+```
+
+Then call `client.Query`, passing a pointer to it:
+
+```Go
+err := client.Query(context.Background(), &query, nil)
+if err != nil {
+ // Handle error.
+}
+fmt.Println(query.Me.Name)
+
+// Output: Luke Skywalker
+```
+
+### Arguments and Variables
+
+Often, you'll want to specify arguments on some fields. You can use the `graphql` struct field tag for this.
+
+For example, to make the following GraphQL query:
+
+```GraphQL
+{
+ human(id: "1000") {
+ name
+ height(unit: METER)
+ }
+}
+```
+
+You can define this variable:
+
+```Go
+var q struct {
+ Human struct {
+ Name graphql.String
+ Height graphql.Float `graphql:"height(unit: METER)"`
+ } `graphql:"human(id: \"1000\")"`
+}
+```
+
+Then call `client.Query`:
+
+```Go
+err := client.Query(context.Background(), &q, nil)
+if err != nil {
+ // Handle error.
+}
+fmt.Println(q.Human.Name)
+fmt.Println(q.Human.Height)
+
+// Output:
+// Luke Skywalker
+// 1.72
+```
+
+However, that'll only work if the arguments are constant and known in advance. Otherwise, you will need to make use of variables. Replace the constants in the struct field tag with variable names:
+
+```Go
+var q struct {
+ Human struct {
+ Name graphql.String
+ Height graphql.Float `graphql:"height(unit: $unit)"`
+ } `graphql:"human(id: $id)"`
+}
+```
+
+Then, define a `variables` map with their values:
+
+```Go
+variables := map[string]any{
+ "id": graphql.ID(id),
+ "unit": starwars.LengthUnit("METER"),
+}
+```
+
+Finally, call `client.Query` providing `variables`:
+
+```Go
+err := client.Query(context.Background(), &q, variables)
+if err != nil {
+ // Handle error.
+}
+```
+
+### Inline Fragments
+
+Some GraphQL queries contain inline fragments. You can use the `graphql` struct field tag to express them.
+
+For example, to make the following GraphQL query:
+
+```GraphQL
+{
+ hero(episode: "JEDI") {
+ name
+ ... on Droid {
+ primaryFunction
+ }
+ ... on Human {
+ height
+ }
+ }
+}
+```
+
+You can define this variable:
+
+```Go
+var q struct {
+ Hero struct {
+ Name graphql.String
+ Droid struct {
+ PrimaryFunction graphql.String
+ } `graphql:"... on Droid"`
+ Human struct {
+ Height graphql.Float
+ } `graphql:"... on Human"`
+ } `graphql:"hero(episode: \"JEDI\")"`
+}
+```
+
+Alternatively, you can define the struct types corresponding to inline fragments, and use them as embedded fields in your query:
+
+```Go
+type (
+ DroidFragment struct {
+ PrimaryFunction graphql.String
+ }
+ HumanFragment struct {
+ Height graphql.Float
+ }
+)
+
+var q struct {
+ Hero struct {
+ Name graphql.String
+ DroidFragment `graphql:"... on Droid"`
+ HumanFragment `graphql:"... on Human"`
+ } `graphql:"hero(episode: \"JEDI\")"`
+}
+```
+
+Then call `client.Query`:
+
+```Go
+err := client.Query(context.Background(), &q, nil)
+if err != nil {
+ // Handle error.
+}
+fmt.Println(q.Hero.Name)
+fmt.Println(q.Hero.PrimaryFunction)
+fmt.Println(q.Hero.Height)
+
+// Output:
+// R2-D2
+// Astromech
+// 0
+```
+
+### Mutations
+
+Mutations often require information that you can only find out by performing a query first. Let's suppose you've already done that.
+
+For example, to make the following GraphQL mutation:
+
+```GraphQL
+mutation($ep: Episode!, $review: ReviewInput!) {
+ createReview(episode: $ep, review: $review) {
+ stars
+ commentary
+ }
+}
+variables {
+ "ep": "JEDI",
+ "review": {
+ "stars": 5,
+ "commentary": "This is a great movie!"
+ }
+}
+```
+
+You can define:
+
+```Go
+var m struct {
+ CreateReview struct {
+ Stars graphql.Int
+ Commentary graphql.String
+ } `graphql:"createReview(episode: $ep, review: $review)"`
+}
+variables := map[string]any{
+ "ep": starwars.Episode("JEDI"),
+ "review": starwars.ReviewInput{
+ Stars: graphql.Int(5),
+ Commentary: graphql.String("This is a great movie!"),
+ },
+}
+```
+
+Then call `client.Mutate`:
+
+```Go
+err := client.Mutate(context.Background(), &m, variables)
+if err != nil {
+ // Handle error.
+}
+fmt.Printf("Created a %v star review: %v\n", m.CreateReview.Stars, m.CreateReview.Commentary)
+
+// Output:
+// Created a 5 star review: This is a great movie!
+```
+
+License
+-------
+
+- [MIT License](LICENSE)
diff --git a/vendor/github.com/cli/shurcooL-graphql/graphql.go b/vendor/github.com/cli/shurcooL-graphql/graphql.go
new file mode 100644
index 000000000..d45cbbb58
--- /dev/null
+++ b/vendor/github.com/cli/shurcooL-graphql/graphql.go
@@ -0,0 +1,148 @@
+package graphql
+
+import (
+ "bytes"
+ "context"
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "strings"
+
+ "github.com/cli/shurcooL-graphql/internal/jsonutil"
+)
+
+// Client is a GraphQL client.
+type Client struct {
+ url string // GraphQL server URL.
+ httpClient *http.Client // Non-nil.
+}
+
+// NewClient creates a GraphQL client targeting the specified GraphQL server URL.
+// If httpClient is nil, then http.DefaultClient is used.
+func NewClient(url string, httpClient *http.Client) *Client {
+ if httpClient == nil {
+ httpClient = http.DefaultClient
+ }
+ return &Client{
+ url: url,
+ httpClient: httpClient,
+ }
+}
+
+// Query executes a single GraphQL query request,
+// with a query derived from q, populating the response into it.
+// Argument q should be a pointer to struct that corresponds to the GraphQL schema.
+func (c *Client) Query(ctx context.Context, q any, variables map[string]any) error {
+ return c.do(ctx, queryOperation, q, variables, "")
+}
+
+// QueryNamed is the same as Query but allows a name to be specified for the query.
+func (c *Client) QueryNamed(ctx context.Context, queryName string, q any, variables map[string]any) error {
+ return c.do(ctx, queryOperation, q, variables, queryName)
+}
+
+// Mutate executes a single GraphQL mutation request,
+// with a mutation derived from m, populating the response into it.
+// Argument m should be a pointer to struct that corresponds to the GraphQL schema.
+func (c *Client) Mutate(ctx context.Context, m any, variables map[string]any) error {
+ return c.do(ctx, mutationOperation, m, variables, "")
+}
+
+// MutateNamed is the same as Mutate but allows a name to be specified for the mutation.
+func (c *Client) MutateNamed(ctx context.Context, queryName string, m any, variables map[string]any) error {
+ return c.do(ctx, mutationOperation, m, variables, queryName)
+}
+
+// do executes a single GraphQL operation.
+func (c *Client) do(ctx context.Context, op operationType, v any, variables map[string]any, queryName string) error {
+ var query string
+ switch op {
+ case queryOperation:
+ query = constructQuery(v, variables, queryName)
+ case mutationOperation:
+ query = constructMutation(v, variables, queryName)
+ }
+ in := struct {
+ Query string `json:"query"`
+ Variables map[string]any `json:"variables,omitempty"`
+ }{
+ Query: query,
+ Variables: variables,
+ }
+ var buf bytes.Buffer
+ err := json.NewEncoder(&buf).Encode(in)
+ if err != nil {
+ return err
+ }
+ req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.url, &buf)
+ if err != nil {
+ return err
+ }
+ req.Header.Set("Content-Type", "application/json")
+ resp, err := c.httpClient.Do(req)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ if resp.StatusCode != http.StatusOK {
+ body, _ := io.ReadAll(resp.Body)
+ return fmt.Errorf("non-200 OK status code: %v body: %q", resp.Status, body)
+ }
+ var out struct {
+ Data *json.RawMessage
+ Errors Errors
+ //Extensions any // Unused.
+ }
+ err = json.NewDecoder(resp.Body).Decode(&out)
+ if err != nil {
+ // TODO: Consider including response body in returned error, if deemed helpful.
+ return err
+ }
+ if out.Data != nil {
+ err := jsonutil.UnmarshalGraphQL(*out.Data, v)
+ if err != nil {
+ // TODO: Consider including response body in returned error, if deemed helpful.
+ return err
+ }
+ }
+ if len(out.Errors) > 0 {
+ return out.Errors
+ }
+ return nil
+}
+
+// Errors represents the "errors" array in a response from a GraphQL server.
+// If returned via error interface, the slice is expected to contain at least 1 element.
+//
+// Specification: https://spec.graphql.org/October2021/#sec-Errors.
+type Errors []struct {
+ Message string
+ Locations []struct {
+ Line int
+ Column int
+ }
+ Path []any
+ Extensions map[string]any
+ Type string
+}
+
+// Error implements error interface.
+func (e Errors) Error() string {
+ b := strings.Builder{}
+ l := len(e)
+ for i, err := range e {
+ b.WriteString(fmt.Sprintf("Message: %s, Locations: %+v", err.Message, err.Locations))
+ if i != l-1 {
+ b.WriteString("\n")
+ }
+ }
+ return b.String()
+}
+
+type operationType uint8
+
+const (
+ queryOperation operationType = iota
+ mutationOperation
+)
diff --git a/vendor/github.com/cli/shurcooL-graphql/ident/ident.go b/vendor/github.com/cli/shurcooL-graphql/ident/ident.go
new file mode 100644
index 000000000..9fa925888
--- /dev/null
+++ b/vendor/github.com/cli/shurcooL-graphql/ident/ident.go
@@ -0,0 +1,241 @@
+// Package ident provides functions for parsing and converting identifier names
+// between various naming convention. It has support for MixedCaps, lowerCamelCase,
+// and SCREAMING_SNAKE_CASE naming conventions.
+package ident
+
+import (
+ "strings"
+ "unicode"
+ "unicode/utf8"
+)
+
+// ParseMixedCaps parses a MixedCaps identifier name.
+//
+// E.g., "ClientMutationID" -> {"Client", "Mutation", "ID"}.
+func ParseMixedCaps(name string) Name {
+ var words Name
+
+ // Split name at any lower -> Upper or Upper -> Upper,lower transitions.
+ // Check each word for initialisms.
+ runes := []rune(name)
+ w, i := 0, 0 // Index of start of word, scan.
+ for i+1 <= len(runes) {
+ eow := false // Whether we hit the end of a word.
+ if i+1 == len(runes) {
+ eow = true
+ } else if unicode.IsLower(runes[i]) && unicode.IsUpper(runes[i+1]) {
+ // lower -> Upper.
+ eow = true
+ } else if i+2 < len(runes) && unicode.IsUpper(runes[i]) && unicode.IsUpper(runes[i+1]) && unicode.IsLower(runes[i+2]) {
+ // Upper -> Upper,lower. End of acronym, followed by a word.
+ eow = true
+
+ if string(runes[i:i+3]) == "IDs" { // Special case, plural form of ID initialism.
+ eow = false
+ }
+ }
+ i++
+ if !eow {
+ continue
+ }
+
+ // [w, i) is a word.
+ word := string(runes[w:i])
+ if initialism, ok := isInitialism(word); ok {
+ words = append(words, initialism)
+ } else if i1, i2, ok := isTwoInitialisms(word); ok {
+ words = append(words, i1, i2)
+ } else {
+ words = append(words, word)
+ }
+ w = i
+ }
+ return words
+}
+
+// ParseLowerCamelCase parses a lowerCamelCase identifier name.
+//
+// E.g., "clientMutationId" -> {"client", "Mutation", "Id"}.
+func ParseLowerCamelCase(name string) Name {
+ var words Name
+
+ // Split name at any Upper letters.
+ runes := []rune(name)
+ w, i := 0, 0 // Index of start of word, scan.
+ for i+1 <= len(runes) {
+ eow := false // Whether we hit the end of a word.
+ if i+1 == len(runes) {
+ eow = true
+ } else if unicode.IsUpper(runes[i+1]) {
+ // Upper letter.
+ eow = true
+ }
+ i++
+ if !eow {
+ continue
+ }
+
+ // [w, i) is a word.
+ words = append(words, string(runes[w:i]))
+ w = i
+ }
+ return words
+}
+
+// ParseScreamingSnakeCase parses a SCREAMING_SNAKE_CASE identifier name.
+//
+// E.g., "CLIENT_MUTATION_ID" -> {"CLIENT", "MUTATION", "ID"}.
+func ParseScreamingSnakeCase(name string) Name {
+ var words Name
+
+ // Split name at '_' characters.
+ runes := []rune(name)
+ w, i := 0, 0 // Index of start of word, scan.
+ for i+1 <= len(runes) {
+ eow := false // Whether we hit the end of a word.
+ if i+1 == len(runes) {
+ eow = true
+ } else if runes[i+1] == '_' {
+ // Underscore.
+ eow = true
+ }
+ i++
+ if !eow {
+ continue
+ }
+
+ // [w, i) is a word.
+ words = append(words, string(runes[w:i]))
+ if i < len(runes) && runes[i] == '_' {
+ // Skip underscore.
+ i++
+ }
+ w = i
+ }
+ return words
+}
+
+// Name is an identifier name, broken up into individual words.
+type Name []string
+
+// ToMixedCaps expresses identifier name in MixedCaps naming convention.
+//
+// E.g., "ClientMutationID".
+func (n Name) ToMixedCaps() string {
+ for i, word := range n {
+ if strings.EqualFold(word, "IDs") { // Special case, plural form of ID initialism.
+ n[i] = "IDs"
+ continue
+ }
+ if initialism, ok := isInitialism(word); ok {
+ n[i] = initialism
+ continue
+ }
+ if brand, ok := isBrand(word); ok {
+ n[i] = brand
+ continue
+ }
+ r, size := utf8.DecodeRuneInString(word)
+ n[i] = string(unicode.ToUpper(r)) + strings.ToLower(word[size:])
+ }
+ return strings.Join(n, "")
+}
+
+// ToLowerCamelCase expresses identifier name in lowerCamelCase naming convention.
+//
+// E.g., "clientMutationId".
+func (n Name) ToLowerCamelCase() string {
+ for i, word := range n {
+ if i == 0 {
+ n[i] = strings.ToLower(word)
+ continue
+ }
+ r, size := utf8.DecodeRuneInString(word)
+ n[i] = string(unicode.ToUpper(r)) + strings.ToLower(word[size:])
+ }
+ return strings.Join(n, "")
+}
+
+// isInitialism reports whether word is an initialism.
+func isInitialism(word string) (string, bool) {
+ initialism := strings.ToUpper(word)
+ _, ok := initialisms[initialism]
+ return initialism, ok
+}
+
+// isTwoInitialisms reports whether word is two initialisms.
+func isTwoInitialisms(word string) (string, string, bool) {
+ word = strings.ToUpper(word)
+ for i := 2; i <= len(word)-2; i++ { // Shortest initialism is 2 characters long.
+ _, ok1 := initialisms[word[:i]]
+ _, ok2 := initialisms[word[i:]]
+ if ok1 && ok2 {
+ return word[:i], word[i:], true
+ }
+ }
+ return "", "", false
+}
+
+// initialisms is the set of initialisms in the MixedCaps naming convention.
+// Only add entries that are highly unlikely to be non-initialisms.
+// For instance, "ID" is fine (Freudian code is rare), but "AND" is not.
+var initialisms = map[string]struct{}{
+ "ACL": {},
+ "API": {},
+ "ASCII": {},
+ "CPU": {},
+ "CSS": {},
+ "DNS": {},
+ "EOF": {},
+ "GUID": {},
+ "HTML": {},
+ "HTTP": {},
+ "HTTPS": {},
+ "ID": {},
+ "IP": {},
+ "JSON": {},
+ "LHS": {},
+ "QPS": {},
+ "RAM": {},
+ "RHS": {},
+ "RPC": {},
+ "RSS": {},
+ "SLA": {},
+ "SMTP": {},
+ "SQL": {},
+ "SSH": {},
+ "TCP": {},
+ "TLS": {},
+ "TTL": {},
+ "UDP": {},
+ "UI": {},
+ "UID": {},
+ "URI": {},
+ "URL": {},
+ "UTF8": {},
+ "UUID": {},
+ "VM": {},
+ "XML": {},
+ "XMPP": {},
+ "XSRF": {},
+ "XSS": {},
+}
+
+// isBrand reports whether word is a brand.
+func isBrand(word string) (string, bool) {
+ brand, ok := brands[strings.ToLower(word)]
+ return brand, ok
+}
+
+// brands is the map of brands in the MixedCaps naming convention;
+// see https://dmitri.shuralyov.com/idiomatic-go#for-brands-or-words-with-more-than-1-capital-letter-lowercase-all-letters.
+// Key is the lower case version of the brand, value is the canonical brand spelling.
+// Only add entries that are highly unlikely to be non-brands.
+var brands = map[string]string{
+ "github": "GitHub",
+ "gitlab": "GitLab",
+ "devops": "DevOps", // For https://en.wikipedia.org/wiki/DevOps.
+ // For https://docs.github.com/en/graphql/reference/enums#fundingplatform.
+ "issuehunt": "IssueHunt",
+ "lfx": "LFX",
+}
diff --git a/vendor/github.com/cli/shurcooL-graphql/internal/jsonutil/graphql.go b/vendor/github.com/cli/shurcooL-graphql/internal/jsonutil/graphql.go
new file mode 100644
index 000000000..5a44ea593
--- /dev/null
+++ b/vendor/github.com/cli/shurcooL-graphql/internal/jsonutil/graphql.go
@@ -0,0 +1,310 @@
+// Package jsonutil provides a function for decoding JSON
+// into a GraphQL query data structure.
+package jsonutil
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "reflect"
+ "strings"
+)
+
+// UnmarshalGraphQL parses the JSON-encoded GraphQL response data and stores
+// the result in the GraphQL query data structure pointed to by v.
+//
+// The implementation is created on top of the JSON tokenizer available
+// in "encoding/json".Decoder.
+func UnmarshalGraphQL(data []byte, v any) error {
+ dec := json.NewDecoder(bytes.NewReader(data))
+ dec.UseNumber()
+ err := (&decoder{tokenizer: dec}).Decode(v)
+ if err != nil {
+ return err
+ }
+ tok, err := dec.Token()
+ switch err {
+ case io.EOF:
+ // Expect to get io.EOF. There shouldn't be any more
+ // tokens left after we've decoded v successfully.
+ return nil
+ case nil:
+ return fmt.Errorf("invalid token '%v' after top-level value", tok)
+ default:
+ return err
+ }
+}
+
+// decoder is a JSON decoder that performs custom unmarshaling behavior
+// for GraphQL query data structures. It's implemented on top of a JSON tokenizer.
+type decoder struct {
+ tokenizer interface {
+ Token() (json.Token, error)
+ }
+
+ // Stack of what part of input JSON we're in the middle of - objects, arrays.
+ parseState []json.Delim
+
+ // Stacks of values where to unmarshal.
+ // The top of each stack is the reflect.Value where to unmarshal next JSON value.
+ //
+ // The reason there's more than one stack is because we might be unmarshaling
+ // a single JSON value into multiple GraphQL fragments or embedded structs, so
+ // we keep track of them all.
+ vs [][]reflect.Value
+}
+
+// Decode decodes a single JSON value from d.tokenizer into v.
+func (d *decoder) Decode(v any) error {
+ rv := reflect.ValueOf(v)
+ if rv.Kind() != reflect.Ptr {
+ return fmt.Errorf("cannot decode into non-pointer %T", v)
+ }
+ d.vs = [][]reflect.Value{{rv.Elem()}}
+ return d.decode()
+}
+
+// decode decodes a single JSON value from d.tokenizer into d.vs.
+func (d *decoder) decode() error {
+ // The loop invariant is that the top of each d.vs stack
+ // is where we try to unmarshal the next JSON value we see.
+ for len(d.vs) > 0 {
+ tok, err := d.tokenizer.Token()
+ if err == io.EOF {
+ return errors.New("unexpected end of JSON input")
+ } else if err != nil {
+ return err
+ }
+
+ switch {
+
+ // Are we inside an object and seeing next key (rather than end of object)?
+ case d.state() == '{' && tok != json.Delim('}'):
+ key, ok := tok.(string)
+ if !ok {
+ return errors.New("unexpected non-key in JSON input")
+ }
+ someFieldExist := false
+ for i := range d.vs {
+ v := d.vs[i][len(d.vs[i])-1]
+ if v.Kind() == reflect.Ptr {
+ v = v.Elem()
+ }
+ var f reflect.Value
+ if v.Kind() == reflect.Struct {
+ f = fieldByGraphQLName(v, key)
+ if f.IsValid() {
+ someFieldExist = true
+ }
+ }
+ d.vs[i] = append(d.vs[i], f)
+ }
+ if !someFieldExist {
+ return fmt.Errorf("struct field for %q doesn't exist in any of %v places to unmarshal", key, len(d.vs))
+ }
+
+ // We've just consumed the current token, which was the key.
+ // Read the next token, which should be the value, and let the rest of code process it.
+ tok, err = d.tokenizer.Token()
+ if err == io.EOF {
+ return errors.New("unexpected end of JSON input")
+ } else if err != nil {
+ return err
+ }
+
+ // Are we inside an array and seeing next value (rather than end of array)?
+ case d.state() == '[' && tok != json.Delim(']'):
+ someSliceExist := false
+ for i := range d.vs {
+ v := d.vs[i][len(d.vs[i])-1]
+ if v.Kind() == reflect.Ptr {
+ v = v.Elem()
+ }
+ var f reflect.Value
+ if v.Kind() == reflect.Slice {
+ v.Set(reflect.Append(v, reflect.Zero(v.Type().Elem()))) // v = append(v, T).
+ f = v.Index(v.Len() - 1)
+ someSliceExist = true
+ }
+ d.vs[i] = append(d.vs[i], f)
+ }
+ if !someSliceExist {
+ return fmt.Errorf("slice doesn't exist in any of %v places to unmarshal", len(d.vs))
+ }
+ }
+
+ switch tok := tok.(type) {
+ case string, json.Number, bool, nil:
+ // Value.
+
+ for i := range d.vs {
+ v := d.vs[i][len(d.vs[i])-1]
+ if !v.IsValid() {
+ continue
+ }
+ err := unmarshalValue(tok, v)
+ if err != nil {
+ return err
+ }
+ }
+ d.popAllVs()
+
+ case json.Delim:
+ switch tok {
+ case '{':
+ // Start of object.
+
+ d.pushState(tok)
+
+ frontier := make([]reflect.Value, len(d.vs)) // Places to look for GraphQL fragments/embedded structs.
+ for i := range d.vs {
+ v := d.vs[i][len(d.vs[i])-1]
+ frontier[i] = v
+ // TODO: Do this recursively or not? Add a test case if needed.
+ if v.Kind() == reflect.Ptr && v.IsNil() {
+ v.Set(reflect.New(v.Type().Elem())) // v = new(T).
+ }
+ }
+ // Find GraphQL fragments/embedded structs recursively, adding to frontier
+ // as new ones are discovered and exploring them further.
+ for len(frontier) > 0 {
+ v := frontier[0]
+ frontier = frontier[1:]
+ if v.Kind() == reflect.Ptr {
+ v = v.Elem()
+ }
+ if v.Kind() != reflect.Struct {
+ continue
+ }
+ for i := 0; i < v.NumField(); i++ {
+ if isGraphQLFragment(v.Type().Field(i)) || v.Type().Field(i).Anonymous {
+ // Add GraphQL fragment or embedded struct.
+ d.vs = append(d.vs, []reflect.Value{v.Field(i)})
+ frontier = append(frontier, v.Field(i))
+ }
+ }
+ }
+ case '[':
+ // Start of array.
+
+ d.pushState(tok)
+
+ for i := range d.vs {
+ v := d.vs[i][len(d.vs[i])-1]
+ // TODO: Confirm this is needed, write a test case.
+ //if v.Kind() == reflect.Ptr && v.IsNil() {
+ // v.Set(reflect.New(v.Type().Elem())) // v = new(T).
+ //}
+
+ // Reset slice to empty (in case it had non-zero initial value).
+ if v.Kind() == reflect.Ptr {
+ v = v.Elem()
+ }
+ if v.Kind() != reflect.Slice {
+ continue
+ }
+ v.Set(reflect.MakeSlice(v.Type(), 0, 0)) // v = make(T, 0, 0).
+ }
+ case '}', ']':
+ // End of object or array.
+ d.popAllVs()
+ d.popState()
+ default:
+ return errors.New("unexpected delimiter in JSON input")
+ }
+ default:
+ return errors.New("unexpected token in JSON input")
+ }
+ }
+ return nil
+}
+
+// pushState pushes a new parse state s onto the stack.
+func (d *decoder) pushState(s json.Delim) {
+ d.parseState = append(d.parseState, s)
+}
+
+// popState pops a parse state (already obtained) off the stack.
+// The stack must be non-empty.
+func (d *decoder) popState() {
+ d.parseState = d.parseState[:len(d.parseState)-1]
+}
+
+// state reports the parse state on top of stack, or 0 if empty.
+func (d *decoder) state() json.Delim {
+ if len(d.parseState) == 0 {
+ return 0
+ }
+ return d.parseState[len(d.parseState)-1]
+}
+
+// popAllVs pops from all d.vs stacks, keeping only non-empty ones.
+func (d *decoder) popAllVs() {
+ var nonEmpty [][]reflect.Value
+ for i := range d.vs {
+ d.vs[i] = d.vs[i][:len(d.vs[i])-1]
+ if len(d.vs[i]) > 0 {
+ nonEmpty = append(nonEmpty, d.vs[i])
+ }
+ }
+ d.vs = nonEmpty
+}
+
+// fieldByGraphQLName returns an exported struct field of struct v
+// that matches GraphQL name, or invalid reflect.Value if none found.
+func fieldByGraphQLName(v reflect.Value, name string) reflect.Value {
+ for i := 0; i < v.NumField(); i++ {
+ if v.Type().Field(i).PkgPath != "" {
+ // Skip unexported field.
+ continue
+ }
+ if hasGraphQLName(v.Type().Field(i), name) {
+ return v.Field(i)
+ }
+ }
+ return reflect.Value{}
+}
+
+// hasGraphQLName reports whether struct field f has GraphQL name.
+func hasGraphQLName(f reflect.StructField, name string) bool {
+ value, ok := f.Tag.Lookup("graphql")
+ if !ok {
+ // TODO: caseconv package is relatively slow. Optimize it, then consider using it here.
+ //return caseconv.MixedCapsToLowerCamelCase(f.Name) == name
+ return strings.EqualFold(f.Name, name)
+ }
+ value = strings.TrimSpace(value) // TODO: Parse better.
+ if strings.HasPrefix(value, "...") {
+ // GraphQL fragment. It doesn't have a name.
+ return false
+ }
+ // Cut off anything that follows the field name,
+ // such as field arguments, aliases, directives.
+ if i := strings.IndexAny(value, "(:@"); i != -1 {
+ value = value[:i]
+ }
+ return strings.TrimSpace(value) == name
+}
+
+// isGraphQLFragment reports whether struct field f is a GraphQL fragment.
+func isGraphQLFragment(f reflect.StructField) bool {
+ value, ok := f.Tag.Lookup("graphql")
+ if !ok {
+ return false
+ }
+ value = strings.TrimSpace(value) // TODO: Parse better.
+ return strings.HasPrefix(value, "...")
+}
+
+// unmarshalValue unmarshals JSON value into v.
+// Argument v must be addressable and not obtained by the use of unexported
+// struct fields, otherwise unmarshalValue will panic.
+func unmarshalValue(value json.Token, v reflect.Value) error {
+ b, err := json.Marshal(value) // TODO: Short-circuit (if profiling says it's worth it).
+ if err != nil {
+ return err
+ }
+ return json.Unmarshal(b, v.Addr().Interface())
+}
diff --git a/vendor/github.com/cli/shurcooL-graphql/query.go b/vendor/github.com/cli/shurcooL-graphql/query.go
new file mode 100644
index 000000000..16eaecd2e
--- /dev/null
+++ b/vendor/github.com/cli/shurcooL-graphql/query.go
@@ -0,0 +1,140 @@
+package graphql
+
+import (
+ "bytes"
+ "encoding/json"
+ "io"
+ "reflect"
+ "sort"
+
+ "github.com/cli/shurcooL-graphql/ident"
+)
+
+func constructQuery(v any, variables map[string]any, queryName string) string {
+ query := query(v)
+ if len(variables) > 0 {
+ return "query" + queryNameFormat(queryName) + "(" + queryArguments(variables) + ")" + query
+ } else if queryName != "" {
+ return "query" + queryNameFormat(queryName) + query
+ }
+ return query
+}
+
+func constructMutation(v any, variables map[string]any, queryName string) string {
+ query := query(v)
+ if len(variables) > 0 {
+ return "mutation" + queryNameFormat(queryName) + "(" + queryArguments(variables) + ")" + query
+ }
+ return "mutation" + queryNameFormat(queryName) + query
+}
+
+func queryNameFormat(n string) string {
+ if n != "" {
+ return " " + n
+ }
+ return n
+}
+
+// queryArguments constructs a minified arguments string for variables.
+//
+// E.g., map[string]any{"a": Int(123), "b": NewBoolean(true)} -> "$a:Int!$b:Boolean".
+func queryArguments(variables map[string]any) string {
+ // Sort keys in order to produce deterministic output for testing purposes.
+ // TODO: If tests can be made to work with non-deterministic output, then no need to sort.
+ keys := make([]string, 0, len(variables))
+ for k := range variables {
+ keys = append(keys, k)
+ }
+ sort.Strings(keys)
+
+ var buf bytes.Buffer
+ for _, k := range keys {
+ _, _ = io.WriteString(&buf, "$")
+ _, _ = io.WriteString(&buf, k)
+ _, _ = io.WriteString(&buf, ":")
+ writeArgumentType(&buf, reflect.TypeOf(variables[k]), true)
+ // Don't insert a comma here.
+ // Commas in GraphQL are insignificant, and we want minified output.
+ // See https://spec.graphql.org/October2021/#sec-Insignificant-Commas.
+ }
+ return buf.String()
+}
+
+// writeArgumentType writes a minified GraphQL type for t to w.
+// Argument value indicates whether t is a value (required) type or pointer (optional) type.
+// If value is true, then "!" is written at the end of t.
+func writeArgumentType(w io.Writer, t reflect.Type, value bool) {
+ if t.Kind() == reflect.Ptr {
+ // Pointer is an optional type, so no "!" at the end of the pointer's underlying type.
+ writeArgumentType(w, t.Elem(), false)
+ return
+ }
+
+ switch t.Kind() {
+ case reflect.Slice, reflect.Array:
+ // List. E.g., "[Int]".
+ _, _ = io.WriteString(w, "[")
+ writeArgumentType(w, t.Elem(), true)
+ _, _ = io.WriteString(w, "]")
+ default:
+ // Named type. E.g., "Int".
+ name := t.Name()
+ if name == "string" { // HACK: Workaround for https://github.com/shurcooL/githubv4/issues/12.
+ name = "ID"
+ }
+ _, _ = io.WriteString(w, name)
+ }
+
+ if value {
+ // Value is a required type, so add "!" to the end.
+ _, _ = io.WriteString(w, "!")
+ }
+}
+
+// query uses writeQuery to recursively construct
+// a minified query string from the provided struct v.
+//
+// E.g., struct{Foo Int, BarBaz *Boolean} -> "{foo,barBaz}".
+func query(v any) string {
+ var buf bytes.Buffer
+ writeQuery(&buf, reflect.TypeOf(v), false)
+ return buf.String()
+}
+
+// writeQuery writes a minified query for t to w.
+// If inline is true, the struct fields of t are inlined into parent struct.
+func writeQuery(w io.Writer, t reflect.Type, inline bool) {
+ switch t.Kind() {
+ case reflect.Ptr, reflect.Slice:
+ writeQuery(w, t.Elem(), false)
+ case reflect.Struct:
+ // If the type implements json.Unmarshaler, it's a scalar. Don't expand it.
+ if reflect.PtrTo(t).Implements(jsonUnmarshaler) {
+ return
+ }
+ if !inline {
+ _, _ = io.WriteString(w, "{")
+ }
+ for i := 0; i < t.NumField(); i++ {
+ if i != 0 {
+ _, _ = io.WriteString(w, ",")
+ }
+ f := t.Field(i)
+ value, ok := f.Tag.Lookup("graphql")
+ inlineField := f.Anonymous && !ok
+ if !inlineField {
+ if ok {
+ _, _ = io.WriteString(w, value)
+ } else {
+ _, _ = io.WriteString(w, ident.ParseMixedCaps(f.Name).ToLowerCamelCase())
+ }
+ }
+ writeQuery(w, f.Type, inlineField)
+ }
+ if !inline {
+ _, _ = io.WriteString(w, "}")
+ }
+ }
+}
+
+var jsonUnmarshaler = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()
diff --git a/vendor/github.com/cli/shurcooL-graphql/scalar.go b/vendor/github.com/cli/shurcooL-graphql/scalar.go
new file mode 100644
index 000000000..8679d34e2
--- /dev/null
+++ b/vendor/github.com/cli/shurcooL-graphql/scalar.go
@@ -0,0 +1,51 @@
+package graphql
+
+// Note: These custom types are meant to be used in queries for now.
+// But the plan is to switch to using native Go types (string, int, bool, time.Time, etc.).
+// See https://github.com/shurcooL/githubv4/issues/9 for details.
+//
+// These custom types currently provide documentation, and their use
+// is required for sending outbound queries. However, native Go types
+// can be used for unmarshaling. Once https://github.com/shurcooL/githubv4/issues/9
+// is resolved, native Go types can completely replace these.
+
+type (
+ // Boolean represents true or false values.
+ Boolean bool
+
+ // Float represents signed double-precision fractional values as
+ // specified by IEEE 754.
+ Float float64
+
+ // ID represents a unique identifier that is Base64 obfuscated. It
+ // is often used to refetch an object or as key for a cache. The ID
+ // type appears in a JSON response as a String; however, it is not
+ // intended to be human-readable. When expected as an input type,
+ // any string (such as "VXNlci0xMA==") or integer (such as 4) input
+ // value will be accepted as an ID.
+ ID any
+
+ // Int represents non-fractional signed whole numeric values.
+ // Int can represent values between -(2^31) and 2^31 - 1.
+ Int int32
+
+ // String represents textual data as UTF-8 character sequences.
+ // This type is most often used by GraphQL to represent free-form
+ // human-readable text.
+ String string
+)
+
+// NewBoolean is a helper to make a new *Boolean.
+func NewBoolean(v Boolean) *Boolean { return &v }
+
+// NewFloat is a helper to make a new *Float.
+func NewFloat(v Float) *Float { return &v }
+
+// NewID is a helper to make a new *ID.
+func NewID(v ID) *ID { return &v }
+
+// NewInt is a helper to make a new *Int.
+func NewInt(v Int) *Int { return &v }
+
+// NewString is a helper to make a new *String.
+func NewString(v String) *String { return &v }
diff --git a/vendor/github.com/danieljoos/wincred/.gitattributes b/vendor/github.com/danieljoos/wincred/.gitattributes
new file mode 100644
index 000000000..d207b1802
--- /dev/null
+++ b/vendor/github.com/danieljoos/wincred/.gitattributes
@@ -0,0 +1 @@
+*.go text eol=lf
diff --git a/vendor/github.com/danieljoos/wincred/.gitignore b/vendor/github.com/danieljoos/wincred/.gitignore
new file mode 100644
index 000000000..6142c0691
--- /dev/null
+++ b/vendor/github.com/danieljoos/wincred/.gitignore
@@ -0,0 +1,25 @@
+# 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
+
+coverage.txt
diff --git a/vendor/github.com/danieljoos/wincred/LICENSE b/vendor/github.com/danieljoos/wincred/LICENSE
new file mode 100644
index 000000000..2f436f1b3
--- /dev/null
+++ b/vendor/github.com/danieljoos/wincred/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Daniel Joos
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/vendor/github.com/danieljoos/wincred/README.md b/vendor/github.com/danieljoos/wincred/README.md
new file mode 100644
index 000000000..8a879b0ce
--- /dev/null
+++ b/vendor/github.com/danieljoos/wincred/README.md
@@ -0,0 +1,145 @@
+wincred
+=======
+
+Go wrapper around the Windows Credential Manager API functions.
+
+[![GitHub release](https://img.shields.io/github/release/danieljoos/wincred.svg?style=flat-square)](https://github.com/danieljoos/wincred/releases/latest)
+[![Test Status](https://img.shields.io/github/actions/workflow/status/danieljoos/wincred/test.yml?label=test&logo=github&style=flat-square)](https://github.com/danieljoos/wincred/actions?query=workflow%3Atest)
+[![Go Report Card](https://goreportcard.com/badge/github.com/danieljoos/wincred)](https://goreportcard.com/report/github.com/danieljoos/wincred)
+[![Codecov](https://img.shields.io/codecov/c/github/danieljoos/wincred?logo=codecov&style=flat-square)](https://codecov.io/gh/danieljoos/wincred)
+[![PkgGoDev](https://img.shields.io/badge/go.dev-docs-007d9c?logo=go&logoColor=white&style=flat-square)](https://pkg.go.dev/github.com/danieljoos/wincred)
+
+Installation
+------------
+
+```Go
+go get github.com/danieljoos/wincred
+```
+
+
+Usage
+-----
+
+See the following examples:
+
+### Create and store a new generic credential object
+```Go
+package main
+
+import (
+ "fmt"
+ "github.com/danieljoos/wincred"
+)
+
+func main() {
+ cred := wincred.NewGenericCredential("myGoApplication")
+ cred.CredentialBlob = []byte("my secret")
+ err := cred.Write()
+
+ if err != nil {
+ fmt.Println(err)
+ }
+}
+```
+
+### Retrieve a credential object
+```Go
+package main
+
+import (
+ "fmt"
+ "github.com/danieljoos/wincred"
+)
+
+func main() {
+ cred, err := wincred.GetGenericCredential("myGoApplication")
+ if err == nil {
+ fmt.Println(string(cred.CredentialBlob))
+ }
+}
+```
+
+### Remove a credential object
+```Go
+package main
+
+import (
+ "fmt"
+ "github.com/danieljoos/wincred"
+)
+
+func main() {
+ cred, err := wincred.GetGenericCredential("myGoApplication")
+ if err != nil {
+ fmt.Println(err)
+ return
+ }
+ cred.Delete()
+}
+```
+
+### List all available credentials
+```Go
+package main
+
+import (
+ "fmt"
+ "github.com/danieljoos/wincred"
+)
+
+func main() {
+ creds, err := wincred.List()
+ if err != nil {
+ fmt.Println(err)
+ return
+ }
+ for i := range(creds) {
+ fmt.Println(creds[i].TargetName)
+ }
+}
+```
+
+Hints
+-----
+
+### Encoding
+
+The credential objects simply store byte arrays without specific meaning or encoding.
+For sharing between different applications, it might make sense to apply an explicit string encoding - for example **UTF-16 LE** (used nearly everywhere in the Win32 API).
+
+```Go
+package main
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/danieljoos/wincred"
+ "golang.org/x/text/encoding/unicode"
+ "golang.org/x/text/transform"
+)
+
+func main() {
+ cred := wincred.NewGenericCredential("myGoApplication")
+
+ encoder := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM).NewEncoder()
+ blob, _, err := transform.Bytes(encoder, []byte("mysecret"))
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+
+ cred.CredentialBlob = blob
+ err = cred.Write()
+
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(1)
+ }
+}
+
+```
+
+### Limitations
+
+The size of a credential blob is limited to **2560 Bytes** by the Windows API.
diff --git a/vendor/github.com/danieljoos/wincred/conversion.go b/vendor/github.com/danieljoos/wincred/conversion.go
new file mode 100644
index 000000000..bc04f50f1
--- /dev/null
+++ b/vendor/github.com/danieljoos/wincred/conversion.go
@@ -0,0 +1,116 @@
+// +build windows
+
+package wincred
+
+import (
+ "encoding/binary"
+ "reflect"
+ "time"
+ "unsafe"
+
+ syscall "golang.org/x/sys/windows"
+)
+
+// utf16ToByte creates a byte array from a given UTF 16 char array.
+func utf16ToByte(wstr []uint16) (result []byte) {
+ result = make([]byte, len(wstr)*2)
+ for i := range wstr {
+ binary.LittleEndian.PutUint16(result[(i*2):(i*2)+2], wstr[i])
+ }
+ return
+}
+
+// utf16FromString creates a UTF16 char array from a string.
+func utf16FromString(str string) []uint16 {
+ res, err := syscall.UTF16FromString(str)
+ if err != nil {
+ return []uint16{}
+ }
+ return res
+}
+
+// goBytes copies the given C byte array to a Go byte array (see `C.GoBytes`).
+// This function avoids having cgo as dependency.
+func goBytes(src uintptr, len uint32) []byte {
+ if src == uintptr(0) {
+ return []byte{}
+ }
+ rv := make([]byte, len)
+ copy(rv, *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
+ Data: src,
+ Len: int(len),
+ Cap: int(len),
+ })))
+ return rv
+}
+
+// Convert the given CREDENTIAL struct to a more usable structure
+func sysToCredential(cred *sysCREDENTIAL) (result *Credential) {
+ if cred == nil {
+ return nil
+ }
+ result = new(Credential)
+ result.Comment = syscall.UTF16PtrToString(cred.Comment)
+ result.TargetName = syscall.UTF16PtrToString(cred.TargetName)
+ result.TargetAlias = syscall.UTF16PtrToString(cred.TargetAlias)
+ result.UserName = syscall.UTF16PtrToString(cred.UserName)
+ result.LastWritten = time.Unix(0, cred.LastWritten.Nanoseconds())
+ result.Persist = CredentialPersistence(cred.Persist)
+ result.CredentialBlob = goBytes(cred.CredentialBlob, cred.CredentialBlobSize)
+ result.Attributes = make([]CredentialAttribute, cred.AttributeCount)
+ attrSlice := *(*[]sysCREDENTIAL_ATTRIBUTE)(unsafe.Pointer(&reflect.SliceHeader{
+ Data: cred.Attributes,
+ Len: int(cred.AttributeCount),
+ Cap: int(cred.AttributeCount),
+ }))
+ for i, attr := range attrSlice {
+ resultAttr := &result.Attributes[i]
+ resultAttr.Keyword = syscall.UTF16PtrToString(attr.Keyword)
+ resultAttr.Value = goBytes(attr.Value, attr.ValueSize)
+ }
+ return result
+}
+
+// Convert the given Credential object back to a CREDENTIAL struct, which can be used for calling the
+// Windows APIs
+func sysFromCredential(cred *Credential) (result *sysCREDENTIAL) {
+ if cred == nil {
+ return nil
+ }
+ result = new(sysCREDENTIAL)
+ result.Flags = 0
+ result.Type = 0
+ result.TargetName, _ = syscall.UTF16PtrFromString(cred.TargetName)
+ result.Comment, _ = syscall.UTF16PtrFromString(cred.Comment)
+ result.LastWritten = syscall.NsecToFiletime(cred.LastWritten.UnixNano())
+ result.CredentialBlobSize = uint32(len(cred.CredentialBlob))
+ if len(cred.CredentialBlob) > 0 {
+ result.CredentialBlob = uintptr(unsafe.Pointer(&cred.CredentialBlob[0]))
+ } else {
+ result.CredentialBlob = 0
+ }
+ result.Persist = uint32(cred.Persist)
+ result.AttributeCount = uint32(len(cred.Attributes))
+ attributes := make([]sysCREDENTIAL_ATTRIBUTE, len(cred.Attributes))
+ if len(attributes) > 0 {
+ result.Attributes = uintptr(unsafe.Pointer(&attributes[0]))
+ } else {
+ result.Attributes = 0
+ }
+ for i := range cred.Attributes {
+ inAttr := &cred.Attributes[i]
+ outAttr := &attributes[i]
+ outAttr.Keyword, _ = syscall.UTF16PtrFromString(inAttr.Keyword)
+ outAttr.Flags = 0
+ outAttr.ValueSize = uint32(len(inAttr.Value))
+ if len(inAttr.Value) > 0 {
+ outAttr.Value = uintptr(unsafe.Pointer(&inAttr.Value[0]))
+ } else {
+ outAttr.Value = 0
+ }
+ }
+ result.TargetAlias, _ = syscall.UTF16PtrFromString(cred.TargetAlias)
+ result.UserName, _ = syscall.UTF16PtrFromString(cred.UserName)
+
+ return
+}
diff --git a/vendor/github.com/danieljoos/wincred/conversion_unsupported.go b/vendor/github.com/danieljoos/wincred/conversion_unsupported.go
new file mode 100644
index 000000000..a1ea72075
--- /dev/null
+++ b/vendor/github.com/danieljoos/wincred/conversion_unsupported.go
@@ -0,0 +1,11 @@
+// +build !windows
+
+package wincred
+
+func utf16ToByte(...interface{}) []byte {
+ return nil
+}
+
+func utf16FromString(...interface{}) []uint16 {
+ return nil
+}
diff --git a/vendor/github.com/danieljoos/wincred/sys.go b/vendor/github.com/danieljoos/wincred/sys.go
new file mode 100644
index 000000000..fb8a6ac0f
--- /dev/null
+++ b/vendor/github.com/danieljoos/wincred/sys.go
@@ -0,0 +1,148 @@
+//go:build windows
+// +build windows
+
+package wincred
+
+import (
+ "reflect"
+ "syscall"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+var (
+ modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
+ procCredRead = modadvapi32.NewProc("CredReadW")
+ procCredWrite proc = modadvapi32.NewProc("CredWriteW")
+ procCredDelete proc = modadvapi32.NewProc("CredDeleteW")
+ procCredFree proc = modadvapi32.NewProc("CredFree")
+ procCredEnumerate = modadvapi32.NewProc("CredEnumerateW")
+)
+
+// Interface for syscall.Proc: helps testing
+type proc interface {
+ Call(a ...uintptr) (r1, r2 uintptr, lastErr error)
+}
+
+// https://docs.microsoft.com/en-us/windows/desktop/api/wincred/ns-wincred-_credentialw
+type sysCREDENTIAL struct {
+ Flags uint32
+ Type uint32
+ TargetName *uint16
+ Comment *uint16
+ LastWritten windows.Filetime
+ CredentialBlobSize uint32
+ CredentialBlob uintptr
+ Persist uint32
+ AttributeCount uint32
+ Attributes uintptr
+ TargetAlias *uint16
+ UserName *uint16
+}
+
+// https://docs.microsoft.com/en-us/windows/desktop/api/wincred/ns-wincred-_credential_attributew
+type sysCREDENTIAL_ATTRIBUTE struct {
+ Keyword *uint16
+ Flags uint32
+ ValueSize uint32
+ Value uintptr
+}
+
+// https://docs.microsoft.com/en-us/windows/desktop/api/wincred/ns-wincred-_credentialw
+type sysCRED_TYPE uint32
+
+const (
+ sysCRED_TYPE_GENERIC sysCRED_TYPE = 0x1
+ sysCRED_TYPE_DOMAIN_PASSWORD sysCRED_TYPE = 0x2
+ sysCRED_TYPE_DOMAIN_CERTIFICATE sysCRED_TYPE = 0x3
+ sysCRED_TYPE_DOMAIN_VISIBLE_PASSWORD sysCRED_TYPE = 0x4
+ sysCRED_TYPE_GENERIC_CERTIFICATE sysCRED_TYPE = 0x5
+ sysCRED_TYPE_DOMAIN_EXTENDED sysCRED_TYPE = 0x6
+
+ // https://docs.microsoft.com/en-us/windows/desktop/Debug/system-error-codes
+ sysERROR_NOT_FOUND = windows.Errno(1168)
+ sysERROR_INVALID_PARAMETER = windows.Errno(87)
+ sysERROR_BAD_USERNAME = windows.Errno(2202)
+)
+
+// https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-credreadw
+func sysCredRead(targetName string, typ sysCRED_TYPE) (*Credential, error) {
+ var pcred *sysCREDENTIAL
+ targetNamePtr, _ := windows.UTF16PtrFromString(targetName)
+ ret, _, err := syscall.SyscallN(
+ procCredRead.Addr(),
+ uintptr(unsafe.Pointer(targetNamePtr)),
+ uintptr(typ),
+ 0,
+ uintptr(unsafe.Pointer(&pcred)),
+ )
+ if ret == 0 {
+ return nil, err
+ }
+ defer procCredFree.Call(uintptr(unsafe.Pointer(pcred)))
+
+ return sysToCredential(pcred), nil
+}
+
+// https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-credwritew
+func sysCredWrite(cred *Credential, typ sysCRED_TYPE) error {
+ ncred := sysFromCredential(cred)
+ ncred.Type = uint32(typ)
+ ret, _, err := procCredWrite.Call(
+ uintptr(unsafe.Pointer(ncred)),
+ 0,
+ )
+ if ret == 0 {
+ return err
+ }
+
+ return nil
+}
+
+// https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-creddeletew
+func sysCredDelete(cred *Credential, typ sysCRED_TYPE) error {
+ targetNamePtr, _ := windows.UTF16PtrFromString(cred.TargetName)
+ ret, _, err := procCredDelete.Call(
+ uintptr(unsafe.Pointer(targetNamePtr)),
+ uintptr(typ),
+ 0,
+ )
+ if ret == 0 {
+ return err
+ }
+
+ return nil
+}
+
+// https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-credenumeratew
+func sysCredEnumerate(filter string, all bool) ([]*Credential, error) {
+ var count int
+ var pcreds uintptr
+ var filterPtr *uint16
+ if !all {
+ filterPtr, _ = windows.UTF16PtrFromString(filter)
+ }
+ ret, _, err := syscall.SyscallN(
+ procCredEnumerate.Addr(),
+ uintptr(unsafe.Pointer(filterPtr)),
+ 0,
+ uintptr(unsafe.Pointer(&count)),
+ uintptr(unsafe.Pointer(&pcreds)),
+ )
+ if ret == 0 {
+ return nil, err
+ }
+ defer procCredFree.Call(pcreds)
+ credsSlice := *(*[]*sysCREDENTIAL)(unsafe.Pointer(&reflect.SliceHeader{
+ Data: pcreds,
+ Len: count,
+ Cap: count,
+ }))
+ creds := make([]*Credential, count, count)
+ for i, cred := range credsSlice {
+ creds[i] = sysToCredential(cred)
+ }
+
+ return creds, nil
+}
diff --git a/vendor/github.com/danieljoos/wincred/sys_unsupported.go b/vendor/github.com/danieljoos/wincred/sys_unsupported.go
new file mode 100644
index 000000000..b47bccf8a
--- /dev/null
+++ b/vendor/github.com/danieljoos/wincred/sys_unsupported.go
@@ -0,0 +1,36 @@
+// +build !windows
+
+package wincred
+
+import (
+ "errors"
+ "syscall"
+)
+
+const (
+ sysCRED_TYPE_GENERIC = 0
+ sysCRED_TYPE_DOMAIN_PASSWORD = 0
+ sysCRED_TYPE_DOMAIN_CERTIFICATE = 0
+ sysCRED_TYPE_DOMAIN_VISIBLE_PASSWORD = 0
+ sysCRED_TYPE_GENERIC_CERTIFICATE = 0
+ sysCRED_TYPE_DOMAIN_EXTENDED = 0
+
+ sysERROR_NOT_FOUND = syscall.Errno(1)
+ sysERROR_INVALID_PARAMETER = syscall.Errno(1)
+)
+
+func sysCredRead(...interface{}) (*Credential, error) {
+ return nil, errors.New("Operation not supported")
+}
+
+func sysCredWrite(...interface{}) error {
+ return errors.New("Operation not supported")
+}
+
+func sysCredDelete(...interface{}) error {
+ return errors.New("Operation not supported")
+}
+
+func sysCredEnumerate(...interface{}) ([]*Credential, error) {
+ return nil, errors.New("Operation not supported")
+}
diff --git a/vendor/github.com/danieljoos/wincred/types.go b/vendor/github.com/danieljoos/wincred/types.go
new file mode 100644
index 000000000..28debc932
--- /dev/null
+++ b/vendor/github.com/danieljoos/wincred/types.go
@@ -0,0 +1,69 @@
+package wincred
+
+import (
+ "time"
+)
+
+// CredentialPersistence describes one of three persistence modes of a credential.
+// A detailed description of the available modes can be found on
+// Docs: https://docs.microsoft.com/en-us/windows/desktop/api/wincred/ns-wincred-_credentialw
+type CredentialPersistence uint32
+
+const (
+ // PersistSession indicates that the credential only persists for the life
+ // of the current Windows login session. Such a credential is not visible in
+ // any other logon session, even from the same user.
+ PersistSession CredentialPersistence = 0x1
+
+ // PersistLocalMachine indicates that the credential persists for this and
+ // all subsequent logon sessions on this local machine/computer. It is
+ // however not visible for logon sessions of this user on a different
+ // machine.
+ PersistLocalMachine CredentialPersistence = 0x2
+
+ // PersistEnterprise indicates that the credential persists for this and all
+ // subsequent logon sessions for this user. It is also visible for logon
+ // sessions on different computers.
+ PersistEnterprise CredentialPersistence = 0x3
+)
+
+// CredentialAttribute represents an application-specific attribute of a credential.
+type CredentialAttribute struct {
+ Keyword string
+ Value []byte
+}
+
+// Credential is the basic credential structure.
+// A credential is identified by its target name.
+// The actual credential secret is available in the CredentialBlob field.
+type Credential struct {
+ TargetName string
+ Comment string
+ LastWritten time.Time
+ CredentialBlob []byte
+ Attributes []CredentialAttribute
+ TargetAlias string
+ UserName string
+ Persist CredentialPersistence
+}
+
+// GenericCredential holds a credential for generic usage.
+// It is typically defined and used by applications that need to manage user
+// secrets.
+//
+// More information about the available kinds of credentials of the Windows
+// Credential Management API can be found on Docs:
+// https://docs.microsoft.com/en-us/windows/desktop/SecAuthN/kinds-of-credentials
+type GenericCredential struct {
+ Credential
+}
+
+// DomainPassword holds a domain credential that is typically used by the
+// operating system for user logon.
+//
+// More information about the available kinds of credentials of the Windows
+// Credential Management API can be found on Docs:
+// https://docs.microsoft.com/en-us/windows/desktop/SecAuthN/kinds-of-credentials
+type DomainPassword struct {
+ Credential
+}
diff --git a/vendor/github.com/danieljoos/wincred/wincred.go b/vendor/github.com/danieljoos/wincred/wincred.go
new file mode 100644
index 000000000..5632ee90c
--- /dev/null
+++ b/vendor/github.com/danieljoos/wincred/wincred.go
@@ -0,0 +1,114 @@
+// Package wincred provides primitives for accessing the Windows Credentials Management API.
+// This includes functions for retrieval, listing and storage of credentials as well as Go structures for convenient access to the credential data.
+//
+// A more detailed description of Windows Credentials Management can be found on
+// Docs: https://docs.microsoft.com/en-us/windows/desktop/SecAuthN/credentials-management
+package wincred
+
+import "errors"
+
+const (
+ // ErrElementNotFound is the error that is returned if a requested element cannot be found.
+ // This error constant can be used to check if a credential could not be found.
+ ErrElementNotFound = sysERROR_NOT_FOUND
+
+ // ErrInvalidParameter is the error that is returned for invalid parameters.
+ // This error constant can be used to check if the given function parameters were invalid.
+ // For example when trying to create a new generic credential with an empty target name.
+ ErrInvalidParameter = sysERROR_INVALID_PARAMETER
+
+ // ErrBadUsername is returned when the credential's username is invalid.
+ ErrBadUsername = sysERROR_BAD_USERNAME
+)
+
+// GetGenericCredential fetches the generic credential with the given name from Windows credential manager.
+// It returns nil and an error if the credential could not be found or an error occurred.
+func GetGenericCredential(targetName string) (*GenericCredential, error) {
+ cred, err := sysCredRead(targetName, sysCRED_TYPE_GENERIC)
+ if cred != nil {
+ return &GenericCredential{Credential: *cred}, err
+ }
+ return nil, err
+}
+
+// NewGenericCredential creates a new generic credential object with the given name.
+// The persist mode of the newly created object is set to a default value that indicates local-machine-wide storage.
+// The credential object is NOT yet persisted to the Windows credential vault.
+func NewGenericCredential(targetName string) (result *GenericCredential) {
+ result = new(GenericCredential)
+ result.TargetName = targetName
+ result.Persist = PersistLocalMachine
+ return
+}
+
+// Write persists the generic credential object to Windows credential manager.
+func (t *GenericCredential) Write() (err error) {
+ err = sysCredWrite(&t.Credential, sysCRED_TYPE_GENERIC)
+ return
+}
+
+// Delete removes the credential object from Windows credential manager.
+func (t *GenericCredential) Delete() (err error) {
+ err = sysCredDelete(&t.Credential, sysCRED_TYPE_GENERIC)
+ return
+}
+
+// GetDomainPassword fetches the domain-password credential with the given target host name from Windows credential manager.
+// It returns nil and an error if the credential could not be found or an error occurred.
+func GetDomainPassword(targetName string) (*DomainPassword, error) {
+ cred, err := sysCredRead(targetName, sysCRED_TYPE_DOMAIN_PASSWORD)
+ if cred != nil {
+ return &DomainPassword{Credential: *cred}, err
+ }
+ return nil, err
+}
+
+// NewDomainPassword creates a new domain-password credential used for login to the given target host name.
+// The persist mode of the newly created object is set to a default value that indicates local-machine-wide storage.
+// The credential object is NOT yet persisted to the Windows credential vault.
+func NewDomainPassword(targetName string) (result *DomainPassword) {
+ result = new(DomainPassword)
+ result.TargetName = targetName
+ result.Persist = PersistLocalMachine
+ return
+}
+
+// Write persists the domain-password credential to Windows credential manager.
+func (t *DomainPassword) Write() (err error) {
+ err = sysCredWrite(&t.Credential, sysCRED_TYPE_DOMAIN_PASSWORD)
+ return
+}
+
+// Delete removes the domain-password credential from Windows credential manager.
+func (t *DomainPassword) Delete() (err error) {
+ err = sysCredDelete(&t.Credential, sysCRED_TYPE_DOMAIN_PASSWORD)
+ return
+}
+
+// SetPassword sets the CredentialBlob field of a domain password credential to the given string.
+func (t *DomainPassword) SetPassword(pw string) {
+ t.CredentialBlob = utf16ToByte(utf16FromString(pw))
+}
+
+// List retrieves all credentials of the Credentials store.
+func List() ([]*Credential, error) {
+ creds, err := sysCredEnumerate("", true)
+ if err != nil && errors.Is(err, ErrElementNotFound) {
+ // Ignore ERROR_NOT_FOUND and return an empty list instead
+ creds = []*Credential{}
+ err = nil
+ }
+ return creds, err
+}
+
+// FilteredList retrieves the list of credentials from the Credentials store that match the given filter.
+// The filter string defines the prefix followed by an asterisk for the `TargetName` attribute of the credentials.
+func FilteredList(filter string) ([]*Credential, error) {
+ creds, err := sysCredEnumerate(filter, false)
+ if err != nil && errors.Is(err, ErrElementNotFound) {
+ // Ignore ERROR_NOT_FOUND and return an empty list instead
+ creds = []*Credential{}
+ err = nil
+ }
+ return creds, err
+}
diff --git a/vendor/github.com/fatih/color/LICENSE.md b/vendor/github.com/fatih/color/LICENSE.md
new file mode 100644
index 000000000..25fdaf639
--- /dev/null
+++ b/vendor/github.com/fatih/color/LICENSE.md
@@ -0,0 +1,20 @@
+The MIT License (MIT)
+
+Copyright (c) 2013 Fatih Arslan
+
+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/fatih/color/README.md b/vendor/github.com/fatih/color/README.md
new file mode 100644
index 000000000..be82827ca
--- /dev/null
+++ b/vendor/github.com/fatih/color/README.md
@@ -0,0 +1,176 @@
+# color [![](https://github.com/fatih/color/workflows/build/badge.svg)](https://github.com/fatih/color/actions) [![PkgGoDev](https://pkg.go.dev/badge/github.com/fatih/color)](https://pkg.go.dev/github.com/fatih/color)
+
+Color lets you use colorized outputs in terms of [ANSI Escape
+Codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors) in Go (Golang). It
+has support for Windows too! The API can be used in several ways, pick one that
+suits you.
+
+![Color](https://user-images.githubusercontent.com/438920/96832689-03b3e000-13f4-11eb-9803-46f4c4de3406.jpg)
+
+## Install
+
+```bash
+go get github.com/fatih/color
+```
+
+## Examples
+
+### Standard colors
+
+```go
+// Print with default helper functions
+color.Cyan("Prints text in cyan.")
+
+// A newline will be appended automatically
+color.Blue("Prints %s in blue.", "text")
+
+// These are using the default foreground colors
+color.Red("We have red")
+color.Magenta("And many others ..")
+
+```
+
+### Mix and reuse colors
+
+```go
+// Create a new color object
+c := color.New(color.FgCyan).Add(color.Underline)
+c.Println("Prints cyan text with an underline.")
+
+// Or just add them to New()
+d := color.New(color.FgCyan, color.Bold)
+d.Printf("This prints bold cyan %s\n", "too!.")
+
+// Mix up foreground and background colors, create new mixes!
+red := color.New(color.FgRed)
+
+boldRed := red.Add(color.Bold)
+boldRed.Println("This will print text in bold red.")
+
+whiteBackground := red.Add(color.BgWhite)
+whiteBackground.Println("Red text with white background.")
+```
+
+### Use your own output (io.Writer)
+
+```go
+// Use your own io.Writer output
+color.New(color.FgBlue).Fprintln(myWriter, "blue color!")
+
+blue := color.New(color.FgBlue)
+blue.Fprint(writer, "This will print text in blue.")
+```
+
+### Custom print functions (PrintFunc)
+
+```go
+// Create a custom print function for convenience
+red := color.New(color.FgRed).PrintfFunc()
+red("Warning")
+red("Error: %s", err)
+
+// Mix up multiple attributes
+notice := color.New(color.Bold, color.FgGreen).PrintlnFunc()
+notice("Don't forget this...")
+```
+
+### Custom fprint functions (FprintFunc)
+
+```go
+blue := color.New(color.FgBlue).FprintfFunc()
+blue(myWriter, "important notice: %s", stars)
+
+// Mix up with multiple attributes
+success := color.New(color.Bold, color.FgGreen).FprintlnFunc()
+success(myWriter, "Don't forget this...")
+```
+
+### Insert into noncolor strings (SprintFunc)
+
+```go
+// Create SprintXxx functions to mix strings with other non-colorized strings:
+yellow := color.New(color.FgYellow).SprintFunc()
+red := color.New(color.FgRed).SprintFunc()
+fmt.Printf("This is a %s and this is %s.\n", yellow("warning"), red("error"))
+
+info := color.New(color.FgWhite, color.BgGreen).SprintFunc()
+fmt.Printf("This %s rocks!\n", info("package"))
+
+// Use helper functions
+fmt.Println("This", color.RedString("warning"), "should be not neglected.")
+fmt.Printf("%v %v\n", color.GreenString("Info:"), "an important message.")
+
+// Windows supported too! Just don't forget to change the output to color.Output
+fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS"))
+```
+
+### Plug into existing code
+
+```go
+// Use handy standard colors
+color.Set(color.FgYellow)
+
+fmt.Println("Existing text will now be in yellow")
+fmt.Printf("This one %s\n", "too")
+
+color.Unset() // Don't forget to unset
+
+// You can mix up parameters
+color.Set(color.FgMagenta, color.Bold)
+defer color.Unset() // Use it in your function
+
+fmt.Println("All text will now be bold magenta.")
+```
+
+### Disable/Enable color
+
+There might be a case where you want to explicitly disable/enable color output. the
+`go-isatty` package will automatically disable color output for non-tty output streams
+(for example if the output were piped directly to `less`).
+
+The `color` package also disables color output if the [`NO_COLOR`](https://no-color.org) environment
+variable is set to a non-empty string.
+
+`Color` has support to disable/enable colors programmatically both globally and
+for single color definitions. For example suppose you have a CLI app and a
+`-no-color` bool flag. You can easily disable the color output with:
+
+```go
+var flagNoColor = flag.Bool("no-color", false, "Disable color output")
+
+if *flagNoColor {
+ color.NoColor = true // disables colorized output
+}
+```
+
+It also has support for single color definitions (local). You can
+disable/enable color output on the fly:
+
+```go
+c := color.New(color.FgCyan)
+c.Println("Prints cyan text")
+
+c.DisableColor()
+c.Println("This is printed without any color")
+
+c.EnableColor()
+c.Println("This prints again cyan...")
+```
+
+## GitHub Actions
+
+To output color in GitHub Actions (or other CI systems that support ANSI colors), make sure to set `color.NoColor = false` so that it bypasses the check for non-tty output streams.
+
+## Todo
+
+* Save/Return previous values
+* Evaluate fmt.Formatter interface
+
+## Credits
+
+* [Fatih Arslan](https://github.com/fatih)
+* Windows support via @mattn: [colorable](https://github.com/mattn/go-colorable)
+
+## License
+
+The MIT License (MIT) - see [`LICENSE.md`](https://github.com/fatih/color/blob/master/LICENSE.md) for more details
diff --git a/vendor/github.com/fatih/color/color.go b/vendor/github.com/fatih/color/color.go
new file mode 100644
index 000000000..c4234287d
--- /dev/null
+++ b/vendor/github.com/fatih/color/color.go
@@ -0,0 +1,650 @@
+package color
+
+import (
+ "fmt"
+ "io"
+ "os"
+ "strconv"
+ "strings"
+ "sync"
+
+ "github.com/mattn/go-colorable"
+ "github.com/mattn/go-isatty"
+)
+
+var (
+ // NoColor defines if the output is colorized or not. It's dynamically set to
+ // false or true based on the stdout's file descriptor referring to a terminal
+ // or not. It's also set to true if the NO_COLOR environment variable is
+ // set (regardless of its value). This is a global option and affects all
+ // colors. For more control over each color block use the methods
+ // DisableColor() individually.
+ NoColor = noColorIsSet() || os.Getenv("TERM") == "dumb" ||
+ (!isatty.IsTerminal(os.Stdout.Fd()) && !isatty.IsCygwinTerminal(os.Stdout.Fd()))
+
+ // Output defines the standard output of the print functions. By default,
+ // os.Stdout is used.
+ Output = colorable.NewColorableStdout()
+
+ // Error defines a color supporting writer for os.Stderr.
+ Error = colorable.NewColorableStderr()
+
+ // colorsCache is used to reduce the count of created Color objects and
+ // allows to reuse already created objects with required Attribute.
+ colorsCache = make(map[Attribute]*Color)
+ colorsCacheMu sync.Mutex // protects colorsCache
+)
+
+// noColorIsSet returns true if the environment variable NO_COLOR is set to a non-empty string.
+func noColorIsSet() bool {
+ return os.Getenv("NO_COLOR") != ""
+}
+
+// Color defines a custom color object which is defined by SGR parameters.
+type Color struct {
+ params []Attribute
+ noColor *bool
+}
+
+// Attribute defines a single SGR Code
+type Attribute int
+
+const escape = "\x1b"
+
+// Base attributes
+const (
+ Reset Attribute = iota
+ Bold
+ Faint
+ Italic
+ Underline
+ BlinkSlow
+ BlinkRapid
+ ReverseVideo
+ Concealed
+ CrossedOut
+)
+
+const (
+ ResetBold Attribute = iota + 22
+ ResetItalic
+ ResetUnderline
+ ResetBlinking
+ _
+ ResetReversed
+ ResetConcealed
+ ResetCrossedOut
+)
+
+var mapResetAttributes map[Attribute]Attribute = map[Attribute]Attribute{
+ Bold: ResetBold,
+ Faint: ResetBold,
+ Italic: ResetItalic,
+ Underline: ResetUnderline,
+ BlinkSlow: ResetBlinking,
+ BlinkRapid: ResetBlinking,
+ ReverseVideo: ResetReversed,
+ Concealed: ResetConcealed,
+ CrossedOut: ResetCrossedOut,
+}
+
+// Foreground text colors
+const (
+ FgBlack Attribute = iota + 30
+ FgRed
+ FgGreen
+ FgYellow
+ FgBlue
+ FgMagenta
+ FgCyan
+ FgWhite
+)
+
+// Foreground Hi-Intensity text colors
+const (
+ FgHiBlack Attribute = iota + 90
+ FgHiRed
+ FgHiGreen
+ FgHiYellow
+ FgHiBlue
+ FgHiMagenta
+ FgHiCyan
+ FgHiWhite
+)
+
+// Background text colors
+const (
+ BgBlack Attribute = iota + 40
+ BgRed
+ BgGreen
+ BgYellow
+ BgBlue
+ BgMagenta
+ BgCyan
+ BgWhite
+)
+
+// Background Hi-Intensity text colors
+const (
+ BgHiBlack Attribute = iota + 100
+ BgHiRed
+ BgHiGreen
+ BgHiYellow
+ BgHiBlue
+ BgHiMagenta
+ BgHiCyan
+ BgHiWhite
+)
+
+// New returns a newly created color object.
+func New(value ...Attribute) *Color {
+ c := &Color{
+ params: make([]Attribute, 0),
+ }
+
+ if noColorIsSet() {
+ c.noColor = boolPtr(true)
+ }
+
+ c.Add(value...)
+ return c
+}
+
+// Set sets the given parameters immediately. It will change the color of
+// output with the given SGR parameters until color.Unset() is called.
+func Set(p ...Attribute) *Color {
+ c := New(p...)
+ c.Set()
+ return c
+}
+
+// Unset resets all escape attributes and clears the output. Usually should
+// be called after Set().
+func Unset() {
+ if NoColor {
+ return
+ }
+
+ fmt.Fprintf(Output, "%s[%dm", escape, Reset)
+}
+
+// Set sets the SGR sequence.
+func (c *Color) Set() *Color {
+ if c.isNoColorSet() {
+ return c
+ }
+
+ fmt.Fprint(Output, c.format())
+ return c
+}
+
+func (c *Color) unset() {
+ if c.isNoColorSet() {
+ return
+ }
+
+ Unset()
+}
+
+// SetWriter is used to set the SGR sequence with the given io.Writer. This is
+// a low-level function, and users should use the higher-level functions, such
+// as color.Fprint, color.Print, etc.
+func (c *Color) SetWriter(w io.Writer) *Color {
+ if c.isNoColorSet() {
+ return c
+ }
+
+ fmt.Fprint(w, c.format())
+ return c
+}
+
+// UnsetWriter resets all escape attributes and clears the output with the give
+// io.Writer. Usually should be called after SetWriter().
+func (c *Color) UnsetWriter(w io.Writer) {
+ if c.isNoColorSet() {
+ return
+ }
+
+ if NoColor {
+ return
+ }
+
+ fmt.Fprintf(w, "%s[%dm", escape, Reset)
+}
+
+// Add is used to chain SGR parameters. Use as many as parameters to combine
+// and create custom color objects. Example: Add(color.FgRed, color.Underline).
+func (c *Color) Add(value ...Attribute) *Color {
+ c.params = append(c.params, value...)
+ return c
+}
+
+// Fprint formats using the default formats for its operands and writes to w.
+// Spaces are added between operands when neither is a string.
+// It returns the number of bytes written and any write error encountered.
+// On Windows, users should wrap w with colorable.NewColorable() if w is of
+// type *os.File.
+func (c *Color) Fprint(w io.Writer, a ...interface{}) (n int, err error) {
+ c.SetWriter(w)
+ defer c.UnsetWriter(w)
+
+ return fmt.Fprint(w, a...)
+}
+
+// Print formats using the default formats for its operands and writes to
+// standard output. Spaces are added between operands when neither is a
+// string. It returns the number of bytes written and any write error
+// encountered. This is the standard fmt.Print() method wrapped with the given
+// color.
+func (c *Color) Print(a ...interface{}) (n int, err error) {
+ c.Set()
+ defer c.unset()
+
+ return fmt.Fprint(Output, a...)
+}
+
+// Fprintf formats according to a format specifier and writes to w.
+// It returns the number of bytes written and any write error encountered.
+// On Windows, users should wrap w with colorable.NewColorable() if w is of
+// type *os.File.
+func (c *Color) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
+ c.SetWriter(w)
+ defer c.UnsetWriter(w)
+
+ return fmt.Fprintf(w, format, a...)
+}
+
+// Printf formats according to a format specifier and writes to standard output.
+// It returns the number of bytes written and any write error encountered.
+// This is the standard fmt.Printf() method wrapped with the given color.
+func (c *Color) Printf(format string, a ...interface{}) (n int, err error) {
+ c.Set()
+ defer c.unset()
+
+ return fmt.Fprintf(Output, format, a...)
+}
+
+// Fprintln formats using the default formats for its operands and writes to w.
+// Spaces are always added between operands and a newline is appended.
+// On Windows, users should wrap w with colorable.NewColorable() if w is of
+// type *os.File.
+func (c *Color) Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
+ return fmt.Fprintln(w, c.wrap(fmt.Sprint(a...)))
+}
+
+// Println formats using the default formats for its operands and writes to
+// standard output. Spaces are always added between operands and a newline is
+// appended. It returns the number of bytes written and any write error
+// encountered. This is the standard fmt.Print() method wrapped with the given
+// color.
+func (c *Color) Println(a ...interface{}) (n int, err error) {
+ return fmt.Fprintln(Output, c.wrap(fmt.Sprint(a...)))
+}
+
+// Sprint is just like Print, but returns a string instead of printing it.
+func (c *Color) Sprint(a ...interface{}) string {
+ return c.wrap(fmt.Sprint(a...))
+}
+
+// Sprintln is just like Println, but returns a string instead of printing it.
+func (c *Color) Sprintln(a ...interface{}) string {
+ return fmt.Sprintln(c.Sprint(a...))
+}
+
+// Sprintf is just like Printf, but returns a string instead of printing it.
+func (c *Color) Sprintf(format string, a ...interface{}) string {
+ return c.wrap(fmt.Sprintf(format, a...))
+}
+
+// FprintFunc returns a new function that prints the passed arguments as
+// colorized with color.Fprint().
+func (c *Color) FprintFunc() func(w io.Writer, a ...interface{}) {
+ return func(w io.Writer, a ...interface{}) {
+ c.Fprint(w, a...)
+ }
+}
+
+// PrintFunc returns a new function that prints the passed arguments as
+// colorized with color.Print().
+func (c *Color) PrintFunc() func(a ...interface{}) {
+ return func(a ...interface{}) {
+ c.Print(a...)
+ }
+}
+
+// FprintfFunc returns a new function that prints the passed arguments as
+// colorized with color.Fprintf().
+func (c *Color) FprintfFunc() func(w io.Writer, format string, a ...interface{}) {
+ return func(w io.Writer, format string, a ...interface{}) {
+ c.Fprintf(w, format, a...)
+ }
+}
+
+// PrintfFunc returns a new function that prints the passed arguments as
+// colorized with color.Printf().
+func (c *Color) PrintfFunc() func(format string, a ...interface{}) {
+ return func(format string, a ...interface{}) {
+ c.Printf(format, a...)
+ }
+}
+
+// FprintlnFunc returns a new function that prints the passed arguments as
+// colorized with color.Fprintln().
+func (c *Color) FprintlnFunc() func(w io.Writer, a ...interface{}) {
+ return func(w io.Writer, a ...interface{}) {
+ c.Fprintln(w, a...)
+ }
+}
+
+// PrintlnFunc returns a new function that prints the passed arguments as
+// colorized with color.Println().
+func (c *Color) PrintlnFunc() func(a ...interface{}) {
+ return func(a ...interface{}) {
+ c.Println(a...)
+ }
+}
+
+// SprintFunc returns a new function that returns colorized strings for the
+// given arguments with fmt.Sprint(). Useful to put into or mix into other
+// string. Windows users should use this in conjunction with color.Output, example:
+//
+// put := New(FgYellow).SprintFunc()
+// fmt.Fprintf(color.Output, "This is a %s", put("warning"))
+func (c *Color) SprintFunc() func(a ...interface{}) string {
+ return func(a ...interface{}) string {
+ return c.wrap(fmt.Sprint(a...))
+ }
+}
+
+// SprintfFunc returns a new function that returns colorized strings for the
+// given arguments with fmt.Sprintf(). Useful to put into or mix into other
+// string. Windows users should use this in conjunction with color.Output.
+func (c *Color) SprintfFunc() func(format string, a ...interface{}) string {
+ return func(format string, a ...interface{}) string {
+ return c.wrap(fmt.Sprintf(format, a...))
+ }
+}
+
+// SprintlnFunc returns a new function that returns colorized strings for the
+// given arguments with fmt.Sprintln(). Useful to put into or mix into other
+// string. Windows users should use this in conjunction with color.Output.
+func (c *Color) SprintlnFunc() func(a ...interface{}) string {
+ return func(a ...interface{}) string {
+ return fmt.Sprintln(c.Sprint(a...))
+ }
+}
+
+// sequence returns a formatted SGR sequence to be plugged into a "\x1b[...m"
+// an example output might be: "1;36" -> bold cyan
+func (c *Color) sequence() string {
+ format := make([]string, len(c.params))
+ for i, v := range c.params {
+ format[i] = strconv.Itoa(int(v))
+ }
+
+ return strings.Join(format, ";")
+}
+
+// wrap wraps the s string with the colors attributes. The string is ready to
+// be printed.
+func (c *Color) wrap(s string) string {
+ if c.isNoColorSet() {
+ return s
+ }
+
+ return c.format() + s + c.unformat()
+}
+
+func (c *Color) format() string {
+ return fmt.Sprintf("%s[%sm", escape, c.sequence())
+}
+
+func (c *Color) unformat() string {
+ //return fmt.Sprintf("%s[%dm", escape, Reset)
+ //for each element in sequence let's use the speficic reset escape, ou the generic one if not found
+ format := make([]string, len(c.params))
+ for i, v := range c.params {
+ format[i] = strconv.Itoa(int(Reset))
+ ra, ok := mapResetAttributes[v]
+ if ok {
+ format[i] = strconv.Itoa(int(ra))
+ }
+ }
+
+ return fmt.Sprintf("%s[%sm", escape, strings.Join(format, ";"))
+}
+
+// DisableColor disables the color output. Useful to not change any existing
+// code and still being able to output. Can be used for flags like
+// "--no-color". To enable back use EnableColor() method.
+func (c *Color) DisableColor() {
+ c.noColor = boolPtr(true)
+}
+
+// EnableColor enables the color output. Use it in conjunction with
+// DisableColor(). Otherwise, this method has no side effects.
+func (c *Color) EnableColor() {
+ c.noColor = boolPtr(false)
+}
+
+func (c *Color) isNoColorSet() bool {
+ // check first if we have user set action
+ if c.noColor != nil {
+ return *c.noColor
+ }
+
+ // if not return the global option, which is disabled by default
+ return NoColor
+}
+
+// Equals returns a boolean value indicating whether two colors are equal.
+func (c *Color) Equals(c2 *Color) bool {
+ if c == nil && c2 == nil {
+ return true
+ }
+ if c == nil || c2 == nil {
+ return false
+ }
+ if len(c.params) != len(c2.params) {
+ return false
+ }
+
+ for _, attr := range c.params {
+ if !c2.attrExists(attr) {
+ return false
+ }
+ }
+
+ return true
+}
+
+func (c *Color) attrExists(a Attribute) bool {
+ for _, attr := range c.params {
+ if attr == a {
+ return true
+ }
+ }
+
+ return false
+}
+
+func boolPtr(v bool) *bool {
+ return &v
+}
+
+func getCachedColor(p Attribute) *Color {
+ colorsCacheMu.Lock()
+ defer colorsCacheMu.Unlock()
+
+ c, ok := colorsCache[p]
+ if !ok {
+ c = New(p)
+ colorsCache[p] = c
+ }
+
+ return c
+}
+
+func colorPrint(format string, p Attribute, a ...interface{}) {
+ c := getCachedColor(p)
+
+ if !strings.HasSuffix(format, "\n") {
+ format += "\n"
+ }
+
+ if len(a) == 0 {
+ c.Print(format)
+ } else {
+ c.Printf(format, a...)
+ }
+}
+
+func colorString(format string, p Attribute, a ...interface{}) string {
+ c := getCachedColor(p)
+
+ if len(a) == 0 {
+ return c.SprintFunc()(format)
+ }
+
+ return c.SprintfFunc()(format, a...)
+}
+
+// Black is a convenient helper function to print with black foreground. A
+// newline is appended to format by default.
+func Black(format string, a ...interface{}) { colorPrint(format, FgBlack, a...) }
+
+// Red is a convenient helper function to print with red foreground. A
+// newline is appended to format by default.
+func Red(format string, a ...interface{}) { colorPrint(format, FgRed, a...) }
+
+// Green is a convenient helper function to print with green foreground. A
+// newline is appended to format by default.
+func Green(format string, a ...interface{}) { colorPrint(format, FgGreen, a...) }
+
+// Yellow is a convenient helper function to print with yellow foreground.
+// A newline is appended to format by default.
+func Yellow(format string, a ...interface{}) { colorPrint(format, FgYellow, a...) }
+
+// Blue is a convenient helper function to print with blue foreground. A
+// newline is appended to format by default.
+func Blue(format string, a ...interface{}) { colorPrint(format, FgBlue, a...) }
+
+// Magenta is a convenient helper function to print with magenta foreground.
+// A newline is appended to format by default.
+func Magenta(format string, a ...interface{}) { colorPrint(format, FgMagenta, a...) }
+
+// Cyan is a convenient helper function to print with cyan foreground. A
+// newline is appended to format by default.
+func Cyan(format string, a ...interface{}) { colorPrint(format, FgCyan, a...) }
+
+// White is a convenient helper function to print with white foreground. A
+// newline is appended to format by default.
+func White(format string, a ...interface{}) { colorPrint(format, FgWhite, a...) }
+
+// BlackString is a convenient helper function to return a string with black
+// foreground.
+func BlackString(format string, a ...interface{}) string { return colorString(format, FgBlack, a...) }
+
+// RedString is a convenient helper function to return a string with red
+// foreground.
+func RedString(format string, a ...interface{}) string { return colorString(format, FgRed, a...) }
+
+// GreenString is a convenient helper function to return a string with green
+// foreground.
+func GreenString(format string, a ...interface{}) string { return colorString(format, FgGreen, a...) }
+
+// YellowString is a convenient helper function to return a string with yellow
+// foreground.
+func YellowString(format string, a ...interface{}) string { return colorString(format, FgYellow, a...) }
+
+// BlueString is a convenient helper function to return a string with blue
+// foreground.
+func BlueString(format string, a ...interface{}) string { return colorString(format, FgBlue, a...) }
+
+// MagentaString is a convenient helper function to return a string with magenta
+// foreground.
+func MagentaString(format string, a ...interface{}) string {
+ return colorString(format, FgMagenta, a...)
+}
+
+// CyanString is a convenient helper function to return a string with cyan
+// foreground.
+func CyanString(format string, a ...interface{}) string { return colorString(format, FgCyan, a...) }
+
+// WhiteString is a convenient helper function to return a string with white
+// foreground.
+func WhiteString(format string, a ...interface{}) string { return colorString(format, FgWhite, a...) }
+
+// HiBlack is a convenient helper function to print with hi-intensity black foreground. A
+// newline is appended to format by default.
+func HiBlack(format string, a ...interface{}) { colorPrint(format, FgHiBlack, a...) }
+
+// HiRed is a convenient helper function to print with hi-intensity red foreground. A
+// newline is appended to format by default.
+func HiRed(format string, a ...interface{}) { colorPrint(format, FgHiRed, a...) }
+
+// HiGreen is a convenient helper function to print with hi-intensity green foreground. A
+// newline is appended to format by default.
+func HiGreen(format string, a ...interface{}) { colorPrint(format, FgHiGreen, a...) }
+
+// HiYellow is a convenient helper function to print with hi-intensity yellow foreground.
+// A newline is appended to format by default.
+func HiYellow(format string, a ...interface{}) { colorPrint(format, FgHiYellow, a...) }
+
+// HiBlue is a convenient helper function to print with hi-intensity blue foreground. A
+// newline is appended to format by default.
+func HiBlue(format string, a ...interface{}) { colorPrint(format, FgHiBlue, a...) }
+
+// HiMagenta is a convenient helper function to print with hi-intensity magenta foreground.
+// A newline is appended to format by default.
+func HiMagenta(format string, a ...interface{}) { colorPrint(format, FgHiMagenta, a...) }
+
+// HiCyan is a convenient helper function to print with hi-intensity cyan foreground. A
+// newline is appended to format by default.
+func HiCyan(format string, a ...interface{}) { colorPrint(format, FgHiCyan, a...) }
+
+// HiWhite is a convenient helper function to print with hi-intensity white foreground. A
+// newline is appended to format by default.
+func HiWhite(format string, a ...interface{}) { colorPrint(format, FgHiWhite, a...) }
+
+// HiBlackString is a convenient helper function to return a string with hi-intensity black
+// foreground.
+func HiBlackString(format string, a ...interface{}) string {
+ return colorString(format, FgHiBlack, a...)
+}
+
+// HiRedString is a convenient helper function to return a string with hi-intensity red
+// foreground.
+func HiRedString(format string, a ...interface{}) string { return colorString(format, FgHiRed, a...) }
+
+// HiGreenString is a convenient helper function to return a string with hi-intensity green
+// foreground.
+func HiGreenString(format string, a ...interface{}) string {
+ return colorString(format, FgHiGreen, a...)
+}
+
+// HiYellowString is a convenient helper function to return a string with hi-intensity yellow
+// foreground.
+func HiYellowString(format string, a ...interface{}) string {
+ return colorString(format, FgHiYellow, a...)
+}
+
+// HiBlueString is a convenient helper function to return a string with hi-intensity blue
+// foreground.
+func HiBlueString(format string, a ...interface{}) string { return colorString(format, FgHiBlue, a...) }
+
+// HiMagentaString is a convenient helper function to return a string with hi-intensity magenta
+// foreground.
+func HiMagentaString(format string, a ...interface{}) string {
+ return colorString(format, FgHiMagenta, a...)
+}
+
+// HiCyanString is a convenient helper function to return a string with hi-intensity cyan
+// foreground.
+func HiCyanString(format string, a ...interface{}) string { return colorString(format, FgHiCyan, a...) }
+
+// HiWhiteString is a convenient helper function to return a string with hi-intensity white
+// foreground.
+func HiWhiteString(format string, a ...interface{}) string {
+ return colorString(format, FgHiWhite, a...)
+}
diff --git a/vendor/github.com/fatih/color/color_windows.go b/vendor/github.com/fatih/color/color_windows.go
new file mode 100644
index 000000000..be01c558e
--- /dev/null
+++ b/vendor/github.com/fatih/color/color_windows.go
@@ -0,0 +1,19 @@
+package color
+
+import (
+ "os"
+
+ "golang.org/x/sys/windows"
+)
+
+func init() {
+ // Opt-in for ansi color support for current process.
+ // https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#output-sequences
+ var outMode uint32
+ out := windows.Handle(os.Stdout.Fd())
+ if err := windows.GetConsoleMode(out, &outMode); err != nil {
+ return
+ }
+ outMode |= windows.ENABLE_PROCESSED_OUTPUT | windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING
+ _ = windows.SetConsoleMode(out, outMode)
+}
diff --git a/vendor/github.com/fatih/color/doc.go b/vendor/github.com/fatih/color/doc.go
new file mode 100644
index 000000000..9491ad541
--- /dev/null
+++ b/vendor/github.com/fatih/color/doc.go
@@ -0,0 +1,134 @@
+/*
+Package color is an ANSI color package to output colorized or SGR defined
+output to the standard output. The API can be used in several way, pick one
+that suits you.
+
+Use simple and default helper functions with predefined foreground colors:
+
+ color.Cyan("Prints text in cyan.")
+
+ // a newline will be appended automatically
+ color.Blue("Prints %s in blue.", "text")
+
+ // More default foreground colors..
+ color.Red("We have red")
+ color.Yellow("Yellow color too!")
+ color.Magenta("And many others ..")
+
+ // Hi-intensity colors
+ color.HiGreen("Bright green color.")
+ color.HiBlack("Bright black means gray..")
+ color.HiWhite("Shiny white color!")
+
+However, there are times when custom color mixes are required. Below are some
+examples to create custom color objects and use the print functions of each
+separate color object.
+
+ // Create a new color object
+ c := color.New(color.FgCyan).Add(color.Underline)
+ c.Println("Prints cyan text with an underline.")
+
+ // Or just add them to New()
+ d := color.New(color.FgCyan, color.Bold)
+ d.Printf("This prints bold cyan %s\n", "too!.")
+
+
+ // Mix up foreground and background colors, create new mixes!
+ red := color.New(color.FgRed)
+
+ boldRed := red.Add(color.Bold)
+ boldRed.Println("This will print text in bold red.")
+
+ whiteBackground := red.Add(color.BgWhite)
+ whiteBackground.Println("Red text with White background.")
+
+ // Use your own io.Writer output
+ color.New(color.FgBlue).Fprintln(myWriter, "blue color!")
+
+ blue := color.New(color.FgBlue)
+ blue.Fprint(myWriter, "This will print text in blue.")
+
+You can create PrintXxx functions to simplify even more:
+
+ // Create a custom print function for convenient
+ red := color.New(color.FgRed).PrintfFunc()
+ red("warning")
+ red("error: %s", err)
+
+ // Mix up multiple attributes
+ notice := color.New(color.Bold, color.FgGreen).PrintlnFunc()
+ notice("don't forget this...")
+
+You can also FprintXxx functions to pass your own io.Writer:
+
+ blue := color.New(FgBlue).FprintfFunc()
+ blue(myWriter, "important notice: %s", stars)
+
+ // Mix up with multiple attributes
+ success := color.New(color.Bold, color.FgGreen).FprintlnFunc()
+ success(myWriter, don't forget this...")
+
+Or create SprintXxx functions to mix strings with other non-colorized strings:
+
+ yellow := New(FgYellow).SprintFunc()
+ red := New(FgRed).SprintFunc()
+
+ fmt.Printf("this is a %s and this is %s.\n", yellow("warning"), red("error"))
+
+ info := New(FgWhite, BgGreen).SprintFunc()
+ fmt.Printf("this %s rocks!\n", info("package"))
+
+Windows support is enabled by default. All Print functions work as intended.
+However, only for color.SprintXXX functions, user should use fmt.FprintXXX and
+set the output to color.Output:
+
+ fmt.Fprintf(color.Output, "Windows support: %s", color.GreenString("PASS"))
+
+ info := New(FgWhite, BgGreen).SprintFunc()
+ fmt.Fprintf(color.Output, "this %s rocks!\n", info("package"))
+
+Using with existing code is possible. Just use the Set() method to set the
+standard output to the given parameters. That way a rewrite of an existing
+code is not required.
+
+ // Use handy standard colors.
+ color.Set(color.FgYellow)
+
+ fmt.Println("Existing text will be now in Yellow")
+ fmt.Printf("This one %s\n", "too")
+
+ color.Unset() // don't forget to unset
+
+ // You can mix up parameters
+ color.Set(color.FgMagenta, color.Bold)
+ defer color.Unset() // use it in your function
+
+ fmt.Println("All text will be now bold magenta.")
+
+There might be a case where you want to disable color output (for example to
+pipe the standard output of your app to somewhere else). `Color` has support to
+disable colors both globally and for single color definition. For example
+suppose you have a CLI app and a `--no-color` bool flag. You can easily disable
+the color output with:
+
+ var flagNoColor = flag.Bool("no-color", false, "Disable color output")
+
+ if *flagNoColor {
+ color.NoColor = true // disables colorized output
+ }
+
+You can also disable the color by setting the NO_COLOR environment variable to any value.
+
+It also has support for single color definitions (local). You can
+disable/enable color output on the fly:
+
+ c := color.New(color.FgCyan)
+ c.Println("Prints cyan text")
+
+ c.DisableColor()
+ c.Println("This is printed without any color")
+
+ c.EnableColor()
+ c.Println("This prints again cyan...")
+*/
+package color
diff --git a/vendor/github.com/godbus/dbus/v5/CONTRIBUTING.md b/vendor/github.com/godbus/dbus/v5/CONTRIBUTING.md
new file mode 100644
index 000000000..c88f9b2bd
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/CONTRIBUTING.md
@@ -0,0 +1,50 @@
+# How to Contribute
+
+## Getting Started
+
+- Fork the repository on GitHub
+- Read the [README](README.markdown) for build and test instructions
+- Play with the project, submit bugs, submit patches!
+
+## Contribution Flow
+
+This is a rough outline of what a contributor's workflow looks like:
+
+- Create a topic branch from where you want to base your work (usually master).
+- Make commits of logical units.
+- Make sure your commit messages are in the proper format (see below).
+- Push your changes to a topic branch in your fork of the repository.
+- Make sure the tests pass, and add any new tests as appropriate.
+- Submit a pull request to the original repository.
+
+Thanks for your contributions!
+
+### Format of the Commit Message
+
+We follow a rough convention for commit messages that is designed to answer two
+questions: what changed and why. The subject line should feature the what and
+the body of the commit should describe the why.
+
+```
+scripts: add the test-cluster command
+
+this uses tmux to setup a test cluster that you can easily kill and
+start for debugging.
+
+Fixes #38
+```
+
+The format can be described more formally as follows:
+
+```
+:
+
+
+
+
+```
+
+The first line is the subject and should be no longer than 70 characters, the
+second line is always blank, and other lines should be wrapped at 80 characters.
+This allows the message to be easier to read on GitHub as well as in various
+git tools.
diff --git a/vendor/github.com/godbus/dbus/v5/LICENSE b/vendor/github.com/godbus/dbus/v5/LICENSE
new file mode 100644
index 000000000..670d88fca
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/LICENSE
@@ -0,0 +1,25 @@
+Copyright (c) 2013, Georg Reinke (), Google
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+2. 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.
+
+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
+HOLDER 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.
diff --git a/vendor/github.com/godbus/dbus/v5/MAINTAINERS b/vendor/github.com/godbus/dbus/v5/MAINTAINERS
new file mode 100644
index 000000000..27618c9cd
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/MAINTAINERS
@@ -0,0 +1,3 @@
+Brandon Philips (@philips)
+Brian Waldon (@bcwaldon)
+John Southworth (@jsouthworth)
diff --git a/vendor/github.com/godbus/dbus/v5/README.md b/vendor/github.com/godbus/dbus/v5/README.md
new file mode 100644
index 000000000..5c2412583
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/README.md
@@ -0,0 +1,46 @@
+![Build Status](https://github.com/godbus/dbus/workflows/Go/badge.svg)
+
+dbus
+----
+
+dbus is a simple library that implements native Go client bindings for the
+D-Bus message bus system.
+
+### Features
+
+* Complete native implementation of the D-Bus message protocol
+* Go-like API (channels for signals / asynchronous method calls, Goroutine-safe connections)
+* Subpackages that help with the introspection / property interfaces
+
+### Installation
+
+This packages requires Go 1.12 or later. It can be installed by running the command below:
+
+```
+go get github.com/godbus/dbus/v5
+```
+
+### Usage
+
+The complete package documentation and some simple examples are available at
+[godoc.org](http://godoc.org/github.com/godbus/dbus). Also, the
+[_examples](https://github.com/godbus/dbus/tree/master/_examples) directory
+gives a short overview over the basic usage.
+
+#### Projects using godbus
+- [fyne](https://github.com/fyne-io/fyne) a cross platform GUI in Go inspired by Material Design.
+- [fynedesk](https://github.com/fyne-io/fynedesk) a full desktop environment for Linux/Unix using Fyne.
+- [go-bluetooth](https://github.com/muka/go-bluetooth) provides a bluetooth client over bluez dbus API.
+- [iwd](https://github.com/shibumi/iwd) go bindings for the internet wireless daemon "iwd".
+- [notify](https://github.com/esiqveland/notify) provides desktop notifications over dbus into a library.
+- [playerbm](https://github.com/altdesktop/playerbm) a bookmark utility for media players.
+
+Please note that the API is considered unstable for now and may change without
+further notice.
+
+### License
+
+go.dbus is available under the Simplified BSD License; see LICENSE for the full
+text.
+
+Nearly all of the credit for this library goes to github.com/guelfey/go.dbus.
diff --git a/vendor/github.com/godbus/dbus/v5/auth.go b/vendor/github.com/godbus/dbus/v5/auth.go
new file mode 100644
index 000000000..0f3b252c0
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/auth.go
@@ -0,0 +1,257 @@
+package dbus
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "io"
+ "os"
+ "strconv"
+)
+
+// AuthStatus represents the Status of an authentication mechanism.
+type AuthStatus byte
+
+const (
+ // AuthOk signals that authentication is finished; the next command
+ // from the server should be an OK.
+ AuthOk AuthStatus = iota
+
+ // AuthContinue signals that additional data is needed; the next command
+ // from the server should be a DATA.
+ AuthContinue
+
+ // AuthError signals an error; the server sent invalid data or some
+ // other unexpected thing happened and the current authentication
+ // process should be aborted.
+ AuthError
+)
+
+type authState byte
+
+const (
+ waitingForData authState = iota
+ waitingForOk
+ waitingForReject
+)
+
+// Auth defines the behaviour of an authentication mechanism.
+type Auth interface {
+ // Return the name of the mechanism, the argument to the first AUTH command
+ // and the next status.
+ FirstData() (name, resp []byte, status AuthStatus)
+
+ // Process the given DATA command, and return the argument to the DATA
+ // command and the next status. If len(resp) == 0, no DATA command is sent.
+ HandleData(data []byte) (resp []byte, status AuthStatus)
+}
+
+// Auth authenticates the connection, trying the given list of authentication
+// mechanisms (in that order). If nil is passed, the EXTERNAL and
+// DBUS_COOKIE_SHA1 mechanisms are tried for the current user. For private
+// connections, this method must be called before sending any messages to the
+// bus. Auth must not be called on shared connections.
+func (conn *Conn) Auth(methods []Auth) error {
+ if methods == nil {
+ uid := strconv.Itoa(os.Geteuid())
+ methods = []Auth{AuthExternal(uid), AuthCookieSha1(uid, getHomeDir())}
+ }
+ in := bufio.NewReader(conn.transport)
+ err := conn.transport.SendNullByte()
+ if err != nil {
+ return err
+ }
+ err = authWriteLine(conn.transport, []byte("AUTH"))
+ if err != nil {
+ return err
+ }
+ s, err := authReadLine(in)
+ if err != nil {
+ return err
+ }
+ if len(s) < 2 || !bytes.Equal(s[0], []byte("REJECTED")) {
+ return errors.New("dbus: authentication protocol error")
+ }
+ s = s[1:]
+ for _, v := range s {
+ for _, m := range methods {
+ if name, _, status := m.FirstData(); bytes.Equal(v, name) {
+ var ok bool
+ err = authWriteLine(conn.transport, []byte("AUTH"), v)
+ if err != nil {
+ return err
+ }
+ switch status {
+ case AuthOk:
+ err, ok = conn.tryAuth(m, waitingForOk, in)
+ case AuthContinue:
+ err, ok = conn.tryAuth(m, waitingForData, in)
+ default:
+ panic("dbus: invalid authentication status")
+ }
+ if err != nil {
+ return err
+ }
+ if ok {
+ if conn.transport.SupportsUnixFDs() {
+ err = authWriteLine(conn, []byte("NEGOTIATE_UNIX_FD"))
+ if err != nil {
+ return err
+ }
+ line, err := authReadLine(in)
+ if err != nil {
+ return err
+ }
+ switch {
+ case bytes.Equal(line[0], []byte("AGREE_UNIX_FD")):
+ conn.EnableUnixFDs()
+ conn.unixFD = true
+ case bytes.Equal(line[0], []byte("ERROR")):
+ default:
+ return errors.New("dbus: authentication protocol error")
+ }
+ }
+ err = authWriteLine(conn.transport, []byte("BEGIN"))
+ if err != nil {
+ return err
+ }
+ go conn.inWorker()
+ return nil
+ }
+ }
+ }
+ }
+ return errors.New("dbus: authentication failed")
+}
+
+// tryAuth tries to authenticate with m as the mechanism, using state as the
+// initial authState and in for reading input. It returns (nil, true) on
+// success, (nil, false) on a REJECTED and (someErr, false) if some other
+// error occurred.
+func (conn *Conn) tryAuth(m Auth, state authState, in *bufio.Reader) (error, bool) {
+ for {
+ s, err := authReadLine(in)
+ if err != nil {
+ return err, false
+ }
+ switch {
+ case state == waitingForData && string(s[0]) == "DATA":
+ if len(s) != 2 {
+ err = authWriteLine(conn.transport, []byte("ERROR"))
+ if err != nil {
+ return err, false
+ }
+ continue
+ }
+ data, status := m.HandleData(s[1])
+ switch status {
+ case AuthOk, AuthContinue:
+ if len(data) != 0 {
+ err = authWriteLine(conn.transport, []byte("DATA"), data)
+ if err != nil {
+ return err, false
+ }
+ }
+ if status == AuthOk {
+ state = waitingForOk
+ }
+ case AuthError:
+ err = authWriteLine(conn.transport, []byte("ERROR"))
+ if err != nil {
+ return err, false
+ }
+ }
+ case state == waitingForData && string(s[0]) == "REJECTED":
+ return nil, false
+ case state == waitingForData && string(s[0]) == "ERROR":
+ err = authWriteLine(conn.transport, []byte("CANCEL"))
+ if err != nil {
+ return err, false
+ }
+ state = waitingForReject
+ case state == waitingForData && string(s[0]) == "OK":
+ if len(s) != 2 {
+ err = authWriteLine(conn.transport, []byte("CANCEL"))
+ if err != nil {
+ return err, false
+ }
+ state = waitingForReject
+ } else {
+ conn.uuid = string(s[1])
+ return nil, true
+ }
+ case state == waitingForData:
+ err = authWriteLine(conn.transport, []byte("ERROR"))
+ if err != nil {
+ return err, false
+ }
+ case state == waitingForOk && string(s[0]) == "OK":
+ if len(s) != 2 {
+ err = authWriteLine(conn.transport, []byte("CANCEL"))
+ if err != nil {
+ return err, false
+ }
+ state = waitingForReject
+ } else {
+ conn.uuid = string(s[1])
+ return nil, true
+ }
+ case state == waitingForOk && string(s[0]) == "DATA":
+ err = authWriteLine(conn.transport, []byte("DATA"))
+ if err != nil {
+ return err, false
+ }
+ case state == waitingForOk && string(s[0]) == "REJECTED":
+ return nil, false
+ case state == waitingForOk && string(s[0]) == "ERROR":
+ err = authWriteLine(conn.transport, []byte("CANCEL"))
+ if err != nil {
+ return err, false
+ }
+ state = waitingForReject
+ case state == waitingForOk:
+ err = authWriteLine(conn.transport, []byte("ERROR"))
+ if err != nil {
+ return err, false
+ }
+ case state == waitingForReject && string(s[0]) == "REJECTED":
+ return nil, false
+ case state == waitingForReject:
+ return errors.New("dbus: authentication protocol error"), false
+ default:
+ panic("dbus: invalid auth state")
+ }
+ }
+}
+
+// authReadLine reads a line and separates it into its fields.
+func authReadLine(in *bufio.Reader) ([][]byte, error) {
+ data, err := in.ReadBytes('\n')
+ if err != nil {
+ return nil, err
+ }
+ data = bytes.TrimSuffix(data, []byte("\r\n"))
+ return bytes.Split(data, []byte{' '}), nil
+}
+
+// authWriteLine writes the given line in the authentication protocol format
+// (elements of data separated by a " " and terminated by "\r\n").
+func authWriteLine(out io.Writer, data ...[]byte) error {
+ buf := make([]byte, 0)
+ for i, v := range data {
+ buf = append(buf, v...)
+ if i != len(data)-1 {
+ buf = append(buf, ' ')
+ }
+ }
+ buf = append(buf, '\r')
+ buf = append(buf, '\n')
+ n, err := out.Write(buf)
+ if err != nil {
+ return err
+ }
+ if n != len(buf) {
+ return io.ErrUnexpectedEOF
+ }
+ return nil
+}
diff --git a/vendor/github.com/godbus/dbus/v5/auth_anonymous.go b/vendor/github.com/godbus/dbus/v5/auth_anonymous.go
new file mode 100644
index 000000000..75f3ad34d
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/auth_anonymous.go
@@ -0,0 +1,16 @@
+package dbus
+
+// AuthAnonymous returns an Auth that uses the ANONYMOUS mechanism.
+func AuthAnonymous() Auth {
+ return &authAnonymous{}
+}
+
+type authAnonymous struct{}
+
+func (a *authAnonymous) FirstData() (name, resp []byte, status AuthStatus) {
+ return []byte("ANONYMOUS"), nil, AuthOk
+}
+
+func (a *authAnonymous) HandleData(data []byte) (resp []byte, status AuthStatus) {
+ return nil, AuthError
+}
diff --git a/vendor/github.com/godbus/dbus/v5/auth_external.go b/vendor/github.com/godbus/dbus/v5/auth_external.go
new file mode 100644
index 000000000..7e376d3ef
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/auth_external.go
@@ -0,0 +1,26 @@
+package dbus
+
+import (
+ "encoding/hex"
+)
+
+// AuthExternal returns an Auth that authenticates as the given user with the
+// EXTERNAL mechanism.
+func AuthExternal(user string) Auth {
+ return authExternal{user}
+}
+
+// AuthExternal implements the EXTERNAL authentication mechanism.
+type authExternal struct {
+ user string
+}
+
+func (a authExternal) FirstData() ([]byte, []byte, AuthStatus) {
+ b := make([]byte, 2*len(a.user))
+ hex.Encode(b, []byte(a.user))
+ return []byte("EXTERNAL"), b, AuthOk
+}
+
+func (a authExternal) HandleData(b []byte) ([]byte, AuthStatus) {
+ return nil, AuthError
+}
diff --git a/vendor/github.com/godbus/dbus/v5/auth_sha1.go b/vendor/github.com/godbus/dbus/v5/auth_sha1.go
new file mode 100644
index 000000000..80286700b
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/auth_sha1.go
@@ -0,0 +1,102 @@
+package dbus
+
+import (
+ "bufio"
+ "bytes"
+ "crypto/rand"
+ "crypto/sha1"
+ "encoding/hex"
+ "os"
+)
+
+// AuthCookieSha1 returns an Auth that authenticates as the given user with the
+// DBUS_COOKIE_SHA1 mechanism. The home parameter should specify the home
+// directory of the user.
+func AuthCookieSha1(user, home string) Auth {
+ return authCookieSha1{user, home}
+}
+
+type authCookieSha1 struct {
+ user, home string
+}
+
+func (a authCookieSha1) FirstData() ([]byte, []byte, AuthStatus) {
+ b := make([]byte, 2*len(a.user))
+ hex.Encode(b, []byte(a.user))
+ return []byte("DBUS_COOKIE_SHA1"), b, AuthContinue
+}
+
+func (a authCookieSha1) HandleData(data []byte) ([]byte, AuthStatus) {
+ challenge := make([]byte, len(data)/2)
+ _, err := hex.Decode(challenge, data)
+ if err != nil {
+ return nil, AuthError
+ }
+ b := bytes.Split(challenge, []byte{' '})
+ if len(b) != 3 {
+ return nil, AuthError
+ }
+ context := b[0]
+ id := b[1]
+ svchallenge := b[2]
+ cookie := a.getCookie(context, id)
+ if cookie == nil {
+ return nil, AuthError
+ }
+ clchallenge := a.generateChallenge()
+ if clchallenge == nil {
+ return nil, AuthError
+ }
+ hash := sha1.New()
+ hash.Write(bytes.Join([][]byte{svchallenge, clchallenge, cookie}, []byte{':'}))
+ hexhash := make([]byte, 2*hash.Size())
+ hex.Encode(hexhash, hash.Sum(nil))
+ data = append(clchallenge, ' ')
+ data = append(data, hexhash...)
+ resp := make([]byte, 2*len(data))
+ hex.Encode(resp, data)
+ return resp, AuthOk
+}
+
+// getCookie searches for the cookie identified by id in context and returns
+// the cookie content or nil. (Since HandleData can't return a specific error,
+// but only whether an error occurred, this function also doesn't bother to
+// return an error.)
+func (a authCookieSha1) getCookie(context, id []byte) []byte {
+ file, err := os.Open(a.home + "/.dbus-keyrings/" + string(context))
+ if err != nil {
+ return nil
+ }
+ defer file.Close()
+ rd := bufio.NewReader(file)
+ for {
+ line, err := rd.ReadBytes('\n')
+ if err != nil {
+ return nil
+ }
+ line = line[:len(line)-1]
+ b := bytes.Split(line, []byte{' '})
+ if len(b) != 3 {
+ return nil
+ }
+ if bytes.Equal(b[0], id) {
+ return b[2]
+ }
+ }
+}
+
+// generateChallenge returns a random, hex-encoded challenge, or nil on error
+// (see above).
+func (a authCookieSha1) generateChallenge() []byte {
+ b := make([]byte, 16)
+ n, err := rand.Read(b)
+ if err != nil {
+ return nil
+ }
+ if n != 16 {
+ return nil
+ }
+ enc := make([]byte, 32)
+ hex.Encode(enc, b)
+ return enc
+}
diff --git a/vendor/github.com/godbus/dbus/v5/call.go b/vendor/github.com/godbus/dbus/v5/call.go
new file mode 100644
index 000000000..b06b06358
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/call.go
@@ -0,0 +1,69 @@
+package dbus
+
+import (
+ "context"
+ "errors"
+)
+
+var errSignature = errors.New("dbus: mismatched signature")
+
+// Call represents a pending or completed method call.
+type Call struct {
+ Destination string
+ Path ObjectPath
+ Method string
+ Args []interface{}
+
+ // Strobes when the call is complete.
+ Done chan *Call
+
+ // After completion, the error status. If this is non-nil, it may be an
+ // error message from the peer (with Error as its type) or some other error.
+ Err error
+
+ // Holds the response once the call is done.
+ Body []interface{}
+
+ // ResponseSequence stores the sequence number of the DBus message containing
+ // the call response (or error). This can be compared to the sequence number
+ // of other call responses and signals on this connection to determine their
+ // relative ordering on the underlying DBus connection.
+ // For errors, ResponseSequence is populated only if the error came from a
+ // DBusMessage that was received or if there was an error receiving. In case of
+ // failure to make the call, ResponseSequence will be NoSequence.
+ ResponseSequence Sequence
+
+ // tracks context and canceler
+ ctx context.Context
+ ctxCanceler context.CancelFunc
+}
+
+func (c *Call) Context() context.Context {
+ if c.ctx == nil {
+ return context.Background()
+ }
+
+ return c.ctx
+}
+
+func (c *Call) ContextCancel() {
+ if c.ctxCanceler != nil {
+ c.ctxCanceler()
+ }
+}
+
+// Store stores the body of the reply into the provided pointers. It returns
+// an error if the signatures of the body and retvalues don't match, or if
+// the error status is not nil.
+func (c *Call) Store(retvalues ...interface{}) error {
+ if c.Err != nil {
+ return c.Err
+ }
+
+ return Store(c.Body, retvalues...)
+}
+
+func (c *Call) done() {
+ c.Done <- c
+ c.ContextCancel()
+}
diff --git a/vendor/github.com/godbus/dbus/v5/conn.go b/vendor/github.com/godbus/dbus/v5/conn.go
new file mode 100644
index 000000000..69978ea26
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/conn.go
@@ -0,0 +1,996 @@
+package dbus
+
+import (
+ "context"
+ "errors"
+ "io"
+ "os"
+ "strings"
+ "sync"
+)
+
+var (
+ systemBus *Conn
+ systemBusLck sync.Mutex
+ sessionBus *Conn
+ sessionBusLck sync.Mutex
+)
+
+// ErrClosed is the error returned by calls on a closed connection.
+var ErrClosed = errors.New("dbus: connection closed by user")
+
+// Conn represents a connection to a message bus (usually, the system or
+// session bus).
+//
+// Connections are either shared or private. Shared connections
+// are shared between calls to the functions that return them. As a result,
+// the methods Close, Auth and Hello must not be called on them.
+//
+// Multiple goroutines may invoke methods on a connection simultaneously.
+type Conn struct {
+ transport
+
+ ctx context.Context
+ cancelCtx context.CancelFunc
+
+ closeOnce sync.Once
+ closeErr error
+
+ busObj BusObject
+ unixFD bool
+ uuid string
+
+ handler Handler
+ signalHandler SignalHandler
+ serialGen SerialGenerator
+ inInt Interceptor
+ outInt Interceptor
+ auth []Auth
+
+ names *nameTracker
+ calls *callTracker
+ outHandler *outputHandler
+
+ eavesdropped chan<- *Message
+ eavesdroppedLck sync.Mutex
+}
+
+// SessionBus returns a shared connection to the session bus, connecting to it
+// if not already done.
+func SessionBus() (conn *Conn, err error) {
+ sessionBusLck.Lock()
+ defer sessionBusLck.Unlock()
+ if sessionBus != nil &&
+ sessionBus.Connected() {
+ return sessionBus, nil
+ }
+ defer func() {
+ if conn != nil {
+ sessionBus = conn
+ }
+ }()
+ conn, err = ConnectSessionBus()
+ return
+}
+
+func getSessionBusAddress(autolaunch bool) (string, error) {
+ if address := os.Getenv("DBUS_SESSION_BUS_ADDRESS"); address != "" && address != "autolaunch:" {
+ return address, nil
+
+ } else if address := tryDiscoverDbusSessionBusAddress(); address != "" {
+ os.Setenv("DBUS_SESSION_BUS_ADDRESS", address)
+ return address, nil
+ }
+ if !autolaunch {
+ return "", errors.New("dbus: couldn't determine address of session bus")
+ }
+ return getSessionBusPlatformAddress()
+}
+
+// SessionBusPrivate returns a new private connection to the session bus.
+func SessionBusPrivate(opts ...ConnOption) (*Conn, error) {
+ address, err := getSessionBusAddress(true)
+ if err != nil {
+ return nil, err
+ }
+
+ return Dial(address, opts...)
+}
+
+// SessionBusPrivate returns a new private connection to the session bus. If
+// the session bus is not already open, do not attempt to launch it.
+func SessionBusPrivateNoAutoStartup(opts ...ConnOption) (*Conn, error) {
+ address, err := getSessionBusAddress(false)
+ if err != nil {
+ return nil, err
+ }
+
+ return Dial(address, opts...)
+}
+
+// SessionBusPrivate returns a new private connection to the session bus.
+//
+// Deprecated: use SessionBusPrivate with options instead.
+func SessionBusPrivateHandler(handler Handler, signalHandler SignalHandler) (*Conn, error) {
+ return SessionBusPrivate(WithHandler(handler), WithSignalHandler(signalHandler))
+}
+
+// SystemBus returns a shared connection to the system bus, connecting to it if
+// not already done.
+func SystemBus() (conn *Conn, err error) {
+ systemBusLck.Lock()
+ defer systemBusLck.Unlock()
+ if systemBus != nil &&
+ systemBus.Connected() {
+ return systemBus, nil
+ }
+ defer func() {
+ if conn != nil {
+ systemBus = conn
+ }
+ }()
+ conn, err = ConnectSystemBus()
+ return
+}
+
+// ConnectSessionBus connects to the session bus.
+func ConnectSessionBus(opts ...ConnOption) (*Conn, error) {
+ address, err := getSessionBusAddress(true)
+ if err != nil {
+ return nil, err
+ }
+ return Connect(address, opts...)
+}
+
+// ConnectSystemBus connects to the system bus.
+func ConnectSystemBus(opts ...ConnOption) (*Conn, error) {
+ return Connect(getSystemBusPlatformAddress(), opts...)
+}
+
+// Connect connects to the given address.
+//
+// Returned connection is ready to use and doesn't require calling
+// Auth and Hello methods to make it usable.
+func Connect(address string, opts ...ConnOption) (*Conn, error) {
+ conn, err := Dial(address, opts...)
+ if err != nil {
+ return nil, err
+ }
+ if err = conn.Auth(conn.auth); err != nil {
+ _ = conn.Close()
+ return nil, err
+ }
+ if err = conn.Hello(); err != nil {
+ _ = conn.Close()
+ return nil, err
+ }
+ return conn, nil
+}
+
+// SystemBusPrivate returns a new private connection to the system bus.
+// Note: this connection is not ready to use. One must perform Auth and Hello
+// on the connection before it is usable.
+func SystemBusPrivate(opts ...ConnOption) (*Conn, error) {
+ return Dial(getSystemBusPlatformAddress(), opts...)
+}
+
+// SystemBusPrivateHandler returns a new private connection to the system bus, using the provided handlers.
+//
+// Deprecated: use SystemBusPrivate with options instead.
+func SystemBusPrivateHandler(handler Handler, signalHandler SignalHandler) (*Conn, error) {
+ return SystemBusPrivate(WithHandler(handler), WithSignalHandler(signalHandler))
+}
+
+// Dial establishes a new private connection to the message bus specified by address.
+func Dial(address string, opts ...ConnOption) (*Conn, error) {
+ tr, err := getTransport(address)
+ if err != nil {
+ return nil, err
+ }
+ return newConn(tr, opts...)
+}
+
+// DialHandler establishes a new private connection to the message bus specified by address, using the supplied handlers.
+//
+// Deprecated: use Dial with options instead.
+func DialHandler(address string, handler Handler, signalHandler SignalHandler) (*Conn, error) {
+ return Dial(address, WithHandler(handler), WithSignalHandler(signalHandler))
+}
+
+// ConnOption is a connection option.
+type ConnOption func(conn *Conn) error
+
+// WithHandler overrides the default handler.
+func WithHandler(handler Handler) ConnOption {
+ return func(conn *Conn) error {
+ conn.handler = handler
+ return nil
+ }
+}
+
+// WithSignalHandler overrides the default signal handler.
+func WithSignalHandler(handler SignalHandler) ConnOption {
+ return func(conn *Conn) error {
+ conn.signalHandler = handler
+ return nil
+ }
+}
+
+// WithSerialGenerator overrides the default signals generator.
+func WithSerialGenerator(gen SerialGenerator) ConnOption {
+ return func(conn *Conn) error {
+ conn.serialGen = gen
+ return nil
+ }
+}
+
+// WithAuth sets authentication methods for the auth conversation.
+func WithAuth(methods ...Auth) ConnOption {
+ return func(conn *Conn) error {
+ conn.auth = methods
+ return nil
+ }
+}
+
+// Interceptor intercepts incoming and outgoing messages.
+type Interceptor func(msg *Message)
+
+// WithIncomingInterceptor sets the given interceptor for incoming messages.
+func WithIncomingInterceptor(interceptor Interceptor) ConnOption {
+ return func(conn *Conn) error {
+ conn.inInt = interceptor
+ return nil
+ }
+}
+
+// WithOutgoingInterceptor sets the given interceptor for outgoing messages.
+func WithOutgoingInterceptor(interceptor Interceptor) ConnOption {
+ return func(conn *Conn) error {
+ conn.outInt = interceptor
+ return nil
+ }
+}
+
+// WithContext overrides the default context for the connection.
+func WithContext(ctx context.Context) ConnOption {
+ return func(conn *Conn) error {
+ conn.ctx = ctx
+ return nil
+ }
+}
+
+// NewConn creates a new private *Conn from an already established connection.
+func NewConn(conn io.ReadWriteCloser, opts ...ConnOption) (*Conn, error) {
+ return newConn(genericTransport{conn}, opts...)
+}
+
+// NewConnHandler creates a new private *Conn from an already established connection, using the supplied handlers.
+//
+// Deprecated: use NewConn with options instead.
+func NewConnHandler(conn io.ReadWriteCloser, handler Handler, signalHandler SignalHandler) (*Conn, error) {
+ return NewConn(genericTransport{conn}, WithHandler(handler), WithSignalHandler(signalHandler))
+}
+
+// newConn creates a new *Conn from a transport.
+func newConn(tr transport, opts ...ConnOption) (*Conn, error) {
+ conn := new(Conn)
+ conn.transport = tr
+ for _, opt := range opts {
+ if err := opt(conn); err != nil {
+ return nil, err
+ }
+ }
+ if conn.ctx == nil {
+ conn.ctx = context.Background()
+ }
+ conn.ctx, conn.cancelCtx = context.WithCancel(conn.ctx)
+
+ conn.calls = newCallTracker()
+ if conn.handler == nil {
+ conn.handler = NewDefaultHandler()
+ }
+ if conn.signalHandler == nil {
+ conn.signalHandler = NewDefaultSignalHandler()
+ }
+ if conn.serialGen == nil {
+ conn.serialGen = newSerialGenerator()
+ }
+ conn.outHandler = &outputHandler{conn: conn}
+ conn.names = newNameTracker()
+ conn.busObj = conn.Object("org.freedesktop.DBus", "/org/freedesktop/DBus")
+
+ go func() {
+ <-conn.ctx.Done()
+ conn.Close()
+ }()
+ return conn, nil
+}
+
+// BusObject returns the object owned by the bus daemon which handles
+// administrative requests.
+func (conn *Conn) BusObject() BusObject {
+ return conn.busObj
+}
+
+// Close closes the connection. Any blocked operations will return with errors
+// and the channels passed to Eavesdrop and Signal are closed. This method must
+// not be called on shared connections.
+func (conn *Conn) Close() error {
+ conn.closeOnce.Do(func() {
+ conn.outHandler.close()
+ if term, ok := conn.signalHandler.(Terminator); ok {
+ term.Terminate()
+ }
+
+ if term, ok := conn.handler.(Terminator); ok {
+ term.Terminate()
+ }
+
+ conn.eavesdroppedLck.Lock()
+ if conn.eavesdropped != nil {
+ close(conn.eavesdropped)
+ }
+ conn.eavesdroppedLck.Unlock()
+
+ conn.cancelCtx()
+
+ conn.closeErr = conn.transport.Close()
+ })
+ return conn.closeErr
+}
+
+// Context returns the context associated with the connection. The
+// context will be cancelled when the connection is closed.
+func (conn *Conn) Context() context.Context {
+ return conn.ctx
+}
+
+// Connected returns whether conn is connected
+func (conn *Conn) Connected() bool {
+ return conn.ctx.Err() == nil
+}
+
+// Eavesdrop causes conn to send all incoming messages to the given channel
+// without further processing. Method replies, errors and signals will not be
+// sent to the appropriate channels and method calls will not be handled. If nil
+// is passed, the normal behaviour is restored.
+//
+// The caller has to make sure that ch is sufficiently buffered;
+// if a message arrives when a write to ch is not possible, the message is
+// discarded.
+func (conn *Conn) Eavesdrop(ch chan<- *Message) {
+ conn.eavesdroppedLck.Lock()
+ conn.eavesdropped = ch
+ conn.eavesdroppedLck.Unlock()
+}
+
+// getSerial returns an unused serial.
+func (conn *Conn) getSerial() uint32 {
+ return conn.serialGen.GetSerial()
+}
+
+// Hello sends the initial org.freedesktop.DBus.Hello call. This method must be
+// called after authentication, but before sending any other messages to the
+// bus. Hello must not be called for shared connections.
+func (conn *Conn) Hello() error {
+ var s string
+ err := conn.busObj.Call("org.freedesktop.DBus.Hello", 0).Store(&s)
+ if err != nil {
+ return err
+ }
+ conn.names.acquireUniqueConnectionName(s)
+ return nil
+}
+
+// inWorker runs in an own goroutine, reading incoming messages from the
+// transport and dispatching them appropriately.
+func (conn *Conn) inWorker() {
+ sequenceGen := newSequenceGenerator()
+ for {
+ msg, err := conn.ReadMessage()
+ if err != nil {
+ if _, ok := err.(InvalidMessageError); !ok {
+ // Some read error occurred (usually EOF); we can't really do
+ // anything but to shut down all stuff and returns errors to all
+ // pending replies.
+ conn.Close()
+ conn.calls.finalizeAllWithError(sequenceGen, err)
+ return
+ }
+ // invalid messages are ignored
+ continue
+ }
+ conn.eavesdroppedLck.Lock()
+ if conn.eavesdropped != nil {
+ select {
+ case conn.eavesdropped <- msg:
+ default:
+ }
+ conn.eavesdroppedLck.Unlock()
+ continue
+ }
+ conn.eavesdroppedLck.Unlock()
+ dest, _ := msg.Headers[FieldDestination].value.(string)
+ found := dest == "" ||
+ !conn.names.uniqueNameIsKnown() ||
+ conn.names.isKnownName(dest)
+ if !found {
+ // Eavesdropped a message, but no channel for it is registered.
+ // Ignore it.
+ continue
+ }
+
+ if conn.inInt != nil {
+ conn.inInt(msg)
+ }
+ sequence := sequenceGen.next()
+ switch msg.Type {
+ case TypeError:
+ conn.serialGen.RetireSerial(conn.calls.handleDBusError(sequence, msg))
+ case TypeMethodReply:
+ conn.serialGen.RetireSerial(conn.calls.handleReply(sequence, msg))
+ case TypeSignal:
+ conn.handleSignal(sequence, msg)
+ case TypeMethodCall:
+ go conn.handleCall(msg)
+ }
+
+ }
+}
+
+func (conn *Conn) handleSignal(sequence Sequence, msg *Message) {
+ iface := msg.Headers[FieldInterface].value.(string)
+ member := msg.Headers[FieldMember].value.(string)
+ // as per http://dbus.freedesktop.org/doc/dbus-specification.html ,
+ // sender is optional for signals.
+ sender, _ := msg.Headers[FieldSender].value.(string)
+ if iface == "org.freedesktop.DBus" && sender == "org.freedesktop.DBus" {
+ if member == "NameLost" {
+ // If we lost the name on the bus, remove it from our
+ // tracking list.
+ name, ok := msg.Body[0].(string)
+ if !ok {
+ panic("Unable to read the lost name")
+ }
+ conn.names.loseName(name)
+ } else if member == "NameAcquired" {
+ // If we acquired the name on the bus, add it to our
+ // tracking list.
+ name, ok := msg.Body[0].(string)
+ if !ok {
+ panic("Unable to read the acquired name")
+ }
+ conn.names.acquireName(name)
+ }
+ }
+ signal := &Signal{
+ Sender: sender,
+ Path: msg.Headers[FieldPath].value.(ObjectPath),
+ Name: iface + "." + member,
+ Body: msg.Body,
+ Sequence: sequence,
+ }
+ conn.signalHandler.DeliverSignal(iface, member, signal)
+}
+
+// Names returns the list of all names that are currently owned by this
+// connection. The slice is always at least one element long, the first element
+// being the unique name of the connection.
+func (conn *Conn) Names() []string {
+ return conn.names.listKnownNames()
+}
+
+// Object returns the object identified by the given destination name and path.
+func (conn *Conn) Object(dest string, path ObjectPath) BusObject {
+ return &Object{conn, dest, path}
+}
+
+func (conn *Conn) sendMessageAndIfClosed(msg *Message, ifClosed func()) {
+ if msg.serial == 0 {
+ msg.serial = conn.getSerial()
+ }
+ if conn.outInt != nil {
+ conn.outInt(msg)
+ }
+ err := conn.outHandler.sendAndIfClosed(msg, ifClosed)
+ if err != nil {
+ conn.handleSendError(msg, err)
+ } else if msg.Type != TypeMethodCall {
+ conn.serialGen.RetireSerial(msg.serial)
+ }
+}
+
+func (conn *Conn) handleSendError(msg *Message, err error) {
+ if msg.Type == TypeMethodCall {
+ conn.calls.handleSendError(msg, err)
+ } else if msg.Type == TypeMethodReply {
+ if _, ok := err.(FormatError); ok {
+ conn.sendError(err, msg.Headers[FieldDestination].value.(string), msg.Headers[FieldReplySerial].value.(uint32))
+ }
+ }
+ conn.serialGen.RetireSerial(msg.serial)
+}
+
+// Send sends the given message to the message bus. You usually don't need to
+// use this; use the higher-level equivalents (Call / Go, Emit and Export)
+// instead. If msg is a method call and NoReplyExpected is not set, a non-nil
+// call is returned and the same value is sent to ch (which must be buffered)
+// once the call is complete. Otherwise, ch is ignored and a Call structure is
+// returned of which only the Err member is valid.
+func (conn *Conn) Send(msg *Message, ch chan *Call) *Call {
+ return conn.send(context.Background(), msg, ch)
+}
+
+// SendWithContext acts like Send but takes a context
+func (conn *Conn) SendWithContext(ctx context.Context, msg *Message, ch chan *Call) *Call {
+ return conn.send(ctx, msg, ch)
+}
+
+func (conn *Conn) send(ctx context.Context, msg *Message, ch chan *Call) *Call {
+ if ctx == nil {
+ panic("nil context")
+ }
+ if ch == nil {
+ ch = make(chan *Call, 1)
+ } else if cap(ch) == 0 {
+ panic("dbus: unbuffered channel passed to (*Conn).Send")
+ }
+
+ var call *Call
+ ctx, canceler := context.WithCancel(ctx)
+ msg.serial = conn.getSerial()
+ if msg.Type == TypeMethodCall && msg.Flags&FlagNoReplyExpected == 0 {
+ call = new(Call)
+ call.Destination, _ = msg.Headers[FieldDestination].value.(string)
+ call.Path, _ = msg.Headers[FieldPath].value.(ObjectPath)
+ iface, _ := msg.Headers[FieldInterface].value.(string)
+ member, _ := msg.Headers[FieldMember].value.(string)
+ call.Method = iface + "." + member
+ call.Args = msg.Body
+ call.Done = ch
+ call.ctx = ctx
+ call.ctxCanceler = canceler
+ conn.calls.track(msg.serial, call)
+ if ctx.Err() != nil {
+ // short path: don't even send the message if context already cancelled
+ conn.calls.handleSendError(msg, ctx.Err())
+ return call
+ }
+ go func() {
+ <-ctx.Done()
+ conn.calls.handleSendError(msg, ctx.Err())
+ }()
+ conn.sendMessageAndIfClosed(msg, func() {
+ conn.calls.handleSendError(msg, ErrClosed)
+ canceler()
+ })
+ } else {
+ canceler()
+ call = &Call{Err: nil, Done: ch}
+ ch <- call
+ conn.sendMessageAndIfClosed(msg, func() {
+ call = &Call{Err: ErrClosed}
+ })
+ }
+ return call
+}
+
+// sendError creates an error message corresponding to the parameters and sends
+// it to conn.out.
+func (conn *Conn) sendError(err error, dest string, serial uint32) {
+ var e *Error
+ switch em := err.(type) {
+ case Error:
+ e = &em
+ case *Error:
+ e = em
+ case DBusError:
+ name, body := em.DBusError()
+ e = NewError(name, body)
+ default:
+ e = MakeFailedError(err)
+ }
+ msg := new(Message)
+ msg.Type = TypeError
+ msg.Headers = make(map[HeaderField]Variant)
+ if dest != "" {
+ msg.Headers[FieldDestination] = MakeVariant(dest)
+ }
+ msg.Headers[FieldErrorName] = MakeVariant(e.Name)
+ msg.Headers[FieldReplySerial] = MakeVariant(serial)
+ msg.Body = e.Body
+ if len(e.Body) > 0 {
+ msg.Headers[FieldSignature] = MakeVariant(SignatureOf(e.Body...))
+ }
+ conn.sendMessageAndIfClosed(msg, nil)
+}
+
+// sendReply creates a method reply message corresponding to the parameters and
+// sends it to conn.out.
+func (conn *Conn) sendReply(dest string, serial uint32, values ...interface{}) {
+ msg := new(Message)
+ msg.Type = TypeMethodReply
+ msg.Headers = make(map[HeaderField]Variant)
+ if dest != "" {
+ msg.Headers[FieldDestination] = MakeVariant(dest)
+ }
+ msg.Headers[FieldReplySerial] = MakeVariant(serial)
+ msg.Body = values
+ if len(values) > 0 {
+ msg.Headers[FieldSignature] = MakeVariant(SignatureOf(values...))
+ }
+ conn.sendMessageAndIfClosed(msg, nil)
+}
+
+// AddMatchSignal registers the given match rule to receive broadcast
+// signals based on their contents.
+func (conn *Conn) AddMatchSignal(options ...MatchOption) error {
+ return conn.AddMatchSignalContext(context.Background(), options...)
+}
+
+// AddMatchSignalContext acts like AddMatchSignal but takes a context.
+func (conn *Conn) AddMatchSignalContext(ctx context.Context, options ...MatchOption) error {
+ options = append([]MatchOption{withMatchType("signal")}, options...)
+ return conn.busObj.CallWithContext(
+ ctx,
+ "org.freedesktop.DBus.AddMatch", 0,
+ formatMatchOptions(options),
+ ).Store()
+}
+
+// RemoveMatchSignal removes the first rule that matches previously registered with AddMatchSignal.
+func (conn *Conn) RemoveMatchSignal(options ...MatchOption) error {
+ return conn.RemoveMatchSignalContext(context.Background(), options...)
+}
+
+// RemoveMatchSignalContext acts like RemoveMatchSignal but takes a context.
+func (conn *Conn) RemoveMatchSignalContext(ctx context.Context, options ...MatchOption) error {
+ options = append([]MatchOption{withMatchType("signal")}, options...)
+ return conn.busObj.CallWithContext(
+ ctx,
+ "org.freedesktop.DBus.RemoveMatch", 0,
+ formatMatchOptions(options),
+ ).Store()
+}
+
+// Signal registers the given channel to be passed all received signal messages.
+//
+// Multiple of these channels can be registered at the same time. The channel is
+// closed if the Conn is closed; it should not be closed by the caller before
+// RemoveSignal was called on it.
+//
+// These channels are "overwritten" by Eavesdrop; i.e., if there currently is a
+// channel for eavesdropped messages, this channel receives all signals, and
+// none of the channels passed to Signal will receive any signals.
+//
+// Panics if the signal handler is not a `SignalRegistrar`.
+func (conn *Conn) Signal(ch chan<- *Signal) {
+ handler, ok := conn.signalHandler.(SignalRegistrar)
+ if !ok {
+ panic("cannot use this method with a non SignalRegistrar handler")
+ }
+ handler.AddSignal(ch)
+}
+
+// RemoveSignal removes the given channel from the list of the registered channels.
+//
+// Panics if the signal handler is not a `SignalRegistrar`.
+func (conn *Conn) RemoveSignal(ch chan<- *Signal) {
+ handler, ok := conn.signalHandler.(SignalRegistrar)
+ if !ok {
+ panic("cannot use this method with a non SignalRegistrar handler")
+ }
+ handler.RemoveSignal(ch)
+}
+
+// SupportsUnixFDs returns whether the underlying transport supports passing of
+// unix file descriptors. If this is false, method calls containing unix file
+// descriptors will return an error and emitted signals containing them will
+// not be sent.
+func (conn *Conn) SupportsUnixFDs() bool {
+ return conn.unixFD
+}
+
+// Error represents a D-Bus message of type Error.
+type Error struct {
+ Name string
+ Body []interface{}
+}
+
+func NewError(name string, body []interface{}) *Error {
+ return &Error{name, body}
+}
+
+func (e Error) Error() string {
+ if len(e.Body) >= 1 {
+ s, ok := e.Body[0].(string)
+ if ok {
+ return s
+ }
+ }
+ return e.Name
+}
+
+// Signal represents a D-Bus message of type Signal. The name member is given in
+// "interface.member" notation, e.g. org.freedesktop.D-Bus.NameLost.
+type Signal struct {
+ Sender string
+ Path ObjectPath
+ Name string
+ Body []interface{}
+ Sequence Sequence
+}
+
+// transport is a D-Bus transport.
+type transport interface {
+ // Read and Write raw data (for example, for the authentication protocol).
+ io.ReadWriteCloser
+
+ // Send the initial null byte used for the EXTERNAL mechanism.
+ SendNullByte() error
+
+ // Returns whether this transport supports passing Unix FDs.
+ SupportsUnixFDs() bool
+
+ // Signal the transport that Unix FD passing is enabled for this connection.
+ EnableUnixFDs()
+
+ // Read / send a message, handling things like Unix FDs.
+ ReadMessage() (*Message, error)
+ SendMessage(*Message) error
+}
+
+var (
+ transports = make(map[string]func(string) (transport, error))
+)
+
+func getTransport(address string) (transport, error) {
+ var err error
+ var t transport
+
+ addresses := strings.Split(address, ";")
+ for _, v := range addresses {
+ i := strings.IndexRune(v, ':')
+ if i == -1 {
+ err = errors.New("dbus: invalid bus address (no transport)")
+ continue
+ }
+ f := transports[v[:i]]
+ if f == nil {
+ err = errors.New("dbus: invalid bus address (invalid or unsupported transport)")
+ continue
+ }
+ t, err = f(v[i+1:])
+ if err == nil {
+ return t, nil
+ }
+ }
+ return nil, err
+}
+
+// getKey gets a key from a the list of keys. Returns "" on error / not found...
+func getKey(s, key string) string {
+ for _, keyEqualsValue := range strings.Split(s, ",") {
+ keyValue := strings.SplitN(keyEqualsValue, "=", 2)
+ if len(keyValue) == 2 && keyValue[0] == key {
+ val, err := UnescapeBusAddressValue(keyValue[1])
+ if err != nil {
+ // No way to return an error.
+ return ""
+ }
+ return val
+ }
+ }
+ return ""
+}
+
+type outputHandler struct {
+ conn *Conn
+ sendLck sync.Mutex
+ closed struct {
+ isClosed bool
+ lck sync.RWMutex
+ }
+}
+
+func (h *outputHandler) sendAndIfClosed(msg *Message, ifClosed func()) error {
+ h.closed.lck.RLock()
+ defer h.closed.lck.RUnlock()
+ if h.closed.isClosed {
+ if ifClosed != nil {
+ ifClosed()
+ }
+ return nil
+ }
+ h.sendLck.Lock()
+ defer h.sendLck.Unlock()
+ return h.conn.SendMessage(msg)
+}
+
+func (h *outputHandler) close() {
+ h.closed.lck.Lock()
+ defer h.closed.lck.Unlock()
+ h.closed.isClosed = true
+}
+
+type serialGenerator struct {
+ lck sync.Mutex
+ nextSerial uint32
+ serialUsed map[uint32]bool
+}
+
+func newSerialGenerator() *serialGenerator {
+ return &serialGenerator{
+ serialUsed: map[uint32]bool{0: true},
+ nextSerial: 1,
+ }
+}
+
+func (gen *serialGenerator) GetSerial() uint32 {
+ gen.lck.Lock()
+ defer gen.lck.Unlock()
+ n := gen.nextSerial
+ for gen.serialUsed[n] {
+ n++
+ }
+ gen.serialUsed[n] = true
+ gen.nextSerial = n + 1
+ return n
+}
+
+func (gen *serialGenerator) RetireSerial(serial uint32) {
+ gen.lck.Lock()
+ defer gen.lck.Unlock()
+ delete(gen.serialUsed, serial)
+}
+
+type nameTracker struct {
+ lck sync.RWMutex
+ unique string
+ names map[string]struct{}
+}
+
+func newNameTracker() *nameTracker {
+ return &nameTracker{names: map[string]struct{}{}}
+}
+func (tracker *nameTracker) acquireUniqueConnectionName(name string) {
+ tracker.lck.Lock()
+ defer tracker.lck.Unlock()
+ tracker.unique = name
+}
+func (tracker *nameTracker) acquireName(name string) {
+ tracker.lck.Lock()
+ defer tracker.lck.Unlock()
+ tracker.names[name] = struct{}{}
+}
+func (tracker *nameTracker) loseName(name string) {
+ tracker.lck.Lock()
+ defer tracker.lck.Unlock()
+ delete(tracker.names, name)
+}
+
+func (tracker *nameTracker) uniqueNameIsKnown() bool {
+ tracker.lck.RLock()
+ defer tracker.lck.RUnlock()
+ return tracker.unique != ""
+}
+func (tracker *nameTracker) isKnownName(name string) bool {
+ tracker.lck.RLock()
+ defer tracker.lck.RUnlock()
+ _, ok := tracker.names[name]
+ return ok || name == tracker.unique
+}
+func (tracker *nameTracker) listKnownNames() []string {
+ tracker.lck.RLock()
+ defer tracker.lck.RUnlock()
+ out := make([]string, 0, len(tracker.names)+1)
+ out = append(out, tracker.unique)
+ for k := range tracker.names {
+ out = append(out, k)
+ }
+ return out
+}
+
+type callTracker struct {
+ calls map[uint32]*Call
+ lck sync.RWMutex
+}
+
+func newCallTracker() *callTracker {
+ return &callTracker{calls: map[uint32]*Call{}}
+}
+
+func (tracker *callTracker) track(sn uint32, call *Call) {
+ tracker.lck.Lock()
+ tracker.calls[sn] = call
+ tracker.lck.Unlock()
+}
+
+func (tracker *callTracker) handleReply(sequence Sequence, msg *Message) uint32 {
+ serial := msg.Headers[FieldReplySerial].value.(uint32)
+ tracker.lck.RLock()
+ _, ok := tracker.calls[serial]
+ tracker.lck.RUnlock()
+ if ok {
+ tracker.finalizeWithBody(serial, sequence, msg.Body)
+ }
+ return serial
+}
+
+func (tracker *callTracker) handleDBusError(sequence Sequence, msg *Message) uint32 {
+ serial := msg.Headers[FieldReplySerial].value.(uint32)
+ tracker.lck.RLock()
+ _, ok := tracker.calls[serial]
+ tracker.lck.RUnlock()
+ if ok {
+ name, _ := msg.Headers[FieldErrorName].value.(string)
+ tracker.finalizeWithError(serial, sequence, Error{name, msg.Body})
+ }
+ return serial
+}
+
+func (tracker *callTracker) handleSendError(msg *Message, err error) {
+ if err == nil {
+ return
+ }
+ tracker.lck.RLock()
+ _, ok := tracker.calls[msg.serial]
+ tracker.lck.RUnlock()
+ if ok {
+ tracker.finalizeWithError(msg.serial, NoSequence, err)
+ }
+}
+
+// finalize was the only func that did not strobe Done
+func (tracker *callTracker) finalize(sn uint32) {
+ tracker.lck.Lock()
+ defer tracker.lck.Unlock()
+ c, ok := tracker.calls[sn]
+ if ok {
+ delete(tracker.calls, sn)
+ c.ContextCancel()
+ }
+}
+
+func (tracker *callTracker) finalizeWithBody(sn uint32, sequence Sequence, body []interface{}) {
+ tracker.lck.Lock()
+ c, ok := tracker.calls[sn]
+ if ok {
+ delete(tracker.calls, sn)
+ }
+ tracker.lck.Unlock()
+ if ok {
+ c.Body = body
+ c.ResponseSequence = sequence
+ c.done()
+ }
+}
+
+func (tracker *callTracker) finalizeWithError(sn uint32, sequence Sequence, err error) {
+ tracker.lck.Lock()
+ c, ok := tracker.calls[sn]
+ if ok {
+ delete(tracker.calls, sn)
+ }
+ tracker.lck.Unlock()
+ if ok {
+ c.Err = err
+ c.ResponseSequence = sequence
+ c.done()
+ }
+}
+
+func (tracker *callTracker) finalizeAllWithError(sequenceGen *sequenceGenerator, err error) {
+ tracker.lck.Lock()
+ closedCalls := make([]*Call, 0, len(tracker.calls))
+ for sn := range tracker.calls {
+ closedCalls = append(closedCalls, tracker.calls[sn])
+ }
+ tracker.calls = map[uint32]*Call{}
+ tracker.lck.Unlock()
+ for _, call := range closedCalls {
+ call.Err = err
+ call.ResponseSequence = sequenceGen.next()
+ call.done()
+ }
+}
diff --git a/vendor/github.com/godbus/dbus/v5/conn_darwin.go b/vendor/github.com/godbus/dbus/v5/conn_darwin.go
new file mode 100644
index 000000000..6e2e40202
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/conn_darwin.go
@@ -0,0 +1,37 @@
+package dbus
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "os/exec"
+)
+
+const defaultSystemBusAddress = "unix:path=/opt/local/var/run/dbus/system_bus_socket"
+
+func getSessionBusPlatformAddress() (string, error) {
+ cmd := exec.Command("launchctl", "getenv", "DBUS_LAUNCHD_SESSION_BUS_SOCKET")
+ b, err := cmd.CombinedOutput()
+
+ if err != nil {
+ return "", err
+ }
+
+ if len(b) == 0 {
+ return "", errors.New("dbus: couldn't determine address of session bus")
+ }
+
+ return "unix:path=" + string(b[:len(b)-1]), nil
+}
+
+func getSystemBusPlatformAddress() string {
+ address := os.Getenv("DBUS_LAUNCHD_SESSION_BUS_SOCKET")
+ if address != "" {
+ return fmt.Sprintf("unix:path=%s", address)
+ }
+ return defaultSystemBusAddress
+}
+
+func tryDiscoverDbusSessionBusAddress() string {
+ return ""
+}
diff --git a/vendor/github.com/godbus/dbus/v5/conn_other.go b/vendor/github.com/godbus/dbus/v5/conn_other.go
new file mode 100644
index 000000000..90289ca85
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/conn_other.go
@@ -0,0 +1,90 @@
+// +build !darwin
+
+package dbus
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "os/user"
+ "path"
+ "strings"
+)
+
+var execCommand = exec.Command
+
+func getSessionBusPlatformAddress() (string, error) {
+ cmd := execCommand("dbus-launch")
+ b, err := cmd.CombinedOutput()
+
+ if err != nil {
+ return "", err
+ }
+
+ i := bytes.IndexByte(b, '=')
+ j := bytes.IndexByte(b, '\n')
+
+ if i == -1 || j == -1 || i > j {
+ return "", errors.New("dbus: couldn't determine address of session bus")
+ }
+
+ env, addr := string(b[0:i]), string(b[i+1:j])
+ os.Setenv(env, addr)
+
+ return addr, nil
+}
+
+// tryDiscoverDbusSessionBusAddress tries to discover an existing dbus session
+// and return the value of its DBUS_SESSION_BUS_ADDRESS.
+// It tries different techniques employed by different operating systems,
+// returning the first valid address it finds, or an empty string.
+//
+// * /run/user//bus if this exists, it *is* the bus socket. present on
+// Ubuntu 18.04
+// * /run/user//dbus-session: if this exists, it can be parsed for the bus
+// address. present on Ubuntu 16.04
+//
+// See https://dbus.freedesktop.org/doc/dbus-launch.1.html
+func tryDiscoverDbusSessionBusAddress() string {
+ if runtimeDirectory, err := getRuntimeDirectory(); err == nil {
+
+ if runUserBusFile := path.Join(runtimeDirectory, "bus"); fileExists(runUserBusFile) {
+ // if /run/user//bus exists, that file itself
+ // *is* the unix socket, so return its path
+ return fmt.Sprintf("unix:path=%s", EscapeBusAddressValue(runUserBusFile))
+ }
+ if runUserSessionDbusFile := path.Join(runtimeDirectory, "dbus-session"); fileExists(runUserSessionDbusFile) {
+ // if /run/user//dbus-session exists, it's a
+ // text file // containing the address of the socket, e.g.:
+ // DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-E1c73yNqrG
+
+ if f, err := ioutil.ReadFile(runUserSessionDbusFile); err == nil {
+ fileContent := string(f)
+
+ prefix := "DBUS_SESSION_BUS_ADDRESS="
+
+ if strings.HasPrefix(fileContent, prefix) {
+ address := strings.TrimRight(strings.TrimPrefix(fileContent, prefix), "\n\r")
+ return address
+ }
+ }
+ }
+ }
+ return ""
+}
+
+func getRuntimeDirectory() (string, error) {
+ if currentUser, err := user.Current(); err != nil {
+ return "", err
+ } else {
+ return fmt.Sprintf("/run/user/%s", currentUser.Uid), nil
+ }
+}
+
+func fileExists(filename string) bool {
+ _, err := os.Stat(filename)
+ return !os.IsNotExist(err)
+}
diff --git a/vendor/github.com/godbus/dbus/v5/conn_unix.go b/vendor/github.com/godbus/dbus/v5/conn_unix.go
new file mode 100644
index 000000000..58aee7d2a
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/conn_unix.go
@@ -0,0 +1,17 @@
+//+build !windows,!solaris,!darwin
+
+package dbus
+
+import (
+ "os"
+)
+
+const defaultSystemBusAddress = "unix:path=/var/run/dbus/system_bus_socket"
+
+func getSystemBusPlatformAddress() string {
+ address := os.Getenv("DBUS_SYSTEM_BUS_ADDRESS")
+ if address != "" {
+ return address
+ }
+ return defaultSystemBusAddress
+}
diff --git a/vendor/github.com/godbus/dbus/v5/conn_windows.go b/vendor/github.com/godbus/dbus/v5/conn_windows.go
new file mode 100644
index 000000000..4291e4519
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/conn_windows.go
@@ -0,0 +1,15 @@
+//+build windows
+
+package dbus
+
+import "os"
+
+const defaultSystemBusAddress = "tcp:host=127.0.0.1,port=12434"
+
+func getSystemBusPlatformAddress() string {
+ address := os.Getenv("DBUS_SYSTEM_BUS_ADDRESS")
+ if address != "" {
+ return address
+ }
+ return defaultSystemBusAddress
+}
diff --git a/vendor/github.com/godbus/dbus/v5/dbus.go b/vendor/github.com/godbus/dbus/v5/dbus.go
new file mode 100644
index 000000000..c188d1048
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/dbus.go
@@ -0,0 +1,430 @@
+package dbus
+
+import (
+ "errors"
+ "fmt"
+ "reflect"
+ "strings"
+)
+
+var (
+ byteType = reflect.TypeOf(byte(0))
+ boolType = reflect.TypeOf(false)
+ uint8Type = reflect.TypeOf(uint8(0))
+ int16Type = reflect.TypeOf(int16(0))
+ uint16Type = reflect.TypeOf(uint16(0))
+ intType = reflect.TypeOf(int(0))
+ uintType = reflect.TypeOf(uint(0))
+ int32Type = reflect.TypeOf(int32(0))
+ uint32Type = reflect.TypeOf(uint32(0))
+ int64Type = reflect.TypeOf(int64(0))
+ uint64Type = reflect.TypeOf(uint64(0))
+ float64Type = reflect.TypeOf(float64(0))
+ stringType = reflect.TypeOf("")
+ signatureType = reflect.TypeOf(Signature{""})
+ objectPathType = reflect.TypeOf(ObjectPath(""))
+ variantType = reflect.TypeOf(Variant{Signature{""}, nil})
+ interfacesType = reflect.TypeOf([]interface{}{})
+ interfaceType = reflect.TypeOf((*interface{})(nil)).Elem()
+ unixFDType = reflect.TypeOf(UnixFD(0))
+ unixFDIndexType = reflect.TypeOf(UnixFDIndex(0))
+ errType = reflect.TypeOf((*error)(nil)).Elem()
+)
+
+// An InvalidTypeError signals that a value which cannot be represented in the
+// D-Bus wire format was passed to a function.
+type InvalidTypeError struct {
+ Type reflect.Type
+}
+
+func (e InvalidTypeError) Error() string {
+ return "dbus: invalid type " + e.Type.String()
+}
+
+// Store copies the values contained in src to dest, which must be a slice of
+// pointers. It converts slices of interfaces from src to corresponding structs
+// in dest. An error is returned if the lengths of src and dest or the types of
+// their elements don't match.
+func Store(src []interface{}, dest ...interface{}) error {
+ if len(src) != len(dest) {
+ return errors.New("dbus.Store: length mismatch")
+ }
+
+ for i := range src {
+ if err := storeInterfaces(src[i], dest[i]); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func storeInterfaces(src, dest interface{}) error {
+ return store(reflect.ValueOf(dest), reflect.ValueOf(src))
+}
+
+func store(dest, src reflect.Value) error {
+ if dest.Kind() == reflect.Ptr {
+ if dest.IsNil() {
+ dest.Set(reflect.New(dest.Type().Elem()))
+ }
+ return store(dest.Elem(), src)
+ }
+ switch src.Kind() {
+ case reflect.Slice:
+ return storeSlice(dest, src)
+ case reflect.Map:
+ return storeMap(dest, src)
+ default:
+ return storeBase(dest, src)
+ }
+}
+
+func storeBase(dest, src reflect.Value) error {
+ return setDest(dest, src)
+}
+
+func setDest(dest, src reflect.Value) error {
+ if !isVariant(src.Type()) && isVariant(dest.Type()) {
+ //special conversion for dbus.Variant
+ dest.Set(reflect.ValueOf(MakeVariant(src.Interface())))
+ return nil
+ }
+ if isVariant(src.Type()) && !isVariant(dest.Type()) {
+ src = getVariantValue(src)
+ return store(dest, src)
+ }
+ if !src.Type().ConvertibleTo(dest.Type()) {
+ return fmt.Errorf(
+ "dbus.Store: type mismatch: cannot convert %s to %s",
+ src.Type(), dest.Type())
+ }
+ dest.Set(src.Convert(dest.Type()))
+ return nil
+}
+
+func kindsAreCompatible(dest, src reflect.Type) bool {
+ switch {
+ case isVariant(dest):
+ return true
+ case dest.Kind() == reflect.Interface:
+ return true
+ default:
+ return dest.Kind() == src.Kind()
+ }
+}
+
+func isConvertibleTo(dest, src reflect.Type) bool {
+ switch {
+ case isVariant(dest):
+ return true
+ case dest.Kind() == reflect.Interface:
+ return true
+ case dest.Kind() == reflect.Slice:
+ return src.Kind() == reflect.Slice &&
+ isConvertibleTo(dest.Elem(), src.Elem())
+ case dest.Kind() == reflect.Ptr:
+ dest = dest.Elem()
+ return isConvertibleTo(dest, src)
+ case dest.Kind() == reflect.Struct:
+ return src == interfacesType || dest.Kind() == src.Kind()
+ default:
+ return src.ConvertibleTo(dest)
+ }
+}
+
+func storeMap(dest, src reflect.Value) error {
+ switch {
+ case !kindsAreCompatible(dest.Type(), src.Type()):
+ return fmt.Errorf(
+ "dbus.Store: type mismatch: "+
+ "map: cannot store a value of %s into %s",
+ src.Type(), dest.Type())
+ case isVariant(dest.Type()):
+ return storeMapIntoVariant(dest, src)
+ case dest.Kind() == reflect.Interface:
+ return storeMapIntoInterface(dest, src)
+ case isConvertibleTo(dest.Type().Key(), src.Type().Key()) &&
+ isConvertibleTo(dest.Type().Elem(), src.Type().Elem()):
+ return storeMapIntoMap(dest, src)
+ default:
+ return fmt.Errorf(
+ "dbus.Store: type mismatch: "+
+ "map: cannot convert a value of %s into %s",
+ src.Type(), dest.Type())
+ }
+}
+
+func storeMapIntoVariant(dest, src reflect.Value) error {
+ dv := reflect.MakeMap(src.Type())
+ err := store(dv, src)
+ if err != nil {
+ return err
+ }
+ return storeBase(dest, dv)
+}
+
+func storeMapIntoInterface(dest, src reflect.Value) error {
+ var dv reflect.Value
+ if isVariant(src.Type().Elem()) {
+ //Convert variants to interface{} recursively when converting
+ //to interface{}
+ dv = reflect.MakeMap(
+ reflect.MapOf(src.Type().Key(), interfaceType))
+ } else {
+ dv = reflect.MakeMap(src.Type())
+ }
+ err := store(dv, src)
+ if err != nil {
+ return err
+ }
+ return storeBase(dest, dv)
+}
+
+func storeMapIntoMap(dest, src reflect.Value) error {
+ if dest.IsNil() {
+ dest.Set(reflect.MakeMap(dest.Type()))
+ }
+ keys := src.MapKeys()
+ for _, key := range keys {
+ dkey := key.Convert(dest.Type().Key())
+ dval := reflect.New(dest.Type().Elem()).Elem()
+ err := store(dval, getVariantValue(src.MapIndex(key)))
+ if err != nil {
+ return err
+ }
+ dest.SetMapIndex(dkey, dval)
+ }
+ return nil
+}
+
+func storeSlice(dest, src reflect.Value) error {
+ switch {
+ case src.Type() == interfacesType && dest.Kind() == reflect.Struct:
+ //The decoder always decodes structs as slices of interface{}
+ return storeStruct(dest, src)
+ case !kindsAreCompatible(dest.Type(), src.Type()):
+ return fmt.Errorf(
+ "dbus.Store: type mismatch: "+
+ "slice: cannot store a value of %s into %s",
+ src.Type(), dest.Type())
+ case isVariant(dest.Type()):
+ return storeSliceIntoVariant(dest, src)
+ case dest.Kind() == reflect.Interface:
+ return storeSliceIntoInterface(dest, src)
+ case isConvertibleTo(dest.Type().Elem(), src.Type().Elem()):
+ return storeSliceIntoSlice(dest, src)
+ default:
+ return fmt.Errorf(
+ "dbus.Store: type mismatch: "+
+ "slice: cannot convert a value of %s into %s",
+ src.Type(), dest.Type())
+ }
+}
+
+func storeStruct(dest, src reflect.Value) error {
+ if isVariant(dest.Type()) {
+ return storeBase(dest, src)
+ }
+ dval := make([]interface{}, 0, dest.NumField())
+ dtype := dest.Type()
+ for i := 0; i < dest.NumField(); i++ {
+ field := dest.Field(i)
+ ftype := dtype.Field(i)
+ if ftype.PkgPath != "" {
+ continue
+ }
+ if ftype.Tag.Get("dbus") == "-" {
+ continue
+ }
+ dval = append(dval, field.Addr().Interface())
+ }
+ if src.Len() != len(dval) {
+ return fmt.Errorf(
+ "dbus.Store: type mismatch: "+
+ "destination struct does not have "+
+ "enough fields need: %d have: %d",
+ src.Len(), len(dval))
+ }
+ return Store(src.Interface().([]interface{}), dval...)
+}
+
+func storeSliceIntoVariant(dest, src reflect.Value) error {
+ dv := reflect.MakeSlice(src.Type(), src.Len(), src.Cap())
+ err := store(dv, src)
+ if err != nil {
+ return err
+ }
+ return storeBase(dest, dv)
+}
+
+func storeSliceIntoInterface(dest, src reflect.Value) error {
+ var dv reflect.Value
+ if isVariant(src.Type().Elem()) {
+ //Convert variants to interface{} recursively when converting
+ //to interface{}
+ dv = reflect.MakeSlice(reflect.SliceOf(interfaceType),
+ src.Len(), src.Cap())
+ } else {
+ dv = reflect.MakeSlice(src.Type(), src.Len(), src.Cap())
+ }
+ err := store(dv, src)
+ if err != nil {
+ return err
+ }
+ return storeBase(dest, dv)
+}
+
+func storeSliceIntoSlice(dest, src reflect.Value) error {
+ if dest.IsNil() || dest.Len() < src.Len() {
+ dest.Set(reflect.MakeSlice(dest.Type(), src.Len(), src.Cap()))
+ } else if dest.Len() > src.Len() {
+ dest.Set(dest.Slice(0, src.Len()))
+ }
+ for i := 0; i < src.Len(); i++ {
+ err := store(dest.Index(i), getVariantValue(src.Index(i)))
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func getVariantValue(in reflect.Value) reflect.Value {
+ if isVariant(in.Type()) {
+ return reflect.ValueOf(in.Interface().(Variant).Value())
+ }
+ return in
+}
+
+func isVariant(t reflect.Type) bool {
+ return t == variantType
+}
+
+// An ObjectPath is an object path as defined by the D-Bus spec.
+type ObjectPath string
+
+// IsValid returns whether the object path is valid.
+func (o ObjectPath) IsValid() bool {
+ s := string(o)
+ if len(s) == 0 {
+ return false
+ }
+ if s[0] != '/' {
+ return false
+ }
+ if s[len(s)-1] == '/' && len(s) != 1 {
+ return false
+ }
+ // probably not used, but technically possible
+ if s == "/" {
+ return true
+ }
+ split := strings.Split(s[1:], "/")
+ for _, v := range split {
+ if len(v) == 0 {
+ return false
+ }
+ for _, c := range v {
+ if !isMemberChar(c) {
+ return false
+ }
+ }
+ }
+ return true
+}
+
+// A UnixFD is a Unix file descriptor sent over the wire. See the package-level
+// documentation for more information about Unix file descriptor passsing.
+type UnixFD int32
+
+// A UnixFDIndex is the representation of a Unix file descriptor in a message.
+type UnixFDIndex uint32
+
+// alignment returns the alignment of values of type t.
+func alignment(t reflect.Type) int {
+ switch t {
+ case variantType:
+ return 1
+ case objectPathType:
+ return 4
+ case signatureType:
+ return 1
+ case interfacesType:
+ return 4
+ }
+ switch t.Kind() {
+ case reflect.Uint8:
+ return 1
+ case reflect.Uint16, reflect.Int16:
+ return 2
+ case reflect.Uint, reflect.Int, reflect.Uint32, reflect.Int32, reflect.String, reflect.Array, reflect.Slice, reflect.Map:
+ return 4
+ case reflect.Uint64, reflect.Int64, reflect.Float64, reflect.Struct:
+ return 8
+ case reflect.Ptr:
+ return alignment(t.Elem())
+ }
+ return 1
+}
+
+// isKeyType returns whether t is a valid type for a D-Bus dict.
+func isKeyType(t reflect.Type) bool {
+ switch t.Kind() {
+ case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
+ reflect.Int16, reflect.Int32, reflect.Int64, reflect.Float64,
+ reflect.String, reflect.Uint, reflect.Int:
+
+ return true
+ }
+ return false
+}
+
+// isValidInterface returns whether s is a valid name for an interface.
+func isValidInterface(s string) bool {
+ if len(s) == 0 || len(s) > 255 || s[0] == '.' {
+ return false
+ }
+ elem := strings.Split(s, ".")
+ if len(elem) < 2 {
+ return false
+ }
+ for _, v := range elem {
+ if len(v) == 0 {
+ return false
+ }
+ if v[0] >= '0' && v[0] <= '9' {
+ return false
+ }
+ for _, c := range v {
+ if !isMemberChar(c) {
+ return false
+ }
+ }
+ }
+ return true
+}
+
+// isValidMember returns whether s is a valid name for a member.
+func isValidMember(s string) bool {
+ if len(s) == 0 || len(s) > 255 {
+ return false
+ }
+ i := strings.Index(s, ".")
+ if i != -1 {
+ return false
+ }
+ if s[0] >= '0' && s[0] <= '9' {
+ return false
+ }
+ for _, c := range s {
+ if !isMemberChar(c) {
+ return false
+ }
+ }
+ return true
+}
+
+func isMemberChar(c rune) bool {
+ return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') ||
+ (c >= 'a' && c <= 'z') || c == '_'
+}
diff --git a/vendor/github.com/godbus/dbus/v5/decoder.go b/vendor/github.com/godbus/dbus/v5/decoder.go
new file mode 100644
index 000000000..89bfed9d1
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/decoder.go
@@ -0,0 +1,292 @@
+package dbus
+
+import (
+ "encoding/binary"
+ "io"
+ "reflect"
+)
+
+type decoder struct {
+ in io.Reader
+ order binary.ByteOrder
+ pos int
+ fds []int
+}
+
+// newDecoder returns a new decoder that reads values from in. The input is
+// expected to be in the given byte order.
+func newDecoder(in io.Reader, order binary.ByteOrder, fds []int) *decoder {
+ dec := new(decoder)
+ dec.in = in
+ dec.order = order
+ dec.fds = fds
+ return dec
+}
+
+// align aligns the input to the given boundary and panics on error.
+func (dec *decoder) align(n int) {
+ if dec.pos%n != 0 {
+ newpos := (dec.pos + n - 1) & ^(n - 1)
+ empty := make([]byte, newpos-dec.pos)
+ if _, err := io.ReadFull(dec.in, empty); err != nil {
+ panic(err)
+ }
+ dec.pos = newpos
+ }
+}
+
+// Calls binary.Read(dec.in, dec.order, v) and panics on read errors.
+func (dec *decoder) binread(v interface{}) {
+ if err := binary.Read(dec.in, dec.order, v); err != nil {
+ panic(err)
+ }
+}
+
+func (dec *decoder) Decode(sig Signature) (vs []interface{}, err error) {
+ defer func() {
+ var ok bool
+ v := recover()
+ if err, ok = v.(error); ok {
+ if err == io.EOF || err == io.ErrUnexpectedEOF {
+ err = FormatError("unexpected EOF")
+ }
+ }
+ }()
+ vs = make([]interface{}, 0)
+ s := sig.str
+ for s != "" {
+ err, rem := validSingle(s, &depthCounter{})
+ if err != nil {
+ return nil, err
+ }
+ v := dec.decode(s[:len(s)-len(rem)], 0)
+ vs = append(vs, v)
+ s = rem
+ }
+ return vs, nil
+}
+
+func (dec *decoder) decode(s string, depth int) interface{} {
+ dec.align(alignment(typeFor(s)))
+ switch s[0] {
+ case 'y':
+ var b [1]byte
+ if _, err := dec.in.Read(b[:]); err != nil {
+ panic(err)
+ }
+ dec.pos++
+ return b[0]
+ case 'b':
+ i := dec.decode("u", depth).(uint32)
+ switch {
+ case i == 0:
+ return false
+ case i == 1:
+ return true
+ default:
+ panic(FormatError("invalid value for boolean"))
+ }
+ case 'n':
+ var i int16
+ dec.binread(&i)
+ dec.pos += 2
+ return i
+ case 'i':
+ var i int32
+ dec.binread(&i)
+ dec.pos += 4
+ return i
+ case 'x':
+ var i int64
+ dec.binread(&i)
+ dec.pos += 8
+ return i
+ case 'q':
+ var i uint16
+ dec.binread(&i)
+ dec.pos += 2
+ return i
+ case 'u':
+ var i uint32
+ dec.binread(&i)
+ dec.pos += 4
+ return i
+ case 't':
+ var i uint64
+ dec.binread(&i)
+ dec.pos += 8
+ return i
+ case 'd':
+ var f float64
+ dec.binread(&f)
+ dec.pos += 8
+ return f
+ case 's':
+ length := dec.decode("u", depth).(uint32)
+ b := make([]byte, int(length)+1)
+ if _, err := io.ReadFull(dec.in, b); err != nil {
+ panic(err)
+ }
+ dec.pos += int(length) + 1
+ return string(b[:len(b)-1])
+ case 'o':
+ return ObjectPath(dec.decode("s", depth).(string))
+ case 'g':
+ length := dec.decode("y", depth).(byte)
+ b := make([]byte, int(length)+1)
+ if _, err := io.ReadFull(dec.in, b); err != nil {
+ panic(err)
+ }
+ dec.pos += int(length) + 1
+ sig, err := ParseSignature(string(b[:len(b)-1]))
+ if err != nil {
+ panic(err)
+ }
+ return sig
+ case 'v':
+ if depth >= 64 {
+ panic(FormatError("input exceeds container depth limit"))
+ }
+ var variant Variant
+ sig := dec.decode("g", depth).(Signature)
+ if len(sig.str) == 0 {
+ panic(FormatError("variant signature is empty"))
+ }
+ err, rem := validSingle(sig.str, &depthCounter{})
+ if err != nil {
+ panic(err)
+ }
+ if rem != "" {
+ panic(FormatError("variant signature has multiple types"))
+ }
+ variant.sig = sig
+ variant.value = dec.decode(sig.str, depth+1)
+ return variant
+ case 'h':
+ idx := dec.decode("u", depth).(uint32)
+ if int(idx) < len(dec.fds) {
+ return UnixFD(dec.fds[idx])
+ }
+ return UnixFDIndex(idx)
+ case 'a':
+ if len(s) > 1 && s[1] == '{' {
+ ksig := s[2:3]
+ vsig := s[3 : len(s)-1]
+ v := reflect.MakeMap(reflect.MapOf(typeFor(ksig), typeFor(vsig)))
+ if depth >= 63 {
+ panic(FormatError("input exceeds container depth limit"))
+ }
+ length := dec.decode("u", depth).(uint32)
+ // Even for empty maps, the correct padding must be included
+ dec.align(8)
+ spos := dec.pos
+ for dec.pos < spos+int(length) {
+ dec.align(8)
+ if !isKeyType(v.Type().Key()) {
+ panic(InvalidTypeError{v.Type()})
+ }
+ kv := dec.decode(ksig, depth+2)
+ vv := dec.decode(vsig, depth+2)
+ v.SetMapIndex(reflect.ValueOf(kv), reflect.ValueOf(vv))
+ }
+ return v.Interface()
+ }
+ if depth >= 64 {
+ panic(FormatError("input exceeds container depth limit"))
+ }
+ sig := s[1:]
+ length := dec.decode("u", depth).(uint32)
+ // capacity can be determined only for fixed-size element types
+ var capacity int
+ if s := sigByteSize(sig); s != 0 {
+ capacity = int(length) / s
+ }
+ v := reflect.MakeSlice(reflect.SliceOf(typeFor(sig)), 0, capacity)
+ // Even for empty arrays, the correct padding must be included
+ align := alignment(typeFor(s[1:]))
+ if len(s) > 1 && s[1] == '(' {
+ //Special case for arrays of structs
+ //structs decode as a slice of interface{} values
+ //but the dbus alignment does not match this
+ align = 8
+ }
+ dec.align(align)
+ spos := dec.pos
+ for dec.pos < spos+int(length) {
+ ev := dec.decode(s[1:], depth+1)
+ v = reflect.Append(v, reflect.ValueOf(ev))
+ }
+ return v.Interface()
+ case '(':
+ if depth >= 64 {
+ panic(FormatError("input exceeds container depth limit"))
+ }
+ dec.align(8)
+ v := make([]interface{}, 0)
+ s = s[1 : len(s)-1]
+ for s != "" {
+ err, rem := validSingle(s, &depthCounter{})
+ if err != nil {
+ panic(err)
+ }
+ ev := dec.decode(s[:len(s)-len(rem)], depth+1)
+ v = append(v, ev)
+ s = rem
+ }
+ return v
+ default:
+ panic(SignatureError{Sig: s})
+ }
+}
+
+// sigByteSize tries to calculates size of the given signature in bytes.
+//
+// It returns zero when it can't, for example when it contains non-fixed size
+// types such as strings, maps and arrays that require reading of the transmitted
+// data, for that we would need to implement the unread method for Decoder first.
+func sigByteSize(sig string) int {
+ var total int
+ for offset := 0; offset < len(sig); {
+ switch sig[offset] {
+ case 'y':
+ total += 1
+ offset += 1
+ case 'n', 'q':
+ total += 2
+ offset += 1
+ case 'b', 'i', 'u', 'h':
+ total += 4
+ offset += 1
+ case 'x', 't', 'd':
+ total += 8
+ offset += 1
+ case '(':
+ i := 1
+ depth := 1
+ for i < len(sig[offset:]) && depth != 0 {
+ if sig[offset+i] == '(' {
+ depth++
+ } else if sig[offset+i] == ')' {
+ depth--
+ }
+ i++
+ }
+ s := sigByteSize(sig[offset+1 : offset+i-1])
+ if s == 0 {
+ return 0
+ }
+ total += s
+ offset += i
+ default:
+ return 0
+ }
+ }
+ return total
+}
+
+// A FormatError is an error in the wire format.
+type FormatError string
+
+func (e FormatError) Error() string {
+ return "dbus: wire format error: " + string(e)
+}
diff --git a/vendor/github.com/godbus/dbus/v5/default_handler.go b/vendor/github.com/godbus/dbus/v5/default_handler.go
new file mode 100644
index 000000000..13132c6b4
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/default_handler.go
@@ -0,0 +1,342 @@
+package dbus
+
+import (
+ "bytes"
+ "reflect"
+ "strings"
+ "sync"
+)
+
+func newIntrospectIntf(h *defaultHandler) *exportedIntf {
+ methods := make(map[string]Method)
+ methods["Introspect"] = exportedMethod{
+ reflect.ValueOf(func(msg Message) (string, *Error) {
+ path := msg.Headers[FieldPath].value.(ObjectPath)
+ return h.introspectPath(path), nil
+ }),
+ }
+ return newExportedIntf(methods, true)
+}
+
+//NewDefaultHandler returns an instance of the default
+//call handler. This is useful if you want to implement only
+//one of the two handlers but not both.
+//
+// Deprecated: this is the default value, don't use it, it will be unexported.
+func NewDefaultHandler() *defaultHandler {
+ h := &defaultHandler{
+ objects: make(map[ObjectPath]*exportedObj),
+ defaultIntf: make(map[string]*exportedIntf),
+ }
+ h.defaultIntf["org.freedesktop.DBus.Introspectable"] = newIntrospectIntf(h)
+ return h
+}
+
+type defaultHandler struct {
+ sync.RWMutex
+ objects map[ObjectPath]*exportedObj
+ defaultIntf map[string]*exportedIntf
+}
+
+func (h *defaultHandler) PathExists(path ObjectPath) bool {
+ _, ok := h.objects[path]
+ return ok
+}
+
+func (h *defaultHandler) introspectPath(path ObjectPath) string {
+ subpath := make(map[string]struct{})
+ var xml bytes.Buffer
+ xml.WriteString("")
+ for obj := range h.objects {
+ p := string(path)
+ if p != "/" {
+ p += "/"
+ }
+ if strings.HasPrefix(string(obj), p) {
+ node_name := strings.Split(string(obj[len(p):]), "/")[0]
+ subpath[node_name] = struct{}{}
+ }
+ }
+ for s := range subpath {
+ xml.WriteString("\n\t ")
+ }
+ xml.WriteString("\n ")
+ return xml.String()
+}
+
+func (h *defaultHandler) LookupObject(path ObjectPath) (ServerObject, bool) {
+ h.RLock()
+ defer h.RUnlock()
+ object, ok := h.objects[path]
+ if ok {
+ return object, ok
+ }
+
+ // If an object wasn't found for this exact path,
+ // look for a matching subtree registration
+ subtreeObject := newExportedObject()
+ path = path[:strings.LastIndex(string(path), "/")]
+ for len(path) > 0 {
+ object, ok = h.objects[path]
+ if ok {
+ for name, iface := range object.interfaces {
+ // Only include this handler if it registered for the subtree
+ if iface.isFallbackInterface() {
+ subtreeObject.interfaces[name] = iface
+ }
+ }
+ break
+ }
+
+ path = path[:strings.LastIndex(string(path), "/")]
+ }
+
+ for name, intf := range h.defaultIntf {
+ if _, exists := subtreeObject.interfaces[name]; exists {
+ continue
+ }
+ subtreeObject.interfaces[name] = intf
+ }
+
+ return subtreeObject, true
+}
+
+func (h *defaultHandler) AddObject(path ObjectPath, object *exportedObj) {
+ h.Lock()
+ h.objects[path] = object
+ h.Unlock()
+}
+
+func (h *defaultHandler) DeleteObject(path ObjectPath) {
+ h.Lock()
+ delete(h.objects, path)
+ h.Unlock()
+}
+
+type exportedMethod struct {
+ reflect.Value
+}
+
+func (m exportedMethod) Call(args ...interface{}) ([]interface{}, error) {
+ t := m.Type()
+
+ params := make([]reflect.Value, len(args))
+ for i := 0; i < len(args); i++ {
+ params[i] = reflect.ValueOf(args[i]).Elem()
+ }
+
+ ret := m.Value.Call(params)
+ var err error
+ nilErr := false // The reflection will find almost-nils, let's only pass back clean ones!
+ if t.NumOut() > 0 {
+ if e, ok := ret[t.NumOut()-1].Interface().(*Error); ok { // godbus *Error
+ nilErr = ret[t.NumOut()-1].IsNil()
+ ret = ret[:t.NumOut()-1]
+ err = e
+ } else if ret[t.NumOut()-1].Type().Implements(errType) { // Go error
+ i := ret[t.NumOut()-1].Interface()
+ if i == nil {
+ nilErr = ret[t.NumOut()-1].IsNil()
+ } else {
+ err = i.(error)
+ }
+ ret = ret[:t.NumOut()-1]
+ }
+ }
+ out := make([]interface{}, len(ret))
+ for i, val := range ret {
+ out[i] = val.Interface()
+ }
+ if nilErr || err == nil {
+ //concrete type to interface nil is a special case
+ return out, nil
+ }
+ return out, err
+}
+
+func (m exportedMethod) NumArguments() int {
+ return m.Value.Type().NumIn()
+}
+
+func (m exportedMethod) ArgumentValue(i int) interface{} {
+ return reflect.Zero(m.Type().In(i)).Interface()
+}
+
+func (m exportedMethod) NumReturns() int {
+ return m.Value.Type().NumOut()
+}
+
+func (m exportedMethod) ReturnValue(i int) interface{} {
+ return reflect.Zero(m.Type().Out(i)).Interface()
+}
+
+func newExportedObject() *exportedObj {
+ return &exportedObj{
+ interfaces: make(map[string]*exportedIntf),
+ }
+}
+
+type exportedObj struct {
+ mu sync.RWMutex
+ interfaces map[string]*exportedIntf
+}
+
+func (obj *exportedObj) LookupInterface(name string) (Interface, bool) {
+ if name == "" {
+ return obj, true
+ }
+ obj.mu.RLock()
+ defer obj.mu.RUnlock()
+ intf, exists := obj.interfaces[name]
+ return intf, exists
+}
+
+func (obj *exportedObj) AddInterface(name string, iface *exportedIntf) {
+ obj.mu.Lock()
+ defer obj.mu.Unlock()
+ obj.interfaces[name] = iface
+}
+
+func (obj *exportedObj) DeleteInterface(name string) {
+ obj.mu.Lock()
+ defer obj.mu.Unlock()
+ delete(obj.interfaces, name)
+}
+
+func (obj *exportedObj) LookupMethod(name string) (Method, bool) {
+ obj.mu.RLock()
+ defer obj.mu.RUnlock()
+ for _, intf := range obj.interfaces {
+ method, exists := intf.LookupMethod(name)
+ if exists {
+ return method, exists
+ }
+ }
+ return nil, false
+}
+
+func (obj *exportedObj) isFallbackInterface() bool {
+ return false
+}
+
+func newExportedIntf(methods map[string]Method, includeSubtree bool) *exportedIntf {
+ return &exportedIntf{
+ methods: methods,
+ includeSubtree: includeSubtree,
+ }
+}
+
+type exportedIntf struct {
+ methods map[string]Method
+
+ // Whether or not this export is for the entire subtree
+ includeSubtree bool
+}
+
+func (obj *exportedIntf) LookupMethod(name string) (Method, bool) {
+ out, exists := obj.methods[name]
+ return out, exists
+}
+
+func (obj *exportedIntf) isFallbackInterface() bool {
+ return obj.includeSubtree
+}
+
+//NewDefaultSignalHandler returns an instance of the default
+//signal handler. This is useful if you want to implement only
+//one of the two handlers but not both.
+//
+// Deprecated: this is the default value, don't use it, it will be unexported.
+func NewDefaultSignalHandler() *defaultSignalHandler {
+ return &defaultSignalHandler{}
+}
+
+type defaultSignalHandler struct {
+ mu sync.RWMutex
+ closed bool
+ signals []*signalChannelData
+}
+
+func (sh *defaultSignalHandler) DeliverSignal(intf, name string, signal *Signal) {
+ sh.mu.RLock()
+ defer sh.mu.RUnlock()
+ if sh.closed {
+ return
+ }
+ for _, scd := range sh.signals {
+ scd.deliver(signal)
+ }
+}
+
+func (sh *defaultSignalHandler) Terminate() {
+ sh.mu.Lock()
+ defer sh.mu.Unlock()
+ if sh.closed {
+ return
+ }
+
+ for _, scd := range sh.signals {
+ scd.close()
+ close(scd.ch)
+ }
+ sh.closed = true
+ sh.signals = nil
+}
+
+func (sh *defaultSignalHandler) AddSignal(ch chan<- *Signal) {
+ sh.mu.Lock()
+ defer sh.mu.Unlock()
+ if sh.closed {
+ return
+ }
+ sh.signals = append(sh.signals, &signalChannelData{
+ ch: ch,
+ done: make(chan struct{}),
+ })
+}
+
+func (sh *defaultSignalHandler) RemoveSignal(ch chan<- *Signal) {
+ sh.mu.Lock()
+ defer sh.mu.Unlock()
+ if sh.closed {
+ return
+ }
+ for i := len(sh.signals) - 1; i >= 0; i-- {
+ if ch == sh.signals[i].ch {
+ sh.signals[i].close()
+ copy(sh.signals[i:], sh.signals[i+1:])
+ sh.signals[len(sh.signals)-1] = nil
+ sh.signals = sh.signals[:len(sh.signals)-1]
+ }
+ }
+}
+
+type signalChannelData struct {
+ wg sync.WaitGroup
+ ch chan<- *Signal
+ done chan struct{}
+}
+
+func (scd *signalChannelData) deliver(signal *Signal) {
+ select {
+ case scd.ch <- signal:
+ case <-scd.done:
+ return
+ default:
+ scd.wg.Add(1)
+ go scd.deferredDeliver(signal)
+ }
+}
+
+func (scd *signalChannelData) deferredDeliver(signal *Signal) {
+ select {
+ case scd.ch <- signal:
+ case <-scd.done:
+ }
+ scd.wg.Done()
+}
+
+func (scd *signalChannelData) close() {
+ close(scd.done)
+ scd.wg.Wait() // wait until all spawned goroutines return
+}
diff --git a/vendor/github.com/godbus/dbus/v5/doc.go b/vendor/github.com/godbus/dbus/v5/doc.go
new file mode 100644
index 000000000..8f25a00d6
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/doc.go
@@ -0,0 +1,71 @@
+/*
+Package dbus implements bindings to the D-Bus message bus system.
+
+To use the message bus API, you first need to connect to a bus (usually the
+session or system bus). The acquired connection then can be used to call methods
+on remote objects and emit or receive signals. Using the Export method, you can
+arrange D-Bus methods calls to be directly translated to method calls on a Go
+value.
+
+Conversion Rules
+
+For outgoing messages, Go types are automatically converted to the
+corresponding D-Bus types. See the official specification at
+https://dbus.freedesktop.org/doc/dbus-specification.html#type-system for more
+information on the D-Bus type system. The following types are directly encoded
+as their respective D-Bus equivalents:
+
+ Go type | D-Bus type
+ ------------+-----------
+ byte | BYTE
+ bool | BOOLEAN
+ int16 | INT16
+ uint16 | UINT16
+ int | INT32
+ uint | UINT32
+ int32 | INT32
+ uint32 | UINT32
+ int64 | INT64
+ uint64 | UINT64
+ float64 | DOUBLE
+ string | STRING
+ ObjectPath | OBJECT_PATH
+ Signature | SIGNATURE
+ Variant | VARIANT
+ interface{} | VARIANT
+ UnixFDIndex | UNIX_FD
+
+Slices and arrays encode as ARRAYs of their element type.
+
+Maps encode as DICTs, provided that their key type can be used as a key for
+a DICT.
+
+Structs other than Variant and Signature encode as a STRUCT containing their
+exported fields in order. Fields whose tags contain `dbus:"-"` and unexported
+fields will be skipped.
+
+Pointers encode as the value they're pointed to.
+
+Types convertible to one of the base types above will be mapped as the
+base type.
+
+Trying to encode any other type or a slice, map or struct containing an
+unsupported type will result in an InvalidTypeError.
+
+For incoming messages, the inverse of these rules are used, with the exception
+of STRUCTs. Incoming STRUCTS are represented as a slice of empty interfaces
+containing the struct fields in the correct order. The Store function can be
+used to convert such values to Go structs.
+
+Unix FD passing
+
+Handling Unix file descriptors deserves special mention. To use them, you should
+first check that they are supported on a connection by calling SupportsUnixFDs.
+If it returns true, all method of Connection will translate messages containing
+UnixFD's to messages that are accompanied by the given file descriptors with the
+UnixFD values being substituted by the correct indices. Similarly, the indices
+of incoming messages are automatically resolved. It shouldn't be necessary to use
+UnixFDIndex.
+
+*/
+package dbus
diff --git a/vendor/github.com/godbus/dbus/v5/encoder.go b/vendor/github.com/godbus/dbus/v5/encoder.go
new file mode 100644
index 000000000..015b26cd5
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/encoder.go
@@ -0,0 +1,235 @@
+package dbus
+
+import (
+ "bytes"
+ "encoding/binary"
+ "io"
+ "reflect"
+ "strings"
+ "unicode/utf8"
+)
+
+// An encoder encodes values to the D-Bus wire format.
+type encoder struct {
+ out io.Writer
+ fds []int
+ order binary.ByteOrder
+ pos int
+}
+
+// NewEncoder returns a new encoder that writes to out in the given byte order.
+func newEncoder(out io.Writer, order binary.ByteOrder, fds []int) *encoder {
+ enc := newEncoderAtOffset(out, 0, order, fds)
+ return enc
+}
+
+// newEncoderAtOffset returns a new encoder that writes to out in the given
+// byte order. Specify the offset to initialize pos for proper alignment
+// computation.
+func newEncoderAtOffset(out io.Writer, offset int, order binary.ByteOrder, fds []int) *encoder {
+ enc := new(encoder)
+ enc.out = out
+ enc.order = order
+ enc.pos = offset
+ enc.fds = fds
+ return enc
+}
+
+// Aligns the next output to be on a multiple of n. Panics on write errors.
+func (enc *encoder) align(n int) {
+ pad := enc.padding(0, n)
+ if pad > 0 {
+ empty := make([]byte, pad)
+ if _, err := enc.out.Write(empty); err != nil {
+ panic(err)
+ }
+ enc.pos += pad
+ }
+}
+
+// pad returns the number of bytes of padding, based on current position and additional offset.
+// and alignment.
+func (enc *encoder) padding(offset, algn int) int {
+ abs := enc.pos + offset
+ if abs%algn != 0 {
+ newabs := (abs + algn - 1) & ^(algn - 1)
+ return newabs - abs
+ }
+ return 0
+}
+
+// Calls binary.Write(enc.out, enc.order, v) and panics on write errors.
+func (enc *encoder) binwrite(v interface{}) {
+ if err := binary.Write(enc.out, enc.order, v); err != nil {
+ panic(err)
+ }
+}
+
+// Encode encodes the given values to the underlying reader. All written values
+// are aligned properly as required by the D-Bus spec.
+func (enc *encoder) Encode(vs ...interface{}) (err error) {
+ defer func() {
+ err, _ = recover().(error)
+ }()
+ for _, v := range vs {
+ enc.encode(reflect.ValueOf(v), 0)
+ }
+ return nil
+}
+
+// encode encodes the given value to the writer and panics on error. depth holds
+// the depth of the container nesting.
+func (enc *encoder) encode(v reflect.Value, depth int) {
+ if depth > 64 {
+ panic(FormatError("input exceeds depth limitation"))
+ }
+ enc.align(alignment(v.Type()))
+ switch v.Kind() {
+ case reflect.Uint8:
+ var b [1]byte
+ b[0] = byte(v.Uint())
+ if _, err := enc.out.Write(b[:]); err != nil {
+ panic(err)
+ }
+ enc.pos++
+ case reflect.Bool:
+ if v.Bool() {
+ enc.encode(reflect.ValueOf(uint32(1)), depth)
+ } else {
+ enc.encode(reflect.ValueOf(uint32(0)), depth)
+ }
+ case reflect.Int16:
+ enc.binwrite(int16(v.Int()))
+ enc.pos += 2
+ case reflect.Uint16:
+ enc.binwrite(uint16(v.Uint()))
+ enc.pos += 2
+ case reflect.Int, reflect.Int32:
+ if v.Type() == unixFDType {
+ fd := v.Int()
+ idx := len(enc.fds)
+ enc.fds = append(enc.fds, int(fd))
+ enc.binwrite(uint32(idx))
+ } else {
+ enc.binwrite(int32(v.Int()))
+ }
+ enc.pos += 4
+ case reflect.Uint, reflect.Uint32:
+ enc.binwrite(uint32(v.Uint()))
+ enc.pos += 4
+ case reflect.Int64:
+ enc.binwrite(v.Int())
+ enc.pos += 8
+ case reflect.Uint64:
+ enc.binwrite(v.Uint())
+ enc.pos += 8
+ case reflect.Float64:
+ enc.binwrite(v.Float())
+ enc.pos += 8
+ case reflect.String:
+ str := v.String()
+ if !utf8.ValidString(str) {
+ panic(FormatError("input has a not-utf8 char in string"))
+ }
+ if strings.IndexByte(str, byte(0)) != -1 {
+ panic(FormatError("input has a null char('\\000') in string"))
+ }
+ if v.Type() == objectPathType {
+ if !ObjectPath(str).IsValid() {
+ panic(FormatError("invalid object path"))
+ }
+ }
+ enc.encode(reflect.ValueOf(uint32(len(str))), depth)
+ b := make([]byte, v.Len()+1)
+ copy(b, str)
+ b[len(b)-1] = 0
+ n, err := enc.out.Write(b)
+ if err != nil {
+ panic(err)
+ }
+ enc.pos += n
+ case reflect.Ptr:
+ enc.encode(v.Elem(), depth)
+ case reflect.Slice, reflect.Array:
+ // Lookahead offset: 4 bytes for uint32 length (with alignment),
+ // plus alignment for elements.
+ n := enc.padding(0, 4) + 4
+ offset := enc.pos + n + enc.padding(n, alignment(v.Type().Elem()))
+
+ var buf bytes.Buffer
+ bufenc := newEncoderAtOffset(&buf, offset, enc.order, enc.fds)
+
+ for i := 0; i < v.Len(); i++ {
+ bufenc.encode(v.Index(i), depth+1)
+ }
+
+ if buf.Len() > 1<<26 {
+ panic(FormatError("input exceeds array size limitation"))
+ }
+
+ enc.fds = bufenc.fds
+ enc.encode(reflect.ValueOf(uint32(buf.Len())), depth)
+ length := buf.Len()
+ enc.align(alignment(v.Type().Elem()))
+ if _, err := buf.WriteTo(enc.out); err != nil {
+ panic(err)
+ }
+ enc.pos += length
+ case reflect.Struct:
+ switch t := v.Type(); t {
+ case signatureType:
+ str := v.Field(0)
+ enc.encode(reflect.ValueOf(byte(str.Len())), depth)
+ b := make([]byte, str.Len()+1)
+ copy(b, str.String())
+ b[len(b)-1] = 0
+ n, err := enc.out.Write(b)
+ if err != nil {
+ panic(err)
+ }
+ enc.pos += n
+ case variantType:
+ variant := v.Interface().(Variant)
+ enc.encode(reflect.ValueOf(variant.sig), depth+1)
+ enc.encode(reflect.ValueOf(variant.value), depth+1)
+ default:
+ for i := 0; i < v.Type().NumField(); i++ {
+ field := t.Field(i)
+ if field.PkgPath == "" && field.Tag.Get("dbus") != "-" {
+ enc.encode(v.Field(i), depth+1)
+ }
+ }
+ }
+ case reflect.Map:
+ // Maps are arrays of structures, so they actually increase the depth by
+ // 2.
+ if !isKeyType(v.Type().Key()) {
+ panic(InvalidTypeError{v.Type()})
+ }
+ keys := v.MapKeys()
+ // Lookahead offset: 4 bytes for uint32 length (with alignment),
+ // plus 8-byte alignment
+ n := enc.padding(0, 4) + 4
+ offset := enc.pos + n + enc.padding(n, 8)
+
+ var buf bytes.Buffer
+ bufenc := newEncoderAtOffset(&buf, offset, enc.order, enc.fds)
+ for _, k := range keys {
+ bufenc.align(8)
+ bufenc.encode(k, depth+2)
+ bufenc.encode(v.MapIndex(k), depth+2)
+ }
+ enc.fds = bufenc.fds
+ enc.encode(reflect.ValueOf(uint32(buf.Len())), depth)
+ length := buf.Len()
+ enc.align(8)
+ if _, err := buf.WriteTo(enc.out); err != nil {
+ panic(err)
+ }
+ enc.pos += length
+ case reflect.Interface:
+ enc.encode(reflect.ValueOf(MakeVariant(v.Interface())), depth)
+ default:
+ panic(InvalidTypeError{v.Type()})
+ }
+}
diff --git a/vendor/github.com/godbus/dbus/v5/escape.go b/vendor/github.com/godbus/dbus/v5/escape.go
new file mode 100644
index 000000000..d1509d945
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/escape.go
@@ -0,0 +1,84 @@
+package dbus
+
+import "net/url"
+
+// EscapeBusAddressValue implements a requirement to escape the values
+// in D-Bus server addresses, as defined by the D-Bus specification at
+// https://dbus.freedesktop.org/doc/dbus-specification.html#addresses.
+func EscapeBusAddressValue(val string) string {
+ toEsc := strNeedsEscape(val)
+ if toEsc == 0 {
+ // Avoid unneeded allocation/copying.
+ return val
+ }
+
+ // Avoid allocation for short paths.
+ var buf [64]byte
+ var out []byte
+ // Every to-be-escaped byte needs 2 extra bytes.
+ required := len(val) + 2*toEsc
+ if required <= len(buf) {
+ out = buf[:required]
+ } else {
+ out = make([]byte, required)
+ }
+
+ j := 0
+ for i := 0; i < len(val); i++ {
+ if ch := val[i]; needsEscape(ch) {
+ // Convert ch to %xx, where xx is hex value.
+ out[j] = '%'
+ out[j+1] = hexchar(ch >> 4)
+ out[j+2] = hexchar(ch & 0x0F)
+ j += 3
+ } else {
+ out[j] = ch
+ j++
+ }
+ }
+
+ return string(out)
+}
+
+// UnescapeBusAddressValue unescapes values in D-Bus server addresses,
+// as defined by the D-Bus specification at
+// https://dbus.freedesktop.org/doc/dbus-specification.html#addresses.
+func UnescapeBusAddressValue(val string) (string, error) {
+ // Looks like url.PathUnescape does exactly what is required.
+ return url.PathUnescape(val)
+}
+
+// hexchar returns an octal representation of a n, where n < 16.
+// For invalid values of n, the function panics.
+func hexchar(n byte) byte {
+ const hex = "0123456789abcdef"
+
+ // For n >= len(hex), runtime will panic.
+ return hex[n]
+}
+
+// needsEscape tells if a byte is NOT one of optionally-escaped bytes.
+func needsEscape(c byte) bool {
+ if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9' {
+ return false
+ }
+ switch c {
+ case '-', '_', '/', '\\', '.', '*':
+ return false
+ }
+
+ return true
+}
+
+// strNeedsEscape tells how many bytes in the string need escaping.
+func strNeedsEscape(val string) int {
+ count := 0
+
+ for i := 0; i < len(val); i++ {
+ if needsEscape(val[i]) {
+ count++
+ }
+ }
+
+ return count
+}
diff --git a/vendor/github.com/godbus/dbus/v5/export.go b/vendor/github.com/godbus/dbus/v5/export.go
new file mode 100644
index 000000000..d3dd9f7cd
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/export.go
@@ -0,0 +1,463 @@
+package dbus
+
+import (
+ "errors"
+ "fmt"
+ "os"
+ "reflect"
+ "strings"
+)
+
+var (
+ ErrMsgInvalidArg = Error{
+ "org.freedesktop.DBus.Error.InvalidArgs",
+ []interface{}{"Invalid type / number of args"},
+ }
+ ErrMsgNoObject = Error{
+ "org.freedesktop.DBus.Error.NoSuchObject",
+ []interface{}{"No such object"},
+ }
+ ErrMsgUnknownMethod = Error{
+ "org.freedesktop.DBus.Error.UnknownMethod",
+ []interface{}{"Unknown / invalid method"},
+ }
+ ErrMsgUnknownInterface = Error{
+ "org.freedesktop.DBus.Error.UnknownInterface",
+ []interface{}{"Object does not implement the interface"},
+ }
+)
+
+func MakeNoObjectError(path ObjectPath) Error {
+ return Error{
+ "org.freedesktop.DBus.Error.NoSuchObject",
+ []interface{}{fmt.Sprintf("No such object '%s'", string(path))},
+ }
+}
+
+func MakeUnknownMethodError(methodName string) Error {
+ return Error{
+ "org.freedesktop.DBus.Error.UnknownMethod",
+ []interface{}{fmt.Sprintf("Unknown / invalid method '%s'", methodName)},
+ }
+}
+
+func MakeUnknownInterfaceError(ifaceName string) Error {
+ return Error{
+ "org.freedesktop.DBus.Error.UnknownInterface",
+ []interface{}{fmt.Sprintf("Object does not implement the interface '%s'", ifaceName)},
+ }
+}
+
+func MakeFailedError(err error) *Error {
+ return &Error{
+ "org.freedesktop.DBus.Error.Failed",
+ []interface{}{err.Error()},
+ }
+}
+
+// Sender is a type which can be used in exported methods to receive the message
+// sender.
+type Sender string
+
+func computeMethodName(name string, mapping map[string]string) string {
+ newname, ok := mapping[name]
+ if ok {
+ name = newname
+ }
+ return name
+}
+
+func getMethods(in interface{}, mapping map[string]string) map[string]reflect.Value {
+ if in == nil {
+ return nil
+ }
+ methods := make(map[string]reflect.Value)
+ val := reflect.ValueOf(in)
+ typ := val.Type()
+ for i := 0; i < typ.NumMethod(); i++ {
+ methtype := typ.Method(i)
+ method := val.Method(i)
+ t := method.Type()
+ // only track valid methods must return *Error as last arg
+ // and must be exported
+ if t.NumOut() == 0 ||
+ t.Out(t.NumOut()-1) != reflect.TypeOf(&ErrMsgInvalidArg) ||
+ methtype.PkgPath != "" {
+ continue
+ }
+ // map names while building table
+ methods[computeMethodName(methtype.Name, mapping)] = method
+ }
+ return methods
+}
+
+func getAllMethods(in interface{}, mapping map[string]string) map[string]reflect.Value {
+ if in == nil {
+ return nil
+ }
+ methods := make(map[string]reflect.Value)
+ val := reflect.ValueOf(in)
+ typ := val.Type()
+ for i := 0; i < typ.NumMethod(); i++ {
+ methtype := typ.Method(i)
+ method := val.Method(i)
+ // map names while building table
+ methods[computeMethodName(methtype.Name, mapping)] = method
+ }
+ return methods
+}
+
+func standardMethodArgumentDecode(m Method, sender string, msg *Message, body []interface{}) ([]interface{}, error) {
+ pointers := make([]interface{}, m.NumArguments())
+ decode := make([]interface{}, 0, len(body))
+
+ for i := 0; i < m.NumArguments(); i++ {
+ tp := reflect.TypeOf(m.ArgumentValue(i))
+ val := reflect.New(tp)
+ pointers[i] = val.Interface()
+ if tp == reflect.TypeOf((*Sender)(nil)).Elem() {
+ val.Elem().SetString(sender)
+ } else if tp == reflect.TypeOf((*Message)(nil)).Elem() {
+ val.Elem().Set(reflect.ValueOf(*msg))
+ } else {
+ decode = append(decode, pointers[i])
+ }
+ }
+
+ if len(decode) != len(body) {
+ return nil, ErrMsgInvalidArg
+ }
+
+ if err := Store(body, decode...); err != nil {
+ return nil, ErrMsgInvalidArg
+ }
+
+ return pointers, nil
+}
+
+func (conn *Conn) decodeArguments(m Method, sender string, msg *Message) ([]interface{}, error) {
+ if decoder, ok := m.(ArgumentDecoder); ok {
+ return decoder.DecodeArguments(conn, sender, msg, msg.Body)
+ }
+ return standardMethodArgumentDecode(m, sender, msg, msg.Body)
+}
+
+// handleCall handles the given method call (i.e. looks if it's one of the
+// pre-implemented ones and searches for a corresponding handler if not).
+func (conn *Conn) handleCall(msg *Message) {
+ name := msg.Headers[FieldMember].value.(string)
+ path := msg.Headers[FieldPath].value.(ObjectPath)
+ ifaceName, _ := msg.Headers[FieldInterface].value.(string)
+ sender, hasSender := msg.Headers[FieldSender].value.(string)
+ serial := msg.serial
+
+ if len(name) == 0 {
+ conn.sendError(ErrMsgUnknownMethod, sender, serial)
+ }
+
+ if ifaceName == "org.freedesktop.DBus.Peer" {
+ switch name {
+ case "Ping":
+ conn.sendReply(sender, serial)
+ case "GetMachineId":
+ conn.sendReply(sender, serial, conn.uuid)
+ default:
+ conn.sendError(MakeUnknownMethodError(name), sender, serial)
+ }
+ return
+ }
+
+ object, ok := conn.handler.LookupObject(path)
+ if !ok {
+ conn.sendError(MakeNoObjectError(path), sender, serial)
+ return
+ }
+
+ iface, exists := object.LookupInterface(ifaceName)
+ if !exists {
+ conn.sendError(MakeUnknownInterfaceError(ifaceName), sender, serial)
+ return
+ }
+
+ m, exists := iface.LookupMethod(name)
+ if !exists {
+ conn.sendError(MakeUnknownMethodError(name), sender, serial)
+ return
+ }
+ args, err := conn.decodeArguments(m, sender, msg)
+ if err != nil {
+ conn.sendError(err, sender, serial)
+ return
+ }
+
+ ret, err := m.Call(args...)
+ if err != nil {
+ conn.sendError(err, sender, serial)
+ return
+ }
+
+ if msg.Flags&FlagNoReplyExpected == 0 {
+ reply := new(Message)
+ reply.Type = TypeMethodReply
+ reply.Headers = make(map[HeaderField]Variant)
+ if hasSender {
+ reply.Headers[FieldDestination] = msg.Headers[FieldSender]
+ }
+ reply.Headers[FieldReplySerial] = MakeVariant(msg.serial)
+ reply.Body = make([]interface{}, len(ret))
+ for i := 0; i < len(ret); i++ {
+ reply.Body[i] = ret[i]
+ }
+ reply.Headers[FieldSignature] = MakeVariant(SignatureOf(reply.Body...))
+
+ if err := reply.IsValid(); err != nil {
+ fmt.Fprintf(os.Stderr, "dbus: dropping invalid reply to %s.%s on obj %s: %s\n", ifaceName, name, path, err)
+ } else {
+ conn.sendMessageAndIfClosed(reply, nil)
+ }
+ }
+}
+
+// Emit emits the given signal on the message bus. The name parameter must be
+// formatted as "interface.member", e.g., "org.freedesktop.DBus.NameLost".
+func (conn *Conn) Emit(path ObjectPath, name string, values ...interface{}) error {
+ i := strings.LastIndex(name, ".")
+ if i == -1 {
+ return errors.New("dbus: invalid method name")
+ }
+ iface := name[:i]
+ member := name[i+1:]
+ msg := new(Message)
+ msg.Type = TypeSignal
+ msg.Headers = make(map[HeaderField]Variant)
+ msg.Headers[FieldInterface] = MakeVariant(iface)
+ msg.Headers[FieldMember] = MakeVariant(member)
+ msg.Headers[FieldPath] = MakeVariant(path)
+ msg.Body = values
+ if len(values) > 0 {
+ msg.Headers[FieldSignature] = MakeVariant(SignatureOf(values...))
+ }
+ if err := msg.IsValid(); err != nil {
+ return err
+ }
+
+ var closed bool
+ conn.sendMessageAndIfClosed(msg, func() {
+ closed = true
+ })
+ if closed {
+ return ErrClosed
+ }
+ return nil
+}
+
+// Export registers the given value to be exported as an object on the
+// message bus.
+//
+// If a method call on the given path and interface is received, an exported
+// method with the same name is called with v as the receiver if the
+// parameters match and the last return value is of type *Error. If this
+// *Error is not nil, it is sent back to the caller as an error.
+// Otherwise, a method reply is sent with the other return values as its body.
+//
+// Any parameters with the special type Sender are set to the sender of the
+// dbus message when the method is called. Parameters of this type do not
+// contribute to the dbus signature of the method (i.e. the method is exposed
+// as if the parameters of type Sender were not there).
+//
+// Similarly, any parameters with the type Message are set to the raw message
+// received on the bus. Again, parameters of this type do not contribute to the
+// dbus signature of the method.
+//
+// Every method call is executed in a new goroutine, so the method may be called
+// in multiple goroutines at once.
+//
+// Method calls on the interface org.freedesktop.DBus.Peer will be automatically
+// handled for every object.
+//
+// Passing nil as the first parameter will cause conn to cease handling calls on
+// the given combination of path and interface.
+//
+// Export returns an error if path is not a valid path name.
+func (conn *Conn) Export(v interface{}, path ObjectPath, iface string) error {
+ return conn.ExportWithMap(v, nil, path, iface)
+}
+
+// ExportAll registers all exported methods defined by the given object on
+// the message bus.
+//
+// Unlike Export there is no requirement to have the last parameter as type
+// *Error. If you want to be able to return error then you can append an error
+// type parameter to your method signature. If the error returned is not nil,
+// it is sent back to the caller as an error. Otherwise, a method reply is
+// sent with the other return values as its body.
+func (conn *Conn) ExportAll(v interface{}, path ObjectPath, iface string) error {
+ return conn.export(getAllMethods(v, nil), path, iface, false)
+}
+
+// ExportWithMap works exactly like Export but provides the ability to remap
+// method names (e.g. export a lower-case method).
+//
+// The keys in the map are the real method names (exported on the struct), and
+// the values are the method names to be exported on DBus.
+func (conn *Conn) ExportWithMap(v interface{}, mapping map[string]string, path ObjectPath, iface string) error {
+ return conn.export(getMethods(v, mapping), path, iface, false)
+}
+
+// ExportSubtree works exactly like Export but registers the given value for
+// an entire subtree rather under the root path provided.
+//
+// In order to make this useful, one parameter in each of the value's exported
+// methods should be a Message, in which case it will contain the raw message
+// (allowing one to get access to the path that caused the method to be called).
+//
+// Note that more specific export paths take precedence over less specific. For
+// example, a method call using the ObjectPath /foo/bar/baz will call a method
+// exported on /foo/bar before a method exported on /foo.
+func (conn *Conn) ExportSubtree(v interface{}, path ObjectPath, iface string) error {
+ return conn.ExportSubtreeWithMap(v, nil, path, iface)
+}
+
+// ExportSubtreeWithMap works exactly like ExportSubtree but provides the
+// ability to remap method names (e.g. export a lower-case method).
+//
+// The keys in the map are the real method names (exported on the struct), and
+// the values are the method names to be exported on DBus.
+func (conn *Conn) ExportSubtreeWithMap(v interface{}, mapping map[string]string, path ObjectPath, iface string) error {
+ return conn.export(getMethods(v, mapping), path, iface, true)
+}
+
+// ExportMethodTable like Export registers the given methods as an object
+// on the message bus. Unlike Export the it uses a method table to define
+// the object instead of a native go object.
+//
+// The method table is a map from method name to function closure
+// representing the method. This allows an object exported on the bus to not
+// necessarily be a native go object. It can be useful for generating exposed
+// methods on the fly.
+//
+// Any non-function objects in the method table are ignored.
+func (conn *Conn) ExportMethodTable(methods map[string]interface{}, path ObjectPath, iface string) error {
+ return conn.exportMethodTable(methods, path, iface, false)
+}
+
+// Like ExportSubtree, but with the same caveats as ExportMethodTable.
+func (conn *Conn) ExportSubtreeMethodTable(methods map[string]interface{}, path ObjectPath, iface string) error {
+ return conn.exportMethodTable(methods, path, iface, true)
+}
+
+func (conn *Conn) exportMethodTable(methods map[string]interface{}, path ObjectPath, iface string, includeSubtree bool) error {
+ var out map[string]reflect.Value
+ if methods != nil {
+ out = make(map[string]reflect.Value)
+ for name, method := range methods {
+ rval := reflect.ValueOf(method)
+ if rval.Kind() != reflect.Func {
+ continue
+ }
+ t := rval.Type()
+ // only track valid methods must return *Error as last arg
+ if t.NumOut() == 0 ||
+ t.Out(t.NumOut()-1) != reflect.TypeOf(&ErrMsgInvalidArg) {
+ continue
+ }
+ out[name] = rval
+ }
+ }
+ return conn.export(out, path, iface, includeSubtree)
+}
+
+func (conn *Conn) unexport(h *defaultHandler, path ObjectPath, iface string) error {
+ if h.PathExists(path) {
+ obj := h.objects[path]
+ obj.DeleteInterface(iface)
+ if len(obj.interfaces) == 0 {
+ h.DeleteObject(path)
+ }
+ }
+ return nil
+}
+
+// export is the worker function for all exports/registrations.
+func (conn *Conn) export(methods map[string]reflect.Value, path ObjectPath, iface string, includeSubtree bool) error {
+ h, ok := conn.handler.(*defaultHandler)
+ if !ok {
+ return fmt.Errorf(
+ `dbus: export only allowed on the default handler. Received: %T"`,
+ conn.handler)
+ }
+
+ if !path.IsValid() {
+ return fmt.Errorf(`dbus: Invalid path name: "%s"`, path)
+ }
+
+ // Remove a previous export if the interface is nil
+ if methods == nil {
+ return conn.unexport(h, path, iface)
+ }
+
+ // If this is the first handler for this path, make a new map to hold all
+ // handlers for this path.
+ if !h.PathExists(path) {
+ h.AddObject(path, newExportedObject())
+ }
+
+ exportedMethods := make(map[string]Method)
+ for name, method := range methods {
+ exportedMethods[name] = exportedMethod{method}
+ }
+
+ // Finally, save this handler
+ obj := h.objects[path]
+ obj.AddInterface(iface, newExportedIntf(exportedMethods, includeSubtree))
+
+ return nil
+}
+
+// ReleaseName calls org.freedesktop.DBus.ReleaseName and awaits a response.
+func (conn *Conn) ReleaseName(name string) (ReleaseNameReply, error) {
+ var r uint32
+ err := conn.busObj.Call("org.freedesktop.DBus.ReleaseName", 0, name).Store(&r)
+ if err != nil {
+ return 0, err
+ }
+ return ReleaseNameReply(r), nil
+}
+
+// RequestName calls org.freedesktop.DBus.RequestName and awaits a response.
+func (conn *Conn) RequestName(name string, flags RequestNameFlags) (RequestNameReply, error) {
+ var r uint32
+ err := conn.busObj.Call("org.freedesktop.DBus.RequestName", 0, name, flags).Store(&r)
+ if err != nil {
+ return 0, err
+ }
+ return RequestNameReply(r), nil
+}
+
+// ReleaseNameReply is the reply to a ReleaseName call.
+type ReleaseNameReply uint32
+
+const (
+ ReleaseNameReplyReleased ReleaseNameReply = 1 + iota
+ ReleaseNameReplyNonExistent
+ ReleaseNameReplyNotOwner
+)
+
+// RequestNameFlags represents the possible flags for a RequestName call.
+type RequestNameFlags uint32
+
+const (
+ NameFlagAllowReplacement RequestNameFlags = 1 << iota
+ NameFlagReplaceExisting
+ NameFlagDoNotQueue
+)
+
+// RequestNameReply is the reply to a RequestName call.
+type RequestNameReply uint32
+
+const (
+ RequestNameReplyPrimaryOwner RequestNameReply = 1 + iota
+ RequestNameReplyInQueue
+ RequestNameReplyExists
+ RequestNameReplyAlreadyOwner
+)
diff --git a/vendor/github.com/godbus/dbus/v5/homedir.go b/vendor/github.com/godbus/dbus/v5/homedir.go
new file mode 100644
index 000000000..c44d9b5fc
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/homedir.go
@@ -0,0 +1,25 @@
+package dbus
+
+import (
+ "os"
+ "os/user"
+)
+
+// Get returns the home directory of the current user, which is usually the
+// value of HOME environment variable. In case it is not set or empty, os/user
+// package is used.
+//
+// If linking statically with cgo enabled against glibc, make sure the
+// osusergo build tag is used.
+//
+// If needing to do nss lookups, do not disable cgo or set osusergo.
+func getHomeDir() string {
+ homeDir := os.Getenv("HOME")
+ if homeDir != "" {
+ return homeDir
+ }
+ if u, err := user.Current(); err == nil {
+ return u.HomeDir
+ }
+ return "/"
+}
diff --git a/vendor/github.com/godbus/dbus/v5/match.go b/vendor/github.com/godbus/dbus/v5/match.go
new file mode 100644
index 000000000..5a607e53e
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/match.go
@@ -0,0 +1,89 @@
+package dbus
+
+import (
+ "strconv"
+ "strings"
+)
+
+// MatchOption specifies option for dbus routing match rule. Options can be constructed with WithMatch* helpers.
+// For full list of available options consult
+// https://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-routing-match-rules
+type MatchOption struct {
+ key string
+ value string
+}
+
+func formatMatchOptions(options []MatchOption) string {
+ items := make([]string, 0, len(options))
+ for _, option := range options {
+ items = append(items, option.key+"='"+option.value+"'")
+ }
+ return strings.Join(items, ",")
+}
+
+// WithMatchOption creates match option with given key and value
+func WithMatchOption(key, value string) MatchOption {
+ return MatchOption{key, value}
+}
+
+// doesn't make sense to export this option because clients can only
+// subscribe to messages with signal type.
+func withMatchType(typ string) MatchOption {
+ return WithMatchOption("type", typ)
+}
+
+// WithMatchSender sets sender match option.
+func WithMatchSender(sender string) MatchOption {
+ return WithMatchOption("sender", sender)
+}
+
+// WithMatchSender sets interface match option.
+func WithMatchInterface(iface string) MatchOption {
+ return WithMatchOption("interface", iface)
+}
+
+// WithMatchMember sets member match option.
+func WithMatchMember(member string) MatchOption {
+ return WithMatchOption("member", member)
+}
+
+// WithMatchObjectPath creates match option that filters events based on given path
+func WithMatchObjectPath(path ObjectPath) MatchOption {
+ return WithMatchOption("path", string(path))
+}
+
+// WithMatchPathNamespace sets path_namespace match option.
+func WithMatchPathNamespace(namespace ObjectPath) MatchOption {
+ return WithMatchOption("path_namespace", string(namespace))
+}
+
+// WithMatchDestination sets destination match option.
+func WithMatchDestination(destination string) MatchOption {
+ return WithMatchOption("destination", destination)
+}
+
+// WithMatchArg sets argN match option, range of N is 0 to 63.
+func WithMatchArg(argIdx int, value string) MatchOption {
+ if argIdx < 0 || argIdx > 63 {
+ panic("range of argument index is 0 to 63")
+ }
+ return WithMatchOption("arg"+strconv.Itoa(argIdx), value)
+}
+
+// WithMatchArgPath sets argN path match option, range of N is 0 to 63.
+func WithMatchArgPath(argIdx int, path string) MatchOption {
+ if argIdx < 0 || argIdx > 63 {
+ panic("range of argument index is 0 to 63")
+ }
+ return WithMatchOption("arg"+strconv.Itoa(argIdx)+"path", path)
+}
+
+// WithMatchArg0Namespace sets arg0namespace match option.
+func WithMatchArg0Namespace(arg0Namespace string) MatchOption {
+ return WithMatchOption("arg0namespace", arg0Namespace)
+}
+
+// WithMatchEavesdrop sets eavesdrop match option.
+func WithMatchEavesdrop(eavesdrop bool) MatchOption {
+ return WithMatchOption("eavesdrop", strconv.FormatBool(eavesdrop))
+}
diff --git a/vendor/github.com/godbus/dbus/v5/message.go b/vendor/github.com/godbus/dbus/v5/message.go
new file mode 100644
index 000000000..bdf43fdd6
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/message.go
@@ -0,0 +1,390 @@
+package dbus
+
+import (
+ "bytes"
+ "encoding/binary"
+ "errors"
+ "io"
+ "reflect"
+ "strconv"
+)
+
+const protoVersion byte = 1
+
+// Flags represents the possible flags of a D-Bus message.
+type Flags byte
+
+const (
+ // FlagNoReplyExpected signals that the message is not expected to generate
+ // a reply. If this flag is set on outgoing messages, any possible reply
+ // will be discarded.
+ FlagNoReplyExpected Flags = 1 << iota
+ // FlagNoAutoStart signals that the message bus should not automatically
+ // start an application when handling this message.
+ FlagNoAutoStart
+ // FlagAllowInteractiveAuthorization may be set on a method call
+ // message to inform the receiving side that the caller is prepared
+ // to wait for interactive authorization, which might take a
+ // considerable time to complete. For instance, if this flag is set,
+ // it would be appropriate to query the user for passwords or
+ // confirmation via Polkit or a similar framework.
+ FlagAllowInteractiveAuthorization
+)
+
+// Type represents the possible types of a D-Bus message.
+type Type byte
+
+const (
+ TypeMethodCall Type = 1 + iota
+ TypeMethodReply
+ TypeError
+ TypeSignal
+ typeMax
+)
+
+func (t Type) String() string {
+ switch t {
+ case TypeMethodCall:
+ return "method call"
+ case TypeMethodReply:
+ return "reply"
+ case TypeError:
+ return "error"
+ case TypeSignal:
+ return "signal"
+ }
+ return "invalid"
+}
+
+// HeaderField represents the possible byte codes for the headers
+// of a D-Bus message.
+type HeaderField byte
+
+const (
+ FieldPath HeaderField = 1 + iota
+ FieldInterface
+ FieldMember
+ FieldErrorName
+ FieldReplySerial
+ FieldDestination
+ FieldSender
+ FieldSignature
+ FieldUnixFDs
+ fieldMax
+)
+
+// An InvalidMessageError describes the reason why a D-Bus message is regarded as
+// invalid.
+type InvalidMessageError string
+
+func (e InvalidMessageError) Error() string {
+ return "dbus: invalid message: " + string(e)
+}
+
+// fieldType are the types of the various header fields.
+var fieldTypes = [fieldMax]reflect.Type{
+ FieldPath: objectPathType,
+ FieldInterface: stringType,
+ FieldMember: stringType,
+ FieldErrorName: stringType,
+ FieldReplySerial: uint32Type,
+ FieldDestination: stringType,
+ FieldSender: stringType,
+ FieldSignature: signatureType,
+ FieldUnixFDs: uint32Type,
+}
+
+// requiredFields lists the header fields that are required by the different
+// message types.
+var requiredFields = [typeMax][]HeaderField{
+ TypeMethodCall: {FieldPath, FieldMember},
+ TypeMethodReply: {FieldReplySerial},
+ TypeError: {FieldErrorName, FieldReplySerial},
+ TypeSignal: {FieldPath, FieldInterface, FieldMember},
+}
+
+// Message represents a single D-Bus message.
+type Message struct {
+ Type
+ Flags
+ Headers map[HeaderField]Variant
+ Body []interface{}
+
+ serial uint32
+}
+
+type header struct {
+ Field byte
+ Variant
+}
+
+func DecodeMessageWithFDs(rd io.Reader, fds []int) (msg *Message, err error) {
+ var order binary.ByteOrder
+ var hlength, length uint32
+ var typ, flags, proto byte
+ var headers []header
+
+ b := make([]byte, 1)
+ _, err = rd.Read(b)
+ if err != nil {
+ return
+ }
+ switch b[0] {
+ case 'l':
+ order = binary.LittleEndian
+ case 'B':
+ order = binary.BigEndian
+ default:
+ return nil, InvalidMessageError("invalid byte order")
+ }
+
+ dec := newDecoder(rd, order, fds)
+ dec.pos = 1
+
+ msg = new(Message)
+ vs, err := dec.Decode(Signature{"yyyuu"})
+ if err != nil {
+ return nil, err
+ }
+ if err = Store(vs, &typ, &flags, &proto, &length, &msg.serial); err != nil {
+ return nil, err
+ }
+ msg.Type = Type(typ)
+ msg.Flags = Flags(flags)
+
+ // get the header length separately because we need it later
+ b = make([]byte, 4)
+ _, err = io.ReadFull(rd, b)
+ if err != nil {
+ return nil, err
+ }
+ binary.Read(bytes.NewBuffer(b), order, &hlength)
+ if hlength+length+16 > 1<<27 {
+ return nil, InvalidMessageError("message is too long")
+ }
+ dec = newDecoder(io.MultiReader(bytes.NewBuffer(b), rd), order, fds)
+ dec.pos = 12
+ vs, err = dec.Decode(Signature{"a(yv)"})
+ if err != nil {
+ return nil, err
+ }
+ if err = Store(vs, &headers); err != nil {
+ return nil, err
+ }
+
+ msg.Headers = make(map[HeaderField]Variant)
+ for _, v := range headers {
+ msg.Headers[HeaderField(v.Field)] = v.Variant
+ }
+
+ dec.align(8)
+ body := make([]byte, int(length))
+ if length != 0 {
+ _, err := io.ReadFull(rd, body)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ if err = msg.IsValid(); err != nil {
+ return nil, err
+ }
+ sig, _ := msg.Headers[FieldSignature].value.(Signature)
+ if sig.str != "" {
+ buf := bytes.NewBuffer(body)
+ dec = newDecoder(buf, order, fds)
+ vs, err := dec.Decode(sig)
+ if err != nil {
+ return nil, err
+ }
+ msg.Body = vs
+ }
+
+ return
+}
+
+// DecodeMessage tries to decode a single message in the D-Bus wire format
+// from the given reader. The byte order is figured out from the first byte.
+// The possibly returned error can be an error of the underlying reader, an
+// InvalidMessageError or a FormatError.
+func DecodeMessage(rd io.Reader) (msg *Message, err error) {
+ return DecodeMessageWithFDs(rd, make([]int, 0))
+}
+
+type nullwriter struct{}
+
+func (nullwriter) Write(p []byte) (cnt int, err error) {
+ return len(p), nil
+}
+
+func (msg *Message) CountFds() (int, error) {
+ if len(msg.Body) == 0 {
+ return 0, nil
+ }
+ enc := newEncoder(nullwriter{}, nativeEndian, make([]int, 0))
+ err := enc.Encode(msg.Body...)
+ return len(enc.fds), err
+}
+
+func (msg *Message) EncodeToWithFDs(out io.Writer, order binary.ByteOrder) (fds []int, err error) {
+ if err := msg.validateHeader(); err != nil {
+ return nil, err
+ }
+ var vs [7]interface{}
+ switch order {
+ case binary.LittleEndian:
+ vs[0] = byte('l')
+ case binary.BigEndian:
+ vs[0] = byte('B')
+ default:
+ return nil, errors.New("dbus: invalid byte order")
+ }
+ body := new(bytes.Buffer)
+ fds = make([]int, 0)
+ enc := newEncoder(body, order, fds)
+ if len(msg.Body) != 0 {
+ err = enc.Encode(msg.Body...)
+ if err != nil {
+ return
+ }
+ }
+ vs[1] = msg.Type
+ vs[2] = msg.Flags
+ vs[3] = protoVersion
+ vs[4] = uint32(len(body.Bytes()))
+ vs[5] = msg.serial
+ headers := make([]header, 0, len(msg.Headers))
+ for k, v := range msg.Headers {
+ headers = append(headers, header{byte(k), v})
+ }
+ vs[6] = headers
+ var buf bytes.Buffer
+ enc = newEncoder(&buf, order, enc.fds)
+ err = enc.Encode(vs[:]...)
+ if err != nil {
+ return
+ }
+ enc.align(8)
+ body.WriteTo(&buf)
+ if buf.Len() > 1<<27 {
+ return make([]int, 0), InvalidMessageError("message is too long")
+ }
+ if _, err := buf.WriteTo(out); err != nil {
+ return make([]int, 0), err
+ }
+ return enc.fds, nil
+}
+
+// EncodeTo encodes and sends a message to the given writer. The byte order must
+// be either binary.LittleEndian or binary.BigEndian. If the message is not
+// valid or an error occurs when writing, an error is returned.
+func (msg *Message) EncodeTo(out io.Writer, order binary.ByteOrder) (err error) {
+ _, err = msg.EncodeToWithFDs(out, order)
+ return err
+}
+
+// IsValid checks whether msg is a valid message and returns an
+// InvalidMessageError or FormatError if it is not.
+func (msg *Message) IsValid() error {
+ var b bytes.Buffer
+ return msg.EncodeTo(&b, nativeEndian)
+}
+
+func (msg *Message) validateHeader() error {
+ if msg.Flags & ^(FlagNoAutoStart|FlagNoReplyExpected|FlagAllowInteractiveAuthorization) != 0 {
+ return InvalidMessageError("invalid flags")
+ }
+ if msg.Type == 0 || msg.Type >= typeMax {
+ return InvalidMessageError("invalid message type")
+ }
+ for k, v := range msg.Headers {
+ if k == 0 || k >= fieldMax {
+ return InvalidMessageError("invalid header")
+ }
+ if reflect.TypeOf(v.value) != fieldTypes[k] {
+ return InvalidMessageError("invalid type of header field")
+ }
+ }
+ for _, v := range requiredFields[msg.Type] {
+ if _, ok := msg.Headers[v]; !ok {
+ return InvalidMessageError("missing required header")
+ }
+ }
+ if path, ok := msg.Headers[FieldPath]; ok {
+ if !path.value.(ObjectPath).IsValid() {
+ return InvalidMessageError("invalid path name")
+ }
+ }
+ if iface, ok := msg.Headers[FieldInterface]; ok {
+ if !isValidInterface(iface.value.(string)) {
+ return InvalidMessageError("invalid interface name")
+ }
+ }
+ if member, ok := msg.Headers[FieldMember]; ok {
+ if !isValidMember(member.value.(string)) {
+ return InvalidMessageError("invalid member name")
+ }
+ }
+ if errname, ok := msg.Headers[FieldErrorName]; ok {
+ if !isValidInterface(errname.value.(string)) {
+ return InvalidMessageError("invalid error name")
+ }
+ }
+ if len(msg.Body) != 0 {
+ if _, ok := msg.Headers[FieldSignature]; !ok {
+ return InvalidMessageError("missing signature")
+ }
+ }
+
+ return nil
+}
+
+// Serial returns the message's serial number. The returned value is only valid
+// for messages received by eavesdropping.
+func (msg *Message) Serial() uint32 {
+ return msg.serial
+}
+
+// String returns a string representation of a message similar to the format of
+// dbus-monitor.
+func (msg *Message) String() string {
+ if err := msg.IsValid(); err != nil {
+ return ""
+ }
+ s := msg.Type.String()
+ if v, ok := msg.Headers[FieldSender]; ok {
+ s += " from " + v.value.(string)
+ }
+ if v, ok := msg.Headers[FieldDestination]; ok {
+ s += " to " + v.value.(string)
+ }
+ s += " serial " + strconv.FormatUint(uint64(msg.serial), 10)
+ if v, ok := msg.Headers[FieldReplySerial]; ok {
+ s += " reply_serial " + strconv.FormatUint(uint64(v.value.(uint32)), 10)
+ }
+ if v, ok := msg.Headers[FieldUnixFDs]; ok {
+ s += " unixfds " + strconv.FormatUint(uint64(v.value.(uint32)), 10)
+ }
+ if v, ok := msg.Headers[FieldPath]; ok {
+ s += " path " + string(v.value.(ObjectPath))
+ }
+ if v, ok := msg.Headers[FieldInterface]; ok {
+ s += " interface " + v.value.(string)
+ }
+ if v, ok := msg.Headers[FieldErrorName]; ok {
+ s += " error " + v.value.(string)
+ }
+ if v, ok := msg.Headers[FieldMember]; ok {
+ s += " member " + v.value.(string)
+ }
+ if len(msg.Body) != 0 {
+ s += "\n"
+ }
+ for i, v := range msg.Body {
+ s += " " + MakeVariant(v).String()
+ if i != len(msg.Body)-1 {
+ s += "\n"
+ }
+ }
+ return s
+}
diff --git a/vendor/github.com/godbus/dbus/v5/object.go b/vendor/github.com/godbus/dbus/v5/object.go
new file mode 100644
index 000000000..664abb7fb
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/object.go
@@ -0,0 +1,174 @@
+package dbus
+
+import (
+ "context"
+ "errors"
+ "strings"
+)
+
+// BusObject is the interface of a remote object on which methods can be
+// invoked.
+type BusObject interface {
+ Call(method string, flags Flags, args ...interface{}) *Call
+ CallWithContext(ctx context.Context, method string, flags Flags, args ...interface{}) *Call
+ Go(method string, flags Flags, ch chan *Call, args ...interface{}) *Call
+ GoWithContext(ctx context.Context, method string, flags Flags, ch chan *Call, args ...interface{}) *Call
+ AddMatchSignal(iface, member string, options ...MatchOption) *Call
+ RemoveMatchSignal(iface, member string, options ...MatchOption) *Call
+ GetProperty(p string) (Variant, error)
+ StoreProperty(p string, value interface{}) error
+ SetProperty(p string, v interface{}) error
+ Destination() string
+ Path() ObjectPath
+}
+
+// Object represents a remote object on which methods can be invoked.
+type Object struct {
+ conn *Conn
+ dest string
+ path ObjectPath
+}
+
+// Call calls a method with (*Object).Go and waits for its reply.
+func (o *Object) Call(method string, flags Flags, args ...interface{}) *Call {
+ return <-o.createCall(context.Background(), method, flags, make(chan *Call, 1), args...).Done
+}
+
+// CallWithContext acts like Call but takes a context
+func (o *Object) CallWithContext(ctx context.Context, method string, flags Flags, args ...interface{}) *Call {
+ return <-o.createCall(ctx, method, flags, make(chan *Call, 1), args...).Done
+}
+
+// AddMatchSignal subscribes BusObject to signals from specified interface,
+// method (member). Additional filter rules can be added via WithMatch* option constructors.
+// Note: To filter events by object path you have to specify this path via an option.
+//
+// Deprecated: use (*Conn) AddMatchSignal instead.
+func (o *Object) AddMatchSignal(iface, member string, options ...MatchOption) *Call {
+ base := []MatchOption{
+ withMatchType("signal"),
+ WithMatchInterface(iface),
+ WithMatchMember(member),
+ }
+
+ options = append(base, options...)
+ return o.conn.BusObject().Call(
+ "org.freedesktop.DBus.AddMatch",
+ 0,
+ formatMatchOptions(options),
+ )
+}
+
+// RemoveMatchSignal unsubscribes BusObject from signals from specified interface,
+// method (member). Additional filter rules can be added via WithMatch* option constructors
+//
+// Deprecated: use (*Conn) RemoveMatchSignal instead.
+func (o *Object) RemoveMatchSignal(iface, member string, options ...MatchOption) *Call {
+ base := []MatchOption{
+ withMatchType("signal"),
+ WithMatchInterface(iface),
+ WithMatchMember(member),
+ }
+
+ options = append(base, options...)
+ return o.conn.BusObject().Call(
+ "org.freedesktop.DBus.RemoveMatch",
+ 0,
+ formatMatchOptions(options),
+ )
+}
+
+// Go calls a method with the given arguments asynchronously. It returns a
+// Call structure representing this method call. The passed channel will
+// return the same value once the call is done. If ch is nil, a new channel
+// will be allocated. Otherwise, ch has to be buffered or Go will panic.
+//
+// If the flags include FlagNoReplyExpected, ch is ignored and a Call structure
+// is returned with any error in Err and a closed channel in Done containing
+// the returned Call as it's one entry.
+//
+// If the method parameter contains a dot ('.'), the part before the last dot
+// specifies the interface on which the method is called.
+func (o *Object) Go(method string, flags Flags, ch chan *Call, args ...interface{}) *Call {
+ return o.createCall(context.Background(), method, flags, ch, args...)
+}
+
+// GoWithContext acts like Go but takes a context
+func (o *Object) GoWithContext(ctx context.Context, method string, flags Flags, ch chan *Call, args ...interface{}) *Call {
+ return o.createCall(ctx, method, flags, ch, args...)
+}
+
+func (o *Object) createCall(ctx context.Context, method string, flags Flags, ch chan *Call, args ...interface{}) *Call {
+ if ctx == nil {
+ panic("nil context")
+ }
+ iface := ""
+ i := strings.LastIndex(method, ".")
+ if i != -1 {
+ iface = method[:i]
+ }
+ method = method[i+1:]
+ msg := new(Message)
+ msg.Type = TypeMethodCall
+ msg.Flags = flags & (FlagNoAutoStart | FlagNoReplyExpected)
+ msg.Headers = make(map[HeaderField]Variant)
+ msg.Headers[FieldPath] = MakeVariant(o.path)
+ msg.Headers[FieldDestination] = MakeVariant(o.dest)
+ msg.Headers[FieldMember] = MakeVariant(method)
+ if iface != "" {
+ msg.Headers[FieldInterface] = MakeVariant(iface)
+ }
+ msg.Body = args
+ if len(args) > 0 {
+ msg.Headers[FieldSignature] = MakeVariant(SignatureOf(args...))
+ }
+ return o.conn.SendWithContext(ctx, msg, ch)
+}
+
+// GetProperty calls org.freedesktop.DBus.Properties.Get on the given
+// object. The property name must be given in interface.member notation.
+func (o *Object) GetProperty(p string) (Variant, error) {
+ var result Variant
+ err := o.StoreProperty(p, &result)
+ return result, err
+}
+
+// StoreProperty calls org.freedesktop.DBus.Properties.Get on the given
+// object. The property name must be given in interface.member notation.
+// It stores the returned property into the provided value.
+func (o *Object) StoreProperty(p string, value interface{}) error {
+ idx := strings.LastIndex(p, ".")
+ if idx == -1 || idx+1 == len(p) {
+ return errors.New("dbus: invalid property " + p)
+ }
+
+ iface := p[:idx]
+ prop := p[idx+1:]
+
+ return o.Call("org.freedesktop.DBus.Properties.Get", 0, iface, prop).
+ Store(value)
+}
+
+// SetProperty calls org.freedesktop.DBus.Properties.Set on the given
+// object. The property name must be given in interface.member notation.
+func (o *Object) SetProperty(p string, v interface{}) error {
+ idx := strings.LastIndex(p, ".")
+ if idx == -1 || idx+1 == len(p) {
+ return errors.New("dbus: invalid property " + p)
+ }
+
+ iface := p[:idx]
+ prop := p[idx+1:]
+
+ return o.Call("org.freedesktop.DBus.Properties.Set", 0, iface, prop, v).Err
+}
+
+// Destination returns the destination that calls on (o *Object) are sent to.
+func (o *Object) Destination() string {
+ return o.dest
+}
+
+// Path returns the path that calls on (o *Object") are sent to.
+func (o *Object) Path() ObjectPath {
+ return o.path
+}
diff --git a/vendor/github.com/godbus/dbus/v5/sequence.go b/vendor/github.com/godbus/dbus/v5/sequence.go
new file mode 100644
index 000000000..89435d393
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/sequence.go
@@ -0,0 +1,24 @@
+package dbus
+
+// Sequence represents the value of a monotonically increasing counter.
+type Sequence uint64
+
+const (
+ // NoSequence indicates the absence of a sequence value.
+ NoSequence Sequence = 0
+)
+
+// sequenceGenerator represents a monotonically increasing counter.
+type sequenceGenerator struct {
+ nextSequence Sequence
+}
+
+func (generator *sequenceGenerator) next() Sequence {
+ result := generator.nextSequence
+ generator.nextSequence++
+ return result
+}
+
+func newSequenceGenerator() *sequenceGenerator {
+ return &sequenceGenerator{nextSequence: 1}
+}
diff --git a/vendor/github.com/godbus/dbus/v5/sequential_handler.go b/vendor/github.com/godbus/dbus/v5/sequential_handler.go
new file mode 100644
index 000000000..ef2fcdba1
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/sequential_handler.go
@@ -0,0 +1,125 @@
+package dbus
+
+import (
+ "sync"
+)
+
+// NewSequentialSignalHandler returns an instance of a new
+// signal handler that guarantees sequential processing of signals. It is a
+// guarantee of this signal handler that signals will be written to
+// channels in the order they are received on the DBus connection.
+func NewSequentialSignalHandler() SignalHandler {
+ return &sequentialSignalHandler{}
+}
+
+type sequentialSignalHandler struct {
+ mu sync.RWMutex
+ closed bool
+ signals []*sequentialSignalChannelData
+}
+
+func (sh *sequentialSignalHandler) DeliverSignal(intf, name string, signal *Signal) {
+ sh.mu.RLock()
+ defer sh.mu.RUnlock()
+ if sh.closed {
+ return
+ }
+ for _, scd := range sh.signals {
+ scd.deliver(signal)
+ }
+}
+
+func (sh *sequentialSignalHandler) Terminate() {
+ sh.mu.Lock()
+ defer sh.mu.Unlock()
+ if sh.closed {
+ return
+ }
+
+ for _, scd := range sh.signals {
+ scd.close()
+ close(scd.ch)
+ }
+ sh.closed = true
+ sh.signals = nil
+}
+
+func (sh *sequentialSignalHandler) AddSignal(ch chan<- *Signal) {
+ sh.mu.Lock()
+ defer sh.mu.Unlock()
+ if sh.closed {
+ return
+ }
+ sh.signals = append(sh.signals, newSequentialSignalChannelData(ch))
+}
+
+func (sh *sequentialSignalHandler) RemoveSignal(ch chan<- *Signal) {
+ sh.mu.Lock()
+ defer sh.mu.Unlock()
+ if sh.closed {
+ return
+ }
+ for i := len(sh.signals) - 1; i >= 0; i-- {
+ if ch == sh.signals[i].ch {
+ sh.signals[i].close()
+ copy(sh.signals[i:], sh.signals[i+1:])
+ sh.signals[len(sh.signals)-1] = nil
+ sh.signals = sh.signals[:len(sh.signals)-1]
+ }
+ }
+}
+
+type sequentialSignalChannelData struct {
+ ch chan<- *Signal
+ in chan *Signal
+ done chan struct{}
+}
+
+func newSequentialSignalChannelData(ch chan<- *Signal) *sequentialSignalChannelData {
+ scd := &sequentialSignalChannelData{
+ ch: ch,
+ in: make(chan *Signal),
+ done: make(chan struct{}),
+ }
+ go scd.bufferSignals()
+ return scd
+}
+
+func (scd *sequentialSignalChannelData) bufferSignals() {
+ defer close(scd.done)
+
+ // Ensure that signals are delivered to scd.ch in the same
+ // order they are received from scd.in.
+ var queue []*Signal
+ for {
+ if len(queue) == 0 {
+ signal, ok := <- scd.in
+ if !ok {
+ return
+ }
+ queue = append(queue, signal)
+ }
+ select {
+ case scd.ch <- queue[0]:
+ copy(queue, queue[1:])
+ queue[len(queue)-1] = nil
+ queue = queue[:len(queue)-1]
+ case signal, ok := <-scd.in:
+ if !ok {
+ return
+ }
+ queue = append(queue, signal)
+ }
+ }
+}
+
+func (scd *sequentialSignalChannelData) deliver(signal *Signal) {
+ scd.in <- signal
+}
+
+func (scd *sequentialSignalChannelData) close() {
+ close(scd.in)
+ // Ensure that bufferSignals() has exited and won't attempt
+ // any future sends on scd.ch
+ <-scd.done
+}
diff --git a/vendor/github.com/godbus/dbus/v5/server_interfaces.go b/vendor/github.com/godbus/dbus/v5/server_interfaces.go
new file mode 100644
index 000000000..e4e0389fd
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/server_interfaces.go
@@ -0,0 +1,107 @@
+package dbus
+
+// Terminator allows a handler to implement a shutdown mechanism that
+// is called when the connection terminates.
+type Terminator interface {
+ Terminate()
+}
+
+// Handler is the representation of a D-Bus Application.
+//
+// The Handler must have a way to lookup objects given
+// an ObjectPath. The returned object must implement the
+// ServerObject interface.
+type Handler interface {
+ LookupObject(path ObjectPath) (ServerObject, bool)
+}
+
+// ServerObject is the representation of an D-Bus Object.
+//
+// Objects are registered at a path for a given Handler.
+// The Objects implement D-Bus interfaces. The semantics
+// of Interface lookup is up to the implementation of
+// the ServerObject. The ServerObject implementation may
+// choose to implement empty string as a valid interface
+// represeting all methods or not per the D-Bus specification.
+type ServerObject interface {
+ LookupInterface(name string) (Interface, bool)
+}
+
+// An Interface is the representation of a D-Bus Interface.
+//
+// Interfaces are a grouping of methods implemented by the Objects.
+// Interfaces are responsible for routing method calls.
+type Interface interface {
+ LookupMethod(name string) (Method, bool)
+}
+
+// A Method represents the exposed methods on D-Bus.
+type Method interface {
+ // Call requires that all arguments are decoded before being passed to it.
+ Call(args ...interface{}) ([]interface{}, error)
+ NumArguments() int
+ NumReturns() int
+ // ArgumentValue returns a representative value for the argument at position
+ // it should be of the proper type. reflect.Zero would be a good mechanism
+ // to use for this Value.
+ ArgumentValue(position int) interface{}
+ // ReturnValue returns a representative value for the return at position
+ // it should be of the proper type. reflect.Zero would be a good mechanism
+ // to use for this Value.
+ ReturnValue(position int) interface{}
+}
+
+// An Argument Decoder can decode arguments using the non-standard mechanism
+//
+// If a method implements this interface then the non-standard
+// decoder will be used.
+//
+// Method arguments must be decoded from the message.
+// The mechanism for doing this will vary based on the
+// implementation of the method. A normal approach is provided
+// as part of this library, but may be replaced with
+// any other decoding scheme.
+type ArgumentDecoder interface {
+ // To decode the arguments of a method the sender and message are
+ // provided in case the semantics of the implementer provides access
+ // to these as part of the method invocation.
+ DecodeArguments(conn *Conn, sender string, msg *Message, args []interface{}) ([]interface{}, error)
+}
+
+// A SignalHandler is responsible for delivering a signal.
+//
+// Signal delivery may be changed from the default channel
+// based approach by Handlers implementing the SignalHandler
+// interface.
+type SignalHandler interface {
+ DeliverSignal(iface, name string, signal *Signal)
+}
+
+// SignalRegistrar manages signal delivery channels.
+//
+// This is an optional set of methods for `SignalHandler`.
+type SignalRegistrar interface {
+ AddSignal(ch chan<- *Signal)
+ RemoveSignal(ch chan<- *Signal)
+}
+
+// A DBusError is used to convert a generic object to a D-Bus error.
+//
+// Any custom error mechanism may implement this interface to provide
+// a custom encoding of the error on D-Bus. By default if a normal
+// error is returned, it will be encoded as the generic
+// "org.freedesktop.DBus.Error.Failed" error. By implementing this
+// interface as well a custom encoding may be provided.
+type DBusError interface {
+ DBusError() (string, []interface{})
+}
+
+// SerialGenerator is responsible for serials generation.
+//
+// Different approaches for the serial generation can be used,
+// maintaining a map guarded with a mutex (the standard way) or
+// simply increment an atomic counter.
+type SerialGenerator interface {
+ GetSerial() uint32
+ RetireSerial(serial uint32)
+}
diff --git a/vendor/github.com/godbus/dbus/v5/sig.go b/vendor/github.com/godbus/dbus/v5/sig.go
new file mode 100644
index 000000000..6b9cadb5f
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/sig.go
@@ -0,0 +1,293 @@
+package dbus
+
+import (
+ "fmt"
+ "reflect"
+ "strings"
+)
+
+var sigToType = map[byte]reflect.Type{
+ 'y': byteType,
+ 'b': boolType,
+ 'n': int16Type,
+ 'q': uint16Type,
+ 'i': int32Type,
+ 'u': uint32Type,
+ 'x': int64Type,
+ 't': uint64Type,
+ 'd': float64Type,
+ 's': stringType,
+ 'g': signatureType,
+ 'o': objectPathType,
+ 'v': variantType,
+ 'h': unixFDIndexType,
+}
+
+// Signature represents a correct type signature as specified by the D-Bus
+// specification. The zero value represents the empty signature, "".
+type Signature struct {
+ str string
+}
+
+// SignatureOf returns the concatenation of all the signatures of the given
+// values. It panics if one of them is not representable in D-Bus.
+func SignatureOf(vs ...interface{}) Signature {
+ var s string
+ for _, v := range vs {
+ s += getSignature(reflect.TypeOf(v), &depthCounter{})
+ }
+ return Signature{s}
+}
+
+// SignatureOfType returns the signature of the given type. It panics if the
+// type is not representable in D-Bus.
+func SignatureOfType(t reflect.Type) Signature {
+ return Signature{getSignature(t, &depthCounter{})}
+}
+
+// getSignature returns the signature of the given type and panics on unknown types.
+func getSignature(t reflect.Type, depth *depthCounter) (sig string) {
+ if !depth.Valid() {
+ panic("container nesting too deep")
+ }
+ defer func() {
+ if len(sig) > 255 {
+ panic("signature exceeds the length limitation")
+ }
+ }()
+ // handle simple types first
+ switch t.Kind() {
+ case reflect.Uint8:
+ return "y"
+ case reflect.Bool:
+ return "b"
+ case reflect.Int16:
+ return "n"
+ case reflect.Uint16:
+ return "q"
+ case reflect.Int, reflect.Int32:
+ if t == unixFDType {
+ return "h"
+ }
+ return "i"
+ case reflect.Uint, reflect.Uint32:
+ if t == unixFDIndexType {
+ return "h"
+ }
+ return "u"
+ case reflect.Int64:
+ return "x"
+ case reflect.Uint64:
+ return "t"
+ case reflect.Float64:
+ return "d"
+ case reflect.Ptr:
+ return getSignature(t.Elem(), depth)
+ case reflect.String:
+ if t == objectPathType {
+ return "o"
+ }
+ return "s"
+ case reflect.Struct:
+ if t == variantType {
+ return "v"
+ } else if t == signatureType {
+ return "g"
+ }
+ var s string
+ for i := 0; i < t.NumField(); i++ {
+ field := t.Field(i)
+ if field.PkgPath == "" && field.Tag.Get("dbus") != "-" {
+ s += getSignature(t.Field(i).Type, depth.EnterStruct())
+ }
+ }
+ if len(s) == 0 {
+ panic(InvalidTypeError{t})
+ }
+ return "(" + s + ")"
+ case reflect.Array, reflect.Slice:
+ return "a" + getSignature(t.Elem(), depth.EnterArray())
+ case reflect.Map:
+ if !isKeyType(t.Key()) {
+ panic(InvalidTypeError{t})
+ }
+ return "a{" + getSignature(t.Key(), depth.EnterArray().EnterDictEntry()) + getSignature(t.Elem(), depth.EnterArray().EnterDictEntry()) + "}"
+ case reflect.Interface:
+ return "v"
+ }
+ panic(InvalidTypeError{t})
+}
+
+// ParseSignature returns the signature represented by this string, or a
+// SignatureError if the string is not a valid signature.
+func ParseSignature(s string) (sig Signature, err error) {
+ if len(s) == 0 {
+ return
+ }
+ if len(s) > 255 {
+ return Signature{""}, SignatureError{s, "too long"}
+ }
+ sig.str = s
+ for err == nil && len(s) != 0 {
+ err, s = validSingle(s, &depthCounter{})
+ }
+ if err != nil {
+ sig = Signature{""}
+ }
+
+ return
+}
+
+// ParseSignatureMust behaves like ParseSignature, except that it panics if s
+// is not valid.
+func ParseSignatureMust(s string) Signature {
+ sig, err := ParseSignature(s)
+ if err != nil {
+ panic(err)
+ }
+ return sig
+}
+
+// Empty returns whether the signature is the empty signature.
+func (s Signature) Empty() bool {
+ return s.str == ""
+}
+
+// Single returns whether the signature represents a single, complete type.
+func (s Signature) Single() bool {
+ err, r := validSingle(s.str, &depthCounter{})
+ return err != nil && r == ""
+}
+
+// String returns the signature's string representation.
+func (s Signature) String() string {
+ return s.str
+}
+
+// A SignatureError indicates that a signature passed to a function or received
+// on a connection is not a valid signature.
+type SignatureError struct {
+ Sig string
+ Reason string
+}
+
+func (e SignatureError) Error() string {
+ return fmt.Sprintf("dbus: invalid signature: %q (%s)", e.Sig, e.Reason)
+}
+
+type depthCounter struct {
+ arrayDepth, structDepth, dictEntryDepth int
+}
+
+func (cnt *depthCounter) Valid() bool {
+ return cnt.arrayDepth <= 32 && cnt.structDepth <= 32 && cnt.dictEntryDepth <= 32
+}
+
+func (cnt depthCounter) EnterArray() *depthCounter {
+ cnt.arrayDepth++
+ return &cnt
+}
+
+func (cnt depthCounter) EnterStruct() *depthCounter {
+ cnt.structDepth++
+ return &cnt
+}
+
+func (cnt depthCounter) EnterDictEntry() *depthCounter {
+ cnt.dictEntryDepth++
+ return &cnt
+}
+
+// Try to read a single type from this string. If it was successful, err is nil
+// and rem is the remaining unparsed part. Otherwise, err is a non-nil
+// SignatureError and rem is "". depth is the current recursion depth which may
+// not be greater than 64 and should be given as 0 on the first call.
+func validSingle(s string, depth *depthCounter) (err error, rem string) {
+ if s == "" {
+ return SignatureError{Sig: s, Reason: "empty signature"}, ""
+ }
+ if !depth.Valid() {
+ return SignatureError{Sig: s, Reason: "container nesting too deep"}, ""
+ }
+ switch s[0] {
+ case 'y', 'b', 'n', 'q', 'i', 'u', 'x', 't', 'd', 's', 'g', 'o', 'v', 'h':
+ return nil, s[1:]
+ case 'a':
+ if len(s) > 1 && s[1] == '{' {
+ i := findMatching(s[1:], '{', '}')
+ if i == -1 {
+ return SignatureError{Sig: s, Reason: "unmatched '{'"}, ""
+ }
+ i++
+ rem = s[i+1:]
+ s = s[2:i]
+ if err, _ = validSingle(s[:1], depth.EnterArray().EnterDictEntry()); err != nil {
+ return err, ""
+ }
+ err, nr := validSingle(s[1:], depth.EnterArray().EnterDictEntry())
+ if err != nil {
+ return err, ""
+ }
+ if nr != "" {
+ return SignatureError{Sig: s, Reason: "too many types in dict"}, ""
+ }
+ return nil, rem
+ }
+ return validSingle(s[1:], depth.EnterArray())
+ case '(':
+ i := findMatching(s, '(', ')')
+ if i == -1 {
+ return SignatureError{Sig: s, Reason: "unmatched ')'"}, ""
+ }
+ rem = s[i+1:]
+ s = s[1:i]
+ for err == nil && s != "" {
+ err, s = validSingle(s, depth.EnterStruct())
+ }
+ if err != nil {
+ rem = ""
+ }
+ return
+ }
+ return SignatureError{Sig: s, Reason: "invalid type character"}, ""
+}
+
+func findMatching(s string, left, right rune) int {
+ n := 0
+ for i, v := range s {
+ if v == left {
+ n++
+ } else if v == right {
+ n--
+ }
+ if n == 0 {
+ return i
+ }
+ }
+ return -1
+}
+
+// typeFor returns the type of the given signature. It ignores any left over
+// characters and panics if s doesn't start with a valid type signature.
+func typeFor(s string) (t reflect.Type) {
+ err, _ := validSingle(s, &depthCounter{})
+ if err != nil {
+ panic(err)
+ }
+
+ if t, ok := sigToType[s[0]]; ok {
+ return t
+ }
+ switch s[0] {
+ case 'a':
+ if s[1] == '{' {
+ i := strings.LastIndex(s, "}")
+ t = reflect.MapOf(sigToType[s[2]], typeFor(s[3:i]))
+ } else {
+ t = reflect.SliceOf(typeFor(s[1:]))
+ }
+ case '(':
+ t = interfacesType
+ }
+ return
+}
diff --git a/vendor/github.com/godbus/dbus/v5/transport_darwin.go b/vendor/github.com/godbus/dbus/v5/transport_darwin.go
new file mode 100644
index 000000000..1bba0d6bf
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/transport_darwin.go
@@ -0,0 +1,6 @@
+package dbus
+
+func (t *unixTransport) SendNullByte() error {
+ _, err := t.Write([]byte{0})
+ return err
+}
diff --git a/vendor/github.com/godbus/dbus/v5/transport_generic.go b/vendor/github.com/godbus/dbus/v5/transport_generic.go
new file mode 100644
index 000000000..a08e2813c
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/transport_generic.go
@@ -0,0 +1,52 @@
+package dbus
+
+import (
+ "encoding/binary"
+ "errors"
+ "io"
+ "unsafe"
+)
+
+var nativeEndian binary.ByteOrder
+
+func detectEndianness() binary.ByteOrder {
+ var x uint32 = 0x01020304
+ if *(*byte)(unsafe.Pointer(&x)) == 0x01 {
+ return binary.BigEndian
+ }
+ return binary.LittleEndian
+}
+
+func init() {
+ nativeEndian = detectEndianness()
+}
+
+type genericTransport struct {
+ io.ReadWriteCloser
+}
+
+func (t genericTransport) SendNullByte() error {
+ _, err := t.Write([]byte{0})
+ return err
+}
+
+func (t genericTransport) SupportsUnixFDs() bool {
+ return false
+}
+
+func (t genericTransport) EnableUnixFDs() {}
+
+func (t genericTransport) ReadMessage() (*Message, error) {
+ return DecodeMessage(t)
+}
+
+func (t genericTransport) SendMessage(msg *Message) error {
+ fds, err := msg.CountFds()
+ if err != nil {
+ return err
+ }
+ if fds != 0 {
+ return errors.New("dbus: unix fd passing not enabled")
+ }
+ return msg.EncodeTo(t, nativeEndian)
+}
diff --git a/vendor/github.com/godbus/dbus/v5/transport_nonce_tcp.go b/vendor/github.com/godbus/dbus/v5/transport_nonce_tcp.go
new file mode 100644
index 000000000..697739efa
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/transport_nonce_tcp.go
@@ -0,0 +1,39 @@
+//+build !windows
+
+package dbus
+
+import (
+ "errors"
+ "io/ioutil"
+ "net"
+)
+
+func init() {
+ transports["nonce-tcp"] = newNonceTcpTransport
+}
+
+func newNonceTcpTransport(keys string) (transport, error) {
+ host := getKey(keys, "host")
+ port := getKey(keys, "port")
+ noncefile := getKey(keys, "noncefile")
+ if host == "" || port == "" || noncefile == "" {
+ return nil, errors.New("dbus: unsupported address (must set host, port and noncefile)")
+ }
+ protocol, err := tcpFamily(keys)
+ if err != nil {
+ return nil, err
+ }
+ socket, err := net.Dial(protocol, net.JoinHostPort(host, port))
+ if err != nil {
+ return nil, err
+ }
+ b, err := ioutil.ReadFile(noncefile)
+ if err != nil {
+ return nil, err
+ }
+ _, err = socket.Write(b)
+ if err != nil {
+ return nil, err
+ }
+ return NewConn(socket)
+}
diff --git a/vendor/github.com/godbus/dbus/v5/transport_tcp.go b/vendor/github.com/godbus/dbus/v5/transport_tcp.go
new file mode 100644
index 000000000..f91c9b7d7
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/transport_tcp.go
@@ -0,0 +1,41 @@
+package dbus
+
+import (
+ "errors"
+ "net"
+)
+
+func init() {
+ transports["tcp"] = newTcpTransport
+}
+
+func tcpFamily(keys string) (string, error) {
+ switch getKey(keys, "family") {
+ case "":
+ return "tcp", nil
+ case "ipv4":
+ return "tcp4", nil
+ case "ipv6":
+ return "tcp6", nil
+ default:
+ return "", errors.New("dbus: invalid tcp family (must be ipv4 or ipv6)")
+ }
+}
+
+func newTcpTransport(keys string) (transport, error) {
+ host := getKey(keys, "host")
+ port := getKey(keys, "port")
+ if host == "" || port == "" {
+ return nil, errors.New("dbus: unsupported address (must set host and port)")
+ }
+
+ protocol, err := tcpFamily(keys)
+ if err != nil {
+ return nil, err
+ }
+ socket, err := net.Dial(protocol, net.JoinHostPort(host, port))
+ if err != nil {
+ return nil, err
+ }
+ return NewConn(socket)
+}
diff --git a/vendor/github.com/godbus/dbus/v5/transport_unix.go b/vendor/github.com/godbus/dbus/v5/transport_unix.go
new file mode 100644
index 000000000..0a8c712eb
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/transport_unix.go
@@ -0,0 +1,212 @@
+//+build !windows,!solaris
+
+package dbus
+
+import (
+ "bytes"
+ "encoding/binary"
+ "errors"
+ "io"
+ "net"
+ "syscall"
+)
+
+type oobReader struct {
+ conn *net.UnixConn
+ oob []byte
+ buf [4096]byte
+}
+
+func (o *oobReader) Read(b []byte) (n int, err error) {
+ n, oobn, flags, _, err := o.conn.ReadMsgUnix(b, o.buf[:])
+ if err != nil {
+ return n, err
+ }
+ if flags&syscall.MSG_CTRUNC != 0 {
+ return n, errors.New("dbus: control data truncated (too many fds received)")
+ }
+ o.oob = append(o.oob, o.buf[:oobn]...)
+ return n, nil
+}
+
+type unixTransport struct {
+ *net.UnixConn
+ rdr *oobReader
+ hasUnixFDs bool
+}
+
+func newUnixTransport(keys string) (transport, error) {
+ var err error
+
+ t := new(unixTransport)
+ abstract := getKey(keys, "abstract")
+ path := getKey(keys, "path")
+ switch {
+ case abstract == "" && path == "":
+ return nil, errors.New("dbus: invalid address (neither path nor abstract set)")
+ case abstract != "" && path == "":
+ t.UnixConn, err = net.DialUnix("unix", nil, &net.UnixAddr{Name: "@" + abstract, Net: "unix"})
+ if err != nil {
+ return nil, err
+ }
+ return t, nil
+ case abstract == "" && path != "":
+ t.UnixConn, err = net.DialUnix("unix", nil, &net.UnixAddr{Name: path, Net: "unix"})
+ if err != nil {
+ return nil, err
+ }
+ return t, nil
+ default:
+ return nil, errors.New("dbus: invalid address (both path and abstract set)")
+ }
+}
+
+func init() {
+ transports["unix"] = newUnixTransport
+}
+
+func (t *unixTransport) EnableUnixFDs() {
+ t.hasUnixFDs = true
+}
+
+func (t *unixTransport) ReadMessage() (*Message, error) {
+ var (
+ blen, hlen uint32
+ csheader [16]byte
+ headers []header
+ order binary.ByteOrder
+ unixfds uint32
+ )
+ // To be sure that all bytes of out-of-band data are read, we use a special
+ // reader that uses ReadUnix on the underlying connection instead of Read
+ // and gathers the out-of-band data in a buffer.
+ if t.rdr == nil {
+ t.rdr = &oobReader{conn: t.UnixConn}
+ } else {
+ t.rdr.oob = nil
+ }
+
+ // read the first 16 bytes (the part of the header that has a constant size),
+ // from which we can figure out the length of the rest of the message
+ if _, err := io.ReadFull(t.rdr, csheader[:]); err != nil {
+ return nil, err
+ }
+ switch csheader[0] {
+ case 'l':
+ order = binary.LittleEndian
+ case 'B':
+ order = binary.BigEndian
+ default:
+ return nil, InvalidMessageError("invalid byte order")
+ }
+ // csheader[4:8] -> length of message body, csheader[12:16] -> length of
+ // header fields (without alignment)
+ binary.Read(bytes.NewBuffer(csheader[4:8]), order, &blen)
+ binary.Read(bytes.NewBuffer(csheader[12:]), order, &hlen)
+ if hlen%8 != 0 {
+ hlen += 8 - (hlen % 8)
+ }
+
+ // decode headers and look for unix fds
+ headerdata := make([]byte, hlen+4)
+ copy(headerdata, csheader[12:])
+ if _, err := io.ReadFull(t.rdr, headerdata[4:]); err != nil {
+ return nil, err
+ }
+ dec := newDecoder(bytes.NewBuffer(headerdata), order, make([]int, 0))
+ dec.pos = 12
+ vs, err := dec.Decode(Signature{"a(yv)"})
+ if err != nil {
+ return nil, err
+ }
+ Store(vs, &headers)
+ for _, v := range headers {
+ if v.Field == byte(FieldUnixFDs) {
+ unixfds, _ = v.Variant.value.(uint32)
+ }
+ }
+ all := make([]byte, 16+hlen+blen)
+ copy(all, csheader[:])
+ copy(all[16:], headerdata[4:])
+ if _, err := io.ReadFull(t.rdr, all[16+hlen:]); err != nil {
+ return nil, err
+ }
+ if unixfds != 0 {
+ if !t.hasUnixFDs {
+ return nil, errors.New("dbus: got unix fds on unsupported transport")
+ }
+ // read the fds from the OOB data
+ scms, err := syscall.ParseSocketControlMessage(t.rdr.oob)
+ if err != nil {
+ return nil, err
+ }
+ if len(scms) != 1 {
+ return nil, errors.New("dbus: received more than one socket control message")
+ }
+ fds, err := syscall.ParseUnixRights(&scms[0])
+ if err != nil {
+ return nil, err
+ }
+ msg, err := DecodeMessageWithFDs(bytes.NewBuffer(all), fds)
+ if err != nil {
+ return nil, err
+ }
+ // substitute the values in the message body (which are indices for the
+ // array receiver via OOB) with the actual values
+ for i, v := range msg.Body {
+ switch index := v.(type) {
+ case UnixFDIndex:
+ if uint32(index) >= unixfds {
+ return nil, InvalidMessageError("invalid index for unix fd")
+ }
+ msg.Body[i] = UnixFD(fds[index])
+ case []UnixFDIndex:
+ fdArray := make([]UnixFD, len(index))
+ for k, j := range index {
+ if uint32(j) >= unixfds {
+ return nil, InvalidMessageError("invalid index for unix fd")
+ }
+ fdArray[k] = UnixFD(fds[j])
+ }
+ msg.Body[i] = fdArray
+ }
+ }
+ return msg, nil
+ }
+ return DecodeMessage(bytes.NewBuffer(all))
+}
+
+func (t *unixTransport) SendMessage(msg *Message) error {
+ fdcnt, err := msg.CountFds()
+ if err != nil {
+ return err
+ }
+ if fdcnt != 0 {
+ if !t.hasUnixFDs {
+ return errors.New("dbus: unix fd passing not enabled")
+ }
+ msg.Headers[FieldUnixFDs] = MakeVariant(uint32(fdcnt))
+ buf := new(bytes.Buffer)
+ fds, err := msg.EncodeToWithFDs(buf, nativeEndian)
+ if err != nil {
+ return err
+ }
+ oob := syscall.UnixRights(fds...)
+ n, oobn, err := t.UnixConn.WriteMsgUnix(buf.Bytes(), oob, nil)
+ if err != nil {
+ return err
+ }
+ if n != buf.Len() || oobn != len(oob) {
+ return io.ErrShortWrite
+ }
+ } else {
+ if err := msg.EncodeTo(t, nativeEndian); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (t *unixTransport) SupportsUnixFDs() bool {
+ return true
+}
diff --git a/vendor/github.com/godbus/dbus/v5/transport_unixcred_dragonfly.go b/vendor/github.com/godbus/dbus/v5/transport_unixcred_dragonfly.go
new file mode 100644
index 000000000..a8cd39395
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/transport_unixcred_dragonfly.go
@@ -0,0 +1,95 @@
+// The UnixCredentials system call is currently only implemented on Linux
+// http://golang.org/src/pkg/syscall/sockcmsg_linux.go
+// https://golang.org/s/go1.4-syscall
+// http://code.google.com/p/go/source/browse/unix/sockcmsg_linux.go?repo=sys
+
+// Local implementation of the UnixCredentials system call for DragonFly BSD
+
+package dbus
+
+/*
+#include
+*/
+import "C"
+
+import (
+ "io"
+ "os"
+ "syscall"
+ "unsafe"
+)
+
+// http://golang.org/src/pkg/syscall/ztypes_linux_amd64.go
+// http://golang.org/src/pkg/syscall/ztypes_dragonfly_amd64.go
+type Ucred struct {
+ Pid int32
+ Uid uint32
+ Gid uint32
+}
+
+// http://golang.org/src/pkg/syscall/types_linux.go
+// http://golang.org/src/pkg/syscall/types_dragonfly.go
+// https://github.com/DragonFlyBSD/DragonFlyBSD/blob/master/sys/sys/ucred.h
+const (
+ SizeofUcred = C.sizeof_struct_ucred
+)
+
+// http://golang.org/src/pkg/syscall/sockcmsg_unix.go
+func cmsgAlignOf(salen int) int {
+ // From http://golang.org/src/pkg/syscall/sockcmsg_unix.go
+ //salign := sizeofPtr
+ // NOTE: It seems like 64-bit Darwin and DragonFly BSD kernels
+ // still require 32-bit aligned access to network subsystem.
+ //if darwin64Bit || dragonfly64Bit {
+ // salign = 4
+ //}
+ salign := 4
+ return (salen + salign - 1) & ^(salign - 1)
+}
+
+// http://golang.org/src/pkg/syscall/sockcmsg_unix.go
+func cmsgData(h *syscall.Cmsghdr) unsafe.Pointer {
+ return unsafe.Pointer(uintptr(unsafe.Pointer(h)) + uintptr(cmsgAlignOf(syscall.SizeofCmsghdr)))
+}
+
+// http://golang.org/src/pkg/syscall/sockcmsg_linux.go
+// UnixCredentials encodes credentials into a socket control message
+// for sending to another process. This can be used for
+// authentication.
+func UnixCredentials(ucred *Ucred) []byte {
+ b := make([]byte, syscall.CmsgSpace(SizeofUcred))
+ h := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
+ h.Level = syscall.SOL_SOCKET
+ h.Type = syscall.SCM_CREDS
+ h.SetLen(syscall.CmsgLen(SizeofUcred))
+ *((*Ucred)(cmsgData(h))) = *ucred
+ return b
+}
+
+// http://golang.org/src/pkg/syscall/sockcmsg_linux.go
+// ParseUnixCredentials decodes a socket control message that contains
+// credentials in a Ucred structure. To receive such a message, the
+// SO_PASSCRED option must be enabled on the socket.
+func ParseUnixCredentials(m *syscall.SocketControlMessage) (*Ucred, error) {
+ if m.Header.Level != syscall.SOL_SOCKET {
+ return nil, syscall.EINVAL
+ }
+ if m.Header.Type != syscall.SCM_CREDS {
+ return nil, syscall.EINVAL
+ }
+ ucred := *(*Ucred)(unsafe.Pointer(&m.Data[0]))
+ return &ucred, nil
+}
+
+func (t *unixTransport) SendNullByte() error {
+ ucred := &Ucred{Pid: int32(os.Getpid()), Uid: uint32(os.Getuid()), Gid: uint32(os.Getgid())}
+ b := UnixCredentials(ucred)
+ _, oobn, err := t.UnixConn.WriteMsgUnix([]byte{0}, b, nil)
+ if err != nil {
+ return err
+ }
+ if oobn != len(b) {
+ return io.ErrShortWrite
+ }
+ return nil
+}
diff --git a/vendor/github.com/godbus/dbus/v5/transport_unixcred_freebsd.go b/vendor/github.com/godbus/dbus/v5/transport_unixcred_freebsd.go
new file mode 100644
index 000000000..1b5ed2089
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/transport_unixcred_freebsd.go
@@ -0,0 +1,92 @@
+// The UnixCredentials system call is currently only implemented on Linux
+// http://golang.org/src/pkg/syscall/sockcmsg_linux.go
+// https://golang.org/s/go1.4-syscall
+// http://code.google.com/p/go/source/browse/unix/sockcmsg_linux.go?repo=sys
+
+// Local implementation of the UnixCredentials system call for FreeBSD
+
+package dbus
+
+/*
+const int sizeofPtr = sizeof(void*);
+#define _WANT_UCRED
+#include
+#include
+*/
+import "C"
+
+import (
+ "io"
+ "os"
+ "syscall"
+ "unsafe"
+)
+
+// http://golang.org/src/pkg/syscall/ztypes_linux_amd64.go
+// https://golang.org/src/syscall/ztypes_freebsd_amd64.go
+type Ucred struct {
+ Pid int32
+ Uid uint32
+ Gid uint32
+}
+
+// http://golang.org/src/pkg/syscall/types_linux.go
+// https://golang.org/src/syscall/types_freebsd.go
+// https://github.com/freebsd/freebsd/blob/master/sys/sys/ucred.h
+const (
+ SizeofUcred = C.sizeof_struct_ucred
+)
+
+// http://golang.org/src/pkg/syscall/sockcmsg_unix.go
+func cmsgAlignOf(salen int) int {
+ salign := C.sizeofPtr
+
+ return (salen + salign - 1) & ^(salign - 1)
+}
+
+// http://golang.org/src/pkg/syscall/sockcmsg_unix.go
+func cmsgData(h *syscall.Cmsghdr) unsafe.Pointer {
+ return unsafe.Pointer(uintptr(unsafe.Pointer(h)) + uintptr(cmsgAlignOf(syscall.SizeofCmsghdr)))
+}
+
+// http://golang.org/src/pkg/syscall/sockcmsg_linux.go
+// UnixCredentials encodes credentials into a socket control message
+// for sending to another process. This can be used for
+// authentication.
+func UnixCredentials(ucred *Ucred) []byte {
+ b := make([]byte, syscall.CmsgSpace(SizeofUcred))
+ h := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
+ h.Level = syscall.SOL_SOCKET
+ h.Type = syscall.SCM_CREDS
+ h.SetLen(syscall.CmsgLen(SizeofUcred))
+ *((*Ucred)(cmsgData(h))) = *ucred
+ return b
+}
+
+// http://golang.org/src/pkg/syscall/sockcmsg_linux.go
+// ParseUnixCredentials decodes a socket control message that contains
+// credentials in a Ucred structure. To receive such a message, the
+// SO_PASSCRED option must be enabled on the socket.
+func ParseUnixCredentials(m *syscall.SocketControlMessage) (*Ucred, error) {
+ if m.Header.Level != syscall.SOL_SOCKET {
+ return nil, syscall.EINVAL
+ }
+ if m.Header.Type != syscall.SCM_CREDS {
+ return nil, syscall.EINVAL
+ }
+ ucred := *(*Ucred)(unsafe.Pointer(&m.Data[0]))
+ return &ucred, nil
+}
+
+func (t *unixTransport) SendNullByte() error {
+ ucred := &Ucred{Pid: int32(os.Getpid()), Uid: uint32(os.Getuid()), Gid: uint32(os.Getgid())}
+ b := UnixCredentials(ucred)
+ _, oobn, err := t.UnixConn.WriteMsgUnix([]byte{0}, b, nil)
+ if err != nil {
+ return err
+ }
+ if oobn != len(b) {
+ return io.ErrShortWrite
+ }
+ return nil
+}
diff --git a/vendor/github.com/godbus/dbus/v5/transport_unixcred_linux.go b/vendor/github.com/godbus/dbus/v5/transport_unixcred_linux.go
new file mode 100644
index 000000000..d9dfdf698
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/transport_unixcred_linux.go
@@ -0,0 +1,25 @@
+// The UnixCredentials system call is currently only implemented on Linux
+// http://golang.org/src/pkg/syscall/sockcmsg_linux.go
+// https://golang.org/s/go1.4-syscall
+// http://code.google.com/p/go/source/browse/unix/sockcmsg_linux.go?repo=sys
+
+package dbus
+
+import (
+ "io"
+ "os"
+ "syscall"
+)
+
+func (t *unixTransport) SendNullByte() error {
+ ucred := &syscall.Ucred{Pid: int32(os.Getpid()), Uid: uint32(os.Getuid()), Gid: uint32(os.Getgid())}
+ b := syscall.UnixCredentials(ucred)
+ _, oobn, err := t.UnixConn.WriteMsgUnix([]byte{0}, b, nil)
+ if err != nil {
+ return err
+ }
+ if oobn != len(b) {
+ return io.ErrShortWrite
+ }
+ return nil
+}
diff --git a/vendor/github.com/godbus/dbus/v5/transport_unixcred_netbsd.go b/vendor/github.com/godbus/dbus/v5/transport_unixcred_netbsd.go
new file mode 100644
index 000000000..af7bafdf9
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/transport_unixcred_netbsd.go
@@ -0,0 +1,14 @@
+package dbus
+
+import "io"
+
+func (t *unixTransport) SendNullByte() error {
+ n, _, err := t.UnixConn.WriteMsgUnix([]byte{0}, nil, nil)
+ if err != nil {
+ return err
+ }
+ if n != 1 {
+ return io.ErrShortWrite
+ }
+ return nil
+}
diff --git a/vendor/github.com/godbus/dbus/v5/transport_unixcred_openbsd.go b/vendor/github.com/godbus/dbus/v5/transport_unixcred_openbsd.go
new file mode 100644
index 000000000..af7bafdf9
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/transport_unixcred_openbsd.go
@@ -0,0 +1,14 @@
+package dbus
+
+import "io"
+
+func (t *unixTransport) SendNullByte() error {
+ n, _, err := t.UnixConn.WriteMsgUnix([]byte{0}, nil, nil)
+ if err != nil {
+ return err
+ }
+ if n != 1 {
+ return io.ErrShortWrite
+ }
+ return nil
+}
diff --git a/vendor/github.com/godbus/dbus/v5/transport_zos.go b/vendor/github.com/godbus/dbus/v5/transport_zos.go
new file mode 100644
index 000000000..1bba0d6bf
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/transport_zos.go
@@ -0,0 +1,6 @@
+package dbus
+
+func (t *unixTransport) SendNullByte() error {
+ _, err := t.Write([]byte{0})
+ return err
+}
diff --git a/vendor/github.com/godbus/dbus/v5/variant.go b/vendor/github.com/godbus/dbus/v5/variant.go
new file mode 100644
index 000000000..ca3dbe16a
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/variant.go
@@ -0,0 +1,150 @@
+package dbus
+
+import (
+ "bytes"
+ "fmt"
+ "reflect"
+ "sort"
+ "strconv"
+)
+
+// Variant represents the D-Bus variant type.
+type Variant struct {
+ sig Signature
+ value interface{}
+}
+
+// MakeVariant converts the given value to a Variant. It panics if v cannot be
+// represented as a D-Bus type.
+func MakeVariant(v interface{}) Variant {
+ return MakeVariantWithSignature(v, SignatureOf(v))
+}
+
+// MakeVariantWithSignature converts the given value to a Variant.
+func MakeVariantWithSignature(v interface{}, s Signature) Variant {
+ return Variant{s, v}
+}
+
+// ParseVariant parses the given string as a variant as described at
+// https://developer.gnome.org/glib/stable/gvariant-text.html. If sig is not
+// empty, it is taken to be the expected signature for the variant.
+func ParseVariant(s string, sig Signature) (Variant, error) {
+ tokens := varLex(s)
+ p := &varParser{tokens: tokens}
+ n, err := varMakeNode(p)
+ if err != nil {
+ return Variant{}, err
+ }
+ if sig.str == "" {
+ sig, err = varInfer(n)
+ if err != nil {
+ return Variant{}, err
+ }
+ }
+ v, err := n.Value(sig)
+ if err != nil {
+ return Variant{}, err
+ }
+ return MakeVariant(v), nil
+}
+
+// format returns a formatted version of v and whether this string can be parsed
+// unambiguously.
+func (v Variant) format() (string, bool) {
+ switch v.sig.str[0] {
+ case 'b', 'i':
+ return fmt.Sprint(v.value), true
+ case 'n', 'q', 'u', 'x', 't', 'd', 'h':
+ return fmt.Sprint(v.value), false
+ case 's':
+ return strconv.Quote(v.value.(string)), true
+ case 'o':
+ return strconv.Quote(string(v.value.(ObjectPath))), false
+ case 'g':
+ return strconv.Quote(v.value.(Signature).str), false
+ case 'v':
+ s, unamb := v.value.(Variant).format()
+ if !unamb {
+ return "<@" + v.value.(Variant).sig.str + " " + s + ">", true
+ }
+ return "<" + s + ">", true
+ case 'y':
+ return fmt.Sprintf("%#x", v.value.(byte)), false
+ }
+ rv := reflect.ValueOf(v.value)
+ switch rv.Kind() {
+ case reflect.Slice:
+ if rv.Len() == 0 {
+ return "[]", false
+ }
+ unamb := true
+ buf := bytes.NewBuffer([]byte("["))
+ for i := 0; i < rv.Len(); i++ {
+ // TODO: slooow
+ s, b := MakeVariant(rv.Index(i).Interface()).format()
+ unamb = unamb && b
+ buf.WriteString(s)
+ if i != rv.Len()-1 {
+ buf.WriteString(", ")
+ }
+ }
+ buf.WriteByte(']')
+ return buf.String(), unamb
+ case reflect.Map:
+ if rv.Len() == 0 {
+ return "{}", false
+ }
+ unamb := true
+ var buf bytes.Buffer
+ kvs := make([]string, rv.Len())
+ for i, k := range rv.MapKeys() {
+ s, b := MakeVariant(k.Interface()).format()
+ unamb = unamb && b
+ buf.Reset()
+ buf.WriteString(s)
+ buf.WriteString(": ")
+ s, b = MakeVariant(rv.MapIndex(k).Interface()).format()
+ unamb = unamb && b
+ buf.WriteString(s)
+ kvs[i] = buf.String()
+ }
+ buf.Reset()
+ buf.WriteByte('{')
+ sort.Strings(kvs)
+ for i, kv := range kvs {
+ if i > 0 {
+ buf.WriteString(", ")
+ }
+ buf.WriteString(kv)
+ }
+ buf.WriteByte('}')
+ return buf.String(), unamb
+ }
+ return `"INVALID"`, true
+}
+
+// Signature returns the D-Bus signature of the underlying value of v.
+func (v Variant) Signature() Signature {
+ return v.sig
+}
+
+// String returns the string representation of the underlying value of v as
+// described at https://developer.gnome.org/glib/stable/gvariant-text.html.
+func (v Variant) String() string {
+ s, unamb := v.format()
+ if !unamb {
+ return "@" + v.sig.str + " " + s
+ }
+ return s
+}
+
+// Value returns the underlying value of v.
+func (v Variant) Value() interface{} {
+ return v.value
+}
+
+// Store converts the variant into a native go type using the same
+// mechanism as the "Store" function.
+func (v Variant) Store(value interface{}) error {
+ return storeInterfaces(v.value, value)
+}
diff --git a/vendor/github.com/godbus/dbus/v5/variant_lexer.go b/vendor/github.com/godbus/dbus/v5/variant_lexer.go
new file mode 100644
index 000000000..bf1398c8f
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/variant_lexer.go
@@ -0,0 +1,284 @@
+package dbus
+
+import (
+ "fmt"
+ "strings"
+ "unicode"
+ "unicode/utf8"
+)
+
+// Heavily inspired by the lexer from text/template.
+
+type varToken struct {
+ typ varTokenType
+ val string
+}
+
+type varTokenType byte
+
+const (
+ tokEOF varTokenType = iota
+ tokError
+ tokNumber
+ tokString
+ tokBool
+ tokArrayStart
+ tokArrayEnd
+ tokDictStart
+ tokDictEnd
+ tokVariantStart
+ tokVariantEnd
+ tokComma
+ tokColon
+ tokType
+ tokByteString
+)
+
+type varLexer struct {
+ input string
+ start int
+ pos int
+ width int
+ tokens []varToken
+}
+
+type lexState func(*varLexer) lexState
+
+func varLex(s string) []varToken {
+ l := &varLexer{input: s}
+ l.run()
+ return l.tokens
+}
+
+func (l *varLexer) accept(valid string) bool {
+ if strings.ContainsRune(valid, l.next()) {
+ return true
+ }
+ l.backup()
+ return false
+}
+
+func (l *varLexer) backup() {
+ l.pos -= l.width
+}
+
+func (l *varLexer) emit(t varTokenType) {
+ l.tokens = append(l.tokens, varToken{t, l.input[l.start:l.pos]})
+ l.start = l.pos
+}
+
+func (l *varLexer) errorf(format string, v ...interface{}) lexState {
+ l.tokens = append(l.tokens, varToken{
+ tokError,
+ fmt.Sprintf(format, v...),
+ })
+ return nil
+}
+
+func (l *varLexer) ignore() {
+ l.start = l.pos
+}
+
+func (l *varLexer) next() rune {
+ var r rune
+
+ if l.pos >= len(l.input) {
+ l.width = 0
+ return -1
+ }
+ r, l.width = utf8.DecodeRuneInString(l.input[l.pos:])
+ l.pos += l.width
+ return r
+}
+
+func (l *varLexer) run() {
+ for state := varLexNormal; state != nil; {
+ state = state(l)
+ }
+}
+
+func (l *varLexer) peek() rune {
+ r := l.next()
+ l.backup()
+ return r
+}
+
+func varLexNormal(l *varLexer) lexState {
+ for {
+ r := l.next()
+ switch {
+ case r == -1:
+ l.emit(tokEOF)
+ return nil
+ case r == '[':
+ l.emit(tokArrayStart)
+ case r == ']':
+ l.emit(tokArrayEnd)
+ case r == '{':
+ l.emit(tokDictStart)
+ case r == '}':
+ l.emit(tokDictEnd)
+ case r == '<':
+ l.emit(tokVariantStart)
+ case r == '>':
+ l.emit(tokVariantEnd)
+ case r == ':':
+ l.emit(tokColon)
+ case r == ',':
+ l.emit(tokComma)
+ case r == '\'' || r == '"':
+ l.backup()
+ return varLexString
+ case r == '@':
+ l.backup()
+ return varLexType
+ case unicode.IsSpace(r):
+ l.ignore()
+ case unicode.IsNumber(r) || r == '+' || r == '-':
+ l.backup()
+ return varLexNumber
+ case r == 'b':
+ pos := l.start
+ if n := l.peek(); n == '"' || n == '\'' {
+ return varLexByteString
+ }
+ // not a byte string; try to parse it as a type or bool below
+ l.pos = pos + 1
+ l.width = 1
+ fallthrough
+ default:
+ // either a bool or a type. Try bools first.
+ l.backup()
+ if l.pos+4 <= len(l.input) {
+ if l.input[l.pos:l.pos+4] == "true" {
+ l.pos += 4
+ l.emit(tokBool)
+ continue
+ }
+ }
+ if l.pos+5 <= len(l.input) {
+ if l.input[l.pos:l.pos+5] == "false" {
+ l.pos += 5
+ l.emit(tokBool)
+ continue
+ }
+ }
+ // must be a type.
+ return varLexType
+ }
+ }
+}
+
+var varTypeMap = map[string]string{
+ "boolean": "b",
+ "byte": "y",
+ "int16": "n",
+ "uint16": "q",
+ "int32": "i",
+ "uint32": "u",
+ "int64": "x",
+ "uint64": "t",
+ "double": "f",
+ "string": "s",
+ "objectpath": "o",
+ "signature": "g",
+}
+
+func varLexByteString(l *varLexer) lexState {
+ q := l.next()
+Loop:
+ for {
+ switch l.next() {
+ case '\\':
+ if r := l.next(); r != -1 {
+ break
+ }
+ fallthrough
+ case -1:
+ return l.errorf("unterminated bytestring")
+ case q:
+ break Loop
+ }
+ }
+ l.emit(tokByteString)
+ return varLexNormal
+}
+
+func varLexNumber(l *varLexer) lexState {
+ l.accept("+-")
+ digits := "0123456789"
+ if l.accept("0") {
+ if l.accept("x") {
+ digits = "0123456789abcdefABCDEF"
+ } else {
+ digits = "01234567"
+ }
+ }
+ for strings.ContainsRune(digits, l.next()) {
+ }
+ l.backup()
+ if l.accept(".") {
+ for strings.ContainsRune(digits, l.next()) {
+ }
+ l.backup()
+ }
+ if l.accept("eE") {
+ l.accept("+-")
+ for strings.ContainsRune("0123456789", l.next()) {
+ }
+ l.backup()
+ }
+ if r := l.peek(); unicode.IsLetter(r) {
+ l.next()
+ return l.errorf("bad number syntax: %q", l.input[l.start:l.pos])
+ }
+ l.emit(tokNumber)
+ return varLexNormal
+}
+
+func varLexString(l *varLexer) lexState {
+ q := l.next()
+Loop:
+ for {
+ switch l.next() {
+ case '\\':
+ if r := l.next(); r != -1 {
+ break
+ }
+ fallthrough
+ case -1:
+ return l.errorf("unterminated string")
+ case q:
+ break Loop
+ }
+ }
+ l.emit(tokString)
+ return varLexNormal
+}
+
+func varLexType(l *varLexer) lexState {
+ at := l.accept("@")
+ for {
+ r := l.next()
+ if r == -1 {
+ break
+ }
+ if unicode.IsSpace(r) {
+ l.backup()
+ break
+ }
+ }
+ if at {
+ if _, err := ParseSignature(l.input[l.start+1 : l.pos]); err != nil {
+ return l.errorf("%s", err)
+ }
+ } else {
+ if _, ok := varTypeMap[l.input[l.start:l.pos]]; ok {
+ l.emit(tokType)
+ return varLexNormal
+ }
+ return l.errorf("unrecognized type %q", l.input[l.start:l.pos])
+ }
+ l.emit(tokType)
+ return varLexNormal
+}
diff --git a/vendor/github.com/godbus/dbus/v5/variant_parser.go b/vendor/github.com/godbus/dbus/v5/variant_parser.go
new file mode 100644
index 000000000..d20f5da6d
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/variant_parser.go
@@ -0,0 +1,817 @@
+package dbus
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+ "reflect"
+ "strconv"
+ "strings"
+ "unicode/utf8"
+)
+
+type varParser struct {
+ tokens []varToken
+ i int
+}
+
+func (p *varParser) backup() {
+ p.i--
+}
+
+func (p *varParser) next() varToken {
+ if p.i < len(p.tokens) {
+ t := p.tokens[p.i]
+ p.i++
+ return t
+ }
+ return varToken{typ: tokEOF}
+}
+
+type varNode interface {
+ Infer() (Signature, error)
+ String() string
+ Sigs() sigSet
+ Value(Signature) (interface{}, error)
+}
+
+func varMakeNode(p *varParser) (varNode, error) {
+ var sig Signature
+
+ for {
+ t := p.next()
+ switch t.typ {
+ case tokEOF:
+ return nil, io.ErrUnexpectedEOF
+ case tokError:
+ return nil, errors.New(t.val)
+ case tokNumber:
+ return varMakeNumNode(t, sig)
+ case tokString:
+ return varMakeStringNode(t, sig)
+ case tokBool:
+ if sig.str != "" && sig.str != "b" {
+ return nil, varTypeError{t.val, sig}
+ }
+ b, err := strconv.ParseBool(t.val)
+ if err != nil {
+ return nil, err
+ }
+ return boolNode(b), nil
+ case tokArrayStart:
+ return varMakeArrayNode(p, sig)
+ case tokVariantStart:
+ return varMakeVariantNode(p, sig)
+ case tokDictStart:
+ return varMakeDictNode(p, sig)
+ case tokType:
+ if sig.str != "" {
+ return nil, errors.New("unexpected type annotation")
+ }
+ if t.val[0] == '@' {
+ sig.str = t.val[1:]
+ } else {
+ sig.str = varTypeMap[t.val]
+ }
+ case tokByteString:
+ if sig.str != "" && sig.str != "ay" {
+ return nil, varTypeError{t.val, sig}
+ }
+ b, err := varParseByteString(t.val)
+ if err != nil {
+ return nil, err
+ }
+ return byteStringNode(b), nil
+ default:
+ return nil, fmt.Errorf("unexpected %q", t.val)
+ }
+ }
+}
+
+type varTypeError struct {
+ val string
+ sig Signature
+}
+
+func (e varTypeError) Error() string {
+ return fmt.Sprintf("dbus: can't parse %q as type %q", e.val, e.sig.str)
+}
+
+type sigSet map[Signature]bool
+
+func (s sigSet) Empty() bool {
+ return len(s) == 0
+}
+
+func (s sigSet) Intersect(s2 sigSet) sigSet {
+ r := make(sigSet)
+ for k := range s {
+ if s2[k] {
+ r[k] = true
+ }
+ }
+ return r
+}
+
+func (s sigSet) Single() (Signature, bool) {
+ if len(s) == 1 {
+ for k := range s {
+ return k, true
+ }
+ }
+ return Signature{}, false
+}
+
+func (s sigSet) ToArray() sigSet {
+ r := make(sigSet, len(s))
+ for k := range s {
+ r[Signature{"a" + k.str}] = true
+ }
+ return r
+}
+
+type numNode struct {
+ sig Signature
+ str string
+ val interface{}
+}
+
+var numSigSet = sigSet{
+ Signature{"y"}: true,
+ Signature{"n"}: true,
+ Signature{"q"}: true,
+ Signature{"i"}: true,
+ Signature{"u"}: true,
+ Signature{"x"}: true,
+ Signature{"t"}: true,
+ Signature{"d"}: true,
+}
+
+func (n numNode) Infer() (Signature, error) {
+ if strings.ContainsAny(n.str, ".e") {
+ return Signature{"d"}, nil
+ }
+ return Signature{"i"}, nil
+}
+
+func (n numNode) String() string {
+ return n.str
+}
+
+func (n numNode) Sigs() sigSet {
+ if n.sig.str != "" {
+ return sigSet{n.sig: true}
+ }
+ if strings.ContainsAny(n.str, ".e") {
+ return sigSet{Signature{"d"}: true}
+ }
+ return numSigSet
+}
+
+func (n numNode) Value(sig Signature) (interface{}, error) {
+ if n.sig.str != "" && n.sig != sig {
+ return nil, varTypeError{n.str, sig}
+ }
+ if n.val != nil {
+ return n.val, nil
+ }
+ return varNumAs(n.str, sig)
+}
+
+func varMakeNumNode(tok varToken, sig Signature) (varNode, error) {
+ if sig.str == "" {
+ return numNode{str: tok.val}, nil
+ }
+ num, err := varNumAs(tok.val, sig)
+ if err != nil {
+ return nil, err
+ }
+ return numNode{sig: sig, val: num}, nil
+}
+
+func varNumAs(s string, sig Signature) (interface{}, error) {
+ isUnsigned := false
+ size := 32
+ switch sig.str {
+ case "n":
+ size = 16
+ case "i":
+ case "x":
+ size = 64
+ case "y":
+ size = 8
+ isUnsigned = true
+ case "q":
+ size = 16
+ isUnsigned = true
+ case "u":
+ isUnsigned = true
+ case "t":
+ size = 64
+ isUnsigned = true
+ case "d":
+ d, err := strconv.ParseFloat(s, 64)
+ if err != nil {
+ return nil, err
+ }
+ return d, nil
+ default:
+ return nil, varTypeError{s, sig}
+ }
+ base := 10
+ if strings.HasPrefix(s, "0x") {
+ base = 16
+ s = s[2:]
+ }
+ if strings.HasPrefix(s, "0") && len(s) != 1 {
+ base = 8
+ s = s[1:]
+ }
+ if isUnsigned {
+ i, err := strconv.ParseUint(s, base, size)
+ if err != nil {
+ return nil, err
+ }
+ var v interface{} = i
+ switch sig.str {
+ case "y":
+ v = byte(i)
+ case "q":
+ v = uint16(i)
+ case "u":
+ v = uint32(i)
+ }
+ return v, nil
+ }
+ i, err := strconv.ParseInt(s, base, size)
+ if err != nil {
+ return nil, err
+ }
+ var v interface{} = i
+ switch sig.str {
+ case "n":
+ v = int16(i)
+ case "i":
+ v = int32(i)
+ }
+ return v, nil
+}
+
+type stringNode struct {
+ sig Signature
+ str string // parsed
+ val interface{} // has correct type
+}
+
+var stringSigSet = sigSet{
+ Signature{"s"}: true,
+ Signature{"g"}: true,
+ Signature{"o"}: true,
+}
+
+func (n stringNode) Infer() (Signature, error) {
+ return Signature{"s"}, nil
+}
+
+func (n stringNode) String() string {
+ return n.str
+}
+
+func (n stringNode) Sigs() sigSet {
+ if n.sig.str != "" {
+ return sigSet{n.sig: true}
+ }
+ return stringSigSet
+}
+
+func (n stringNode) Value(sig Signature) (interface{}, error) {
+ if n.sig.str != "" && n.sig != sig {
+ return nil, varTypeError{n.str, sig}
+ }
+ if n.val != nil {
+ return n.val, nil
+ }
+ switch {
+ case sig.str == "g":
+ return Signature{n.str}, nil
+ case sig.str == "o":
+ return ObjectPath(n.str), nil
+ case sig.str == "s":
+ return n.str, nil
+ default:
+ return nil, varTypeError{n.str, sig}
+ }
+}
+
+func varMakeStringNode(tok varToken, sig Signature) (varNode, error) {
+ if sig.str != "" && sig.str != "s" && sig.str != "g" && sig.str != "o" {
+ return nil, fmt.Errorf("invalid type %q for string", sig.str)
+ }
+ s, err := varParseString(tok.val)
+ if err != nil {
+ return nil, err
+ }
+ n := stringNode{str: s}
+ if sig.str == "" {
+ return stringNode{str: s}, nil
+ }
+ n.sig = sig
+ switch sig.str {
+ case "o":
+ n.val = ObjectPath(s)
+ case "g":
+ n.val = Signature{s}
+ case "s":
+ n.val = s
+ }
+ return n, nil
+}
+
+func varParseString(s string) (string, error) {
+ // quotes are guaranteed to be there
+ s = s[1 : len(s)-1]
+ buf := new(bytes.Buffer)
+ for len(s) != 0 {
+ r, size := utf8.DecodeRuneInString(s)
+ if r == utf8.RuneError && size == 1 {
+ return "", errors.New("invalid UTF-8")
+ }
+ s = s[size:]
+ if r != '\\' {
+ buf.WriteRune(r)
+ continue
+ }
+ r, size = utf8.DecodeRuneInString(s)
+ if r == utf8.RuneError && size == 1 {
+ return "", errors.New("invalid UTF-8")
+ }
+ s = s[size:]
+ switch r {
+ case 'a':
+ buf.WriteRune(0x7)
+ case 'b':
+ buf.WriteRune(0x8)
+ case 'f':
+ buf.WriteRune(0xc)
+ case 'n':
+ buf.WriteRune('\n')
+ case 'r':
+ buf.WriteRune('\r')
+ case 't':
+ buf.WriteRune('\t')
+ case '\n':
+ case 'u':
+ if len(s) < 4 {
+ return "", errors.New("short unicode escape")
+ }
+ r, err := strconv.ParseUint(s[:4], 16, 32)
+ if err != nil {
+ return "", err
+ }
+ buf.WriteRune(rune(r))
+ s = s[4:]
+ case 'U':
+ if len(s) < 8 {
+ return "", errors.New("short unicode escape")
+ }
+ r, err := strconv.ParseUint(s[:8], 16, 32)
+ if err != nil {
+ return "", err
+ }
+ buf.WriteRune(rune(r))
+ s = s[8:]
+ default:
+ buf.WriteRune(r)
+ }
+ }
+ return buf.String(), nil
+}
+
+var boolSigSet = sigSet{Signature{"b"}: true}
+
+type boolNode bool
+
+func (boolNode) Infer() (Signature, error) {
+ return Signature{"b"}, nil
+}
+
+func (b boolNode) String() string {
+ if b {
+ return "true"
+ }
+ return "false"
+}
+
+func (boolNode) Sigs() sigSet {
+ return boolSigSet
+}
+
+func (b boolNode) Value(sig Signature) (interface{}, error) {
+ if sig.str != "b" {
+ return nil, varTypeError{b.String(), sig}
+ }
+ return bool(b), nil
+}
+
+type arrayNode struct {
+ set sigSet
+ children []varNode
+ val interface{}
+}
+
+func (n arrayNode) Infer() (Signature, error) {
+ for _, v := range n.children {
+ csig, err := varInfer(v)
+ if err != nil {
+ continue
+ }
+ return Signature{"a" + csig.str}, nil
+ }
+ return Signature{}, fmt.Errorf("can't infer type for %q", n.String())
+}
+
+func (n arrayNode) String() string {
+ s := "["
+ for i, v := range n.children {
+ s += v.String()
+ if i != len(n.children)-1 {
+ s += ", "
+ }
+ }
+ return s + "]"
+}
+
+func (n arrayNode) Sigs() sigSet {
+ return n.set
+}
+
+func (n arrayNode) Value(sig Signature) (interface{}, error) {
+ if n.set.Empty() {
+ // no type information whatsoever, so this must be an empty slice
+ return reflect.MakeSlice(typeFor(sig.str), 0, 0).Interface(), nil
+ }
+ if !n.set[sig] {
+ return nil, varTypeError{n.String(), sig}
+ }
+ s := reflect.MakeSlice(typeFor(sig.str), len(n.children), len(n.children))
+ for i, v := range n.children {
+ rv, err := v.Value(Signature{sig.str[1:]})
+ if err != nil {
+ return nil, err
+ }
+ s.Index(i).Set(reflect.ValueOf(rv))
+ }
+ return s.Interface(), nil
+}
+
+func varMakeArrayNode(p *varParser, sig Signature) (varNode, error) {
+ var n arrayNode
+ if sig.str != "" {
+ n.set = sigSet{sig: true}
+ }
+ if t := p.next(); t.typ == tokArrayEnd {
+ return n, nil
+ } else {
+ p.backup()
+ }
+Loop:
+ for {
+ t := p.next()
+ switch t.typ {
+ case tokEOF:
+ return nil, io.ErrUnexpectedEOF
+ case tokError:
+ return nil, errors.New(t.val)
+ }
+ p.backup()
+ cn, err := varMakeNode(p)
+ if err != nil {
+ return nil, err
+ }
+ if cset := cn.Sigs(); !cset.Empty() {
+ if n.set.Empty() {
+ n.set = cset.ToArray()
+ } else {
+ nset := cset.ToArray().Intersect(n.set)
+ if nset.Empty() {
+ return nil, fmt.Errorf("can't parse %q with given type information", cn.String())
+ }
+ n.set = nset
+ }
+ }
+ n.children = append(n.children, cn)
+ switch t := p.next(); t.typ {
+ case tokEOF:
+ return nil, io.ErrUnexpectedEOF
+ case tokError:
+ return nil, errors.New(t.val)
+ case tokArrayEnd:
+ break Loop
+ case tokComma:
+ continue
+ default:
+ return nil, fmt.Errorf("unexpected %q", t.val)
+ }
+ }
+ return n, nil
+}
+
+type variantNode struct {
+ n varNode
+}
+
+var variantSet = sigSet{
+ Signature{"v"}: true,
+}
+
+func (variantNode) Infer() (Signature, error) {
+ return Signature{"v"}, nil
+}
+
+func (n variantNode) String() string {
+ return "<" + n.n.String() + ">"
+}
+
+func (variantNode) Sigs() sigSet {
+ return variantSet
+}
+
+func (n variantNode) Value(sig Signature) (interface{}, error) {
+ if sig.str != "v" {
+ return nil, varTypeError{n.String(), sig}
+ }
+ sig, err := varInfer(n.n)
+ if err != nil {
+ return nil, err
+ }
+ v, err := n.n.Value(sig)
+ if err != nil {
+ return nil, err
+ }
+ return MakeVariant(v), nil
+}
+
+func varMakeVariantNode(p *varParser, sig Signature) (varNode, error) {
+ n, err := varMakeNode(p)
+ if err != nil {
+ return nil, err
+ }
+ if t := p.next(); t.typ != tokVariantEnd {
+ return nil, fmt.Errorf("unexpected %q", t.val)
+ }
+ vn := variantNode{n}
+ if sig.str != "" && sig.str != "v" {
+ return nil, varTypeError{vn.String(), sig}
+ }
+ return variantNode{n}, nil
+}
+
+type dictEntry struct {
+ key, val varNode
+}
+
+type dictNode struct {
+ kset, vset sigSet
+ children []dictEntry
+ val interface{}
+}
+
+func (n dictNode) Infer() (Signature, error) {
+ for _, v := range n.children {
+ ksig, err := varInfer(v.key)
+ if err != nil {
+ continue
+ }
+ vsig, err := varInfer(v.val)
+ if err != nil {
+ continue
+ }
+ return Signature{"a{" + ksig.str + vsig.str + "}"}, nil
+ }
+ return Signature{}, fmt.Errorf("can't infer type for %q", n.String())
+}
+
+func (n dictNode) String() string {
+ s := "{"
+ for i, v := range n.children {
+ s += v.key.String() + ": " + v.val.String()
+ if i != len(n.children)-1 {
+ s += ", "
+ }
+ }
+ return s + "}"
+}
+
+func (n dictNode) Sigs() sigSet {
+ r := sigSet{}
+ for k := range n.kset {
+ for v := range n.vset {
+ sig := "a{" + k.str + v.str + "}"
+ r[Signature{sig}] = true
+ }
+ }
+ return r
+}
+
+func (n dictNode) Value(sig Signature) (interface{}, error) {
+ set := n.Sigs()
+ if set.Empty() {
+ // no type information -> empty dict
+ return reflect.MakeMap(typeFor(sig.str)).Interface(), nil
+ }
+ if !set[sig] {
+ return nil, varTypeError{n.String(), sig}
+ }
+ m := reflect.MakeMap(typeFor(sig.str))
+ ksig := Signature{sig.str[2:3]}
+ vsig := Signature{sig.str[3 : len(sig.str)-1]}
+ for _, v := range n.children {
+ kv, err := v.key.Value(ksig)
+ if err != nil {
+ return nil, err
+ }
+ vv, err := v.val.Value(vsig)
+ if err != nil {
+ return nil, err
+ }
+ m.SetMapIndex(reflect.ValueOf(kv), reflect.ValueOf(vv))
+ }
+ return m.Interface(), nil
+}
+
+func varMakeDictNode(p *varParser, sig Signature) (varNode, error) {
+ var n dictNode
+
+ if sig.str != "" {
+ if len(sig.str) < 5 {
+ return nil, fmt.Errorf("invalid signature %q for dict type", sig)
+ }
+ ksig := Signature{string(sig.str[2])}
+ vsig := Signature{sig.str[3 : len(sig.str)-1]}
+ n.kset = sigSet{ksig: true}
+ n.vset = sigSet{vsig: true}
+ }
+ if t := p.next(); t.typ == tokDictEnd {
+ return n, nil
+ } else {
+ p.backup()
+ }
+Loop:
+ for {
+ t := p.next()
+ switch t.typ {
+ case tokEOF:
+ return nil, io.ErrUnexpectedEOF
+ case tokError:
+ return nil, errors.New(t.val)
+ }
+ p.backup()
+ kn, err := varMakeNode(p)
+ if err != nil {
+ return nil, err
+ }
+ if kset := kn.Sigs(); !kset.Empty() {
+ if n.kset.Empty() {
+ n.kset = kset
+ } else {
+ n.kset = kset.Intersect(n.kset)
+ if n.kset.Empty() {
+ return nil, fmt.Errorf("can't parse %q with given type information", kn.String())
+ }
+ }
+ }
+ t = p.next()
+ switch t.typ {
+ case tokEOF:
+ return nil, io.ErrUnexpectedEOF
+ case tokError:
+ return nil, errors.New(t.val)
+ case tokColon:
+ default:
+ return nil, fmt.Errorf("unexpected %q", t.val)
+ }
+ t = p.next()
+ switch t.typ {
+ case tokEOF:
+ return nil, io.ErrUnexpectedEOF
+ case tokError:
+ return nil, errors.New(t.val)
+ }
+ p.backup()
+ vn, err := varMakeNode(p)
+ if err != nil {
+ return nil, err
+ }
+ if vset := vn.Sigs(); !vset.Empty() {
+ if n.vset.Empty() {
+ n.vset = vset
+ } else {
+ n.vset = n.vset.Intersect(vset)
+ if n.vset.Empty() {
+ return nil, fmt.Errorf("can't parse %q with given type information", vn.String())
+ }
+ }
+ }
+ n.children = append(n.children, dictEntry{kn, vn})
+ t = p.next()
+ switch t.typ {
+ case tokEOF:
+ return nil, io.ErrUnexpectedEOF
+ case tokError:
+ return nil, errors.New(t.val)
+ case tokDictEnd:
+ break Loop
+ case tokComma:
+ continue
+ default:
+ return nil, fmt.Errorf("unexpected %q", t.val)
+ }
+ }
+ return n, nil
+}
+
+type byteStringNode []byte
+
+var byteStringSet = sigSet{
+ Signature{"ay"}: true,
+}
+
+func (byteStringNode) Infer() (Signature, error) {
+ return Signature{"ay"}, nil
+}
+
+func (b byteStringNode) String() string {
+ return string(b)
+}
+
+func (b byteStringNode) Sigs() sigSet {
+ return byteStringSet
+}
+
+func (b byteStringNode) Value(sig Signature) (interface{}, error) {
+ if sig.str != "ay" {
+ return nil, varTypeError{b.String(), sig}
+ }
+ return []byte(b), nil
+}
+
+func varParseByteString(s string) ([]byte, error) {
+ // quotes and b at start are guaranteed to be there
+ b := make([]byte, 0, 1)
+ s = s[2 : len(s)-1]
+ for len(s) != 0 {
+ c := s[0]
+ s = s[1:]
+ if c != '\\' {
+ b = append(b, c)
+ continue
+ }
+ c = s[0]
+ s = s[1:]
+ switch c {
+ case 'a':
+ b = append(b, 0x7)
+ case 'b':
+ b = append(b, 0x8)
+ case 'f':
+ b = append(b, 0xc)
+ case 'n':
+ b = append(b, '\n')
+ case 'r':
+ b = append(b, '\r')
+ case 't':
+ b = append(b, '\t')
+ case 'x':
+ if len(s) < 2 {
+ return nil, errors.New("short escape")
+ }
+ n, err := strconv.ParseUint(s[:2], 16, 8)
+ if err != nil {
+ return nil, err
+ }
+ b = append(b, byte(n))
+ s = s[2:]
+ case '0':
+ if len(s) < 3 {
+ return nil, errors.New("short escape")
+ }
+ n, err := strconv.ParseUint(s[:3], 8, 8)
+ if err != nil {
+ return nil, err
+ }
+ b = append(b, byte(n))
+ s = s[3:]
+ default:
+ b = append(b, c)
+ }
+ }
+ return append(b, 0), nil
+}
+
+func varInfer(n varNode) (Signature, error) {
+ if sig, ok := n.Sigs().Single(); ok {
+ return sig, nil
+ }
+ return n.Infer()
+}
diff --git a/vendor/github.com/google/shlex/COPYING b/vendor/github.com/google/shlex/COPYING
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/vendor/github.com/google/shlex/COPYING
@@ -0,0 +1,202 @@
+
+ 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/google/shlex/README b/vendor/github.com/google/shlex/README
new file mode 100644
index 000000000..c86bcc066
--- /dev/null
+++ b/vendor/github.com/google/shlex/README
@@ -0,0 +1,2 @@
+go-shlex is a simple lexer for go that supports shell-style quoting,
+commenting, and escaping.
diff --git a/vendor/github.com/google/shlex/shlex.go b/vendor/github.com/google/shlex/shlex.go
new file mode 100644
index 000000000..d98308bce
--- /dev/null
+++ b/vendor/github.com/google/shlex/shlex.go
@@ -0,0 +1,416 @@
+/*
+Copyright 2012 Google Inc. All Rights Reserved.
+
+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.
+*/
+
+/*
+Package shlex implements a simple lexer which splits input in to tokens using
+shell-style rules for quoting and commenting.
+
+The basic use case uses the default ASCII lexer to split a string into sub-strings:
+
+ shlex.Split("one \"two three\" four") -> []string{"one", "two three", "four"}
+
+To process a stream of strings:
+
+ l := NewLexer(os.Stdin)
+ for ; token, err := l.Next(); err != nil {
+ // process token
+ }
+
+To access the raw token stream (which includes tokens for comments):
+
+ t := NewTokenizer(os.Stdin)
+ for ; token, err := t.Next(); err != nil {
+ // process token
+ }
+
+*/
+package shlex
+
+import (
+ "bufio"
+ "fmt"
+ "io"
+ "strings"
+)
+
+// TokenType is a top-level token classification: A word, space, comment, unknown.
+type TokenType int
+
+// runeTokenClass is the type of a UTF-8 character classification: A quote, space, escape.
+type runeTokenClass int
+
+// the internal state used by the lexer state machine
+type lexerState int
+
+// Token is a (type, value) pair representing a lexographical token.
+type Token struct {
+ tokenType TokenType
+ value string
+}
+
+// Equal reports whether tokens a, and b, are equal.
+// Two tokens are equal if both their types and values are equal. A nil token can
+// never be equal to another token.
+func (a *Token) Equal(b *Token) bool {
+ if a == nil || b == nil {
+ return false
+ }
+ if a.tokenType != b.tokenType {
+ return false
+ }
+ return a.value == b.value
+}
+
+// Named classes of UTF-8 runes
+const (
+ spaceRunes = " \t\r\n"
+ escapingQuoteRunes = `"`
+ nonEscapingQuoteRunes = "'"
+ escapeRunes = `\`
+ commentRunes = "#"
+)
+
+// Classes of rune token
+const (
+ unknownRuneClass runeTokenClass = iota
+ spaceRuneClass
+ escapingQuoteRuneClass
+ nonEscapingQuoteRuneClass
+ escapeRuneClass
+ commentRuneClass
+ eofRuneClass
+)
+
+// Classes of lexographic token
+const (
+ UnknownToken TokenType = iota
+ WordToken
+ SpaceToken
+ CommentToken
+)
+
+// Lexer state machine states
+const (
+ startState lexerState = iota // no runes have been seen
+ inWordState // processing regular runes in a word
+ escapingState // we have just consumed an escape rune; the next rune is literal
+ escapingQuotedState // we have just consumed an escape rune within a quoted string
+ quotingEscapingState // we are within a quoted string that supports escaping ("...")
+ quotingState // we are within a string that does not support escaping ('...')
+ commentState // we are within a comment (everything following an unquoted or unescaped #
+)
+
+// tokenClassifier is used for classifying rune characters.
+type tokenClassifier map[rune]runeTokenClass
+
+func (typeMap tokenClassifier) addRuneClass(runes string, tokenType runeTokenClass) {
+ for _, runeChar := range runes {
+ typeMap[runeChar] = tokenType
+ }
+}
+
+// newDefaultClassifier creates a new classifier for ASCII characters.
+func newDefaultClassifier() tokenClassifier {
+ t := tokenClassifier{}
+ t.addRuneClass(spaceRunes, spaceRuneClass)
+ t.addRuneClass(escapingQuoteRunes, escapingQuoteRuneClass)
+ t.addRuneClass(nonEscapingQuoteRunes, nonEscapingQuoteRuneClass)
+ t.addRuneClass(escapeRunes, escapeRuneClass)
+ t.addRuneClass(commentRunes, commentRuneClass)
+ return t
+}
+
+// ClassifyRune classifiees a rune
+func (t tokenClassifier) ClassifyRune(runeVal rune) runeTokenClass {
+ return t[runeVal]
+}
+
+// Lexer turns an input stream into a sequence of tokens. Whitespace and comments are skipped.
+type Lexer Tokenizer
+
+// NewLexer creates a new lexer from an input stream.
+func NewLexer(r io.Reader) *Lexer {
+
+ return (*Lexer)(NewTokenizer(r))
+}
+
+// Next returns the next word, or an error. If there are no more words,
+// the error will be io.EOF.
+func (l *Lexer) Next() (string, error) {
+ for {
+ token, err := (*Tokenizer)(l).Next()
+ if err != nil {
+ return "", err
+ }
+ switch token.tokenType {
+ case WordToken:
+ return token.value, nil
+ case CommentToken:
+ // skip comments
+ default:
+ return "", fmt.Errorf("Unknown token type: %v", token.tokenType)
+ }
+ }
+}
+
+// Tokenizer turns an input stream into a sequence of typed tokens
+type Tokenizer struct {
+ input bufio.Reader
+ classifier tokenClassifier
+}
+
+// NewTokenizer creates a new tokenizer from an input stream.
+func NewTokenizer(r io.Reader) *Tokenizer {
+ input := bufio.NewReader(r)
+ classifier := newDefaultClassifier()
+ return &Tokenizer{
+ input: *input,
+ classifier: classifier}
+}
+
+// scanStream scans the stream for the next token using the internal state machine.
+// It will panic if it encounters a rune which it does not know how to handle.
+func (t *Tokenizer) scanStream() (*Token, error) {
+ state := startState
+ var tokenType TokenType
+ var value []rune
+ var nextRune rune
+ var nextRuneType runeTokenClass
+ var err error
+
+ for {
+ nextRune, _, err = t.input.ReadRune()
+ nextRuneType = t.classifier.ClassifyRune(nextRune)
+
+ if err == io.EOF {
+ nextRuneType = eofRuneClass
+ err = nil
+ } else if err != nil {
+ return nil, err
+ }
+
+ switch state {
+ case startState: // no runes read yet
+ {
+ switch nextRuneType {
+ case eofRuneClass:
+ {
+ return nil, io.EOF
+ }
+ case spaceRuneClass:
+ {
+ }
+ case escapingQuoteRuneClass:
+ {
+ tokenType = WordToken
+ state = quotingEscapingState
+ }
+ case nonEscapingQuoteRuneClass:
+ {
+ tokenType = WordToken
+ state = quotingState
+ }
+ case escapeRuneClass:
+ {
+ tokenType = WordToken
+ state = escapingState
+ }
+ case commentRuneClass:
+ {
+ tokenType = CommentToken
+ state = commentState
+ }
+ default:
+ {
+ tokenType = WordToken
+ value = append(value, nextRune)
+ state = inWordState
+ }
+ }
+ }
+ case inWordState: // in a regular word
+ {
+ switch nextRuneType {
+ case eofRuneClass:
+ {
+ token := &Token{
+ tokenType: tokenType,
+ value: string(value)}
+ return token, err
+ }
+ case spaceRuneClass:
+ {
+ token := &Token{
+ tokenType: tokenType,
+ value: string(value)}
+ return token, err
+ }
+ case escapingQuoteRuneClass:
+ {
+ state = quotingEscapingState
+ }
+ case nonEscapingQuoteRuneClass:
+ {
+ state = quotingState
+ }
+ case escapeRuneClass:
+ {
+ state = escapingState
+ }
+ default:
+ {
+ value = append(value, nextRune)
+ }
+ }
+ }
+ case escapingState: // the rune after an escape character
+ {
+ switch nextRuneType {
+ case eofRuneClass:
+ {
+ err = fmt.Errorf("EOF found after escape character")
+ token := &Token{
+ tokenType: tokenType,
+ value: string(value)}
+ return token, err
+ }
+ default:
+ {
+ state = inWordState
+ value = append(value, nextRune)
+ }
+ }
+ }
+ case escapingQuotedState: // the next rune after an escape character, in double quotes
+ {
+ switch nextRuneType {
+ case eofRuneClass:
+ {
+ err = fmt.Errorf("EOF found after escape character")
+ token := &Token{
+ tokenType: tokenType,
+ value: string(value)}
+ return token, err
+ }
+ default:
+ {
+ state = quotingEscapingState
+ value = append(value, nextRune)
+ }
+ }
+ }
+ case quotingEscapingState: // in escaping double quotes
+ {
+ switch nextRuneType {
+ case eofRuneClass:
+ {
+ err = fmt.Errorf("EOF found when expecting closing quote")
+ token := &Token{
+ tokenType: tokenType,
+ value: string(value)}
+ return token, err
+ }
+ case escapingQuoteRuneClass:
+ {
+ state = inWordState
+ }
+ case escapeRuneClass:
+ {
+ state = escapingQuotedState
+ }
+ default:
+ {
+ value = append(value, nextRune)
+ }
+ }
+ }
+ case quotingState: // in non-escaping single quotes
+ {
+ switch nextRuneType {
+ case eofRuneClass:
+ {
+ err = fmt.Errorf("EOF found when expecting closing quote")
+ token := &Token{
+ tokenType: tokenType,
+ value: string(value)}
+ return token, err
+ }
+ case nonEscapingQuoteRuneClass:
+ {
+ state = inWordState
+ }
+ default:
+ {
+ value = append(value, nextRune)
+ }
+ }
+ }
+ case commentState: // in a comment
+ {
+ switch nextRuneType {
+ case eofRuneClass:
+ {
+ token := &Token{
+ tokenType: tokenType,
+ value: string(value)}
+ return token, err
+ }
+ case spaceRuneClass:
+ {
+ if nextRune == '\n' {
+ state = startState
+ token := &Token{
+ tokenType: tokenType,
+ value: string(value)}
+ return token, err
+ } else {
+ value = append(value, nextRune)
+ }
+ }
+ default:
+ {
+ value = append(value, nextRune)
+ }
+ }
+ }
+ default:
+ {
+ return nil, fmt.Errorf("Unexpected state: %v", state)
+ }
+ }
+ }
+}
+
+// Next returns the next token in the stream.
+func (t *Tokenizer) Next() (*Token, error) {
+ return t.scanStream()
+}
+
+// Split partitions a string into a slice of strings.
+func Split(s string) ([]string, error) {
+ l := NewLexer(strings.NewReader(s))
+ subStrings := make([]string, 0)
+ for {
+ word, err := l.Next()
+ if err != nil {
+ if err == io.EOF {
+ return subStrings, nil
+ }
+ return subStrings, err
+ }
+ subStrings = append(subStrings, word)
+ }
+}
diff --git a/vendor/github.com/h2non/gock/.editorconfig b/vendor/github.com/h2non/gock/.editorconfig
new file mode 100644
index 000000000..b570cb169
--- /dev/null
+++ b/vendor/github.com/h2non/gock/.editorconfig
@@ -0,0 +1,12 @@
+root = true
+
+[*]
+indent_style = tab
+indent_size = 2
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
diff --git a/vendor/github.com/h2non/gock/.gitignore b/vendor/github.com/h2non/gock/.gitignore
new file mode 100644
index 000000000..173b0298b
--- /dev/null
+++ b/vendor/github.com/h2non/gock/.gitignore
@@ -0,0 +1,30 @@
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+go.sum
+
+# 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
+
+.idea/
+*.iml
+*.out
+*.tmp
diff --git a/vendor/github.com/h2non/gock/.travis.yml b/vendor/github.com/h2non/gock/.travis.yml
new file mode 100644
index 000000000..d8ea0713d
--- /dev/null
+++ b/vendor/github.com/h2non/gock/.travis.yml
@@ -0,0 +1,26 @@
+language: go
+
+go:
+ - "1.15"
+ - "1.14"
+ - "stable"
+
+before_install:
+ - go get -u github.com/nbio/st
+ - go get -u github.com/codemodus/parth
+ - go get -u gopkg.in/h2non/gentleman.v1
+ - go get -u -v github.com/axw/gocov/gocov
+ - go get -u -v github.com/mattn/goveralls
+ - go get -v -u golang.org/x/lint/golint
+ - mkdir -p $GOPATH/src/gopkg.in/h2non/gock.v1
+ - cp -r . $GOPATH/src/gopkg.in/h2non/gock.v1
+
+script:
+ - diff -u <(echo -n) <(gofmt -s -d ./)
+ - diff -u <(echo -n) <(go vet ./...)
+ - diff -u <(echo -n) <(golint ./...)
+ - go test -v -race -covermode=atomic -coverprofile=coverage.out
+ - go test ./_examples/*/ -v -race
+
+after_success:
+ - goveralls -coverprofile=coverage.out -service=travis-ci -repotoken $COVERALLS_TOKEN
diff --git a/vendor/github.com/h2non/gock/History.md b/vendor/github.com/h2non/gock/History.md
new file mode 100644
index 000000000..6260df6c0
--- /dev/null
+++ b/vendor/github.com/h2non/gock/History.md
@@ -0,0 +1,143 @@
+## v1.2.0 / 2022-10-19
+
+ * refactor(package): import path changed to github.com/h2non/gock
+
+## v1.1.2 / 2021-08-03
+
+ * fix(mock): fix race condition in mock.go file (#92)
+
+## v1.1.1 / 2021-07-14
+
+ * feat(matchers): Support custom MIME types (#88)
+
+## v1.1.0 / 2021-06-02
+
+ * Add context expiration cancellation support (#86)
+
+## v1.0.16 / 2020-11-23
+
+ * Fix regexp matching issues in headers (#59)
+
+## v1.0.15 / 2019-07-03
+
+ * NewMatcher() will now return objects that completely separate one another. (#55)
+ * add request Options (#49)
+ * fix typo: function -> func (#52)
+ * feat(docs): change note
+ * feat(docs): add net/http support
+ * Add Basic Auth (#47)
+ * Update LICENSE (#46)
+
+## v1.0.14 / 2019-01-31
+
+ * feat(version): bump to v1.0.14
+ * feat: add go.mod
+
+## v1.0.13 / 2019-01-30
+
+ * Add PathParam matcher (#42)
+
+## v1.0.12 / 2018-11-13
+
+ * Fix possible data race. (#41)
+
+## v1.0.11 / 2018-10-29
+
+ * Do not reset response body (#40)
+ * refactor(travis): remove unsupported versions for golint based on Go release policy support
+ * feat(gock): add gock.Observe to support inspection of the outgoing intercepted HTTP traffic (#38)
+
+## v1.0.10 / 2018-09-09
+
+ * Support multiple response headers with same name #35 (#36)
+
+## v1.0.9 / 2018-06-14
+
+ * fix(url-encoding) add exact match test in MatchPath (#34)
+ * fix(travis): use string notation for Go versions
+
+## v1.0.8 / 2018-02-28
+
+ * chore(LICENSE): update year ;)
+ * feat(docs): add additional tips and examples
+ * feat(gock): ignore already intercepted http.Client
+
+## v1.0.7 / 2017-12-21
+
+ * Make MatchHost case insensitive. (#31)
+ * refactor(docs): remove codesponsor :(
+ * add example when request reply with error (#28)
+ * feat(docs): add sponsor ad
+ * Add example networking partially enabled (#23)
+
+## v1.0.6 / 2017-07-27
+
+ * fix(#23): mock transport deadlock
+
+## v1.0.5 / 2017-07-26
+
+ * feat(#25, #24): use content type only if missing while matching JSON/XML
+ * feat(#24): add CleanUnmatchedRequests() and OffAll() public functions
+ * feat(version): bump to v1.0.5
+ * fix(store): use proper indent style
+ * fix(mutex): use different mutex for store
+ * feat(travis): add Go 1.8 CI support
+
+## v1.0.4 / 2017-02-14
+
+ * Update README to include most up to date version (#17)
+ * Update MatchBody() to compare if key + value pairs of JSON match regardless of order they are in. (#16)
+ * feat(examples): add new example for unmatch case
+ * refactor(docs): add pook reference
+
+## 1.0.3 / 14-11-2016
+
+- feat(#13): adds `GetUnmatchedRequests()` and `HasUnmatchedRequests()` API functions.
+
+## 1.0.2 / 10-11-2016
+
+- fix(#11): adds `Compression()` method for output HTTP traffic body compression processing and matching.
+
+## 1.0.1 / 07-09-2016
+
+- fix(#9): missing URL query param matcher.
+
+## 1.0.0 / 19-04-2016
+
+- feat(version): first major version release.
+
+## 0.1.6 / 19-04-2016
+
+- fix(#7): if error configured, RoundTripper should reply with `nil` response.
+
+## 0.1.5 / 09-04-2016
+
+- feat(#5): support `ReplyFunc` for convenience.
+
+## 0.1.4 / 16-03-2016
+
+- feat(api): add `IsDone()` method.
+- fix(responder): return mock error if present.
+- feat(#4): support define request/response body from file disk.
+
+## 0.1.3 / 09-03-2016
+
+- feat(matcher): add content type matcher helper method supporting aliases.
+- feat(interceptor): add function to restore HTTP client transport.
+- feat(matcher): add URL scheme matcher function.
+- fix(request): ignore base slash path.
+- feat(api): add Off() method for easier restore and clean up.
+- feat(store): add public API for pending mocks.
+
+## 0.1.2 / 04-03-2016
+
+- fix(matcher): body matchers no used by default.
+- feat(matcher): add matcher factories for multiple cases.
+
+## 0.1.1 / 04-03-2016
+
+- fix(params): persist query params accordingly.
+
+## 0.1.0 / 02-03-2016
+
+- First release.
diff --git a/vendor/github.com/h2non/gock/LICENSE b/vendor/github.com/h2non/gock/LICENSE
new file mode 100644
index 000000000..1911b1778
--- /dev/null
+++ b/vendor/github.com/h2non/gock/LICENSE
@@ -0,0 +1,24 @@
+The MIT License
+
+Copyright (c) 2016-2019 Tomas Aparicio
+
+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/h2non/gock/README.md b/vendor/github.com/h2non/gock/README.md
new file mode 100644
index 000000000..37a835f42
--- /dev/null
+++ b/vendor/github.com/h2non/gock/README.md
@@ -0,0 +1,380 @@
+# gock [![Build Status](https://travis-ci.org/h2non/gock.svg?branch=master)](https://travis-ci.org/h2non/gock) [![GitHub release](https://img.shields.io/badge/version-v1.0-orange.svg?style=flat)](https://github.com/h2non/gock/releases) [![GoDoc](https://godoc.org/github.com/h2non/gock?status.svg)](https://godoc.org/github.com/h2non/gock) [![Coverage Status](https://coveralls.io/repos/github/h2non/gock/badge.svg?branch=master)](https://coveralls.io/github/h2non/gock?branch=master) [![Go Report Card](https://img.shields.io/badge/go_report-A+-brightgreen.svg)](https://goreportcard.com/report/github.com/h2non/gock) [![license](https://img.shields.io/badge/license-MIT-blue.svg)]()
+
+Versatile HTTP mocking made easy in [Go](https://golang.org) that works with any `net/http` based stdlib implementation.
+
+Heavily inspired by [nock](https://github.com/node-nock/nock).
+There is also its Python port, [pook](https://github.com/h2non/pook).
+
+To get started, take a look to the [examples](#examples).
+
+## Features
+
+- Simple, expressive, fluent API.
+- Semantic API DSL for declarative HTTP mock declarations.
+- Built-in helpers for easy JSON/XML mocking.
+- Supports persistent and volatile TTL-limited mocks.
+- Full regular expressions capable HTTP request mock matching.
+- Designed for both testing and runtime scenarios.
+- Match request by method, URL params, headers and bodies.
+- Extensible and pluggable HTTP matching rules.
+- Ability to switch between mock and real networking modes.
+- Ability to filter/map HTTP requests for accurate mock matching.
+- Supports map and filters to handle mocks easily.
+- Wide compatible HTTP interceptor using `http.RoundTripper` interface.
+- Works with any `net/http` compatible client, such as [gentleman](https://github.com/h2non/gentleman).
+- Network timeout/cancelation delay simulation.
+- Extensible and hackable API.
+- Dependency free.
+
+## Installation
+
+```bash
+go get -u github.com/h2non/gock
+```
+
+## API
+
+See [godoc reference](https://godoc.org/github.com/h2non/gock) for detailed API documentation.
+
+## How it mocks
+
+1. Intercepts any HTTP outgoing request via `http.DefaultTransport` or custom `http.Transport` used by any `http.Client`.
+2. Matches outgoing HTTP requests against a pool of defined HTTP mock expectations in FIFO declaration order.
+3. If at least one mock matches, it will be used in order to compose the mock HTTP response.
+4. If no mock can be matched, it will resolve the request with an error, unless real networking mode is enable, in which case a real HTTP request will be performed.
+
+## Tips
+
+#### Testing
+
+Declare your mocks before you start declaring the concrete test logic:
+
+```go
+func TestFoo(t *testing.T) {
+ defer gock.Off() // Flush pending mocks after test execution
+
+ gock.New("http://server.com").
+ Get("/bar").
+ Reply(200).
+ JSON(map[string]string{"foo": "bar"})
+
+ // Your test code starts here...
+}
+```
+
+#### Race conditions
+
+If you're running concurrent code, be aware that your mocks are declared first to avoid unexpected
+race conditions while configuring `gock` or intercepting custom HTTP clients.
+
+`gock` is not fully thread-safe, but sensible parts are.
+Any help making `gock` more reliable in this sense is appreciated.
+
+#### Define complex mocks first
+
+If you're mocking a bunch of mocks in the same test suite, it's recommended to define the more
+concrete mocks first, and then the generic ones.
+
+This approach usually avoids matching unexpected generic mocks (e.g: specific header, body payload...) instead of the generic ones that performs less complex matches.
+
+#### Disable `gock` traffic interception once done
+
+In other to minimize potential side effects within your test code, it's a good practice
+disabling `gock` once you are done with your HTTP testing logic.
+
+A Go idiomatic approach for doing this can be using it in a `defer` statement, such as:
+
+```go
+func TestGock (t *testing.T) {
+ defer gock.Off()
+
+ // ... my test code goes here
+}
+```
+
+#### Intercept an `http.Client` just once
+
+You don't need to intercept multiple times the same `http.Client` instance.
+
+Just call `gock.InterceptClient(client)` once, typically at the beginning of your test scenarios.
+
+#### Restore an `http.Client` after interception
+
+**NOTE**: this is not required is you are using `http.DefaultClient` or `http.DefaultTransport`.
+
+As a good testing pattern, you should call `gock.RestoreClient(client)` after running your test scenario, typically as after clean up hook.
+
+You can also use a `defer` statement for doing it, as you do with `gock.Off()`, such as:
+
+```go
+func TestGock (t *testing.T) {
+ defer gock.Off()
+ defer gock.RestoreClient(client)
+
+ // ... my test code goes here
+}
+```
+
+## Examples
+
+See [examples](https://github.com/h2non/gock/tree/master/_examples) directory for more featured use cases.
+
+#### Simple mocking via tests
+
+```go
+package test
+
+import (
+ "io/ioutil"
+ "net/http"
+ "testing"
+
+ "github.com/nbio/st"
+ "github.com/h2non/gock"
+)
+
+func TestSimple(t *testing.T) {
+ defer gock.Off()
+
+ gock.New("http://foo.com").
+ Get("/bar").
+ Reply(200).
+ JSON(map[string]string{"foo": "bar"})
+
+ res, err := http.Get("http://foo.com/bar")
+ st.Expect(t, err, nil)
+ st.Expect(t, res.StatusCode, 200)
+
+ body, _ := ioutil.ReadAll(res.Body)
+ st.Expect(t, string(body)[:13], `{"foo":"bar"}`)
+
+ // Verify that we don't have pending mocks
+ st.Expect(t, gock.IsDone(), true)
+}
+```
+
+#### Request headers matching
+
+```go
+package test
+
+import (
+ "io/ioutil"
+ "net/http"
+ "testing"
+
+ "github.com/nbio/st"
+ "github.com/h2non/gock"
+)
+
+func TestMatchHeaders(t *testing.T) {
+ defer gock.Off()
+
+ gock.New("http://foo.com").
+ MatchHeader("Authorization", "^foo bar$").
+ MatchHeader("API", "1.[0-9]+").
+ HeaderPresent("Accept").
+ Reply(200).
+ BodyString("foo foo")
+
+ req, err := http.NewRequest("GET", "http://foo.com", nil)
+ req.Header.Set("Authorization", "foo bar")
+ req.Header.Set("API", "1.0")
+ req.Header.Set("Accept", "text/plain")
+
+ res, err := (&http.Client{}).Do(req)
+ st.Expect(t, err, nil)
+ st.Expect(t, res.StatusCode, 200)
+ body, _ := ioutil.ReadAll(res.Body)
+ st.Expect(t, string(body), "foo foo")
+
+ // Verify that we don't have pending mocks
+ st.Expect(t, gock.IsDone(), true)
+}
+```
+
+#### Request param matching
+
+```go
+package test
+
+import (
+ "io/ioutil"
+ "net/http"
+ "testing"
+
+ "github.com/nbio/st"
+ "github.com/h2non/gock"
+)
+
+func TestMatchParams(t *testing.T) {
+ defer gock.Off()
+
+ gock.New("http://foo.com").
+ MatchParam("page", "1").
+ MatchParam("per_page", "10").
+ Reply(200).
+ BodyString("foo foo")
+
+ req, err := http.NewRequest("GET", "http://foo.com?page=1&per_page=10", nil)
+
+ res, err := (&http.Client{}).Do(req)
+ st.Expect(t, err, nil)
+ st.Expect(t, res.StatusCode, 200)
+ body, _ := ioutil.ReadAll(res.Body)
+ st.Expect(t, string(body), "foo foo")
+
+ // Verify that we don't have pending mocks
+ st.Expect(t, gock.IsDone(), true)
+}
+```
+
+#### JSON body matching and response
+
+```go
+package test
+
+import (
+ "bytes"
+ "io/ioutil"
+ "net/http"
+ "testing"
+
+ "github.com/nbio/st"
+ "github.com/h2non/gock"
+)
+
+func TestMockSimple(t *testing.T) {
+ defer gock.Off()
+
+ gock.New("http://foo.com").
+ Post("/bar").
+ MatchType("json").
+ JSON(map[string]string{"foo": "bar"}).
+ Reply(201).
+ JSON(map[string]string{"bar": "foo"})
+
+ body := bytes.NewBuffer([]byte(`{"foo":"bar"}`))
+ res, err := http.Post("http://foo.com/bar", "application/json", body)
+ st.Expect(t, err, nil)
+ st.Expect(t, res.StatusCode, 201)
+
+ resBody, _ := ioutil.ReadAll(res.Body)
+ st.Expect(t, string(resBody)[:13], `{"bar":"foo"}`)
+
+ // Verify that we don't have pending mocks
+ st.Expect(t, gock.IsDone(), true)
+}
+```
+
+#### Mocking a custom http.Client and http.RoundTripper
+
+```go
+package test
+
+import (
+ "io/ioutil"
+ "net/http"
+ "testing"
+
+ "github.com/nbio/st"
+ "github.com/h2non/gock"
+)
+
+func TestClient(t *testing.T) {
+ defer gock.Off()
+
+ gock.New("http://foo.com").
+ Reply(200).
+ BodyString("foo foo")
+
+ req, err := http.NewRequest("GET", "http://foo.com", nil)
+ client := &http.Client{Transport: &http.Transport{}}
+ gock.InterceptClient(client)
+
+ res, err := client.Do(req)
+ st.Expect(t, err, nil)
+ st.Expect(t, res.StatusCode, 200)
+ body, _ := ioutil.ReadAll(res.Body)
+ st.Expect(t, string(body), "foo foo")
+
+ // Verify that we don't have pending mocks
+ st.Expect(t, gock.IsDone(), true)
+}
+```
+
+#### Enable real networking
+
+```go
+package main
+
+import (
+ "fmt"
+ "io/ioutil"
+ "net/http"
+
+ "github.com/h2non/gock"
+)
+
+func main() {
+ defer gock.Off()
+ defer gock.DisableNetworking()
+
+ gock.EnableNetworking()
+ gock.New("http://httpbin.org").
+ Get("/get").
+ Reply(201).
+ SetHeader("Server", "gock")
+
+ res, err := http.Get("http://httpbin.org/get")
+ if err != nil {
+ fmt.Errorf("Error: %s", err)
+ }
+
+ // The response status comes from the mock
+ fmt.Printf("Status: %d\n", res.StatusCode)
+ // The server header comes from mock as well
+ fmt.Printf("Server header: %s\n", res.Header.Get("Server"))
+ // Response body is the original
+ body, _ := ioutil.ReadAll(res.Body)
+ fmt.Printf("Body: %s", string(body))
+}
+```
+
+#### Debug intercepted http requests
+
+```go
+package main
+
+import (
+ "bytes"
+ "net/http"
+
+ "github.com/h2non/gock"
+)
+
+func main() {
+ defer gock.Off()
+ gock.Observe(gock.DumpRequest)
+
+ gock.New("http://foo.com").
+ Post("/bar").
+ MatchType("json").
+ JSON(map[string]string{"foo": "bar"}).
+ Reply(200)
+
+ body := bytes.NewBuffer([]byte(`{"foo":"bar"}`))
+ http.Post("http://foo.com/bar", "application/json", body)
+}
+
+```
+
+## Hacking it!
+
+You can easily hack `gock` defining custom matcher functions with own matching rules.
+
+See [add matcher functions](https://github.com/h2non/gock/blob/master/_examples/add_matchers/matchers.go) and [custom matching layer](https://github.com/h2non/gock/blob/master/_examples/custom_matcher/matcher.go) examples for further details.
+
+## License
+
+MIT - Tomas Aparicio
diff --git a/vendor/github.com/h2non/gock/gock.go b/vendor/github.com/h2non/gock/gock.go
new file mode 100644
index 000000000..c3a8333b5
--- /dev/null
+++ b/vendor/github.com/h2non/gock/gock.go
@@ -0,0 +1,178 @@
+package gock
+
+import (
+ "fmt"
+ "net/http"
+ "net/http/httputil"
+ "net/url"
+ "regexp"
+ "sync"
+)
+
+// mutex is used interally for locking thread-sensitive functions.
+var mutex = &sync.Mutex{}
+
+// config global singleton store.
+var config = struct {
+ Networking bool
+ NetworkingFilters []FilterRequestFunc
+ Observer ObserverFunc
+}{}
+
+// ObserverFunc is implemented by users to inspect the outgoing intercepted HTTP traffic
+type ObserverFunc func(*http.Request, Mock)
+
+// DumpRequest is a default implementation of ObserverFunc that dumps
+// the HTTP/1.x wire representation of the http request
+var DumpRequest ObserverFunc = func(request *http.Request, mock Mock) {
+ bytes, _ := httputil.DumpRequestOut(request, true)
+ fmt.Println(string(bytes))
+ fmt.Printf("\nMatches: %v\n---\n", mock != nil)
+}
+
+// track unmatched requests so they can be tested for
+var unmatchedRequests = []*http.Request{}
+
+// New creates and registers a new HTTP mock with
+// default settings and returns the Request DSL for HTTP mock
+// definition and set up.
+func New(uri string) *Request {
+ Intercept()
+
+ res := NewResponse()
+ req := NewRequest()
+ req.URLStruct, res.Error = url.Parse(normalizeURI(uri))
+
+ // Create the new mock expectation
+ exp := NewMock(req, res)
+ Register(exp)
+
+ return req
+}
+
+// Intercepting returns true if gock is currently able to intercept.
+func Intercepting() bool {
+ mutex.Lock()
+ defer mutex.Unlock()
+ return http.DefaultTransport == DefaultTransport
+}
+
+// Intercept enables HTTP traffic interception via http.DefaultTransport.
+// If you are using a custom HTTP transport, you have to use `gock.Transport()`
+func Intercept() {
+ if !Intercepting() {
+ mutex.Lock()
+ http.DefaultTransport = DefaultTransport
+ mutex.Unlock()
+ }
+}
+
+// InterceptClient allows the developer to intercept HTTP traffic using
+// a custom http.Client who uses a non default http.Transport/http.RoundTripper implementation.
+func InterceptClient(cli *http.Client) {
+ _, ok := cli.Transport.(*Transport)
+ if ok {
+ return // if transport already intercepted, just ignore it
+ }
+ trans := NewTransport()
+ trans.Transport = cli.Transport
+ cli.Transport = trans
+}
+
+// RestoreClient allows the developer to disable and restore the
+// original transport in the given http.Client.
+func RestoreClient(cli *http.Client) {
+ trans, ok := cli.Transport.(*Transport)
+ if !ok {
+ return
+ }
+ cli.Transport = trans.Transport
+}
+
+// Disable disables HTTP traffic interception by gock.
+func Disable() {
+ mutex.Lock()
+ defer mutex.Unlock()
+ http.DefaultTransport = NativeTransport
+}
+
+// Off disables the default HTTP interceptors and removes
+// all the registered mocks, even if they has not been intercepted yet.
+func Off() {
+ Flush()
+ Disable()
+}
+
+// OffAll is like `Off()`, but it also removes the unmatched requests registry.
+func OffAll() {
+ Flush()
+ Disable()
+ CleanUnmatchedRequest()
+}
+
+// Observe provides a hook to support inspection of the request and matched mock
+func Observe(fn ObserverFunc) {
+ mutex.Lock()
+ defer mutex.Unlock()
+ config.Observer = fn
+}
+
+// EnableNetworking enables real HTTP networking
+func EnableNetworking() {
+ mutex.Lock()
+ defer mutex.Unlock()
+ config.Networking = true
+}
+
+// DisableNetworking disables real HTTP networking
+func DisableNetworking() {
+ mutex.Lock()
+ defer mutex.Unlock()
+ config.Networking = false
+}
+
+// NetworkingFilter determines if an http.Request should be triggered or not.
+func NetworkingFilter(fn FilterRequestFunc) {
+ mutex.Lock()
+ defer mutex.Unlock()
+ config.NetworkingFilters = append(config.NetworkingFilters, fn)
+}
+
+// DisableNetworkingFilters disables registered networking filters.
+func DisableNetworkingFilters() {
+ mutex.Lock()
+ defer mutex.Unlock()
+ config.NetworkingFilters = []FilterRequestFunc{}
+}
+
+// GetUnmatchedRequests returns all requests that have been received but haven't matched any mock
+func GetUnmatchedRequests() []*http.Request {
+ mutex.Lock()
+ defer mutex.Unlock()
+ return unmatchedRequests
+}
+
+// HasUnmatchedRequest returns true if gock has received any requests that didn't match a mock
+func HasUnmatchedRequest() bool {
+ return len(GetUnmatchedRequests()) > 0
+}
+
+// CleanUnmatchedRequest cleans the unmatched requests internal registry.
+func CleanUnmatchedRequest() {
+ mutex.Lock()
+ defer mutex.Unlock()
+ unmatchedRequests = []*http.Request{}
+}
+
+func trackUnmatchedRequest(req *http.Request) {
+ mutex.Lock()
+ defer mutex.Unlock()
+ unmatchedRequests = append(unmatchedRequests, req)
+}
+
+func normalizeURI(uri string) string {
+ if ok, _ := regexp.MatchString("^http[s]?", uri); !ok {
+ return "http://" + uri
+ }
+ return uri
+}
diff --git a/vendor/github.com/h2non/gock/matcher.go b/vendor/github.com/h2non/gock/matcher.go
new file mode 100644
index 000000000..11a1d7eac
--- /dev/null
+++ b/vendor/github.com/h2non/gock/matcher.go
@@ -0,0 +1,137 @@
+package gock
+
+import "net/http"
+
+// MatchersHeader exposes an slice of HTTP header specific mock matchers.
+var MatchersHeader = []MatchFunc{
+ MatchMethod,
+ MatchScheme,
+ MatchHost,
+ MatchPath,
+ MatchHeaders,
+ MatchQueryParams,
+ MatchPathParams,
+}
+
+// MatchersBody exposes an slice of HTTP body specific built-in mock matchers.
+var MatchersBody = []MatchFunc{
+ MatchBody,
+}
+
+// Matchers stores all the built-in mock matchers.
+var Matchers = append(MatchersHeader, MatchersBody...)
+
+// DefaultMatcher stores the default Matcher instance used to match mocks.
+var DefaultMatcher = NewMatcher()
+
+// MatchFunc represents the required function
+// interface implemented by matchers.
+type MatchFunc func(*http.Request, *Request) (bool, error)
+
+// Matcher represents the required interface implemented by mock matchers.
+type Matcher interface {
+ // Get returns a slice of registered function matchers.
+ Get() []MatchFunc
+
+ // Add adds a new matcher function.
+ Add(MatchFunc)
+
+ // Set sets the matchers functions stack.
+ Set([]MatchFunc)
+
+ // Flush flushes the current matchers function stack.
+ Flush()
+
+ // Match matches the given http.Request with a mock Request.
+ Match(*http.Request, *Request) (bool, error)
+}
+
+// MockMatcher implements a mock matcher
+type MockMatcher struct {
+ Matchers []MatchFunc
+}
+
+// NewMatcher creates a new mock matcher
+// using the default matcher functions.
+func NewMatcher() *MockMatcher {
+ m := NewEmptyMatcher()
+ for _, matchFn := range Matchers {
+ m.Add(matchFn)
+ }
+ return m
+}
+
+// NewBasicMatcher creates a new matcher with header only mock matchers.
+func NewBasicMatcher() *MockMatcher {
+ m := NewEmptyMatcher()
+ for _, matchFn := range MatchersHeader {
+ m.Add(matchFn)
+ }
+ return m
+}
+
+// NewEmptyMatcher creates a new empty matcher without default matchers.
+func NewEmptyMatcher() *MockMatcher {
+ return &MockMatcher{Matchers: []MatchFunc{}}
+}
+
+// Get returns a slice of registered function matchers.
+func (m *MockMatcher) Get() []MatchFunc {
+ mutex.Lock()
+ defer mutex.Unlock()
+ return m.Matchers
+}
+
+// Add adds a new function matcher.
+func (m *MockMatcher) Add(fn MatchFunc) {
+ m.Matchers = append(m.Matchers, fn)
+}
+
+// Set sets a new stack of matchers functions.
+func (m *MockMatcher) Set(stack []MatchFunc) {
+ m.Matchers = stack
+}
+
+// Flush flushes the current matcher
+func (m *MockMatcher) Flush() {
+ m.Matchers = []MatchFunc{}
+}
+
+// Clone returns a separate MockMatcher instance that has a copy of the same MatcherFuncs
+func (m *MockMatcher) Clone() *MockMatcher {
+ m2 := NewEmptyMatcher()
+ for _, mFn := range m.Get() {
+ m2.Add(mFn)
+ }
+ return m2
+}
+
+// Match matches the given http.Request with a mock request
+// returning true in case that the request matches, otherwise false.
+func (m *MockMatcher) Match(req *http.Request, ereq *Request) (bool, error) {
+ for _, matcher := range m.Matchers {
+ matches, err := matcher(req, ereq)
+ if err != nil {
+ return false, err
+ }
+ if !matches {
+ return false, nil
+ }
+ }
+ return true, nil
+}
+
+// MatchMock is a helper function that matches the given http.Request
+// in the list of registered mocks, returning it if matches or error if it fails.
+func MatchMock(req *http.Request) (Mock, error) {
+ for _, mock := range GetAll() {
+ matches, err := mock.Match(req)
+ if err != nil {
+ return nil, err
+ }
+ if matches {
+ return mock, nil
+ }
+ }
+ return nil, nil
+}
diff --git a/vendor/github.com/h2non/gock/matchers.go b/vendor/github.com/h2non/gock/matchers.go
new file mode 100644
index 000000000..658c9a6e6
--- /dev/null
+++ b/vendor/github.com/h2non/gock/matchers.go
@@ -0,0 +1,266 @@
+package gock
+
+import (
+ "compress/gzip"
+ "encoding/json"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "reflect"
+ "regexp"
+ "strings"
+
+ "github.com/h2non/parth"
+)
+
+// EOL represents the end of line character.
+const EOL = 0xa
+
+// BodyTypes stores the supported MIME body types for matching.
+// Currently only text-based types.
+var BodyTypes = []string{
+ "text/html",
+ "text/plain",
+ "application/json",
+ "application/xml",
+ "multipart/form-data",
+ "application/x-www-form-urlencoded",
+}
+
+// BodyTypeAliases stores a generic MIME type by alias.
+var BodyTypeAliases = map[string]string{
+ "html": "text/html",
+ "text": "text/plain",
+ "json": "application/json",
+ "xml": "application/xml",
+ "form": "multipart/form-data",
+ "url": "application/x-www-form-urlencoded",
+}
+
+// CompressionSchemes stores the supported Content-Encoding types for decompression.
+var CompressionSchemes = []string{
+ "gzip",
+}
+
+// MatchMethod matches the HTTP method of the given request.
+func MatchMethod(req *http.Request, ereq *Request) (bool, error) {
+ return ereq.Method == "" || req.Method == ereq.Method, nil
+}
+
+// MatchScheme matches the request URL protocol scheme.
+func MatchScheme(req *http.Request, ereq *Request) (bool, error) {
+ return ereq.URLStruct.Scheme == "" || req.URL.Scheme == "" || ereq.URLStruct.Scheme == req.URL.Scheme, nil
+}
+
+// MatchHost matches the HTTP host header field of the given request.
+func MatchHost(req *http.Request, ereq *Request) (bool, error) {
+ url := ereq.URLStruct
+ if strings.EqualFold(url.Host, req.URL.Host) {
+ return true, nil
+ }
+ if !ereq.Options.DisableRegexpHost {
+ return regexp.MatchString(url.Host, req.URL.Host)
+ }
+ return false, nil
+}
+
+// MatchPath matches the HTTP URL path of the given request.
+func MatchPath(req *http.Request, ereq *Request) (bool, error) {
+ if req.URL.Path == ereq.URLStruct.Path {
+ return true, nil
+ }
+ return regexp.MatchString(ereq.URLStruct.Path, req.URL.Path)
+}
+
+// MatchHeaders matches the headers fields of the given request.
+func MatchHeaders(req *http.Request, ereq *Request) (bool, error) {
+ for key, value := range ereq.Header {
+ var err error
+ var match bool
+ var matchEscaped bool
+
+ for _, field := range req.Header[key] {
+ match, err = regexp.MatchString(value[0], field)
+ // Some values may contain reserved regex params e.g. "()", try matching with these escaped.
+ matchEscaped, err = regexp.MatchString(regexp.QuoteMeta(value[0]), field)
+
+ if err != nil {
+ return false, err
+ }
+ if match || matchEscaped {
+ break
+ }
+
+ }
+
+ if !match && !matchEscaped {
+ return false, nil
+ }
+ }
+ return true, nil
+}
+
+// MatchQueryParams matches the URL query params fields of the given request.
+func MatchQueryParams(req *http.Request, ereq *Request) (bool, error) {
+ for key, value := range ereq.URLStruct.Query() {
+ var err error
+ var match bool
+
+ for _, field := range req.URL.Query()[key] {
+ match, err = regexp.MatchString(value[0], field)
+ if err != nil {
+ return false, err
+ }
+ if match {
+ break
+ }
+ }
+
+ if !match {
+ return false, nil
+ }
+ }
+ return true, nil
+}
+
+// MatchPathParams matches the URL path parameters of the given request.
+func MatchPathParams(req *http.Request, ereq *Request) (bool, error) {
+ for key, value := range ereq.PathParams {
+ var s string
+
+ if err := parth.Sequent(req.URL.Path, key, &s); err != nil {
+ return false, nil
+ }
+
+ if s != value {
+ return false, nil
+ }
+ }
+ return true, nil
+}
+
+// MatchBody tries to match the request body.
+// TODO: not too smart now, needs several improvements.
+func MatchBody(req *http.Request, ereq *Request) (bool, error) {
+ // If match body is empty, just continue
+ if req.Method == "HEAD" || len(ereq.BodyBuffer) == 0 {
+ return true, nil
+ }
+
+ // Only can match certain MIME body types
+ if !supportedType(req, ereq) {
+ return false, nil
+ }
+
+ // Can only match certain compression schemes
+ if !supportedCompressionScheme(req) {
+ return false, nil
+ }
+
+ // Create a reader for the body depending on compression type
+ bodyReader := req.Body
+ if ereq.CompressionScheme != "" {
+ if ereq.CompressionScheme != req.Header.Get("Content-Encoding") {
+ return false, nil
+ }
+ compressedBodyReader, err := compressionReader(req.Body, ereq.CompressionScheme)
+ if err != nil {
+ return false, err
+ }
+ bodyReader = compressedBodyReader
+ }
+
+ // Read the whole request body
+ body, err := ioutil.ReadAll(bodyReader)
+ if err != nil {
+ return false, err
+ }
+
+ // Restore body reader stream
+ req.Body = createReadCloser(body)
+
+ // If empty, ignore the match
+ if len(body) == 0 && len(ereq.BodyBuffer) != 0 {
+ return false, nil
+ }
+
+ // Match body by atomic string comparison
+ bodyStr := castToString(body)
+ matchStr := castToString(ereq.BodyBuffer)
+ if bodyStr == matchStr {
+ return true, nil
+ }
+
+ // Match request body by regexp
+ match, _ := regexp.MatchString(matchStr, bodyStr)
+ if match == true {
+ return true, nil
+ }
+
+ // todo - add conditional do only perform the conversion of body bytes
+ // representation of JSON to a map and then compare them for equality.
+
+ // Check if the key + value pairs match
+ var bodyMap map[string]interface{}
+ var matchMap map[string]interface{}
+
+ // Ensure that both byte bodies that that should be JSON can be converted to maps.
+ umErr := json.Unmarshal(body, &bodyMap)
+ umErr2 := json.Unmarshal(ereq.BodyBuffer, &matchMap)
+ if umErr == nil && umErr2 == nil && reflect.DeepEqual(bodyMap, matchMap) {
+ return true, nil
+ }
+
+ return false, nil
+}
+
+func supportedType(req *http.Request, ereq *Request) bool {
+ mime := req.Header.Get("Content-Type")
+ if mime == "" {
+ return true
+ }
+
+ mimeToMatch := ereq.Header.Get("Content-Type")
+ if mimeToMatch != "" {
+ return mime == mimeToMatch
+ }
+
+ for _, kind := range BodyTypes {
+ if match, _ := regexp.MatchString(kind, mime); match {
+ return true
+ }
+ }
+ return false
+}
+
+func supportedCompressionScheme(req *http.Request) bool {
+ encoding := req.Header.Get("Content-Encoding")
+ if encoding == "" {
+ return true
+ }
+
+ for _, kind := range CompressionSchemes {
+ if match, _ := regexp.MatchString(kind, encoding); match {
+ return true
+ }
+ }
+ return false
+}
+
+func castToString(buf []byte) string {
+ str := string(buf)
+ tail := len(str) - 1
+ if str[tail] == EOL {
+ str = str[:tail]
+ }
+ return str
+}
+
+func compressionReader(r io.ReadCloser, scheme string) (io.ReadCloser, error) {
+ switch scheme {
+ case "gzip":
+ return gzip.NewReader(r)
+ default:
+ return r, nil
+ }
+}
diff --git a/vendor/github.com/h2non/gock/mock.go b/vendor/github.com/h2non/gock/mock.go
new file mode 100644
index 000000000..d28875bf3
--- /dev/null
+++ b/vendor/github.com/h2non/gock/mock.go
@@ -0,0 +1,172 @@
+package gock
+
+import (
+ "net/http"
+ "sync"
+)
+
+// Mock represents the required interface that must
+// be implemented by HTTP mock instances.
+type Mock interface {
+ // Disable disables the current mock manually.
+ Disable()
+
+ // Done returns true if the current mock is disabled.
+ Done() bool
+
+ // Request returns the mock Request instance.
+ Request() *Request
+
+ // Response returns the mock Response instance.
+ Response() *Response
+
+ // Match matches the given http.Request with the current mock.
+ Match(*http.Request) (bool, error)
+
+ // AddMatcher adds a new matcher function.
+ AddMatcher(MatchFunc)
+
+ // SetMatcher uses a new matcher implementation.
+ SetMatcher(Matcher)
+}
+
+// Mocker implements a Mock capable interface providing
+// a default mock configuration used internally to store mocks.
+type Mocker struct {
+ // disabler stores a disabler for thread safety checking current mock is disabled
+ disabler *disabler
+
+ // mutex stores the mock mutex for thread safety.
+ mutex sync.Mutex
+
+ // matcher stores a Matcher capable instance to match the given http.Request.
+ matcher Matcher
+
+ // request stores the mock Request to match.
+ request *Request
+
+ // response stores the mock Response to use in case of match.
+ response *Response
+}
+
+type disabler struct {
+ // disabled stores if the current mock is disabled.
+ disabled bool
+
+ // mutex stores the disabler mutex for thread safety.
+ mutex sync.RWMutex
+}
+
+func (d *disabler) isDisabled() bool {
+ d.mutex.RLock()
+ defer d.mutex.RUnlock()
+ return d.disabled
+}
+
+func (d *disabler) Disable() {
+ d.mutex.Lock()
+ defer d.mutex.Unlock()
+ d.disabled = true
+}
+
+// NewMock creates a new HTTP mock based on the given request and response instances.
+// It's mostly used internally.
+func NewMock(req *Request, res *Response) *Mocker {
+ mock := &Mocker{
+ disabler: new(disabler),
+ request: req,
+ response: res,
+ matcher: DefaultMatcher.Clone(),
+ }
+ res.Mock = mock
+ req.Mock = mock
+ req.Response = res
+ return mock
+}
+
+// Disable disables the current mock manually.
+func (m *Mocker) Disable() {
+ m.disabler.Disable()
+}
+
+// Done returns true in case that the current mock
+// instance is disabled and therefore must be removed.
+func (m *Mocker) Done() bool {
+ // prevent deadlock with m.mutex
+ if m.disabler.isDisabled() {
+ return true
+ }
+
+ m.mutex.Lock()
+ defer m.mutex.Unlock()
+ return !m.request.Persisted && m.request.Counter == 0
+}
+
+// Request returns the Request instance
+// configured for the current HTTP mock.
+func (m *Mocker) Request() *Request {
+ return m.request
+}
+
+// Response returns the Response instance
+// configured for the current HTTP mock.
+func (m *Mocker) Response() *Response {
+ return m.response
+}
+
+// Match matches the given http.Request with the current Request
+// mock expectation, returning true if matches.
+func (m *Mocker) Match(req *http.Request) (bool, error) {
+ if m.disabler.isDisabled() {
+ return false, nil
+ }
+
+ // Filter
+ for _, filter := range m.request.Filters {
+ if !filter(req) {
+ return false, nil
+ }
+ }
+
+ // Map
+ for _, mapper := range m.request.Mappers {
+ if treq := mapper(req); treq != nil {
+ req = treq
+ }
+ }
+
+ // Match
+ matches, err := m.matcher.Match(req, m.request)
+ if matches {
+ m.decrement()
+ }
+
+ return matches, err
+}
+
+// SetMatcher sets a new matcher implementation
+// for the current mock expectation.
+func (m *Mocker) SetMatcher(matcher Matcher) {
+ m.matcher = matcher
+}
+
+// AddMatcher adds a new matcher function
+// for the current mock expectation.
+func (m *Mocker) AddMatcher(fn MatchFunc) {
+ m.matcher.Add(fn)
+}
+
+// decrement decrements the current mock Request counter.
+func (m *Mocker) decrement() {
+ if m.request.Persisted {
+ return
+ }
+
+ m.mutex.Lock()
+ defer m.mutex.Unlock()
+
+ m.request.Counter--
+ if m.request.Counter == 0 {
+ m.disabler.Disable()
+ }
+}
diff --git a/vendor/github.com/h2non/gock/options.go b/vendor/github.com/h2non/gock/options.go
new file mode 100644
index 000000000..188aa58d8
--- /dev/null
+++ b/vendor/github.com/h2non/gock/options.go
@@ -0,0 +1,8 @@
+package gock
+
+// Options represents customized option for gock
+type Options struct {
+ // DisableRegexpHost stores if the host is only a plain string rather than regular expression,
+ // if DisableRegexpHost is true, host sets in gock.New(...) will be treated as plain string
+ DisableRegexpHost bool
+}
diff --git a/vendor/github.com/h2non/gock/request.go b/vendor/github.com/h2non/gock/request.go
new file mode 100644
index 000000000..5702417b2
--- /dev/null
+++ b/vendor/github.com/h2non/gock/request.go
@@ -0,0 +1,325 @@
+package gock
+
+import (
+ "encoding/base64"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "strings"
+)
+
+// MapRequestFunc represents the required function interface for request mappers.
+type MapRequestFunc func(*http.Request) *http.Request
+
+// FilterRequestFunc represents the required function interface for request filters.
+type FilterRequestFunc func(*http.Request) bool
+
+// Request represents the high-level HTTP request used to store
+// request fields used to match intercepted requests.
+type Request struct {
+ // Mock stores the parent mock reference for the current request mock used for method delegation.
+ Mock Mock
+
+ // Response stores the current Response instance for the current matches Request.
+ Response *Response
+
+ // Error stores the latest mock request configuration error.
+ Error error
+
+ // Counter stores the pending times that the current mock should be active.
+ Counter int
+
+ // Persisted stores if the current mock should be always active.
+ Persisted bool
+
+ // Options stores options for current Request.
+ Options Options
+
+ // URLStruct stores the parsed URL as *url.URL struct.
+ URLStruct *url.URL
+
+ // Method stores the Request HTTP method to match.
+ Method string
+
+ // CompressionScheme stores the Request Compression scheme to match and use for decompression.
+ CompressionScheme string
+
+ // Header stores the HTTP header fields to match.
+ Header http.Header
+
+ // Cookies stores the Request HTTP cookies values to match.
+ Cookies []*http.Cookie
+
+ // PathParams stores the path parameters to match.
+ PathParams map[string]string
+
+ // BodyBuffer stores the body data to match.
+ BodyBuffer []byte
+
+ // Mappers stores the request functions mappers used for matching.
+ Mappers []MapRequestFunc
+
+ // Filters stores the request functions filters used for matching.
+ Filters []FilterRequestFunc
+}
+
+// NewRequest creates a new Request instance.
+func NewRequest() *Request {
+ return &Request{
+ Counter: 1,
+ URLStruct: &url.URL{},
+ Header: make(http.Header),
+ PathParams: make(map[string]string),
+ }
+}
+
+// URL defines the mock URL to match.
+func (r *Request) URL(uri string) *Request {
+ r.URLStruct, r.Error = url.Parse(uri)
+ return r
+}
+
+// SetURL defines the url.URL struct to be used for matching.
+func (r *Request) SetURL(u *url.URL) *Request {
+ r.URLStruct = u
+ return r
+}
+
+// Path defines the mock URL path value to match.
+func (r *Request) Path(path string) *Request {
+ r.URLStruct.Path = path
+ return r
+}
+
+// Get specifies the GET method and the given URL path to match.
+func (r *Request) Get(path string) *Request {
+ return r.method("GET", path)
+}
+
+// Post specifies the POST method and the given URL path to match.
+func (r *Request) Post(path string) *Request {
+ return r.method("POST", path)
+}
+
+// Put specifies the PUT method and the given URL path to match.
+func (r *Request) Put(path string) *Request {
+ return r.method("PUT", path)
+}
+
+// Delete specifies the DELETE method and the given URL path to match.
+func (r *Request) Delete(path string) *Request {
+ return r.method("DELETE", path)
+}
+
+// Patch specifies the PATCH method and the given URL path to match.
+func (r *Request) Patch(path string) *Request {
+ return r.method("PATCH", path)
+}
+
+// Head specifies the HEAD method and the given URL path to match.
+func (r *Request) Head(path string) *Request {
+ return r.method("HEAD", path)
+}
+
+// method is a DRY shortcut used to declare the expected HTTP method and URL path.
+func (r *Request) method(method, path string) *Request {
+ if path != "/" {
+ r.URLStruct.Path = path
+ }
+ r.Method = strings.ToUpper(method)
+ return r
+}
+
+// Body defines the body data to match based on a io.Reader interface.
+func (r *Request) Body(body io.Reader) *Request {
+ r.BodyBuffer, r.Error = ioutil.ReadAll(body)
+ return r
+}
+
+// BodyString defines the body to match based on a given string.
+func (r *Request) BodyString(body string) *Request {
+ r.BodyBuffer = []byte(body)
+ return r
+}
+
+// File defines the body to match based on the given file path string.
+func (r *Request) File(path string) *Request {
+ r.BodyBuffer, r.Error = ioutil.ReadFile(path)
+ return r
+}
+
+// Compression defines the request compression scheme, and enables automatic body decompression.
+// Supports only the "gzip" scheme so far.
+func (r *Request) Compression(scheme string) *Request {
+ r.Header.Set("Content-Encoding", scheme)
+ r.CompressionScheme = scheme
+ return r
+}
+
+// JSON defines the JSON body to match based on a given structure.
+func (r *Request) JSON(data interface{}) *Request {
+ if r.Header.Get("Content-Type") == "" {
+ r.Header.Set("Content-Type", "application/json")
+ }
+ r.BodyBuffer, r.Error = readAndDecode(data, "json")
+ return r
+}
+
+// XML defines the XML body to match based on a given structure.
+func (r *Request) XML(data interface{}) *Request {
+ if r.Header.Get("Content-Type") == "" {
+ r.Header.Set("Content-Type", "application/xml")
+ }
+ r.BodyBuffer, r.Error = readAndDecode(data, "xml")
+ return r
+}
+
+// MatchType defines the request Content-Type MIME header field.
+// Supports custom MIME types and type aliases. E.g: json, xml, form, text...
+func (r *Request) MatchType(kind string) *Request {
+ mime := BodyTypeAliases[kind]
+ if mime != "" {
+ kind = mime
+ }
+ r.Header.Set("Content-Type", kind)
+ return r
+}
+
+// BasicAuth defines a username and password for HTTP Basic Authentication
+func (r *Request) BasicAuth(username, password string) *Request {
+ r.Header.Set("Authorization", "Basic "+basicAuth(username, password))
+ return r
+}
+
+// MatchHeader defines a new key and value header to match.
+func (r *Request) MatchHeader(key, value string) *Request {
+ r.Header.Set(key, value)
+ return r
+}
+
+// HeaderPresent defines that a header field must be present in the request.
+func (r *Request) HeaderPresent(key string) *Request {
+ r.Header.Set(key, ".*")
+ return r
+}
+
+// MatchHeaders defines a map of key-value headers to match.
+func (r *Request) MatchHeaders(headers map[string]string) *Request {
+ for key, value := range headers {
+ r.Header.Set(key, value)
+ }
+ return r
+}
+
+// MatchParam defines a new key and value URL query param to match.
+func (r *Request) MatchParam(key, value string) *Request {
+ query := r.URLStruct.Query()
+ query.Set(key, value)
+ r.URLStruct.RawQuery = query.Encode()
+ return r
+}
+
+// MatchParams defines a map of URL query param key-value to match.
+func (r *Request) MatchParams(params map[string]string) *Request {
+ query := r.URLStruct.Query()
+ for key, value := range params {
+ query.Set(key, value)
+ }
+ r.URLStruct.RawQuery = query.Encode()
+ return r
+}
+
+// ParamPresent matches if the given query param key is present in the URL.
+func (r *Request) ParamPresent(key string) *Request {
+ r.MatchParam(key, ".*")
+ return r
+}
+
+// PathParam matches if a given path parameter key is present in the URL.
+//
+// The value is representative of the restful resource the key defines, e.g.
+// // /users/123/name
+// r.PathParam("users", "123")
+// would match.
+func (r *Request) PathParam(key, val string) *Request {
+ r.PathParams[key] = val
+
+ return r
+}
+
+// Persist defines the current HTTP mock as persistent and won't be removed after intercepting it.
+func (r *Request) Persist() *Request {
+ r.Persisted = true
+ return r
+}
+
+// WithOptions sets the options for the request.
+func (r *Request) WithOptions(options Options) *Request {
+ r.Options = options
+ return r
+}
+
+// Times defines the number of times that the current HTTP mock should remain active.
+func (r *Request) Times(num int) *Request {
+ r.Counter = num
+ return r
+}
+
+// AddMatcher adds a new matcher function to match the request.
+func (r *Request) AddMatcher(fn MatchFunc) *Request {
+ r.Mock.AddMatcher(fn)
+ return r
+}
+
+// SetMatcher sets a new matcher function to match the request.
+func (r *Request) SetMatcher(matcher Matcher) *Request {
+ r.Mock.SetMatcher(matcher)
+ return r
+}
+
+// Map adds a new request mapper function to map http.Request before the matching process.
+func (r *Request) Map(fn MapRequestFunc) *Request {
+ r.Mappers = append(r.Mappers, fn)
+ return r
+}
+
+// Filter filters a new request filter function to filter http.Request before the matching process.
+func (r *Request) Filter(fn FilterRequestFunc) *Request {
+ r.Filters = append(r.Filters, fn)
+ return r
+}
+
+// EnableNetworking enables the use real networking for the current mock.
+func (r *Request) EnableNetworking() *Request {
+ if r.Response != nil {
+ r.Response.UseNetwork = true
+ }
+ return r
+}
+
+// Reply defines the Response status code and returns the mock Response DSL.
+func (r *Request) Reply(status int) *Response {
+ return r.Response.Status(status)
+}
+
+// ReplyError defines the Response simulated error.
+func (r *Request) ReplyError(err error) *Response {
+ return r.Response.SetError(err)
+}
+
+// ReplyFunc allows the developer to define the mock response via a custom function.
+func (r *Request) ReplyFunc(replier func(*Response)) *Response {
+ replier(r.Response)
+ return r.Response
+}
+
+// See 2 (end of page 4) https://www.ietf.org/rfc/rfc2617.txt
+// "To receive authorization, the client sends the userid and password,
+// separated by a single colon (":") character, within a base64
+// encoded string in the credentials."
+// It is not meant to be urlencoded.
+func basicAuth(username, password string) string {
+ auth := username + ":" + password
+ return base64.StdEncoding.EncodeToString([]byte(auth))
+}
diff --git a/vendor/github.com/h2non/gock/responder.go b/vendor/github.com/h2non/gock/responder.go
new file mode 100644
index 000000000..b71c7424f
--- /dev/null
+++ b/vendor/github.com/h2non/gock/responder.go
@@ -0,0 +1,105 @@
+package gock
+
+import (
+ "bytes"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "strconv"
+ "time"
+)
+
+// Responder builds a mock http.Response based on the given Response mock.
+func Responder(req *http.Request, mock *Response, res *http.Response) (*http.Response, error) {
+ // If error present, reply it
+ err := mock.Error
+ if err != nil {
+ return nil, err
+ }
+
+ if res == nil {
+ res = createResponse(req)
+ }
+
+ // Apply response filter
+ for _, filter := range mock.Filters {
+ if !filter(res) {
+ return res, nil
+ }
+ }
+
+ // Define mock status code
+ if mock.StatusCode != 0 {
+ res.Status = strconv.Itoa(mock.StatusCode) + " " + http.StatusText(mock.StatusCode)
+ res.StatusCode = mock.StatusCode
+ }
+
+ // Define headers by merging fields
+ res.Header = mergeHeaders(res, mock)
+
+ // Define mock body, if present
+ if len(mock.BodyBuffer) > 0 {
+ res.ContentLength = int64(len(mock.BodyBuffer))
+ res.Body = createReadCloser(mock.BodyBuffer)
+ }
+
+ // Apply response mappers
+ for _, mapper := range mock.Mappers {
+ if tres := mapper(res); tres != nil {
+ res = tres
+ }
+ }
+
+ // Sleep to simulate delay, if necessary
+ if mock.ResponseDelay > 0 {
+ // allow escaping from sleep due to request context expiration or cancellation
+ t := time.NewTimer(mock.ResponseDelay)
+ select {
+ case <-t.C:
+ case <-req.Context().Done():
+ // cleanly stop the timer
+ if !t.Stop() {
+ <-t.C
+ }
+ }
+ }
+
+ // check if the request context has ended. we could put this up in the delay code above, but putting it here
+ // has the added benefit of working even when there is no delay (very small timeouts, already-done contexts, etc.)
+ if err = req.Context().Err(); err != nil {
+ // cleanly close the response and return the context error
+ io.Copy(ioutil.Discard, res.Body)
+ res.Body.Close()
+ return nil, err
+ }
+
+ return res, err
+}
+
+// createResponse creates a new http.Response with default fields.
+func createResponse(req *http.Request) *http.Response {
+ return &http.Response{
+ ProtoMajor: 1,
+ ProtoMinor: 1,
+ Proto: "HTTP/1.1",
+ Request: req,
+ Header: make(http.Header),
+ Body: createReadCloser([]byte{}),
+ }
+}
+
+// mergeHeaders copies the mock headers.
+func mergeHeaders(res *http.Response, mres *Response) http.Header {
+ for key, values := range mres.Header {
+ for _, value := range values {
+ res.Header.Add(key, value)
+ }
+ }
+ return res.Header
+}
+
+// createReadCloser creates an io.ReadCloser from a byte slice that is suitable for use as an
+// http response body.
+func createReadCloser(body []byte) io.ReadCloser {
+ return ioutil.NopCloser(bytes.NewReader(body))
+}
diff --git a/vendor/github.com/h2non/gock/response.go b/vendor/github.com/h2non/gock/response.go
new file mode 100644
index 000000000..07b715809
--- /dev/null
+++ b/vendor/github.com/h2non/gock/response.go
@@ -0,0 +1,186 @@
+package gock
+
+import (
+ "bytes"
+ "encoding/json"
+ "encoding/xml"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "time"
+)
+
+// MapResponseFunc represents the required function interface impletemed by response mappers.
+type MapResponseFunc func(*http.Response) *http.Response
+
+// FilterResponseFunc represents the required function interface impletemed by response filters.
+type FilterResponseFunc func(*http.Response) bool
+
+// Response represents high-level HTTP fields to configure
+// and define HTTP responses intercepted by gock.
+type Response struct {
+ // Mock stores the parent mock reference for the current response mock used for method delegation.
+ Mock Mock
+
+ // Error stores the latest response configuration or injected error.
+ Error error
+
+ // UseNetwork enables the use of real network for the current mock.
+ UseNetwork bool
+
+ // StatusCode stores the response status code.
+ StatusCode int
+
+ // Headers stores the response headers.
+ Header http.Header
+
+ // Cookies stores the response cookie fields.
+ Cookies []*http.Cookie
+
+ // BodyBuffer stores the array of bytes to use as body.
+ BodyBuffer []byte
+
+ // ResponseDelay stores the simulated response delay.
+ ResponseDelay time.Duration
+
+ // Mappers stores the request functions mappers used for matching.
+ Mappers []MapResponseFunc
+
+ // Filters stores the request functions filters used for matching.
+ Filters []FilterResponseFunc
+}
+
+// NewResponse creates a new Response.
+func NewResponse() *Response {
+ return &Response{Header: make(http.Header)}
+}
+
+// Status defines the desired HTTP status code to reply in the current response.
+func (r *Response) Status(code int) *Response {
+ r.StatusCode = code
+ return r
+}
+
+// Type defines the response Content-Type MIME header field.
+// Supports type alias. E.g: json, xml, form, text...
+func (r *Response) Type(kind string) *Response {
+ mime := BodyTypeAliases[kind]
+ if mime != "" {
+ kind = mime
+ }
+ r.Header.Set("Content-Type", kind)
+ return r
+}
+
+// SetHeader sets a new header field in the mock response.
+func (r *Response) SetHeader(key, value string) *Response {
+ r.Header.Set(key, value)
+ return r
+}
+
+// AddHeader adds a new header field in the mock response
+// with out removing an existent one.
+func (r *Response) AddHeader(key, value string) *Response {
+ r.Header.Add(key, value)
+ return r
+}
+
+// SetHeaders sets a map of header fields in the mock response.
+func (r *Response) SetHeaders(headers map[string]string) *Response {
+ for key, value := range headers {
+ r.Header.Add(key, value)
+ }
+ return r
+}
+
+// Body sets the HTTP response body to be used.
+func (r *Response) Body(body io.Reader) *Response {
+ r.BodyBuffer, r.Error = ioutil.ReadAll(body)
+ return r
+}
+
+// BodyString defines the response body as string.
+func (r *Response) BodyString(body string) *Response {
+ r.BodyBuffer = []byte(body)
+ return r
+}
+
+// File defines the response body reading the data
+// from disk based on the file path string.
+func (r *Response) File(path string) *Response {
+ r.BodyBuffer, r.Error = ioutil.ReadFile(path)
+ return r
+}
+
+// JSON defines the response body based on a JSON based input.
+func (r *Response) JSON(data interface{}) *Response {
+ r.Header.Set("Content-Type", "application/json")
+ r.BodyBuffer, r.Error = readAndDecode(data, "json")
+ return r
+}
+
+// XML defines the response body based on a XML based input.
+func (r *Response) XML(data interface{}) *Response {
+ r.Header.Set("Content-Type", "application/xml")
+ r.BodyBuffer, r.Error = readAndDecode(data, "xml")
+ return r
+}
+
+// SetError defines the response simulated error.
+func (r *Response) SetError(err error) *Response {
+ r.Error = err
+ return r
+}
+
+// Delay defines the response simulated delay.
+// This feature is still experimental and will be improved in the future.
+func (r *Response) Delay(delay time.Duration) *Response {
+ r.ResponseDelay = delay
+ return r
+}
+
+// Map adds a new response mapper function to map http.Response before the matching process.
+func (r *Response) Map(fn MapResponseFunc) *Response {
+ r.Mappers = append(r.Mappers, fn)
+ return r
+}
+
+// Filter filters a new request filter function to filter http.Request before the matching process.
+func (r *Response) Filter(fn FilterResponseFunc) *Response {
+ r.Filters = append(r.Filters, fn)
+ return r
+}
+
+// EnableNetworking enables the use real networking for the current mock.
+func (r *Response) EnableNetworking() *Response {
+ r.UseNetwork = true
+ return r
+}
+
+// Done returns true if the mock was done and disabled.
+func (r *Response) Done() bool {
+ return r.Mock.Done()
+}
+
+func readAndDecode(data interface{}, kind string) ([]byte, error) {
+ buf := &bytes.Buffer{}
+
+ switch data.(type) {
+ case string:
+ buf.WriteString(data.(string))
+ case []byte:
+ buf.Write(data.([]byte))
+ default:
+ var err error
+ if kind == "xml" {
+ err = xml.NewEncoder(buf).Encode(data)
+ } else {
+ err = json.NewEncoder(buf).Encode(data)
+ }
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return ioutil.ReadAll(buf)
+}
diff --git a/vendor/github.com/h2non/gock/store.go b/vendor/github.com/h2non/gock/store.go
new file mode 100644
index 000000000..7ed131674
--- /dev/null
+++ b/vendor/github.com/h2non/gock/store.go
@@ -0,0 +1,100 @@
+package gock
+
+import (
+ "sync"
+)
+
+// storeMutex is used interally for store synchronization.
+var storeMutex = sync.RWMutex{}
+
+// mocks is internally used to store registered mocks.
+var mocks = []Mock{}
+
+// Register registers a new mock in the current mocks stack.
+func Register(mock Mock) {
+ if Exists(mock) {
+ return
+ }
+
+ // Make ops thread safe
+ storeMutex.Lock()
+ defer storeMutex.Unlock()
+
+ // Expose mock in request/response for delegation
+ mock.Request().Mock = mock
+ mock.Response().Mock = mock
+
+ // Registers the mock in the global store
+ mocks = append(mocks, mock)
+}
+
+// GetAll returns the current stack of registered mocks.
+func GetAll() []Mock {
+ storeMutex.RLock()
+ defer storeMutex.RUnlock()
+ return mocks
+}
+
+// Exists checks if the given Mock is already registered.
+func Exists(m Mock) bool {
+ storeMutex.RLock()
+ defer storeMutex.RUnlock()
+ for _, mock := range mocks {
+ if mock == m {
+ return true
+ }
+ }
+ return false
+}
+
+// Remove removes a registered mock by reference.
+func Remove(m Mock) {
+ for i, mock := range mocks {
+ if mock == m {
+ storeMutex.Lock()
+ mocks = append(mocks[:i], mocks[i+1:]...)
+ storeMutex.Unlock()
+ }
+ }
+}
+
+// Flush flushes the current stack of registered mocks.
+func Flush() {
+ storeMutex.Lock()
+ defer storeMutex.Unlock()
+ mocks = []Mock{}
+}
+
+// Pending returns an slice of pending mocks.
+func Pending() []Mock {
+ Clean()
+ storeMutex.RLock()
+ defer storeMutex.RUnlock()
+ return mocks
+}
+
+// IsDone returns true if all the registered mocks has been triggered successfully.
+func IsDone() bool {
+ return !IsPending()
+}
+
+// IsPending returns true if there are pending mocks.
+func IsPending() bool {
+ return len(Pending()) > 0
+}
+
+// Clean cleans the mocks store removing disabled or obsolete mocks.
+func Clean() {
+ storeMutex.Lock()
+ defer storeMutex.Unlock()
+
+ buf := []Mock{}
+ for _, mock := range mocks {
+ if mock.Done() {
+ continue
+ }
+ buf = append(buf, mock)
+ }
+
+ mocks = buf
+}
diff --git a/vendor/github.com/h2non/gock/transport.go b/vendor/github.com/h2non/gock/transport.go
new file mode 100644
index 000000000..5b2bba283
--- /dev/null
+++ b/vendor/github.com/h2non/gock/transport.go
@@ -0,0 +1,112 @@
+package gock
+
+import (
+ "errors"
+ "net/http"
+ "sync"
+)
+
+// var mutex *sync.Mutex = &sync.Mutex{}
+
+var (
+ // DefaultTransport stores the default mock transport used by gock.
+ DefaultTransport = NewTransport()
+
+ // NativeTransport stores the native net/http default transport
+ // in order to restore it when needed.
+ NativeTransport = http.DefaultTransport
+)
+
+var (
+ // ErrCannotMatch store the error returned in case of no matches.
+ ErrCannotMatch = errors.New("gock: cannot match any request")
+)
+
+// Transport implements http.RoundTripper, which fulfills single http requests issued by
+// an http.Client.
+//
+// gock's Transport encapsulates a given or default http.Transport for further
+// delegation, if needed.
+type Transport struct {
+ // mutex is used to make transport thread-safe of concurrent uses across goroutines.
+ mutex sync.Mutex
+
+ // Transport encapsulates the original http.RoundTripper transport interface for delegation.
+ Transport http.RoundTripper
+}
+
+// NewTransport creates a new *Transport with no responders.
+func NewTransport() *Transport {
+ return &Transport{Transport: NativeTransport}
+}
+
+// RoundTrip receives HTTP requests and routes them to the appropriate responder. It is required to
+// implement the http.RoundTripper interface. You will not interact with this directly, instead
+// the *http.Client you are using will call it for you.
+func (m *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
+ // Just act as a proxy if not intercepting
+ if !Intercepting() {
+ return m.Transport.RoundTrip(req)
+ }
+
+ m.mutex.Lock()
+ defer Clean()
+
+ var err error
+ var res *http.Response
+
+ // Match mock for the incoming http.Request
+ mock, err := MatchMock(req)
+ if err != nil {
+ m.mutex.Unlock()
+ return nil, err
+ }
+
+ // Invoke the observer with the intercepted http.Request and matched mock
+ if config.Observer != nil {
+ config.Observer(req, mock)
+ }
+
+ // Verify if should use real networking
+ networking := shouldUseNetwork(req, mock)
+ if !networking && mock == nil {
+ m.mutex.Unlock()
+ trackUnmatchedRequest(req)
+ return nil, ErrCannotMatch
+ }
+
+ // Ensure me unlock the mutex before building the response
+ m.mutex.Unlock()
+
+ // Perform real networking via original transport
+ if networking {
+ res, err = m.Transport.RoundTrip(req)
+ // In no mock matched, continue with the response
+ if err != nil || mock == nil {
+ return res, err
+ }
+ }
+
+ return Responder(req, mock.Response(), res)
+}
+
+// CancelRequest is a no-op function.
+func (m *Transport) CancelRequest(req *http.Request) {}
+
+func shouldUseNetwork(req *http.Request, mock Mock) bool {
+ if mock != nil && mock.Response().UseNetwork {
+ return true
+ }
+ if !config.Networking {
+ return false
+ }
+ if len(config.NetworkingFilters) == 0 {
+ return true
+ }
+ for _, filter := range config.NetworkingFilters {
+ if !filter(req) {
+ return false
+ }
+ }
+ return true
+}
diff --git a/vendor/github.com/h2non/gock/version.go b/vendor/github.com/h2non/gock/version.go
new file mode 100644
index 000000000..3ff99a271
--- /dev/null
+++ b/vendor/github.com/h2non/gock/version.go
@@ -0,0 +1,4 @@
+package gock
+
+// Version defines the current package semantic version.
+const Version = "1.2.0"
diff --git a/vendor/github.com/h2non/parth/LICENSE b/vendor/github.com/h2non/parth/LICENSE
new file mode 100644
index 000000000..a5325703a
--- /dev/null
+++ b/vendor/github.com/h2non/parth/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2018 codemodus
+
+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/h2non/parth/README.md b/vendor/github.com/h2non/parth/README.md
new file mode 100644
index 000000000..f8dd8df8e
--- /dev/null
+++ b/vendor/github.com/h2non/parth/README.md
@@ -0,0 +1,196 @@
+# parth
+
+ go get -u github.com/h2non/parth
+
+Package parth provides path parsing for segment unmarshaling and slicing. In
+other words, parth provides simple and flexible access to (URL) path parameters.
+
+Along with string, all basic non-alias types are supported. An interface is
+available for implementation by user-defined types. When handling an int, uint,
+or float of any size, the first valid value within the specified segment will be
+used.
+
+## Usage
+
+```go
+Variables
+func Segment(path string, i int, v interface{}) error
+func Sequent(path, key string, v interface{}) error
+func Span(path string, i, j int) (string, error)
+func SubSeg(path, key string, i int, v interface{}) error
+func SubSpan(path, key string, i, j int) (string, error)
+type Parth
+ func New(path string) *Parth
+ func NewBySpan(path string, i, j int) *Parth
+ func NewBySubSpan(path, key string, i, j int) *Parth
+ func (p *Parth) Err() error
+ func (p *Parth) Segment(i int, v interface{})
+ func (p *Parth) Sequent(key string, v interface{})
+ func (p *Parth) Span(i, j int) string
+ func (p *Parth) SubSeg(key string, i int, v interface{})
+ func (p *Parth) SubSpan(key string, i, j int) string
+type Unmarshaler
+```
+
+### Setup ("By Index")
+
+```go
+import (
+ "fmt"
+
+ "github.com/codemodus/parth"
+)
+
+func handler(w http.ResponseWriter, r *http.Request) {
+ var s string
+ if err := parth.Segment(r.URL.Path, 4, &s); err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ }
+
+ fmt.Println(r.URL.Path)
+ fmt.Printf("%v (%T)\n", s, s)
+
+ // Output:
+ // /some/path/things/42/others/3
+ // others (string)
+}
+```
+
+### Setup ("By Key")
+
+```go
+import (
+ "fmt"
+
+ "github.com/codemodus/parth"
+)
+
+func handler(w http.ResponseWriter, r *http.Request) {
+ var i int64
+ if err := parth.Sequent(r.URL.Path, "things", &i); err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ }
+
+ fmt.Println(r.URL.Path)
+ fmt.Printf("%v (%T)\n", i, i)
+
+ // Output:
+ // /some/path/things/42/others/3
+ // 42 (int64)
+}
+```
+
+### Setup (Parth Type)
+
+```go
+import (
+ "fmt"
+
+ "github.com/codemodus/parth"
+)
+
+func handler(w http.ResponseWriter, r *http.Request) {
+ var s string
+ var f float32
+
+ p := parth.New(r.URL.Path)
+ p.Segment(2, &s)
+ p.SubSeg("key", 1, &f)
+ if err := p.Err(); err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ }
+
+ fmt.Println(r.URL.Path)
+ fmt.Printf("%v (%T)\n", s, s)
+ fmt.Printf("%v (%T)\n", f, f)
+
+ // Output:
+ // /zero/one/two/key/four/5.5/six
+ // two (string)
+ // 5.5 (float32)
+}
+```
+
+### Setup (Unmarshaler)
+
+```go
+import (
+ "fmt"
+
+ "github.com/codemodus/parth"
+)
+
+func handler(w http.ResponseWriter, r *http.Request) {
+ /*
+ type mytype []byte
+
+ func (m *mytype) UnmarshalSegment(seg string) error {
+ *m = []byte(seg)
+ }
+ */
+
+ var m mytype
+ if err := parth.Segment(r.URL.Path, 4, &m); err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ }
+
+ fmt.Println(r.URL.Path)
+ fmt.Printf("%v == %q (%T)\n", m, m, m)
+
+ // Output:
+ // /zero/one/two/key/four/5.5/six
+ // [102 111 117 114] == "four" (mypkg.mytype)
+}
+```
+
+## More Info
+
+### Keep Using http.HandlerFunc And Minimize context.Context Usage
+
+The most obvious use case for parth is when working with any URL path such as
+the one found at http.Request.URL.Path. parth is fast enough that it can be used
+multiple times in place of a single use of similar router-parameter schemes or
+even context.Context. There is no need to use an alternate http handler function
+definition in order to pass data that is already being passed. The http.Request
+type already holds URL data and parth is great at handling it. Additionally,
+parth takes care of parsing selected path segments into the types actually
+needed. Parth not only does more, it's usually faster and less intrusive than
+the alternatives.
+
+### Indexes
+
+If an index is negative, the negative count begins with the last segment.
+Providing a 0 for the second index is a special case which acts as an alias for
+the end of the path. An error is returned if: 1. Any index is out of range of
+the path; 2. When there are two indexes, the first index does not precede the
+second index.
+
+### Keys
+
+If a key is involved, functions will only handle the portion of the path
+subsequent to the provided key. An error is returned if the key cannot be found
+in the path.
+
+### First Whole, First Decimal (Restated - Important!)
+
+When handling an int, uint, or float of any size, the first valid value within
+the specified segment will be used.
+
+## Documentation
+
+View the [GoDoc](http://godoc.org/github.com/codemodus/parth)
+
+## Benchmarks
+
+ Go 1.11
+ benchmark iter time/iter bytes alloc allocs
+ --------- ---- --------- ----------- ------
+ BenchmarkSegmentString-8 30000000 39.60 ns/op 0 B/op 0 allocs/op
+ BenchmarkSegmentInt-8 20000000 65.60 ns/op 0 B/op 0 allocs/op
+ BenchmarkSegmentIntNegIndex-8 20000000 86.60 ns/op 0 B/op 0 allocs/op
+ BenchmarkSpan-8 100000000 18.20 ns/op 0 B/op 0 allocs/op
+ BenchmarkStdlibSegmentString-8 5000000 454.00 ns/op 50 B/op 2 allocs/op
+ BenchmarkStdlibSegmentInt-8 3000000 526.00 ns/op 50 B/op 2 allocs/op
+ BenchmarkStdlibSpan-8 3000000 518.00 ns/op 69 B/op 2 allocs/op
+ BenchmarkContextLookupSetGet-8 1000000 1984.00 ns/op 480 B/op 6 allocs/op
+
diff --git a/vendor/github.com/h2non/parth/parth.go b/vendor/github.com/h2non/parth/parth.go
new file mode 100644
index 000000000..3e64d8fee
--- /dev/null
+++ b/vendor/github.com/h2non/parth/parth.go
@@ -0,0 +1,349 @@
+// Package parth provides path parsing for segment unmarshaling and slicing. In
+// other words, parth provides simple and flexible access to (URL) path
+// parameters.
+//
+// Along with string, all basic non-alias types are supported. An interface is
+// available for implementation by user-defined types. When handling an int,
+// uint, or float of any size, the first valid value within the specified
+// segment will be used.
+package parth
+
+import (
+ "errors"
+)
+
+// Unmarshaler is the interface implemented by types that can unmarshal a path
+// segment representation of themselves. It is safe to assume that the segment
+// data will not include slashes.
+type Unmarshaler interface {
+ UnmarshalSegment(string) error
+}
+
+// Err{Name} values facilitate error identification.
+var (
+ ErrUnknownType = errors.New("unknown type provided")
+
+ ErrFirstSegNotFound = errors.New("first segment not found by index")
+ ErrLastSegNotFound = errors.New("last segment not found by index")
+ ErrSegOrderReversed = errors.New("first segment must precede last segment")
+ ErrKeySegNotFound = errors.New("segment not found by key")
+
+ ErrDataUnparsable = errors.New("data cannot be parsed")
+)
+
+// Segment locates the path segment indicated by the index i and unmarshals it
+// into the provided type v. If the index is negative, the negative count
+// begins with the last segment. An error is returned if: 1. The type is not a
+// pointer to an instance of one of the basic non-alias types and does not
+// implement the Unmarshaler interface; 2. The index is out of range of the
+// path; 3. The located path segment data cannot be parsed as the provided type
+// or if an error is returned when using a provided Unmarshaler implementation.
+func Segment(path string, i int, v interface{}) error { //nolint
+ var err error
+
+ switch v := v.(type) {
+ case *bool:
+ *v, err = segmentToBool(path, i)
+
+ case *float32:
+ var f float64
+ f, err = segmentToFloatN(path, i, 32)
+ *v = float32(f)
+
+ case *float64:
+ *v, err = segmentToFloatN(path, i, 64)
+
+ case *int:
+ var n int64
+ n, err = segmentToIntN(path, i, 0)
+ *v = int(n)
+
+ case *int16:
+ var n int64
+ n, err = segmentToIntN(path, i, 16)
+ *v = int16(n)
+
+ case *int32:
+ var n int64
+ n, err = segmentToIntN(path, i, 32)
+ *v = int32(n)
+
+ case *int64:
+ *v, err = segmentToIntN(path, i, 64)
+
+ case *int8:
+ var n int64
+ n, err = segmentToIntN(path, i, 8)
+ *v = int8(n)
+
+ case *string:
+ *v, err = segmentToString(path, i)
+
+ case *uint:
+ var n uint64
+ n, err = segmentToUintN(path, i, 0)
+ *v = uint(n)
+
+ case *uint16:
+ var n uint64
+ n, err = segmentToUintN(path, i, 16)
+ *v = uint16(n)
+
+ case *uint32:
+ var n uint64
+ n, err = segmentToUintN(path, i, 32)
+ *v = uint32(n)
+
+ case *uint64:
+ *v, err = segmentToUintN(path, i, 64)
+
+ case *uint8:
+ var n uint64
+ n, err = segmentToUintN(path, i, 8)
+ *v = uint8(n)
+
+ case Unmarshaler:
+ var s string
+ s, err = segmentToString(path, i)
+ if err == nil {
+ err = v.UnmarshalSegment(s)
+ }
+
+ default:
+ err = ErrUnknownType
+ }
+
+ return err
+}
+
+// Sequent is similar to Segment, but uses a key to locate a segment and then
+// unmarshal the subsequent segment. It is a simple wrapper over SubSeg with an
+// index of 0.
+func Sequent(path, key string, v interface{}) error {
+ return SubSeg(path, key, 0, v)
+}
+
+// Span returns the path segments between two segment indexes i and j including
+// the first segment. If an index is negative, the negative count begins with
+// the last segment. Providing a 0 for the last index j is a special case which
+// acts as an alias for the end of the path. If the first segment does not begin
+// with a slash and it is part of the requested span, no slash will be added. An
+// error is returned if: 1. Either index is out of range of the path; 2. The
+// first index i does not precede the last index j.
+func Span(path string, i, j int) (string, error) {
+ var f, l int
+ var ok bool
+
+ if i < 0 {
+ f, ok = segStartIndexFromEnd(path, i)
+ } else {
+ f, ok = segStartIndexFromStart(path, i)
+ }
+ if !ok {
+ return "", ErrFirstSegNotFound
+ }
+
+ if j > 0 {
+ l, ok = segEndIndexFromStart(path, j)
+ } else {
+ l, ok = segEndIndexFromEnd(path, j)
+ }
+ if !ok {
+ return "", ErrLastSegNotFound
+ }
+
+ if f == l {
+ return "", nil
+ }
+
+ if f > l {
+ return "", ErrSegOrderReversed
+ }
+
+ return path[f:l], nil
+}
+
+// SubSeg is similar to Segment, but only handles the portion of the path
+// subsequent to the provided key. For example, to access the segment
+// immediately after a key, an index of 0 should be provided (see Sequent). An
+// error is returned if the key cannot be found in the path.
+func SubSeg(path, key string, i int, v interface{}) error { //nolint
+ var err error
+
+ switch v := v.(type) {
+ case *bool:
+ *v, err = subSegToBool(path, key, i)
+
+ case *float32:
+ var f float64
+ f, err = subSegToFloatN(path, key, i, 32)
+ *v = float32(f)
+
+ case *float64:
+ *v, err = subSegToFloatN(path, key, i, 64)
+
+ case *int:
+ var n int64
+ n, err = subSegToIntN(path, key, i, 0)
+ *v = int(n)
+
+ case *int16:
+ var n int64
+ n, err = subSegToIntN(path, key, i, 16)
+ *v = int16(n)
+
+ case *int32:
+ var n int64
+ n, err = subSegToIntN(path, key, i, 32)
+ *v = int32(n)
+
+ case *int64:
+ *v, err = subSegToIntN(path, key, i, 64)
+
+ case *int8:
+ var n int64
+ n, err = subSegToIntN(path, key, i, 8)
+ *v = int8(n)
+
+ case *string:
+ *v, err = subSegToString(path, key, i)
+
+ case *uint:
+ var n uint64
+ n, err = subSegToUintN(path, key, i, 0)
+ *v = uint(n)
+
+ case *uint16:
+ var n uint64
+ n, err = subSegToUintN(path, key, i, 16)
+ *v = uint16(n)
+
+ case *uint32:
+ var n uint64
+ n, err = subSegToUintN(path, key, i, 32)
+ *v = uint32(n)
+
+ case *uint64:
+ *v, err = subSegToUintN(path, key, i, 64)
+
+ case *uint8:
+ var n uint64
+ n, err = subSegToUintN(path, key, i, 8)
+ *v = uint8(n)
+
+ case Unmarshaler:
+ var s string
+ s, err = subSegToString(path, key, i)
+ if err == nil {
+ err = v.UnmarshalSegment(s)
+ }
+
+ default:
+ err = ErrUnknownType
+ }
+
+ return err
+}
+
+// SubSpan is similar to Span, but only handles the portion of the path
+// subsequent to the provided key. An error is returned if the key cannot be
+// found in the path.
+func SubSpan(path, key string, i, j int) (string, error) {
+ si, ok := segIndexByKey(path, key)
+ if !ok {
+ return "", ErrKeySegNotFound
+ }
+
+ if i >= 0 {
+ i++
+ }
+ if j > 0 {
+ j++
+ }
+
+ s, err := Span(path[si:], i, j)
+ if err != nil {
+ return "", err
+ }
+
+ return s, nil
+}
+
+// Parth manages path and error data for processing a single path multiple
+// times while error checking only once. Only the first encountered error is
+// stored as all subsequent calls to Parth methods that can error are elided.
+type Parth struct {
+ path string
+ err error
+}
+
+// New constructs a pointer to an instance of Parth around the provided path.
+func New(path string) *Parth {
+ return &Parth{path: path}
+}
+
+// NewBySpan constructs a pointer to an instance of Parth after preprocessing
+// the provided path with Span.
+func NewBySpan(path string, i, j int) *Parth {
+ s, err := Span(path, i, j)
+ return &Parth{s, err}
+}
+
+// NewBySubSpan constructs a pointer to an instance of Parth after
+// preprocessing the provided path with SubSpan.
+func NewBySubSpan(path, key string, i, j int) *Parth {
+ s, err := SubSpan(path, key, i, j)
+ return &Parth{s, err}
+}
+
+// Err returns the first error encountered by the *Parth receiver.
+func (p *Parth) Err() error {
+ return p.err
+}
+
+// Segment operates the same as the package-level function Segment.
+func (p *Parth) Segment(i int, v interface{}) {
+ if p.err != nil {
+ return
+ }
+
+ p.err = Segment(p.path, i, v)
+}
+
+// Sequent operates the same as the package-level function Sequent.
+func (p *Parth) Sequent(key string, v interface{}) {
+ p.SubSeg(key, 0, v)
+}
+
+// Span operates the same as the package-level function Span.
+func (p *Parth) Span(i, j int) string {
+ if p.err != nil {
+ return ""
+ }
+
+ s, err := Span(p.path, i, j)
+ p.err = err
+
+ return s
+}
+
+// SubSeg operates the same as the package-level function SubSeg.
+func (p *Parth) SubSeg(key string, i int, v interface{}) {
+ if p.err != nil {
+ return
+ }
+
+ p.err = SubSeg(p.path, key, i, v)
+}
+
+// SubSpan operates the same as the package-level function SubSpan.
+func (p *Parth) SubSpan(key string, i, j int) string {
+ if p.err != nil {
+ return ""
+ }
+
+ s, err := SubSpan(p.path, key, i, j)
+ p.err = err
+
+ return s
+}
diff --git a/vendor/github.com/h2non/parth/segindex.go b/vendor/github.com/h2non/parth/segindex.go
new file mode 100644
index 000000000..77861f99a
--- /dev/null
+++ b/vendor/github.com/h2non/parth/segindex.go
@@ -0,0 +1,118 @@
+package parth
+
+func segStartIndexFromStart(path string, seg int) (int, bool) {
+ if seg < 0 {
+ return 0, false
+ }
+
+ for n, ct := 0, 0; n < len(path); n++ {
+ if n > 0 && path[n] == '/' {
+ ct++
+ }
+
+ if ct == seg {
+ return n, true
+ }
+ }
+
+ return 0, false
+}
+
+func segStartIndexFromEnd(path string, seg int) (int, bool) {
+ if seg > -1 {
+ return 0, false
+ }
+
+ for n, ct := len(path)-1, 0; n >= 0; n-- {
+ if path[n] == '/' || n == 0 {
+ ct--
+ }
+
+ if ct == seg {
+ return n, true
+ }
+ }
+
+ return 0, false
+}
+
+func segEndIndexFromStart(path string, seg int) (int, bool) {
+ if seg < 1 {
+ return 0, false
+ }
+
+ for n, ct := 0, 0; n < len(path); n++ {
+ if path[n] == '/' && n > 0 {
+ ct++
+ }
+
+ if ct == seg {
+ return n, true
+ }
+
+ if n+1 == len(path) && ct+1 == seg {
+ return n + 1, true
+ }
+ }
+
+ return 0, false
+}
+
+func segEndIndexFromEnd(path string, seg int) (int, bool) {
+ if seg > 0 {
+ return 0, false
+ }
+
+ if seg == 0 {
+ return len(path), true
+ }
+
+ if len(path) == 1 && path[0] == '/' {
+ return 0, true
+ }
+
+ for n, ct := len(path)-1, 0; n >= 0; n-- {
+ if n == 0 || path[n] == '/' {
+ ct--
+ }
+
+ if ct == seg {
+ return n, true
+ }
+
+ }
+
+ return 0, false
+}
+
+func segIndexByKey(path, key string) (int, bool) { //nolint
+ if path == "" || key == "" {
+ return 0, false
+ }
+
+ for n := 0; n < len(path); n++ {
+ si, ok := segStartIndexFromStart(path, n)
+ if !ok {
+ return 0, false
+ }
+
+ if len(path[si:]) == len(key)+1 {
+ if path[si+1:] == key {
+ return si, true
+ }
+
+ return 0, false
+ }
+
+ tmpEI, ok := segStartIndexFromStart(path[si:], 1)
+ if !ok {
+ return 0, false
+ }
+
+ if path[si+1:tmpEI+si] == key || n == 0 && path[0] != '/' && path[si:tmpEI+si] == key {
+ return si, true
+ }
+ }
+
+ return 0, false
+}
diff --git a/vendor/github.com/h2non/parth/segtostr.go b/vendor/github.com/h2non/parth/segtostr.go
new file mode 100644
index 000000000..6e16a911b
--- /dev/null
+++ b/vendor/github.com/h2non/parth/segtostr.go
@@ -0,0 +1,305 @@
+package parth
+
+import (
+ "strconv"
+ "unicode"
+)
+
+func segmentToBool(path string, i int) (bool, error) {
+ s, err := segmentToString(path, i)
+ if err != nil {
+ return false, err
+ }
+
+ v, err := strconv.ParseBool(s)
+ if err != nil {
+ return false, ErrDataUnparsable
+ }
+
+ return v, nil
+}
+
+func segmentToFloatN(path string, i, size int) (float64, error) {
+ ss, err := segmentToString(path, i)
+ if err != nil {
+ return 0.0, err
+ }
+
+ s, ok := firstFloatFromString(ss)
+ if !ok {
+ return 0.0, err
+ }
+
+ v, err := strconv.ParseFloat(s, size)
+ if err != nil {
+ return 0.0, ErrDataUnparsable
+ }
+
+ return v, nil
+}
+
+func segmentToIntN(path string, i, size int) (int64, error) {
+ ss, err := segmentToString(path, i)
+ if err != nil {
+ return 0, err
+ }
+
+ s, ok := firstIntFromString(ss)
+ if !ok {
+ return 0, ErrDataUnparsable
+ }
+
+ v, err := strconv.ParseInt(s, 10, size)
+ if err != nil {
+ return 0, ErrDataUnparsable
+ }
+
+ return v, nil
+}
+
+func segmentToString(path string, i int) (string, error) {
+ j := i + 1
+ if i < 0 {
+ i--
+ }
+
+ s, err := Span(path, i, j)
+ if err != nil {
+ return "", err
+ }
+
+ if s[0] == '/' {
+ s = s[1:]
+ }
+
+ return s, nil
+}
+
+func segmentToUintN(path string, i, size int) (uint64, error) {
+ ss, err := segmentToString(path, i)
+ if err != nil {
+ return 0, err
+ }
+
+ s, ok := firstUintFromString(ss)
+ if !ok {
+ return 0, ErrDataUnparsable
+ }
+
+ v, err := strconv.ParseUint(s, 10, size)
+ if err != nil {
+ return 0, ErrDataUnparsable
+ }
+
+ return v, nil
+}
+
+func subSegToBool(path, key string, i int) (bool, error) {
+ s, err := subSegToString(path, key, i)
+ if err != nil {
+ return false, err
+ }
+
+ v, err := strconv.ParseBool(s)
+ if err != nil {
+ return false, ErrDataUnparsable
+ }
+
+ return v, nil
+}
+
+func subSegToFloatN(path, key string, i, size int) (float64, error) {
+ ss, err := subSegToString(path, key, i)
+ if err != nil {
+ return 0.0, err
+ }
+
+ s, ok := firstFloatFromString(ss)
+ if !ok {
+ return 0.0, ErrDataUnparsable
+ }
+
+ v, err := strconv.ParseFloat(s, size)
+ if err != nil {
+ return 0.0, ErrDataUnparsable
+ }
+
+ return v, nil
+}
+
+func subSegToIntN(path, key string, i, size int) (int64, error) {
+ ss, err := subSegToString(path, key, i)
+ if err != nil {
+ return 0, err
+ }
+
+ s, ok := firstIntFromString(ss)
+ if !ok {
+ return 0, ErrDataUnparsable
+ }
+
+ v, err := strconv.ParseInt(s, 10, size)
+ if err != nil {
+ return 0, ErrDataUnparsable
+ }
+
+ return v, nil
+}
+
+func subSegToString(path, key string, i int) (string, error) {
+ ki, ok := segIndexByKey(path, key)
+ if !ok {
+ return "", ErrKeySegNotFound
+ }
+
+ i++
+
+ s, err := segmentToString(path[ki:], i)
+ if err != nil {
+ return "", err
+ }
+
+ return s, nil
+}
+
+func subSegToUintN(path, key string, i, size int) (uint64, error) {
+ ss, err := subSegToString(path, key, i)
+ if err != nil {
+ return 0, err
+ }
+
+ s, ok := firstUintFromString(ss)
+ if !ok {
+ return 0, ErrDataUnparsable
+ }
+
+ v, err := strconv.ParseUint(s, 10, size)
+ if err != nil {
+ return 0, ErrDataUnparsable
+ }
+
+ return v, nil
+}
+
+func firstUintFromString(s string) (string, bool) {
+ ind, l := 0, 0
+
+ for n := 0; n < len(s); n++ {
+ if unicode.IsDigit(rune(s[n])) {
+ if l == 0 {
+ ind = n
+ }
+
+ l++
+ } else {
+ if l == 0 && s[n] == '.' {
+ if n+1 < len(s) && unicode.IsDigit(rune(s[n+1])) {
+ return "0", true
+ }
+
+ break
+ }
+
+ if l > 0 {
+ break
+ }
+ }
+ }
+
+ if l == 0 {
+ return "", false
+ }
+
+ return s[ind : ind+l], true
+}
+
+func firstIntFromString(s string) (string, bool) { //nolint
+ ind, l := 0, 0
+
+ for n := 0; n < len(s); n++ {
+ if unicode.IsDigit(rune(s[n])) {
+ if l == 0 {
+ ind = n
+ }
+
+ l++
+ } else if s[n] == '-' {
+ if l == 0 {
+ ind = n
+ l++
+ } else {
+ break
+ }
+ } else {
+ if l == 0 && s[n] == '.' {
+ if n+1 < len(s) && unicode.IsDigit(rune(s[n+1])) {
+ return "0", true
+ }
+
+ break
+ }
+
+ if l > 0 {
+ break
+ }
+ }
+ }
+
+ if l == 0 {
+ return "", false
+ }
+
+ return s[ind : ind+l], true
+}
+
+func firstFloatFromString(s string) (string, bool) { //nolint
+ c, ind, l := 0, 0, 0
+
+ for n := 0; n < len(s); n++ {
+ if unicode.IsDigit(rune(s[n])) {
+ if l == 0 {
+ ind = n
+ }
+
+ l++
+ } else if s[n] == '-' {
+ if l == 0 {
+ ind = n
+ l++
+ } else {
+ break
+ }
+ } else if s[n] == '.' {
+ if l == 0 {
+ ind = n
+ }
+
+ if c > 0 {
+ break
+ }
+
+ l++
+ c++
+ } else if s[n] == 'e' && l > 0 && n+1 < len(s) && s[n+1] == '+' {
+ l++
+ } else if s[n] == '+' && l > 0 && s[n-1] == 'e' {
+ if n+1 < len(s) && unicode.IsDigit(rune(s[n+1])) {
+ l++
+ continue
+ }
+
+ l--
+ break
+ } else {
+ if l > 0 {
+ break
+ }
+ }
+ }
+
+ if l == 0 || s[ind:ind+l] == "." {
+ return "", false
+ }
+
+ return s[ind : ind+l], true
+}
diff --git a/vendor/github.com/henvic/httpretty/.gitignore b/vendor/github.com/henvic/httpretty/.gitignore
new file mode 100644
index 000000000..9655699f7
--- /dev/null
+++ b/vendor/github.com/henvic/httpretty/.gitignore
@@ -0,0 +1,35 @@
+# Docs
+doc/*.md
+doc/*.1
+
+# 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
+
+.cover
+
+coverage.html
+coverage.out
+
+*.coverprofile
diff --git a/vendor/github.com/henvic/httpretty/CONTRIBUTING.md b/vendor/github.com/henvic/httpretty/CONTRIBUTING.md
new file mode 100644
index 000000000..8323a0069
--- /dev/null
+++ b/vendor/github.com/henvic/httpretty/CONTRIBUTING.md
@@ -0,0 +1,12 @@
+# Contributing to httpretty
+## Bug reports
+When reporting bugs, please add information about your operating system and Go version used to compile the code.
+
+If you can provide a code snippet reproducing the issue, please do so.
+
+## Code
+Please write code that satisfies [Go Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments) before submitting a pull-request.
+Your code should be properly covered by extensive unit tests.
+
+## Commit messages
+Please follow the Go [commit messages](https://github.com/golang/go/wiki/CommitMessage) convention when contributing code.
diff --git a/vendor/github.com/henvic/httpretty/LICENSE.md b/vendor/github.com/henvic/httpretty/LICENSE.md
new file mode 100644
index 000000000..426f2a874
--- /dev/null
+++ b/vendor/github.com/henvic/httpretty/LICENSE.md
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 Henrique Vicente
+
+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/henvic/httpretty/README.md b/vendor/github.com/henvic/httpretty/README.md
new file mode 100644
index 000000000..ae2c674fa
--- /dev/null
+++ b/vendor/github.com/henvic/httpretty/README.md
@@ -0,0 +1,100 @@
+# httpretty
+[![Go Reference](https://pkg.go.dev/badge/github.com/henvic/httpretty.svg)](https://pkg.go.dev/github.com/henvic/httpretty) [![Build Status](https://github.com/henvic/httpretty/workflows/Tests/badge.svg)](https://github.com/henvic/httpretty/actions?query=workflow%3ATests) [![Coverage Status](https://coveralls.io/repos/henvic/httpretty/badge.svg)](https://coveralls.io/r/henvic/httpretty) [![Go Report Card](https://goreportcard.com/badge/github.com/henvic/httpretty)](https://goreportcard.com/report/github.com/henvic/httpretty) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/3669/badge)](https://bestpractices.coreinfrastructure.org/projects/3669)
+
+Package httpretty prints the HTTP requests of your Go programs pretty on your terminal screen. It is mostly inspired in [curl](https://curl.haxx.se)'s `--verbose` mode, and also on the [httputil.DumpRequest](https://golang.org/pkg/net/http/httputil/) and similar functions.
+
+[![asciicast](https://asciinema.org/a/297429.svg)](https://asciinema.org/a/297429)
+
+## Setting up a logger
+You can define a logger with something like
+
+```go
+logger := &httpretty.Logger{
+ Time: true,
+ TLS: true,
+ RequestHeader: true,
+ RequestBody: true,
+ ResponseHeader: true,
+ ResponseBody: true,
+ Colors: true, // erase line if you don't like colors
+ Formatters: []httpretty.Formatter{&httpretty.JSONFormatter{}},
+}
+```
+
+This code will set up a logger with sane settings. By default the logger prints nothing but the request line (and the remote address, when using it on the server-side).
+
+### Using on the client-side
+You can set the transport for the [*net/http.Client](https://golang.org/pkg/net/http/#Client) you are using like this:
+
+```go
+client := &http.Client{
+ Transport: logger.RoundTripper(http.DefaultTransport),
+}
+
+// from now on, you can use client.Do, client.Get, etc. to create requests.
+```
+
+If you don't care about setting a new client, you can safely replace your existing http.DefaultClient with this:
+
+```go
+http.DefaultClient.Transport = logger.RoundTripper(http.DefaultClient.Transport)
+```
+
+Then httpretty is going to print information about regular requests to your terminal when code such as this is called:
+```go
+if _, err := http.Get("https://www.google.com/"); err != nil {
+ fmt.Fprintf(os.Stderr, "%+v\n", err)
+ os.Exit(1)
+}
+```
+
+However, have in mind you usually want to use a custom *http.Client to control things such as timeout.
+
+## Logging on the server-side
+You can use the logger quickly to log requests on your server. For example:
+
+```go
+logger.Middleware(mux)
+```
+
+The handler should by a http.Handler. Usually, you want this to be your `http.ServeMux` HTTP entrypoint.
+
+For working examples, please see the example directory.
+
+## Filtering
+You have two ways to filter a request so it isn't printed by the logger.
+
+### httpretty.WithHide
+You can filter any request by setting a request context before the request reaches `httpretty.RoundTripper`:
+
+```go
+req = req.WithContext(httpretty.WithHide(ctx))
+```
+
+### Filter function
+A second option is to implement
+
+```go
+type Filter func(req *http.Request) (skip bool, err error)
+```
+
+and set it as the filter for your logger. For example:
+
+```go
+logger.SetFilter(func filteredURIs(req *http.Request) (bool, error) {
+ if req.Method != http.MethodGet {
+ return true, nil
+ }
+
+ if path := req.URL.Path; path == "/debug" || strings.HasPrefix(path, "/debug/") {
+ return true, nil
+ }
+
+ return false
+})
+```
+
+## Formatters
+You can define a formatter for any media type by implementing the Formatter interface.
+
+We provide a JSONFormatter for convenience (it is not enabled by default).
diff --git a/vendor/github.com/henvic/httpretty/httpretty.go b/vendor/github.com/henvic/httpretty/httpretty.go
new file mode 100644
index 000000000..f757b0f18
--- /dev/null
+++ b/vendor/github.com/henvic/httpretty/httpretty.go
@@ -0,0 +1,418 @@
+// Package httpretty prints your HTTP requests pretty on your terminal screen.
+// You can use this package both on the client-side and on the server-side.
+//
+// This package provides a better way to view HTTP traffic without httputil
+// DumpRequest, DumpRequestOut, and DumpResponse heavy debugging functions.
+//
+// You can use the logger quickly to log requests you are opening. For example:
+//
+// package main
+//
+// import (
+// "fmt"
+// "net/http"
+// "os"
+//
+// "github.com/henvic/httpretty"
+// )
+//
+// func main() {
+// logger := &httpretty.Logger{
+// Time: true,
+// TLS: true,
+// RequestHeader: true,
+// RequestBody: true,
+// ResponseHeader: true,
+// ResponseBody: true,
+// Colors: true,
+// Formatters: []httpretty.Formatter{&httpretty.JSONFormatter{}},
+// }
+//
+// http.DefaultClient.Transport = logger.RoundTripper(http.DefaultClient.Transport) // tip: you can use it on any *http.Client
+//
+// if _, err := http.Get("https://www.google.com/"); err != nil {
+// fmt.Fprintf(os.Stderr, "%+v\n", err)
+// os.Exit(1)
+// }
+// }
+//
+// If you pass nil to the logger.RoundTripper it is going to fallback to http.DefaultTransport.
+//
+// You can use the logger quickly to log requests on your server. For example:
+//
+// logger := &httpretty.Logger{
+// Time: true,
+// TLS: true,
+// RequestHeader: true,
+// RequestBody: true,
+// ResponseHeader: true,
+// ResponseBody: true,
+// }
+//
+// logger.Middleware(handler)
+//
+// Note: server logs don't include response headers set by the server.
+// Client logs don't include request headers set by the HTTP client.
+package httpretty
+
+import (
+ "bytes"
+ "context"
+ "crypto/tls"
+ "encoding/json"
+ "errors"
+ "io"
+ "net/http"
+ "net/textproto"
+ "os"
+ "regexp"
+ "sync"
+
+ "github.com/henvic/httpretty/internal/color"
+)
+
+// Formatter can be used to format body.
+//
+// If the Format function returns an error, the content is printed in verbatim after a warning.
+// Match receives a media type from the Content-Type field. The body is formatted if it returns true.
+type Formatter interface {
+ Match(mediatype string) bool
+ Format(w io.Writer, src []byte) error
+}
+
+// WithHide can be used to protect a request from being exposed.
+func WithHide(ctx context.Context) context.Context {
+ return context.WithValue(ctx, contextHide{}, struct{}{})
+}
+
+// Logger provides a way for you to print client and server-side information about your HTTP traffic.
+type Logger struct {
+ // SkipRequestInfo avoids printing a line showing the request URI on all requests plus a line
+ // containing the remote address on server-side requests.
+ SkipRequestInfo bool
+
+ // Time the request began and its duration.
+ Time bool
+
+ // TLS information, such as certificates and ciphers.
+ // BUG(henvic): Currently, the TLS information prints after the response header, although it
+ // should be printed before the request header.
+ TLS bool
+
+ // RequestHeader set by the client or received from the server.
+ RequestHeader bool
+
+ // RequestBody sent by the client or received by the server.
+ RequestBody bool
+
+ // ResponseHeader received by the client or set by the HTTP handlers.
+ ResponseHeader bool
+
+ // ResponseBody received by the client or set by the server.
+ ResponseBody bool
+
+ // SkipSanitize bypasses sanitizing headers containing credentials (such as Authorization).
+ SkipSanitize bool
+
+ // Colors set ANSI escape codes that terminals use to print text in different colors.
+ Colors bool
+
+ // Formatters for the request and response bodies.
+ // No standard formatters are used. You need to add what you want to use explicitly.
+ // We provide a JSONFormatter for convenience (add it manually).
+ Formatters []Formatter
+
+ // MaxRequestBody the logger can print.
+ // If value is not set and Content-Length is not sent, 4096 bytes is considered.
+ MaxRequestBody int64
+
+ // MaxResponseBody the logger can print.
+ // If value is not set and Content-Length is not sent, 4096 bytes is considered.
+ MaxResponseBody int64
+
+ mu sync.Mutex // ensures atomic writes; protects the following fields
+ w io.Writer
+ filter Filter
+ skipHeader map[string]struct{}
+ bodyFilter BodyFilter
+ flusher Flusher
+}
+
+// Filter allows you to skip requests.
+//
+// If an error happens and you want to log it, you can pass a not-null error value.
+type Filter func(req *http.Request) (skip bool, err error)
+
+// BodyFilter allows you to skip printing a HTTP body based on its associated Header.
+//
+// It can be used for omitting HTTP Request and Response bodies.
+// You can filter by checking properties such as Content-Type or Content-Length.
+//
+// On a HTTP server, this function is called even when no body is present due to
+// http.Request always carrying a non-nil value.
+type BodyFilter func(h http.Header) (skip bool, err error)
+
+// Flusher defines how logger prints requests.
+type Flusher int
+
+// Logger can print without flushing, when they are available, or when the request is done.
+const (
+ // NoBuffer strategy prints anything immediately, without buffering.
+ // It has the issue of mingling concurrent requests in unpredictable ways.
+ NoBuffer Flusher = iota
+
+ // OnReady buffers and prints each step of the request or response (header, body) whenever they are ready.
+ // It reduces mingling caused by mingling but does not give any ordering guarantee, so responses can still be out of order.
+ OnReady
+
+ // OnEnd buffers the whole request and flushes it once, in the end.
+ OnEnd
+)
+
+// SetFilter allows you to set a function to skip requests.
+// Pass nil to remove the filter. This method is concurrency safe.
+func (l *Logger) SetFilter(f Filter) {
+ l.mu.Lock()
+ defer l.mu.Unlock()
+ l.filter = f
+}
+
+// SkipHeader allows you to skip printing specific headers.
+// This method is concurrency safe.
+func (l *Logger) SkipHeader(headers []string) {
+ l.mu.Lock()
+ defer l.mu.Unlock()
+ m := map[string]struct{}{}
+ for _, h := range headers {
+ m[textproto.CanonicalMIMEHeaderKey(h)] = struct{}{}
+ }
+ l.skipHeader = m
+}
+
+// SetBodyFilter allows you to set a function to skip printing a body.
+// Pass nil to remove the body filter. This method is concurrency safe.
+func (l *Logger) SetBodyFilter(f BodyFilter) {
+ l.mu.Lock()
+ defer l.mu.Unlock()
+ l.bodyFilter = f
+}
+
+// SetOutput sets the output destination for the logger.
+func (l *Logger) SetOutput(w io.Writer) {
+ l.mu.Lock()
+ defer l.mu.Unlock()
+ l.w = w
+}
+
+// SetFlusher sets the flush strategy for the logger.
+func (l *Logger) SetFlusher(f Flusher) {
+ l.mu.Lock()
+ defer l.mu.Unlock()
+ l.flusher = f
+}
+
+func (l *Logger) getWriter() io.Writer {
+ if l.w == nil {
+ return os.Stdout
+ }
+
+ return l.w
+}
+
+func (l *Logger) getFilter() Filter {
+ l.mu.Lock()
+ f := l.filter
+ defer l.mu.Unlock()
+ return f
+}
+
+func (l *Logger) getBodyFilter() BodyFilter {
+ l.mu.Lock()
+ f := l.bodyFilter
+ defer l.mu.Unlock()
+ return f
+}
+
+func (l *Logger) cloneSkipHeader() map[string]struct{} {
+ l.mu.Lock()
+ skipped := l.skipHeader
+ l.mu.Unlock()
+
+ m := map[string]struct{}{}
+ for h := range skipped {
+ m[h] = struct{}{}
+ }
+
+ return m
+}
+
+type contextHide struct{}
+
+type roundTripper struct {
+ logger *Logger
+ rt http.RoundTripper
+}
+
+// RoundTripper returns a RoundTripper that uses the logger.
+func (l *Logger) RoundTripper(rt http.RoundTripper) http.RoundTripper {
+ return roundTripper{
+ logger: l,
+ rt: rt,
+ }
+}
+
+// RoundTrip implements the http.RoundTrip interface.
+func (r roundTripper) RoundTrip(req *http.Request) (resp *http.Response, err error) {
+ tripper := r.rt
+ if tripper == nil {
+ // BUG(henvic): net/http data race condition when the client
+ // does concurrent requests using the very same HTTP transport.
+ // See Go standard library issue https://golang.org/issue/30597
+ tripper = http.RoundTripper(http.DefaultTransport)
+ }
+ l := r.logger
+ p := newPrinter(l)
+ defer p.flush()
+ if hide := req.Context().Value(contextHide{}); hide != nil || p.checkFilter(req) {
+ return tripper.RoundTrip(req)
+ }
+ var tlsClientConfig *tls.Config
+ if l.Time {
+ defer p.printTimeRequest()()
+ }
+ if !l.SkipRequestInfo {
+ p.printRequestInfo(req)
+ }
+ // Try to get some information from transport
+ transport, ok := tripper.(*http.Transport)
+ // If proxy is used, then print information about proxy server
+ if ok && transport.Proxy != nil {
+ proxyUrl, err := transport.Proxy(req)
+ if proxyUrl != nil && err == nil {
+ p.printf("* Using proxy: %s\n", p.format(color.FgBlue, proxyUrl.String()))
+ }
+ }
+ if ok && transport.TLSClientConfig != nil {
+ tlsClientConfig = transport.TLSClientConfig
+ if tlsClientConfig.InsecureSkipVerify {
+ p.printf("* Skipping TLS verification: %s\n",
+ p.format(color.FgRed, "connection is susceptible to man-in-the-middle attacks."))
+ }
+ }
+ // Maybe print outgoing TLS information.
+ if l.TLS && tlsClientConfig != nil {
+ // please remember http.Request.TLS is ignored by the HTTP client.
+ p.printOutgoingClientTLS(tlsClientConfig)
+ }
+ p.printRequest(req)
+ defer func() {
+ if err != nil {
+ p.printf("* %s\n", p.format(color.FgRed, err.Error()))
+ if resp == nil {
+ return
+ }
+ }
+ if l.TLS {
+ p.printTLSInfo(resp.TLS, false)
+ p.printTLSServer(req.Host, resp.TLS)
+ }
+ p.printResponse(resp)
+ }()
+ return tripper.RoundTrip(req)
+}
+
+// Middleware for logging incoming requests to a HTTP server.
+func (l *Logger) Middleware(next http.Handler) http.Handler {
+ return httpHandler{
+ logger: l,
+ next: next,
+ }
+}
+
+type httpHandler struct {
+ logger *Logger
+ next http.Handler
+}
+
+// ServeHTTP is a middleware for logging incoming requests to a HTTP server.
+func (h httpHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+ l := h.logger
+ p := newPrinter(l)
+ defer p.flush()
+ if hide := req.Context().Value(contextHide{}); hide != nil || p.checkFilter(req) {
+ h.next.ServeHTTP(w, req)
+ return
+ }
+ if p.logger.Time {
+ defer p.printTimeRequest()()
+ }
+ if !p.logger.SkipRequestInfo {
+ p.printRequestInfo(req)
+ }
+ if p.logger.TLS {
+ p.printTLSInfo(req.TLS, true)
+ p.printIncomingClientTLS(req.TLS)
+ }
+ p.printRequest(req)
+ rec := &responseRecorder{
+ ResponseWriter: w,
+ statusCode: http.StatusOK,
+ maxReadableBody: l.MaxResponseBody,
+ buf: &bytes.Buffer{},
+ }
+ defer p.printServerResponse(req, rec)
+ h.next.ServeHTTP(rec, req)
+}
+
+// PrintRequest prints a request, even when WithHide is used to hide it.
+//
+// It doesn't log TLS connection details or request duration.
+func (l *Logger) PrintRequest(req *http.Request) {
+ var p = printer{logger: l}
+ if skip := p.checkFilter(req); skip {
+ return
+ }
+ p.printRequest(req)
+}
+
+// PrintResponse prints a response.
+func (l *Logger) PrintResponse(resp *http.Response) {
+ var p = printer{logger: l}
+ p.printResponse(resp)
+}
+
+// JSONFormatter helps you read unreadable JSON documents.
+//
+// github.com/tidwall/pretty could be used to add colors to it.
+// However, it would add an external dependency. If you want, you can define
+// your own formatter using it or anything else. See Formatter.
+type JSONFormatter struct{}
+
+// jsonTypeRE can be used to identify JSON media types, such as
+// application/json or application/vnd.api+json.
+//
+// Source: https://github.com/cli/cli/blob/63a4319f6caedccbadf1bf0317d70b6f0cb1b5b9/internal/authflow/flow.go#L27
+var jsonTypeRE = regexp.MustCompile(`[/+]json($|;)`)
+
+// Match JSON media type.
+func (j *JSONFormatter) Match(mediatype string) bool {
+ return jsonTypeRE.MatchString(mediatype)
+}
+
+// Format JSON content.
+func (j *JSONFormatter) Format(w io.Writer, src []byte) error {
+ if !json.Valid(src) {
+ // We want to get the error of json.checkValid, not unmarshal it.
+ // The happy path has been optimized, maybe prematurely.
+ if err := json.Unmarshal(src, &json.RawMessage{}); err != nil {
+ return err
+ }
+ }
+ // avoiding allocation as we use *bytes.Buffer to store the formatted body before printing
+ dst, ok := w.(*bytes.Buffer)
+ if !ok {
+ // mitigating panic to avoid upsetting anyone who uses this directly
+ return errors.New("underlying writer for JSONFormatter must be *bytes.Buffer")
+ }
+ return json.Indent(dst, src, "", " ")
+}
diff --git a/vendor/github.com/henvic/httpretty/internal/color/color.go b/vendor/github.com/henvic/httpretty/internal/color/color.go
new file mode 100644
index 000000000..fb8a6dba3
--- /dev/null
+++ b/vendor/github.com/henvic/httpretty/internal/color/color.go
@@ -0,0 +1,164 @@
+// Package color can be used to add color to your terminal using ANSI escape code (or sequences).
+//
+// See https://en.wikipedia.org/wiki/ANSI_escape_code
+// Copy modified from https://github.com/fatih/color
+// Copyright 2013 Fatih Arslan
+package color
+
+import (
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+// Attribute defines a single SGR (Select Graphic Rendition) code.
+type Attribute int
+
+// Base attributes
+const (
+ Reset Attribute = iota
+ Bold
+ Faint
+ Italic
+ Underline
+ BlinkSlow
+ BlinkRapid
+ ReverseVideo
+ Concealed
+ CrossedOut
+)
+
+// Foreground text colors
+const (
+ FgBlack Attribute = iota + 30
+ FgRed
+ FgGreen
+ FgYellow
+ FgBlue
+ FgMagenta
+ FgCyan
+ FgWhite
+)
+
+// Foreground Hi-Intensity text colors
+const (
+ FgHiBlack Attribute = iota + 90
+ FgHiRed
+ FgHiGreen
+ FgHiYellow
+ FgHiBlue
+ FgHiMagenta
+ FgHiCyan
+ FgHiWhite
+)
+
+// Background text colors
+const (
+ BgBlack Attribute = iota + 40
+ BgRed
+ BgGreen
+ BgYellow
+ BgBlue
+ BgMagenta
+ BgCyan
+ BgWhite
+)
+
+// Background Hi-Intensity text colors
+const (
+ BgHiBlack Attribute = iota + 100
+ BgHiRed
+ BgHiGreen
+ BgHiYellow
+ BgHiBlue
+ BgHiMagenta
+ BgHiCyan
+ BgHiWhite
+)
+
+const (
+ escape = "\x1b"
+ unescape = "\\x1b"
+)
+
+// Format text for terminal.
+// You can pass an arbitrary number of Attribute or []Attribute followed by any other values,
+// that can either be a string or something else (that is converted to string using fmt.Sprint).
+func Format(s ...interface{}) string {
+ if len(s) == 0 {
+ return ""
+ }
+
+ params := []Attribute{}
+ in := -1
+ for i, v := range s {
+ switch vt := v.(type) {
+ case []Attribute:
+ if in == -1 {
+ params = append(params, vt...)
+ } else {
+ s[i] = printExtraColorAttribute(v)
+ }
+ case Attribute:
+ if in == -1 {
+ params = append(params, vt)
+ } else {
+ s[i] = printExtraColorAttribute(v)
+ }
+ default:
+ if in == -1 {
+ in = i
+ }
+ }
+ }
+ if in == -1 || len(s[in:]) == 0 {
+ return ""
+ }
+ return wrap(params, fmt.Sprint(s[in:]...))
+}
+
+func printExtraColorAttribute(v interface{}) string {
+ return fmt.Sprintf("(EXTRA color.Attribute=%v)", v)
+}
+
+// StripAttributes from input arguments and return unformatted text.
+func StripAttributes(s ...interface{}) (raw string) {
+ in := -1
+ for i, v := range s {
+ switch v.(type) {
+ case []Attribute, Attribute:
+ if in != -1 {
+ s[i] = printExtraColorAttribute(v)
+ }
+ default:
+ if in == -1 {
+ in = i
+ }
+ }
+ }
+ if in == -1 {
+ in = 0
+ }
+ return fmt.Sprint(s[in:]...)
+}
+
+// Escape text for terminal.
+func Escape(s string) string {
+ return strings.Replace(s, escape, unescape, -1)
+}
+
+// sequence returns a formated SGR sequence to be plugged into a "\x1b[...m"
+// an example output might be: "1;36" -> bold cyan.
+func sequence(params []Attribute) string {
+ format := make([]string, len(params))
+ for i, v := range params {
+ format[i] = strconv.Itoa(int(v))
+ }
+
+ return strings.Join(format, ";")
+}
+
+// wrap the s string with the colors attributes.
+func wrap(params []Attribute, s string) string {
+ return fmt.Sprintf("%s[%sm%s%s[%dm", escape, sequence(params), s, escape, Reset)
+}
diff --git a/vendor/github.com/henvic/httpretty/internal/header/header.go b/vendor/github.com/henvic/httpretty/internal/header/header.go
new file mode 100644
index 000000000..5221ab5d3
--- /dev/null
+++ b/vendor/github.com/henvic/httpretty/internal/header/header.go
@@ -0,0 +1,114 @@
+// Package header can be used to sanitize HTTP request and response headers.
+package header
+
+import (
+ "fmt"
+ "net/http"
+ "strings"
+)
+
+// Sanitize list of headers.
+// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ can be consulted for header syntax.
+func Sanitize(sanitizers map[string]SanitizeHeaderFunc, headers http.Header) http.Header {
+ var redacted = http.Header{}
+
+ for k, values := range headers {
+ if s, ok := sanitizers[http.CanonicalHeaderKey(k)]; ok {
+ redacted[k] = sanitize(s, values)
+ continue
+ }
+
+ redacted[k] = values
+ }
+
+ return redacted
+}
+
+func sanitize(s SanitizeHeaderFunc, values []string) []string {
+ var redacted = []string{}
+
+ for _, v := range values {
+ redacted = append(redacted, s(v))
+ }
+
+ return redacted
+}
+
+// DefaultSanitizers contains a list of sanitizers to be used for common headers.
+var DefaultSanitizers = map[string]SanitizeHeaderFunc{
+ "Authorization": AuthorizationSanitizer,
+ "Set-Cookie": SetCookieSanitizer,
+ "Cookie": CookieSanitizer,
+ "Proxy-Authorization": AuthorizationSanitizer,
+}
+
+// SanitizeHeaderFunc implements sanitization for a header value.
+type SanitizeHeaderFunc func(string) string
+
+// AuthorizationSanitizer is used to sanitize Authorization and Proxy-Authorization headers.
+func AuthorizationSanitizer(unsafe string) string {
+ if unsafe == "" {
+ return ""
+ }
+
+ directives := strings.SplitN(unsafe, " ", 2)
+
+ l := 0
+
+ if len(directives) > 1 {
+ l = len(directives[1])
+ }
+
+ if l == 0 {
+ return directives[0]
+ }
+
+ return directives[0] + " " + redact(l)
+}
+
+// SetCookieSanitizer is used to sanitize Set-Cookie header.
+func SetCookieSanitizer(unsafe string) string {
+ directives := strings.SplitN(unsafe, ";", 2)
+
+ cookie := strings.SplitN(directives[0], "=", 2)
+
+ l := 0
+
+ if len(cookie) > 1 {
+ l = len(cookie[1])
+ }
+
+ if len(directives) == 2 {
+ return fmt.Sprintf("%s=%s; %s", cookie[0], redact(l), strings.TrimPrefix(directives[1], " "))
+ }
+
+ return fmt.Sprintf("%s=%s", cookie[0], redact(l))
+}
+
+// CookieSanitizer is used to sanitize Cookie header.
+func CookieSanitizer(unsafe string) string {
+ cookies := strings.Split(unsafe, ";")
+
+ var list []string
+
+ for _, unsafeCookie := range cookies {
+ cookie := strings.SplitN(unsafeCookie, "=", 2)
+ l := 0
+
+ if len(cookie) > 1 {
+ l = len(cookie[1])
+ }
+
+ list = append(list, fmt.Sprintf("%s=%s", cookie[0], redact(l)))
+ }
+
+ return strings.Join(list, "; ")
+}
+
+func redact(count int) string {
+ if count == 0 {
+ return ""
+ }
+
+ return "████████████████████"
+}
diff --git a/vendor/github.com/henvic/httpretty/printer.go b/vendor/github.com/henvic/httpretty/printer.go
new file mode 100644
index 000000000..ab6e6a7c3
--- /dev/null
+++ b/vendor/github.com/henvic/httpretty/printer.go
@@ -0,0 +1,589 @@
+package httpretty
+
+import (
+ "bytes"
+ "crypto/tls"
+ "crypto/x509"
+ "fmt"
+ "io"
+ "mime"
+ "net"
+ "net/http"
+ "sort"
+ "strings"
+ "time"
+
+ "github.com/henvic/httpretty/internal/color"
+ "github.com/henvic/httpretty/internal/header"
+)
+
+func newPrinter(l *Logger) printer {
+ l.mu.Lock()
+ defer l.mu.Unlock()
+ return printer{
+ logger: l,
+ flusher: l.flusher,
+ }
+}
+
+type printer struct {
+ flusher Flusher
+ logger *Logger
+ buf bytes.Buffer
+}
+
+func (p *printer) maybeOnReady() {
+ if p.flusher == OnReady {
+ p.flush()
+ }
+}
+
+func (p *printer) flush() {
+ if p.flusher == NoBuffer {
+ return
+ }
+ p.logger.mu.Lock()
+ defer p.logger.mu.Unlock()
+ defer p.buf.Reset()
+ w := p.logger.getWriter()
+ fmt.Fprint(w, p.buf.String())
+}
+
+func (p *printer) print(a ...interface{}) {
+ p.logger.mu.Lock()
+ defer p.logger.mu.Unlock()
+ w := p.logger.getWriter()
+ if p.flusher == NoBuffer {
+ fmt.Fprint(w, a...)
+ return
+ }
+ fmt.Fprint(&p.buf, a...)
+}
+
+func (p *printer) println(a ...interface{}) {
+ p.logger.mu.Lock()
+ defer p.logger.mu.Unlock()
+ w := p.logger.getWriter()
+ if p.flusher == NoBuffer {
+ fmt.Fprintln(w, a...)
+ return
+ }
+ fmt.Fprintln(&p.buf, a...)
+}
+
+func (p *printer) printf(format string, a ...interface{}) {
+ p.logger.mu.Lock()
+ defer p.logger.mu.Unlock()
+ w := p.logger.getWriter()
+ if p.flusher == NoBuffer {
+ fmt.Fprintf(w, format, a...)
+ return
+ }
+ fmt.Fprintf(&p.buf, format, a...)
+}
+
+func (p *printer) printRequest(req *http.Request) {
+ if p.logger.RequestHeader {
+ p.printRequestHeader(req)
+ p.maybeOnReady()
+ }
+ if p.logger.RequestBody && req.Body != nil {
+ p.printRequestBody(req)
+ p.maybeOnReady()
+ }
+}
+
+func (p *printer) printRequestInfo(req *http.Request) {
+ to := req.URL.String()
+ // req.URL.Host is empty on the request received by a server
+ if req.URL.Host == "" {
+ to = req.Host + to
+ schema := "http://"
+ if req.TLS != nil {
+ schema = "https://"
+ }
+ to = schema + to
+ }
+ p.printf("* Request to %s\n", p.format(color.FgBlue, to))
+ if req.RemoteAddr != "" {
+ p.printf("* Request from %s\n", p.format(color.FgBlue, req.RemoteAddr))
+ }
+}
+
+// checkFilter checkes if the request is filtered and if the Request value is nil.
+func (p *printer) checkFilter(req *http.Request) (skip bool) {
+ filter := p.logger.getFilter()
+ if req == nil {
+ p.printf("> %s\n", p.format(color.FgRed, "error: null request"))
+ return true
+ }
+ if filter == nil {
+ return false
+ }
+ ok, err := safeFilter(filter, req)
+ if err != nil {
+ p.printf("* cannot filter request: %s: %s\n", p.format(color.FgBlue, fmt.Sprintf("%s %s", req.Method, req.URL)), p.format(color.FgRed, err.Error()))
+ return false // never filter out the request if the filter errored
+ }
+ return ok
+}
+
+func safeFilter(filter Filter, req *http.Request) (skip bool, err error) {
+ defer func() {
+ if e := recover(); e != nil {
+ err = fmt.Errorf("panic: %v", e)
+ }
+ }()
+ return filter(req)
+}
+
+func (p *printer) printResponse(resp *http.Response) {
+ if resp == nil {
+ p.printf("< %s\n", p.format(color.FgRed, "error: null response"))
+ p.maybeOnReady()
+ return
+ }
+ if p.logger.ResponseHeader {
+ p.printResponseHeader(resp.Proto, resp.Status, resp.Header)
+ p.maybeOnReady()
+ }
+ if p.logger.ResponseBody && resp.Body != nil && (resp.Request == nil || resp.Request.Method != http.MethodHead) {
+ p.printResponseBodyOut(resp)
+ p.maybeOnReady()
+ }
+}
+
+func (p *printer) checkBodyFiltered(h http.Header) (skip bool, err error) {
+ if f := p.logger.getBodyFilter(); f != nil {
+ defer func() {
+ if e := recover(); e != nil {
+ p.printf("* panic while filtering body: %v\n", e)
+ }
+ }()
+ return f(h)
+ }
+ return false, nil
+}
+
+func (p *printer) printResponseBodyOut(resp *http.Response) {
+ if resp.ContentLength == 0 {
+ return
+ }
+ skip, err := p.checkBodyFiltered(resp.Header)
+ if err != nil {
+ p.printf("* %s\n", p.format(color.FgRed, "error on response body filter: ", err.Error()))
+ }
+ if skip {
+ return
+ }
+ if contentType := resp.Header.Get("Content-Type"); contentType != "" && isBinaryMediatype(contentType) {
+ p.println("* body contains binary data")
+ return
+ }
+ if p.logger.MaxResponseBody > 0 && resp.ContentLength > p.logger.MaxResponseBody {
+ p.printf("* body is too long (%d bytes) to print, skipping (longer than %d bytes)\n", resp.ContentLength, p.logger.MaxResponseBody)
+ return
+ }
+ contentType := resp.Header.Get("Content-Type")
+ if resp.ContentLength == -1 {
+ if newBody := p.printBodyUnknownLength(contentType, p.logger.MaxResponseBody, resp.Body); newBody != nil {
+ resp.Body = newBody
+ }
+ return
+ }
+ var buf bytes.Buffer
+ tee := io.TeeReader(resp.Body, &buf)
+ defer resp.Body.Close()
+ defer func() {
+ resp.Body = io.NopCloser(&buf)
+ }()
+ p.printBodyReader(contentType, tee)
+}
+
+// isBinary uses heuristics to guess if file is binary (actually, "printable" in the terminal).
+// See discussion at https://groups.google.com/forum/#!topic/golang-nuts/YeLL7L7SwWs
+func isBinary(body []byte) bool {
+ if len(body) > 512 {
+ body = body[512:]
+ }
+ // If file contains UTF-8 OR UTF-16 BOM, consider it non-binary.
+ // Reference: https://tools.ietf.org/html/draft-ietf-websec-mime-sniff-03#section-5
+ if len(body) >= 3 && (bytes.Equal(body[:2], []byte{0xFE, 0xFF}) || // UTF-16BE BOM
+ bytes.Equal(body[:2], []byte{0xFF, 0xFE}) || // UTF-16LE BOM
+ bytes.Equal(body[:3], []byte{0xEF, 0xBB, 0xBF})) { // UTF-8 BOM
+ return false
+ }
+ // If all of the first n octets are binary data octets, consider it binary.
+ // Reference: https://github.com/golang/go/blob/349e7df2c3d0f9b5429e7c86121499c137faac7e/src/net/http/sniff.go#L297-L309
+ // c.f. section 5, step 4.
+ for _, b := range body {
+ switch {
+ case b <= 0x08,
+ b == 0x0B,
+ 0x0E <= b && b <= 0x1A,
+ 0x1C <= b && b <= 0x1F:
+ return true
+ }
+ }
+ // Otherwise, check against a white list of binary mimetypes.
+ mediatype, _, err := mime.ParseMediaType(http.DetectContentType(body))
+ if err != nil {
+ return false
+ }
+ return isBinaryMediatype(mediatype)
+}
+
+var binaryMediatypes = map[string]struct{}{
+ "application/pdf": {},
+ "application/postscript": {},
+ "image": {}, // for practical reasons, any image (including SVG) is considered binary data
+ "audio": {},
+ "application/ogg": {},
+ "video": {},
+ "application/vnd.ms-fontobject": {},
+ "font": {},
+ "application/x-gzip": {},
+ "application/zip": {},
+ "application/x-rar-compressed": {},
+ "application/wasm": {},
+}
+
+func isBinaryMediatype(mediatype string) bool {
+ if _, ok := binaryMediatypes[mediatype]; ok {
+ return true
+ }
+ if parts := strings.SplitN(mediatype, "/", 2); len(parts) == 2 {
+ if _, ok := binaryMediatypes[parts[0]]; ok {
+ return true
+ }
+ }
+ return false
+}
+
+const maxDefaultUnknownReadable = 4096 // bytes
+
+func (p *printer) printBodyUnknownLength(contentType string, maxLength int64, r io.ReadCloser) (newBody io.ReadCloser) {
+ if maxLength == 0 {
+ maxLength = maxDefaultUnknownReadable
+ }
+ pb := make([]byte, maxLength+1) // read one extra bit to assure the length is longer than acceptable
+ n, err := io.ReadFull(r, pb)
+ pb = pb[0:n] // trim any nil symbols left after writing in the byte slice.
+ buf := bytes.NewReader(pb)
+ newBody = newBodyReaderBuf(buf, r)
+ switch {
+ // Server requests always return req.Body != nil, but the Reader returns io.EOF immediately.
+ // Avoiding returning early to mitigate any risk of bad reader implementations that might
+ // send something even after returning io.EOF if read again.
+ case err == io.EOF && n == 0:
+ case err == nil && int64(n) > maxLength:
+ p.printf("* body is too long, skipping (contains more than %d bytes)\n", n-1)
+ case err == io.ErrUnexpectedEOF || err == nil:
+ // cannot pass same bytes reader below because we only read it once.
+ p.printBodyReader(contentType, bytes.NewReader(pb))
+ default:
+ p.printf("* cannot read body: %v (%d bytes read)\n", err, n)
+ }
+ return
+}
+
+func findPeerCertificate(hostname string, state *tls.ConnectionState) (cert *x509.Certificate) {
+ if chains := state.VerifiedChains; chains != nil && chains[0] != nil && chains[0][0] != nil {
+ return chains[0][0]
+ }
+ if hostname == "" && len(state.PeerCertificates) > 0 {
+ // skip finding a match for a given hostname if hostname is not available (e.g., a client certificate)
+ return state.PeerCertificates[0]
+ }
+ // the chain is not created when tls.Config.InsecureSkipVerify is set, then let's try to find a match to display
+ for _, cert := range state.PeerCertificates {
+ if err := cert.VerifyHostname(hostname); err == nil {
+ return cert
+ }
+ }
+ return nil
+}
+
+func (p *printer) printTLSInfo(state *tls.ConnectionState, skipVerifyChains bool) {
+ if state == nil {
+ return
+ }
+ protocol := tlsProtocolVersions[state.Version]
+ if protocol == "" {
+ protocol = fmt.Sprintf("%#v", state.Version)
+ }
+ cipher := tlsCiphers[state.CipherSuite]
+ if cipher == "" {
+ cipher = fmt.Sprintf("%#v", state.CipherSuite)
+ }
+ p.printf("* TLS connection using %s / %s", p.format(color.FgBlue, protocol), p.format(color.FgBlue, cipher))
+ if !skipVerifyChains && state.VerifiedChains == nil {
+ p.print(" (insecure=true)")
+ }
+ p.println()
+ if state.NegotiatedProtocol != "" {
+ p.printf("* ALPN: %v accepted\n", p.format(color.FgBlue, state.NegotiatedProtocol))
+ }
+}
+
+func (p *printer) printOutgoingClientTLS(config *tls.Config) {
+ if config == nil || len(config.Certificates) == 0 {
+ return
+ }
+ p.println("* Client certificate:")
+ // Please notice tls.Config.BuildNameToCertificate() doesn't store the certificate Leaf field.
+ // You need to explicitly parse and store it with something such as:
+ // cert.Leaf, err = x509.ParseCertificate(cert.Certificate)
+ if cert := config.Certificates[0].Leaf; cert != nil {
+ p.printCertificate("", cert)
+ } else {
+ p.println(`** unparsed certificate found, skipping`)
+ }
+}
+
+func (p *printer) printIncomingClientTLS(state *tls.ConnectionState) {
+ // if no TLS state is null or no client TLS certificate is found, return early.
+ if state == nil || len(state.PeerCertificates) == 0 {
+ return
+ }
+ p.println("* Client certificate:")
+ if cert := findPeerCertificate("", state); cert != nil {
+ p.printCertificate("", cert)
+ } else {
+ p.println(p.format(color.FgRed, "** No valid certificate was found"))
+ }
+}
+
+func (p *printer) printTLSServer(host string, state *tls.ConnectionState) {
+ if state == nil {
+ return
+ }
+ hostname, _, err := net.SplitHostPort(host)
+ if err != nil {
+ // assume the error is due to "missing port in address"
+ hostname = host
+ }
+ p.println("* Server certificate:")
+ if cert := findPeerCertificate(hostname, state); cert != nil {
+ // server certificate messages are slightly similar to how "curl -v" shows
+ p.printCertificate(hostname, cert)
+ } else {
+ p.println(p.format(color.FgRed, "** No valid certificate was found"))
+ }
+}
+
+func (p *printer) printCertificate(hostname string, cert *x509.Certificate) {
+ p.printf(`* subject: %v
+* start date: %v
+* expire date: %v
+* issuer: %v
+`,
+ p.format(color.FgBlue, cert.Subject),
+ p.format(color.FgBlue, cert.NotBefore.Format(time.UnixDate)),
+ p.format(color.FgBlue, cert.NotAfter.Format(time.UnixDate)),
+ p.format(color.FgBlue, cert.Issuer),
+ )
+ if hostname == "" {
+ return
+ }
+ if err := cert.VerifyHostname(hostname); err != nil {
+ p.printf("* %s\n", p.format(color.FgRed, err.Error()))
+ return
+ }
+ p.println("* TLS certificate verify ok.")
+}
+
+func (p *printer) printServerResponse(req *http.Request, rec *responseRecorder) {
+ if p.logger.ResponseHeader {
+ // TODO(henvic): see how httptest.ResponseRecorder adds extra headers due to Content-Type detection
+ // and other stuff (Date). It would be interesting to show them here too (either as default or opt-in).
+ p.printResponseHeader(req.Proto, fmt.Sprintf("%d %s", rec.statusCode, http.StatusText(rec.statusCode)), rec.Header())
+ }
+ if !p.logger.ResponseBody || rec.size == 0 {
+ return
+ }
+ skip, err := p.checkBodyFiltered(rec.Header())
+ if err != nil {
+ p.printf("* %s\n", p.format(color.FgRed, "error on response body filter: ", err.Error()))
+ }
+ if skip {
+ return
+ }
+ if mediatype := req.Header.Get("Content-Type"); mediatype != "" && isBinaryMediatype(mediatype) {
+ p.println("* body contains binary data")
+ return
+ }
+ if p.logger.MaxResponseBody > 0 && rec.size > p.logger.MaxResponseBody {
+ p.printf("* body is too long (%d bytes) to print, skipping (longer than %d bytes)\n", rec.size, p.logger.MaxResponseBody)
+ return
+ }
+ p.printBodyReader(rec.Header().Get("Content-Type"), rec.buf)
+}
+
+func (p *printer) printResponseHeader(proto, status string, h http.Header) {
+ p.printf("< %s %s\n",
+ p.format(color.FgBlue, color.Bold, proto),
+ p.format(color.FgRed, status))
+ p.printHeaders('<', h)
+ p.println()
+}
+
+func (p *printer) printBodyReader(contentType string, r io.Reader) {
+ mediatype, _, _ := mime.ParseMediaType(contentType)
+ body, err := io.ReadAll(r)
+ if err != nil {
+ p.printf("* cannot read body: %v\n", p.format(color.FgRed, err.Error()))
+ return
+ }
+ if isBinary(body) {
+ p.println("* body contains binary data")
+ return
+ }
+ for _, f := range p.logger.Formatters {
+ if ok := p.safeBodyMatch(f, mediatype); !ok {
+ continue
+ }
+ var formatted bytes.Buffer
+ switch err := p.safeBodyFormat(f, &formatted, body); {
+ case err != nil:
+ p.printf("* body cannot be formatted: %v\n%s\n", p.format(color.FgRed, err.Error()), string(body))
+ default:
+ p.println(formatted.String())
+ }
+ return
+ }
+
+ p.println(string(body))
+}
+
+func (p *printer) safeBodyMatch(f Formatter, mediatype string) bool {
+ defer func() {
+ if e := recover(); e != nil {
+ p.printf("* panic while testing body format: %v\n", e)
+ }
+ }()
+ return f.Match(mediatype)
+}
+
+func (p *printer) safeBodyFormat(f Formatter, w io.Writer, src []byte) (err error) {
+ defer func() {
+ // should not return panic as error because we want to try the next formatter
+ if e := recover(); e != nil {
+ err = fmt.Errorf("panic: %v", e)
+ }
+ }()
+ return f.Format(w, src)
+}
+
+func (p *printer) format(s ...interface{}) string {
+ if p.logger.Colors {
+ return color.Format(s...)
+ }
+ return color.StripAttributes(s...)
+}
+
+func (p *printer) printHeaders(prefix rune, h http.Header) {
+ if !p.logger.SkipSanitize {
+ h = header.Sanitize(header.DefaultSanitizers, h)
+ }
+ skipped := p.logger.cloneSkipHeader()
+ for _, key := range sortHeaderKeys(h) {
+ for _, v := range h[key] {
+ if _, skip := skipped[key]; skip {
+ continue
+ }
+ p.printf("%c %s%s %s\n", prefix,
+ p.format(color.FgBlue, color.Bold, key),
+ p.format(color.FgRed, ":"),
+ p.format(color.FgYellow, v))
+ }
+ }
+}
+
+func sortHeaderKeys(h http.Header) []string {
+ keys := make([]string, 0, len(h))
+ for key := range h {
+ keys = append(keys, key)
+ }
+ sort.Strings(keys)
+ return keys
+}
+
+func (p *printer) printRequestHeader(req *http.Request) {
+ p.printf("> %s %s %s\n",
+ p.format(color.FgBlue, color.Bold, req.Method),
+ p.format(color.FgYellow, req.URL.RequestURI()),
+ p.format(color.FgBlue, req.Proto))
+ host := req.Host
+ if host == "" {
+ host = req.URL.Host
+ }
+ if host != "" {
+ p.printf("> %s%s %s\n",
+ p.format(color.FgBlue, color.Bold, "Host"),
+ p.format(color.FgRed, ":"),
+ p.format(color.FgYellow, host),
+ )
+ }
+ p.printHeaders('>', addHeaderContentLength(req))
+ p.println()
+}
+
+// addHeaderContentLength returns a copy of the given header with an additional header, Content-Length, if it's known.
+func addHeaderContentLength(req *http.Request) http.Header {
+ if req.ContentLength == 0 && len(req.Header.Values("Content-Length")) == 0 {
+ return req.Header
+ }
+ cp := http.Header{}
+ for k, v := range req.Header {
+ cp[k] = v
+ }
+ cp.Set("Content-Length", fmt.Sprintf("%d", req.ContentLength))
+ return cp
+}
+
+func (p *printer) printRequestBody(req *http.Request) {
+ // For client requests, a request with zero content-length and no body is also treated as unknown.
+ if req.Body == nil {
+ return
+ }
+ skip, err := p.checkBodyFiltered(req.Header)
+ if err != nil {
+ p.printf("* %s\n", p.format(color.FgRed, "error on request body filter: ", err.Error()))
+ }
+ if skip {
+ return
+ }
+ if mediatype := req.Header.Get("Content-Type"); mediatype != "" && isBinaryMediatype(mediatype) {
+ p.println("* body contains binary data")
+ return
+ }
+ // TODO(henvic): add support for printing multipart/formdata information as body (to responses too).
+ if p.logger.MaxRequestBody > 0 && req.ContentLength > p.logger.MaxRequestBody {
+ p.printf("* body is too long (%d bytes) to print, skipping (longer than %d bytes)\n",
+ req.ContentLength, p.logger.MaxRequestBody)
+ return
+ }
+ contentType := req.Header.Get("Content-Type")
+ if req.ContentLength > 0 {
+ var buf bytes.Buffer
+ tee := io.TeeReader(req.Body, &buf)
+ defer req.Body.Close()
+ defer func() {
+ req.Body = io.NopCloser(&buf)
+ }()
+ p.printBodyReader(contentType, tee)
+ return
+ }
+ if newBody := p.printBodyUnknownLength(contentType, p.logger.MaxRequestBody, req.Body); newBody != nil {
+ req.Body = newBody
+ }
+}
+
+func (p *printer) printTimeRequest() (end func()) {
+ startRequest := time.Now()
+ p.printf("* Request at %v\n", startRequest)
+ return func() {
+ p.printf("* Request took %v\n", time.Since(startRequest))
+ }
+}
diff --git a/vendor/github.com/henvic/httpretty/recorder.go b/vendor/github.com/henvic/httpretty/recorder.go
new file mode 100644
index 000000000..9b55a6559
--- /dev/null
+++ b/vendor/github.com/henvic/httpretty/recorder.go
@@ -0,0 +1,53 @@
+package httpretty
+
+import (
+ "bytes"
+ "io"
+ "net/http"
+)
+
+type bodyCloser struct {
+ r io.Reader
+ close func() error
+}
+
+func (bc *bodyCloser) Read(p []byte) (n int, err error) {
+ return bc.r.Read(p)
+}
+
+func (bc *bodyCloser) Close() error {
+ return bc.close()
+}
+
+func newBodyReaderBuf(buf io.Reader, body io.ReadCloser) *bodyCloser {
+ return &bodyCloser{
+ r: io.MultiReader(buf, body),
+ close: body.Close,
+ }
+}
+
+type responseRecorder struct {
+ http.ResponseWriter
+ statusCode int
+ maxReadableBody int64
+ size int64
+ buf *bytes.Buffer
+}
+
+// Write the data to the connection as part of an HTTP reply, and records it.
+func (rr *responseRecorder) Write(p []byte) (int, error) {
+ rr.size += int64(len(p))
+ if rr.maxReadableBody > 0 && rr.size > rr.maxReadableBody {
+ rr.buf = nil
+ return rr.ResponseWriter.Write(p)
+ }
+ defer rr.buf.Write(p)
+ return rr.ResponseWriter.Write(p)
+}
+
+// WriteHeader sends an HTTP response header with the provided
+// status code, and records it.
+func (rr *responseRecorder) WriteHeader(statusCode int) {
+ rr.ResponseWriter.WriteHeader(statusCode)
+ rr.statusCode = statusCode
+}
diff --git a/vendor/github.com/henvic/httpretty/tls.go b/vendor/github.com/henvic/httpretty/tls.go
new file mode 100644
index 000000000..70c09d18c
--- /dev/null
+++ b/vendor/github.com/henvic/httpretty/tls.go
@@ -0,0 +1,49 @@
+package httpretty
+
+// A list of cipher suite IDs that are, or have been, implemented by the
+// crypto/tls package.
+// See https://www.iana.org/assignments/tls-parameters/tls-parameters.xml
+// See https://github.com/golang/go/blob/c2edcf4b1253fdebc13df8a25979904c3ef01c66/src/crypto/tls/cipher_suites.go
+var tlsCiphers = map[uint16]string{
+ // TLS 1.0 - 1.2 cipher suites.
+ 0x0005: "TLS_RSA_WITH_RC4_128_SHA",
+ 0x000a: "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
+ 0x002f: "TLS_RSA_WITH_AES_128_CBC_SHA",
+ 0x0035: "TLS_RSA_WITH_AES_256_CBC_SHA",
+ 0x003c: "TLS_RSA_WITH_AES_128_CBC_SHA256",
+ 0x009c: "TLS_RSA_WITH_AES_128_GCM_SHA256",
+ 0x009d: "TLS_RSA_WITH_AES_256_GCM_SHA384",
+ 0xc007: "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
+ 0xc009: "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
+ 0xc00a: "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
+ 0xc011: "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
+ 0xc012: "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
+ 0xc013: "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
+ 0xc014: "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
+ 0xc023: "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
+ 0xc027: "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
+ 0xc02f: "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+ 0xc02b: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
+ 0xc030: "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+ 0xc02c: "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
+ 0xcca8: "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
+ 0xcca9: "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
+
+ // TLS 1.3 cipher suites.
+ 0x1301: "TLS_AES_128_GCM_SHA256",
+ 0x1302: "TLS_AES_256_GCM_SHA384",
+ 0x1303: "TLS_CHACHA20_POLY1305_SHA256",
+
+ // TLS_FALLBACK_SCSV isn't a standard cipher suite but an indicator
+ // that the client is doing version fallback. See RFC 7507.
+ 0x5600: "TLS_FALLBACK_SCSV",
+}
+
+// List of TLS protocol versions supported by Go.
+// See https://github.com/golang/go/blob/f4a8bf128364e852cff87cf404a5c16c457ef8f6/src/crypto/tls/common.go
+var tlsProtocolVersions = map[uint16]string{
+ 0x0301: "TLS 1.0",
+ 0x0302: "TLS 1.1",
+ 0x0303: "TLS 1.2",
+ 0x0304: "TLS 1.3",
+}
diff --git a/vendor/github.com/itchyny/gojq/.dockerignore b/vendor/github.com/itchyny/gojq/.dockerignore
new file mode 100644
index 000000000..54095155c
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/.dockerignore
@@ -0,0 +1,16 @@
+/gojq
+/goxz
+/CREDITS
+/y.output
+*.exe
+*.test
+*.out
+*.md
+*.y
+**/*.jq
+**/*.json
+**/*.yaml
+**/*_test.go
+.github
+_gojq
+_tools
diff --git a/vendor/github.com/itchyny/gojq/.gitattributes b/vendor/github.com/itchyny/gojq/.gitattributes
new file mode 100644
index 000000000..797f39593
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/.gitattributes
@@ -0,0 +1,3 @@
+**/testdata/** binary
+/builtin.go eol=lf linguist-generated=true
+/parser.go eol=lf linguist-generated=true
diff --git a/vendor/github.com/itchyny/gojq/.gitignore b/vendor/github.com/itchyny/gojq/.gitignore
new file mode 100644
index 000000000..bbeb991f8
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/.gitignore
@@ -0,0 +1,7 @@
+/gojq
+/goxz
+/CREDITS
+/y.output
+*.exe
+*.test
+*.out
diff --git a/vendor/github.com/itchyny/gojq/CHANGELOG.md b/vendor/github.com/itchyny/gojq/CHANGELOG.md
new file mode 100644
index 000000000..599f62210
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/CHANGELOG.md
@@ -0,0 +1,372 @@
+# Changelog
+## [v0.12.15](https://github.com/itchyny/gojq/compare/v0.12.14..v0.12.15) (2024-04-01)
+* implement `ltrim`, `rtrim`, and `trim` functions
+* implement `gojq.ParseError` for getting the offset and token of query parsing error
+* implement `gojq.HaltError` for detecting halt errors and stopping outer iteration
+* fix object construction with duplicate keys (`{x:0,y:1} | {a:.x,a:.y}`)
+* fix `halt` and `halt_error` functions to stop the command execution immediately
+* fix variable scope of binding syntax (`"a" as $v | def f: $v; "b" as $v | f`)
+* fix pre-defined variables to be available in initial modules (`$ARGS` in `~/.jq`)
+* fix `ltrimstr` and `rtrimstr` functions to emit error on non-string input
+* fix `nearbyint` and `rint` functions to round ties to even
+* improve parser to allow `reduce`, `foreach`, `if`, `try`-`catch` syntax as object values
+* remove `pow10` in favor of `exp10`, define `scalbn` and `scalbln` by `ldexp`
+
+## [v0.12.14](https://github.com/itchyny/gojq/compare/v0.12.13..v0.12.14) (2023-12-01)
+* implement `abs`, `pick`, and `debug/1` functions
+* implement `--raw-output0` option, and remove `--nul-output` (`-0`) option
+* fix string multiplication by zero to emit an empty string
+* fix zero divided by zero to emit an error, not `nan`
+* fix modulo operator to emit `nan` if either side is `nan`
+* fix `implode` function to emit replacement characters on invalid code points
+* fix `stderr` function to output strings in raw format
+* fix `error` function to throw an error even for `null`
+* fix `walk` function on multiple outputs arguments
+* fix `--from-file` option to work with `--args` and `--jsonargs` options
+* fix the default module search path `../lib` relative to the executable
+* improve query parser to support comment continuation with backslash
+* improve `modulemeta` function to include defined function names in the module
+* improve search path of `import` and `include` directives to support `$ORIGIN` expansion
+* remove deprecated `leaf_paths` function
+
+## [v0.12.13](https://github.com/itchyny/gojq/compare/v0.12.12..v0.12.13) (2023-06-01)
+* implement `@urid` format string to decode URI values
+* fix functions returning arrays not to emit nil slices (`flatten`, `group_by`,
+ `unique`, `unique_by`, `nth`, `indices`, `path`, and `modulemeta.deps`)
+
+## [v0.12.12](https://github.com/itchyny/gojq/compare/v0.12.11..v0.12.12) (2023-03-01)
+* fix assignment operator (`=`) with overlapping paths and multiple values (`[[]] | .. = ..`)
+* fix crash on multiplying large numbers to an empty string (`9223372036854775807 * ""`)
+* improve zsh completion file
+
+## [v0.12.11](https://github.com/itchyny/gojq/compare/v0.12.10..v0.12.11) (2022-12-24)
+* fix crash on assignment operator (`=`) with multiple values (`. = (0,0)`)
+* fix `isnormal` and `normals` functions against subnormal numbers
+
+## [v0.12.10](https://github.com/itchyny/gojq/compare/v0.12.9..v0.12.10) (2022-12-01)
+* fix `break` in `try`-`catch` query (`label $x | try break $x catch .`)
+* fix path value validation for `getpath` function (`path(getpath([[0]][0]))`)
+* fix path value validation for custom iterator functions
+* fix `walk` function with argument emitting multiple values (`[1],{x:1} | walk(.,0)`)
+* fix `@csv`, `@tsv`, `@sh` to escape the null character (`["\u0000"] | @csv,@tsv,@sh`)
+* improve performance of assignment operator (`=`), update-assignment operator (`|=`),
+ `map_values`, `del`, `delpaths`, `walk`, `ascii_downcase`, and `ascii_upcase` functions
+
+## [v0.12.9](https://github.com/itchyny/gojq/compare/v0.12.8..v0.12.9) (2022-09-01)
+* fix `fromjson` to emit error on unexpected trailing string
+* fix path analyzer on variable argument evaluation (`def f($x): .y; path(f(.x))`)
+* fix raw input option `--raw-input` (`-R`) to keep carriage returns and support 64KiB+ lines
+
+## [v0.12.8](https://github.com/itchyny/gojq/compare/v0.12.7..v0.12.8) (2022-06-01)
+* implement `gojq.Compare` for comparing values in custom internal functions
+* implement `gojq.TypeOf` for obtaining type name of values in custom internal functions
+* implement `gojq.Preview` for previewing values for error messages of custom internal functions
+* fix query lexer to parse string literals as JSON to support surrogate pairs (`"\ud83d\ude04"`)
+* fix priority bug of declared and builtin functions (`def empty: .; null | select(.)`)
+* fix string indexing by index out of bounds to emit `null` (`"abc" | .[3]`)
+* fix array binding pattern not to match against strings (`"abc" as [$a] ?// $a | $a`)
+* fix `sub` and `gsub` functions to emit results in the same order of jq
+* fix `fromjson` to keep integer precision (`"10000000000000000" | fromjson + 1`)
+* fix stream option to raise error against incomplete JSON input
+* improve array updating index and string repetition to increase limitations
+* improve `mktime` to support nanoseconds, just like `gmtime` and `now`
+* improve query lexer to report unterminated string literals
+* improve performance of string indexing and slicing by reducing allocations
+* improve performance of object and array indexing, slicing, and iteration,
+ by validating path values by comparing data addresses. This change improves jq
+ compatibility of path value validation (`{} | {}.x = 0`, `[0] | [.[]][] = 1`).
+ Also optimize constant indexing and slicing by specialized instruction
+* improve performance of `add` (on array of strings), `flatten`, `min`, `max`,
+ `sort`, `unique`, `join`, `to_entries`, `from_entries`, `indices`, `index`,
+ `rindex`, `startswith`, `endswith`, `ltrimstr`, `rtrimstr`, `explode`,
+ `capture`, `sub`, and `gsub` functions
+
+## [v0.12.7](https://github.com/itchyny/gojq/compare/v0.12.6..v0.12.7) (2022-03-01)
+* fix precedence of try expression against operators (`try 0 * error(0)`)
+* fix iterator suffix with optional operator (`0 | .x[]?`)
+* fix stream option with slurp option or `input`, `inputs` functions
+* fix the command flag parser to support equal sign in short options with argument
+* fix string conversion of query including empty strings in module and import metadata
+* improve performance of `isempty` function
+
+## [v0.12.6](https://github.com/itchyny/gojq/compare/v0.12.5..v0.12.6) (2021-12-01)
+* implement options for consuming remaining arguments (`--args`, `--jsonargs`, `$ARGS.positional`)
+* fix `delpaths` function with overlapped paths
+* fix `--exit-status` flag with `halt`, `halt_error` functions
+* fix `input_filename` function with null input option
+* fix path value validation for `nan`
+* fix crash on branch optimization (`if 0 then . else 0|0 end`)
+* add validation on regular expression flags to reject unsupported ones
+* improve performance of `range`, `join`, `flatten` functions
+* improve constant value optimization for object with quoted keys
+* remove dependency on forked `go-flags` package
+
+## [v0.12.5](https://github.com/itchyny/gojq/compare/v0.12.4..v0.12.5) (2021-09-01)
+* implement `input_filename` function for the command
+* fix priority bug of declared functions and arguments (`def g: 1; def f(g): g; f(2)`)
+* fix label handling to catch the correct break error (`first((0, 0) | first(0))`)
+* fix `null|error` and `error(null)` to behave like `empty` (`null | [0, error, error(null), 1]`)
+* fix integer division to keep precision when divisible (`1 / 1 * 1000000000000000000000`)
+* fix modulo operator on negative number and large number (`(-1) % 10000000000`)
+* fix combination of slurp (`--slurp`) and raw input option (`--raw-input`) to keep newlines
+* change the default module paths to `~/.jq`, `$ORIGIN/../lib/gojq`, `$ORIGIN/lib`
+ where `$ORIGIN` is the directory where the executable is located in
+* improve command argument parser to recognize query with leading hyphen,
+ allow hyphen for standard input, and force posix style on Windows
+* improve `@base64d` to allow input without padding characters
+* improve `fromdate`, `fromdateiso8601` to parse date time strings with timezone offset
+* improve `halt_error` to print error values without prefix
+* improve `sub`, `gsub` to allow the replacement string emitting multiple values
+* improve encoding `\b` and `\f` in strings
+* improve module loader for search path in query, and absolute path
+* improve query lexer to support string literal including newlines
+* improve performance of `index`, `rindex`, `indices`, `transpose`, and `walk` functions
+* improve performance of value preview in errors and debug mode
+* improve runtime performance including tail call optimization
+* switch Docker base image to `distroless/static:debug`
+
+## [v0.12.4](https://github.com/itchyny/gojq/compare/v0.12.3..v0.12.4) (2021-06-01)
+* fix numeric conversion of large floating-point numbers in modulo operator
+* implement a compiler option for adding custom iterator functions
+* implement `gojq.NewIter` function for creating a new iterator from values
+* implement `$ARGS.named` for listing command line variables
+* remove `debug` and `stderr` functions from the library
+* stop printing newlines on `stderr` function for jq compatibility
+
+## [v0.12.3](https://github.com/itchyny/gojq/compare/v0.12.2..v0.12.3) (2021-04-01)
+* fix array slicing with infinities and large numbers (`[0][-infinite:infinite], [0][:1e20]`)
+* fix multiplying strings and modulo by infinities on MIPS 64 architecture
+* fix git revision information in Docker images
+* release multi-platform Docker images for ARM 64
+* switch to `distroless` image for Docker base image
+
+## [v0.12.2](https://github.com/itchyny/gojq/compare/v0.12.1..v0.12.2) (2021-03-01)
+* implement `GOJQ_COLORS` environment variable to configure individual colors
+* respect `--color-output` (`-C`) option even if `NO_COLOR` is set
+* implement `gojq.ValueError` interface for custom internal functions
+* fix crash on timestamps in YAML input
+* fix calculation on `infinite` (`infinite-infinite | isnan`)
+* fix comparison on `nan` (`nan < nan`)
+* fix validation of `implode` (`[-1] | implode`)
+* fix number normalization for custom JSON module loader
+* print error line numbers on invalid JSON and YAML
+* improve `strftime`, `strptime` for time zone offsets
+* improve performance on reading a large JSON file given by command line argument
+* improve performance and reduce memory allocation of the lexer, compiler and executor
+
+## [v0.12.1](https://github.com/itchyny/gojq/compare/v0.12.0..v0.12.1) (2021-01-17)
+* skip adding `$HOME/.jq` to module paths when `$HOME` is unset
+* fix optional operator followed by division operator (`1?/1`)
+* fix undefined format followed by optional operator (`@foo?`)
+* fix parsing invalid consecutive dots while scanning a number (`0..[empty]`)
+* fix panic on printing a query with `%#v`
+* improve performance and reduce memory allocation of `query.String()`
+* change all methods of `ModuleLoader` optional
+
+## [v0.12.0](https://github.com/itchyny/gojq/compare/v0.11.2..v0.12.0) (2020-12-24)
+* implement tab indentation option (`--tab`)
+* implement a compiler option for adding custom internal functions
+* implement `gojq.Marshal` function for jq-flavored encoding
+* fix slurp option with JSON file arguments
+* fix escaping characters in object keys
+* fix normalizing negative `int64` to `int` on 32-bit architecture
+* fix crash on continuing iteration after emitting an error
+* `iter.Next()` does not normalize `NaN` and infinities anymore. Library users
+ should take care of them. To handle them for encoding as JSON bytes, use
+ `gojq.Marshal`. Also, `iter.Next()` does not clone values deeply anymore for
+ performance reason. Users must not update the elements of the returned arrays
+ and objects
+* improve performance of outputting JSON values by about 3.5 times
+
+## [v0.11.2](https://github.com/itchyny/gojq/compare/v0.11.1..v0.11.2) (2020-10-01)
+* fix build for 32bit architecture
+* release to [GitHub Container Registry](https://github.com/users/itchyny/packages/container/package/gojq)
+
+## [v0.11.1](https://github.com/itchyny/gojq/compare/v0.11.0..v0.11.1) (2020-08-22)
+* improve compatibility of `strftime`, `strptime` functions with jq
+* fix YAML input with numbers in keys
+* fix crash on multiplying a large number or `infinite` to a string
+* fix crash on error while slicing a string (`""[:{}]`)
+* fix crash on modulo by a number near 0.0 (`1 % 0.1`)
+* include `CREDITS` file in artifacts
+
+## [v0.11.0](https://github.com/itchyny/gojq/compare/v0.10.4..v0.11.0) (2020-07-08)
+* improve parsing performance significantly
+* rewrite the parser from `participle` library to `goyacc` generated parser
+* release to [itchyny/gojq - Docker Hub](https://hub.docker.com/r/itchyny/gojq)
+* support string interpolation for object pattern key
+
+## [v0.10.4](https://github.com/itchyny/gojq/compare/v0.10.3..v0.10.4) (2020-06-30)
+* implement variable in object key (`. as $x | { $x: 1 }`)
+* fix modify operator (`|=`) with `try` `catch` expression
+* fix optional operator (`?`) with alternative operator (`//`) in `map_values` function
+* fix normalizing numeric types for library users
+* export `gojq.NewModuleLoader` function for library users
+
+## [v0.10.3](https://github.com/itchyny/gojq/compare/v0.10.2..v0.10.3) (2020-06-06)
+* implement `add`, `unique_by`, `max_by`, `min_by`, `reverse` by internal
+ functions for performance and reducing the binary size
+* improve performance of `setpath`, `delpaths` functions
+* fix assignment against nested slicing (`[1,2,3] | .[1:][:1] = [5]`)
+* limit the array index of assignment operator
+* optimize constant arrays and objects
+
+## [v0.10.2](https://github.com/itchyny/gojq/compare/v0.10.1..v0.10.2) (2020-05-24)
+* implement `sort_by`, `group_by`, `bsearch` by internal functions for performance
+ and reducing the binary size
+* fix object construction and constant object to allow trailing commas
+* fix `tonumber` function to allow leading zeros
+* minify the builtin functions to reduce the binary size
+
+## [v0.10.1](https://github.com/itchyny/gojq/compare/v0.10.0..v0.10.1) (2020-04-24)
+* fix array addition not to modify the left hand side
+
+## [v0.10.0](https://github.com/itchyny/gojq/compare/v0.9.0..v0.10.0) (2020-04-02)
+* implement various functions (`format`, `significand`, `modulemeta`, `halt_error`)
+* implement `input`, `inputs` functions
+* implement stream option (`--stream`)
+* implement slicing with object (`.[{"start": 1, "end": 2}]`)
+* implement `NO_COLOR` environment variable support
+* implement `nul` output option (`-0`, `--nul-output`)
+* implement exit status option (`-e`, `--exit-status`)
+* implement `search` field of module meta object
+* implement combination of `--yaml-input` and `--slurp`
+* improve string token lexer and support nested string interpolation
+* improve the exit code for jq compatibility
+* improve default module search paths for jq compatibility
+* improve documentation for the usage as a library
+* change methods of `ModuleLoader` optional, implement `LoadModuleWithMeta` and `LoadJSONWithMeta`
+* fix number normalization for JSON arguments (`--argjson`, `--slurpfile`)
+* fix `0/0` and `infinite/infinite`
+* fix `error` function against `null`
+
+## [v0.9.0](https://github.com/itchyny/gojq/compare/v0.8.0..v0.9.0) (2020-03-15)
+* implement various functions (`infinite`, `isfinite`, `isinfinite`, `finites`, `isnormal`, `normals`)
+* implement environment variables loader as a compiler option
+* implement `$NAME::NAME` syntax for imported JSON variable
+* fix modify operator with empty against array (`[range(9)] | (.[] | select(. % 2 > 0)) |= empty`)
+* fix variable and function scopes (`{ x: 1 } | . as $x | (.x as $x | $x) | ., $x`)
+* fix path analyzer
+* fix type check in `startswith` and `endswith`
+* ignore type error of `ltrimstr` and `rtrimstr`
+* remove nano seconds from `mktime` output
+* trim newline at the end of error messages
+* improve documents and examples
+
+## [v0.8.0](https://github.com/itchyny/gojq/compare/v0.7.0..v0.8.0) (2020-03-02)
+* implement format strings (`@text`, `@json`, `@html`, `@uri`, `@csv`, `@tsv`,
+ `@sh`, `@base64`, `@base64d`)
+* implement modules feature (`-L` option for directory to search modules from)
+* implement options for binding variables from arguments (`--arg`, `--argjson`)
+* implement options for binding variables from files (`--slurpfile`, `--rawfile`)
+* implement an option for indentation count (`--indent`)
+* fix `isnan` for `null`
+* fix path analyzer
+* fix error after optional operator (`1? | .x`)
+* add `$ENV` variable
+* add zsh completion file
+
+## [v0.7.0](https://github.com/itchyny/gojq/compare/v0.6.0..v0.7.0) (2019-12-22)
+* implement YAML input (`--yaml-input`) and output (`--yaml-output`)
+* fix pipe in object value
+* fix precedence of `if`, `try`, `reduce` and `foreach` expressions
+* release from GitHub Actions
+
+## [v0.6.0](https://github.com/itchyny/gojq/compare/v0.5.0..v0.6.0) (2019-08-26)
+* implement arbitrary-precision integer calculation
+* implement various functions (`repeat`, `pow10`, `nan`, `isnan`, `nearbyint`,
+ `halt`, `INDEX`, `JOIN`, `IN`)
+* implement long options (`--compact-output`, `--raw-output`, `--join-output`,
+ `--color-output`, `--monochrome-output`, `--null-input`, `--raw-input`,
+ `--slurp`, `--from-file`, `--version`)
+* implement join output options (`-j`, `--join-output`)
+* implement color/monochrome output options (`-C`, `--color-output`,
+ `-M`, `--monochrome-output`)
+* refactor builtin functions
+
+## [v0.5.0](https://github.com/itchyny/gojq/compare/v0.4.0..v0.5.0) (2019-08-03)
+* implement various functions (`with_entries`, `from_entries`, `leaf_paths`,
+ `contains`, `inside`, `split`, `stream`, `fromstream`, `truncate_stream`,
+ `bsearch`, `path`, `paths`, `map_values`, `del`, `delpaths`, `getpath`,
+ `gmtime`, `localtime`, `mktime`, `strftime`, `strflocaltime`, `strptime`,
+ `todate`, `fromdate`, `now`, `match`, `test`, `capture`, `scan`, `splits`,
+ `sub`, `gsub`, `debug`, `stderr`)
+* implement assignment operator (`=`)
+* implement modify operator (`|=`)
+* implement update operators (`+=`, `-=`, `*=`, `/=`, `%=`, `//=`)
+* implement destructuring alternative operator (`?//`)
+* allow function declaration inside query
+* implement `-f` flag for loading query from file
+* improve error message for parsing multiple line query
+
+## [v0.4.0](https://github.com/itchyny/gojq/compare/v0.3.0..v0.4.0) (2019-07-20)
+* improve performance significantly
+* rewrite from recursive interpreter to stack machine based interpreter
+* allow debugging with `make install-debug` and `export GOJQ_DEBUG=1`
+* parse built-in functions and generate syntax trees before compilation
+* optimize tail recursion
+* fix behavior of optional operator
+* fix scopes of arguments of recursive function call
+* fix duplicate function argument names
+* implement `setpath` function
+
+## [v0.3.0](https://github.com/itchyny/gojq/compare/v0.2.0..v0.3.0) (2019-06-05)
+* implement `reduce`, `foreach`, `label`, `break` syntax
+* improve binding variable syntax to bind to an object or an array
+* implement string interpolation
+* implement object index by string (`."example"`)
+* implement various functions (`add`, `flatten`, `min`, `min_by`, `max`,
+ `max_by`, `sort`, `sort_by`, `group_by`, `unique`, `unique_by`, `tostring`,
+ `indices`, `index`, `rindex`, `walk`, `transpose`, `first`, `last`, `nth`,
+ `limit`, `all`, `any`, `isempty`, `error`, `builtins`, `env`)
+* implement math functions (`sin`, `cos`, `tan`, `asin`, `acos`, `atan`,
+ `sinh`, `cosh`, `tanh`, `asinh`, `acosh`, `atanh`, `floor`, `round`,
+ `rint`, `ceil`, `trunc`, `fabs`, `sqrt`, `cbrt`, `exp`, `exp10`, `exp2`,
+ `expm1`, `frexp`, `modf`, `log`, `log10`, `log1p`, `log2`, `logb`,
+ `gamma`, `tgamma`, `lgamma`, `erf`, `erfc`, `j0`, `j1`, `y0`, `y1`,
+ `atan2/2`, `copysign/2`, `drem/2`, `fdim/2`, `fmax/2`, `fmin/2`, `fmod/2`,
+ `hypot/2`, `jn/2`, `ldexp/2`, `nextafter/2`, `nexttoward/2`, `remainder/2`,
+ `scalb/2`, `scalbln/2`, `pow/2`, `yn/2`, `fma/3`)
+* support object construction with variables
+* support indexing against strings
+* fix function evaluation for recursive call
+* fix error handling of `//` operator
+* fix string representation of NaN and Inf
+* implement `-R` flag for reading input as raw strings
+* implement `-c` flag for compact output
+* implement `-n` flag for using null as input value
+* implement `-r` flag for outputting raw string
+* implement `-s` flag for reading all inputs into an array
+
+## [v0.2.0](https://github.com/itchyny/gojq/compare/v0.1.0..v0.2.0) (2019-05-06)
+* implement binding variable syntax (`... as $var`)
+* implement `try` `catch` syntax
+* implement alternative operator (`//`)
+* implement various functions (`in`, `to_entries`, `startswith`, `endswith`,
+ `ltrimstr`, `rtrimstr`, `combinations`, `ascii_downcase`, `ascii_upcase`,
+ `tojson`, `fromjson`)
+* support query for object indexing
+* support object construction with variables
+* support indexing against strings
+
+## [v0.1.0](https://github.com/itchyny/gojq/compare/v0.0.1..v0.1.0) (2019-05-02)
+* implement binary operators (`+`, `-`, `*`, `/`, `%`, `==`, `!=`, `>`, `<`,
+ `>=`, `<=`, `and`, `or`)
+* implement unary operators (`+`, `-`)
+* implement booleans (`false`, `true`), `null`, number and string constant
+ values
+* implement `empty` value
+* implement conditional syntax (`if` `then` `elif` `else` `end`)
+* implement various functions (`length`, `utf8bytelength`, `not`, `keys`,
+ `has`, `map`, `select`, `recurse`, `while`, `until`, `range`, `tonumber`,
+ `type`, `arrays`, `objects`, `iterables`, `booleans`, `numbers`, `strings`,
+ `nulls`, `values`, `scalars`, `reverse`, `explode`, `implode`, `join`)
+* support function declaration
+* support iterators in object keys
+* support object construction shortcut
+* support query in array indices
+* support negative number indexing against arrays
+* support json file name arguments
+
+## [v0.0.1](https://github.com/itchyny/gojq/compare/0fa3241..v0.0.1) (2019-04-14)
+* initial implementation
diff --git a/vendor/github.com/itchyny/gojq/Dockerfile b/vendor/github.com/itchyny/gojq/Dockerfile
new file mode 100644
index 000000000..d5e0dce63
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/Dockerfile
@@ -0,0 +1,14 @@
+FROM golang:1.22 AS builder
+
+WORKDIR /app
+COPY go.* ./
+RUN go mod download
+COPY . .
+ENV CGO_ENABLED 0
+RUN make build
+
+FROM gcr.io/distroless/static:debug
+
+COPY --from=builder /app/gojq /
+ENTRYPOINT ["/gojq"]
+CMD ["--help"]
diff --git a/vendor/github.com/itchyny/gojq/LICENSE b/vendor/github.com/itchyny/gojq/LICENSE
new file mode 100644
index 000000000..fe5900407
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2019-2024 itchyny
+
+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/itchyny/gojq/Makefile b/vendor/github.com/itchyny/gojq/Makefile
new file mode 100644
index 000000000..b7cdb4001
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/Makefile
@@ -0,0 +1,103 @@
+BIN := gojq
+VERSION := $$(make -s show-version)
+VERSION_PATH := cli
+CURRENT_REVISION = $(shell git rev-parse --short HEAD)
+BUILD_LDFLAGS = "-s -w -X github.com/itchyny/$(BIN)/cli.revision=$(CURRENT_REVISION)"
+GOBIN ?= $(shell go env GOPATH)/bin
+SHELL := /bin/bash
+
+.PHONY: all
+all: build
+
+.PHONY: build
+build:
+ go build -ldflags=$(BUILD_LDFLAGS) -o $(BIN) ./cmd/$(BIN)
+
+.PHONY: build-dev
+build-dev: parser.go builtin.go
+ go build -ldflags=$(BUILD_LDFLAGS) -o $(BIN) ./cmd/$(BIN)
+
+.PHONY: build-debug
+build-debug: parser.go builtin.go
+ go build -tags gojq_debug -ldflags=$(BUILD_LDFLAGS) -o $(BIN) ./cmd/$(BIN)
+
+builtin.go: builtin.jq parser.go.y parser.go query.go operator.go _tools/*
+ GOOS= GOARCH= go generate
+
+.SUFFIXES:
+parser.go: parser.go.y $(GOBIN)/goyacc
+ goyacc -o $@ $<
+
+$(GOBIN)/goyacc:
+ @go install golang.org/x/tools/cmd/goyacc@latest
+
+.PHONY: install
+install:
+ go install -ldflags=$(BUILD_LDFLAGS) ./cmd/$(BIN)
+
+.PHONY: install-dev
+install-dev: parser.go builtin.go
+ go install -ldflags=$(BUILD_LDFLAGS) ./cmd/$(BIN)
+
+.PHONY: install-debug
+install-debug: parser.go builtin.go
+ go install -tags gojq_debug -ldflags=$(BUILD_LDFLAGS) ./cmd/$(BIN)
+
+.PHONY: show-version
+show-version: $(GOBIN)/gobump
+ @gobump show -r "$(VERSION_PATH)"
+
+$(GOBIN)/gobump:
+ @go install github.com/x-motemen/gobump/cmd/gobump@latest
+
+.PHONY: cross
+cross: $(GOBIN)/goxz CREDITS
+ goxz -n $(BIN) -pv=v$(VERSION) -include _$(BIN) \
+ -build-ldflags=$(BUILD_LDFLAGS) ./cmd/$(BIN)
+
+$(GOBIN)/goxz:
+ go install github.com/Songmu/goxz/cmd/goxz@latest
+
+CREDITS: $(GOBIN)/gocredits go.sum
+ go mod tidy
+ gocredits -w .
+
+$(GOBIN)/gocredits:
+ go install github.com/Songmu/gocredits/cmd/gocredits@latest
+
+.PHONY: test
+test: build
+ go test -v -race ./...
+
+.PHONY: lint
+lint: $(GOBIN)/staticcheck
+ go vet ./...
+ staticcheck -checks all -tags gojq_debug ./...
+
+$(GOBIN)/staticcheck:
+ go install honnef.co/go/tools/cmd/staticcheck@latest
+
+.PHONY: check-tools
+check-tools:
+ go run _tools/print_builtin.go
+
+.PHONY: clean
+clean:
+ rm -rf $(BIN) goxz CREDITS
+ go clean
+
+.PHONY: update
+update: export GOPROXY=direct
+update:
+ go get -u -d ./... && go mod tidy
+ go mod edit -modfile=go.dev.mod -droprequire=github.com/itchyny/{astgen,timefmt}-go
+ go get -u -d -modfile=go.dev.mod github.com/itchyny/{astgen,timefmt}-go && go generate
+
+.PHONY: bump
+bump: $(GOBIN)/gobump
+ test -z "$$(git status --porcelain || echo .)"
+ test "$$(git branch --show-current)" = "main"
+ @gobump up -w "$(VERSION_PATH)"
+ git commit -am "bump up version to $(VERSION)"
+ git tag "v$(VERSION)"
+ git push --atomic origin main tag "v$(VERSION)"
diff --git a/vendor/github.com/itchyny/gojq/README.md b/vendor/github.com/itchyny/gojq/README.md
new file mode 100644
index 000000000..7b34f93c3
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/README.md
@@ -0,0 +1,160 @@
+# gojq
+[![CI Status](https://github.com/itchyny/gojq/actions/workflows/ci.yaml/badge.svg?branch=main)](https://github.com/itchyny/gojq/actions?query=branch:main)
+[![Go Report Card](https://goreportcard.com/badge/github.com/itchyny/gojq)](https://goreportcard.com/report/github.com/itchyny/gojq)
+[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/itchyny/gojq/blob/main/LICENSE)
+[![release](https://img.shields.io/github/release/itchyny/gojq/all.svg)](https://github.com/itchyny/gojq/releases)
+[![pkg.go.dev](https://pkg.go.dev/badge/github.com/itchyny/gojq)](https://pkg.go.dev/github.com/itchyny/gojq)
+
+### Pure Go implementation of [jq](https://github.com/jqlang/jq)
+This is an implementation of jq command written in Go language.
+You can also embed gojq as a library to your Go products.
+
+## Usage
+```sh
+ $ echo '{"foo": 128}' | gojq '.foo'
+128
+ $ echo '{"a": {"b": 42}}' | gojq '.a.b'
+42
+ $ echo '{"id": "sample", "10": {"b": 42}}' | gojq '{(.id): .["10"].b}'
+{
+ "sample": 42
+}
+ $ echo '[{"id":1},{"id":2},{"id":3}]' | gojq '.[] | .id'
+1
+2
+3
+ $ echo '{"a":1,"b":2}' | gojq '.a += 1 | .b *= 2'
+{
+ "a": 2,
+ "b": 4
+}
+ $ echo '{"a":1} [2] 3' | gojq '. as {$a} ?// [$a] ?// $a | $a'
+1
+2
+3
+ $ echo '{"foo": 4722366482869645213696}' | gojq .foo
+4722366482869645213696 # keeps the precision of large numbers
+ $ gojq -n 'def fact($n): if $n < 1 then 1 else $n * fact($n - 1) end; fact(50)'
+30414093201713378043612608166064768844377641568960512000000000000 # arbitrary-precision integer calculation
+```
+
+Nice error messages.
+```sh
+ $ echo '[1,2,3]' | gojq '.foo & .bar'
+gojq: invalid query: .foo & .bar
+ .foo & .bar
+ ^ unexpected token "&"
+ $ echo '{"foo": { bar: [] } }' | gojq '.'
+gojq: invalid json:
+ {"foo": { bar: [] } }
+ ^ invalid character 'b' looking for beginning of object key string
+```
+
+## Installation
+### Homebrew
+```sh
+brew install gojq
+```
+
+### Zero Install
+```sh
+0install add gojq https://apps.0install.net/utils/gojq.xml
+```
+
+### Build from source
+```sh
+go install github.com/itchyny/gojq/cmd/gojq@latest
+```
+
+### Docker
+```sh
+docker run -i --rm itchyny/gojq
+docker run -i --rm ghcr.io/itchyny/gojq
+```
+
+## Difference to jq
+- gojq is purely implemented with Go language and is completely portable. jq depends on the C standard library so the availability of math functions depends on the library. jq also depends on the regular expression library and it makes build scripts complex.
+- gojq implements nice error messages for invalid query and JSON input. The error message of jq is sometimes difficult to tell where to fix the query.
+- gojq does not keep the order of object keys. I understand this might cause problems for some scripts but basically, we should not rely on the order of object keys. Due to this limitation, gojq does not have `keys_unsorted` function and `--sort-keys` (`-S`) option. I would implement when ordered map is implemented in the standard library of Go but I'm less motivated.
+- gojq supports arbitrary-precision integer calculation while jq does not; jq loses the precision of large integers when calculation is involved. Note that even with gojq, all mathematical functions, including `floor` and `round`, convert integers to floating-point numbers; only addition, subtraction, multiplication, modulo, and division operators (when divisible) keep the integer precision. To calculate floor division of integers without losing the precision, use `def idivide($n): (. - . % $n) / $n;`. To round down floating-point numbers to integers, use `def ifloor: floor | tostring | tonumber;`, but note that this function does not work with large floating-point numbers and also loses the precision of large integers.
+- gojq behaves differently than jq in some features, hoping that jq will fix the behaviors in the future. gojq consistently counts by characters (not by bytes) in `index`, `rindex`, and `indices` functions; `"12345" | .[index("3"):]` results in `"345"` ([jq#1430](https://github.com/jqlang/jq/issues/1430), [jq#1624](https://github.com/jqlang/jq/issues/1624)). gojq supports string indexing; `"abcde"[2]` ([jq#1520](https://github.com/jqlang/jq/issues/1520)). gojq fixes handling files with no newline characters at the end ([jq#2374](https://github.com/jqlang/jq/issues/2374)). gojq consistently truncates down floating-point number indices both in indexing (`[0] | .[0.5]` results in `0`), and slicing (`[0,1,2] | .[0.5:1.5]` results in `[0]`). gojq parses unary operators with higher precedence than variable binding (`[-1 as $x | 1,$x]` results in `[1,-1]` not `[-1,-1]`) ([jq#3053](https://github.com/jqlang/jq/pull/3053)). gojq fixes `@base64d` to allow binary string as the decoded string ([jq#1931](https://github.com/jqlang/jq/issues/1931)). gojq improves time formatting and parsing; deals with `%f` in `strftime` and `strptime` ([jq#1409](https://github.com/jqlang/jq/issues/1409)), parses timezone offsets with `fromdate` and `fromdateiso8601` ([jq#1053](https://github.com/jqlang/jq/issues/1053)), supports timezone name/offset with `%Z`/`%z` in `strptime` ([jq#929](https://github.com/jqlang/jq/issues/929), [jq#2195](https://github.com/jqlang/jq/issues/2195)), and looks up correct timezone during daylight saving time on formatting with `%Z` ([jq#1912](https://github.com/jqlang/jq/issues/1912)). gojq supports nanoseconds in date and time functions.
+- gojq does not support some functions intentionally; `get_jq_origin`, `get_prog_origin`, `get_search_list` (unstable, not listed in jq document), `input_line_number`, `$__loc__` (performance issue). gojq does not support some flags; `--ascii-output, -a` (performance issue), `--seq` (not used commonly), `--sort-keys, -S` (sorts by default because `map[string]any` does not keep the order), `--unbuffered` (unbuffered by default). gojq does not parse JSON extensions supported by jq; `NaN`, `Infinity`, and `[000]`. gojq normalizes floating-point numbers to fit to double-precision floating-point numbers. gojq does not support some regular expression metacharacters, backreferences, look-around assertions, and some flags (regular expression engine differences). gojq does not support BOM (`encoding/json` does not support this). gojq disallows using keywords for function names (`def true: .; true` is a confusing query), and module name prefixes in function declarations (using module prefixes like `def m::f: .;` is undocumented).
+- gojq supports reading from YAML input (`--yaml-input`) while jq does not. gojq also supports YAML output (`--yaml-output`). gojq supports `@urid` format string ([jq#798](https://github.com/jqlang/jq/issues/798), [jq#2261](https://github.com/jqlang/jq/issues/2261)).
+
+### Color configuration
+The gojq command automatically disables coloring output when the output is not a tty.
+To force coloring output, specify `--color-output` (`-C`) option.
+When [`NO_COLOR` environment variable](https://no-color.org/) is present or `--monochrome-output` (`-M`) option is specified, gojq disables coloring output.
+
+Use `GOJQ_COLORS` environment variable to configure individual colors.
+The variable is a colon-separated list of ANSI escape sequences of `null`, `false`, `true`, numbers, strings, object keys, arrays, and objects.
+The default configuration is `90:33:33:36:32:34;1`.
+
+## Usage as a library
+You can use the gojq parser and interpreter from your Go products.
+
+```go
+package main
+
+import (
+ "fmt"
+ "log"
+
+ "github.com/itchyny/gojq"
+)
+
+func main() {
+ query, err := gojq.Parse(".foo | ..")
+ if err != nil {
+ log.Fatalln(err)
+ }
+ input := map[string]any{"foo": []any{1, 2, 3}}
+ iter := query.Run(input) // or query.RunWithContext
+ for {
+ v, ok := iter.Next()
+ if !ok {
+ break
+ }
+ if err, ok := v.(error); ok {
+ if err, ok := err.(*gojq.HaltError); ok && err.Value() == nil {
+ break
+ }
+ log.Fatalln(err)
+ }
+ fmt.Printf("%#v\n", v)
+ }
+}
+```
+
+- Firstly, use [`gojq.Parse(string) (*Query, error)`](https://pkg.go.dev/github.com/itchyny/gojq#Parse) to get the query from a string.
+ - Use [`gojq.ParseError`](https://pkg.go.dev/github.com/itchyny/gojq#ParseError) to get the error position and token of the parsing error.
+- Secondly, get the result iterator
+ - using [`query.Run`](https://pkg.go.dev/github.com/itchyny/gojq#Query.Run) or [`query.RunWithContext`](https://pkg.go.dev/github.com/itchyny/gojq#Query.RunWithContext)
+ - or alternatively, compile the query using [`gojq.Compile`](https://pkg.go.dev/github.com/itchyny/gojq#Compile) and then [`code.Run`](https://pkg.go.dev/github.com/itchyny/gojq#Code.Run) or [`code.RunWithContext`](https://pkg.go.dev/github.com/itchyny/gojq#Code.RunWithContext). You can reuse the `*Code` against multiple inputs to avoid compilation of the same query. But for arguments of `code.Run`, do not give values sharing same data between multiple calls.
+ - In either case, you cannot use custom type values as the query input. The type should be `[]any` for an array and `map[string]any` for a map (just like decoded to an `any` using the [encoding/json](https://golang.org/pkg/encoding/json/) package). You can't use `[]int` or `map[string]string`, for example. If you want to query your custom struct, marshal to JSON, unmarshal to `any` and use it as the query input.
+- Thirdly, iterate through the results using [`iter.Next() (any, bool)`](https://pkg.go.dev/github.com/itchyny/gojq#Iter). The iterator can emit an error so make sure to handle it. The method returns `true` with results, and `false` when the iterator terminates.
+ - The return type is not `(any, error)` because the iterator may emit multiple errors. The `jq` and `gojq` commands stop the iteration on the first error, but the library user can choose to stop the iteration on errors, or to continue until it terminates.
+ - In any case, it is recommended to stop the iteration on [`gojq.HaltError`](https://pkg.go.dev/github.com/itchyny/gojq#HaltError), which is emitted by `halt` and `halt_error` functions, although these functions are rarely used.
+ The error implements [`gojq.ValueError`](https://pkg.go.dev/github.com/itchyny/gojq#ValueError), and if the error value is `nil`, stop the iteration without handling the error.
+ Technically speaking, we can fix the iterator to terminate on the halting error, but it does not terminate at the moment.
+ The `halt` function in jq not only stops the iteration, but also terminates the command execution, even if there are still input values.
+ So, gojq leaves it up to the library user how to handle the halting error.
+ - Note that the result iterator may emit infinite number of values; `repeat(0)` and `range(infinite)`. It may stuck with no output value; `def f: f; f`. Use `RunWithContext` when you want to limit the execution time.
+
+[`gojq.Compile`](https://pkg.go.dev/github.com/itchyny/gojq#Compile) allows to configure the following compiler options.
+
+- [`gojq.WithModuleLoader`](https://pkg.go.dev/github.com/itchyny/gojq#WithModuleLoader) allows to load modules. By default, the module feature is disabled. If you want to load modules from the file system, use [`gojq.NewModuleLoader`](https://pkg.go.dev/github.com/itchyny/gojq#NewModuleLoader).
+- [`gojq.WithEnvironLoader`](https://pkg.go.dev/github.com/itchyny/gojq#WithEnvironLoader) allows to configure the environment variables referenced by `env` and `$ENV`. By default, OS environment variables are not accessible due to security reasons. You can use `gojq.WithEnvironLoader(os.Environ)` if you want.
+- [`gojq.WithVariables`](https://pkg.go.dev/github.com/itchyny/gojq#WithVariables) allows to configure the variables which can be used in the query. Pass the values of the variables to [`code.Run`](https://pkg.go.dev/github.com/itchyny/gojq#Code.Run) in the same order.
+- [`gojq.WithFunction`](https://pkg.go.dev/github.com/itchyny/gojq#WithFunction) allows to add a custom internal function. An internal function can return a single value (which can be an error) each invocation. To add a jq function (which may include a comma operator to emit multiple values, `empty` function, accept a filter for its argument, or call another built-in function), use `LoadInitModules` of the module loader.
+- [`gojq.WithIterFunction`](https://pkg.go.dev/github.com/itchyny/gojq#WithIterFunction) allows to add a custom iterator function. An iterator function returns an iterator to emit multiple values. You cannot define both iterator and non-iterator functions of the same name (with possibly different arities). You can use [`gojq.NewIter`](https://pkg.go.dev/github.com/itchyny/gojq#NewIter) to convert values or an error to a [`gojq.Iter`](https://pkg.go.dev/github.com/itchyny/gojq#Iter).
+- [`gojq.WithInputIter`](https://pkg.go.dev/github.com/itchyny/gojq#WithInputIter) allows to use `input` and `inputs` functions. By default, these functions are disabled.
+
+## Bug Tracker
+Report bug at [Issues・itchyny/gojq - GitHub](https://github.com/itchyny/gojq/issues).
+
+## Author
+itchyny ()
+
+## License
+This software is released under the MIT License, see LICENSE.
diff --git a/vendor/github.com/itchyny/gojq/_gojq b/vendor/github.com/itchyny/gojq/_gojq
new file mode 100644
index 000000000..01e4c4f77
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/_gojq
@@ -0,0 +1,43 @@
+#compdef gojq
+
+_gojq()
+{
+ _arguments -s -S \
+ '(-r --raw-output --raw-output0 -j --join-output)'{-r,--raw-output}'[output raw strings]' \
+ '(-r --raw-output -j --join-output)--raw-output0[implies -r with NUL character delimiter]' \
+ '(-r --raw-output --raw-output0 -j --join-output)'{-j,--join-output}'[implies -r with no newline delimiter]' \
+ '(-c --compact-output --indent --tab --yaml-output)'{-c,--compact-output}'[output without pretty-printing]' \
+ '(-c --compact-output --tab --yaml-output)--indent=[number of spaces for indentation]:indentation count:(2 4 8)' \
+ '(-c --compact-output --indent --yaml-output)--tab[use tabs for indentation]' \
+ '(-c --compact-output --indent --tab )--yaml-output[output in YAML format]' \
+ '(-C --color-output -M --monochrome-output)'{-C,--color-output}'[output with colors even if piped]' \
+ '(-C --color-output -M --monochrome-output)'{-M,--monochrome-output}'[output without colors]' \
+ '(-n --null-input)'{-n,--null-input}'[use null as input value]' \
+ '(-R --raw-input --stream --yaml-input)'{-R,--raw-input}'[read input as raw strings]' \
+ '(-R --raw-input --yaml-input)--stream[parse input in stream fashion]' \
+ '(-R --raw-input --stream )--yaml-input[read input as YAML format]' \
+ '(-s --slurp)'{-s,--slurp}'[read all inputs into an array]' \
+ '(-f --from-file 1)'{-f,--from-file}'[load query from file]:filename of jq query:_files' \
+ '*-L=[directory to search modules from]:module directory:_directories' \
+ '*--arg[set a string value to a variable]:variable name: :string value' \
+ '*--argjson[set a JSON value to a variable]:variable name: :JSON value' \
+ '*--slurpfile[set the JSON contents of a file to a variable]:variable name: :JSON file:_files' \
+ '*--rawfile[set the contents of a file to a variable]:variable name: :file:_files' \
+ '*--args[consume remaining arguments as positional string values]' \
+ '*--jsonargs[consume remaining arguments as positional JSON values]' \
+ '(-e --exit-status)'{-e,--exit-status}'[exit 1 when the last value is false or null]' \
+ '(- 1 *)'{-v,--version}'[display version information]' \
+ '(- 1 *)'{-h,--help}'[display help information]' \
+ '1: :_guard "^-([[:alpha:]0]#|-*)" "jq query"' \
+ '*: :_gojq_args'
+}
+
+_gojq_args() {
+ if (($words[(I)--args] > $words[(I)--jsonargs])); then
+ _message 'string value'
+ elif (($words[(I)--args] < $words[(I)--jsonargs])); then
+ _message 'JSON value'
+ else
+ _arguments '*:input file:_files'
+ fi
+}
diff --git a/vendor/github.com/itchyny/gojq/builtin.go b/vendor/github.com/itchyny/gojq/builtin.go
new file mode 100644
index 000000000..7da4a93ea
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/builtin.go
@@ -0,0 +1,69 @@
+// Code generated by _tools/gen_builtin.go; DO NOT EDIT.
+
+package gojq
+
+func init() {
+ builtinFuncDefs = map[string][]*FuncDef{
+ "IN": {{Name: "IN", Args: []string{"s"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{{Left: &Query{Func: "s"}, Op: OpEq, Right: &Query{Func: "."}}, {Func: "."}}}}}}, {Name: "IN", Args: []string{"src", "s"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{{Left: &Query{Func: "src"}, Op: OpEq, Right: &Query{Func: "s"}}, {Func: "."}}}}}}},
+ "INDEX": {{Name: "INDEX", Args: []string{"stream", "idx_expr"}, Body: &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "stream"}}, Pattern: &Pattern{Name: "$row"}, Start: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{}}}, Update: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Left: &Query{Func: "$row"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "idx_expr"}, Op: OpPipe, Right: &Query{Func: "tostring"}}}}}}, Op: OpAssign, Right: &Query{Func: "$row"}}}}}}, {Name: "INDEX", Args: []string{"idx_expr"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "INDEX", Args: []*Query{{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}}, {Func: "idx_expr"}}}}}}},
+ "JOIN": {{Name: "JOIN", Args: []string{"$idx", "idx_expr"}, Body: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$idx"}, SuffixList: []*Suffix{{Index: &Index{Start: &Query{Func: "idx_expr"}}}}}}}}}}}}}}}, {Name: "JOIN", Args: []string{"$idx", "stream", "idx_expr"}, Body: &Query{Left: &Query{Func: "stream"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$idx"}, SuffixList: []*Suffix{{Index: &Index{Start: &Query{Func: "idx_expr"}}}}}}}}}}}}, {Name: "JOIN", Args: []string{"$idx", "stream", "idx_expr", "join_expr"}, Body: &Query{Left: &Query{Func: "stream"}, Op: OpPipe, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$idx"}, SuffixList: []*Suffix{{Index: &Index{Start: &Query{Func: "idx_expr"}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "join_expr"}}}}},
+ "_assign": {},
+ "_modify": {},
+ "all": {{Name: "all", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "all", Args: []*Query{{Func: "."}}}}}}, {Name: "all", Args: []string{"y"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "all", Args: []*Query{{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}}, {Func: "y"}}}}}}, {Name: "all", Args: []string{"g", "y"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "isempty", Args: []*Query{{Left: &Query{Func: "g"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "y"}, Op: OpPipe, Right: &Query{Func: "not"}}}}}}}}}}}}},
+ "any": {{Name: "any", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{{Func: "."}}}}}}, {Name: "any", Args: []string{"y"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "any", Args: []*Query{{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}}, {Func: "y"}}}}}}, {Name: "any", Args: []string{"g", "y"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "isempty", Args: []*Query{{Left: &Query{Func: "g"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Func: "y"}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "not"}}}},
+ "arrays": {{Name: "arrays", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}}}}}}}},
+ "booleans": {{Name: "booleans", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "boolean"}}}}}}}}}},
+ "capture": {{Name: "capture", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "capture", Args: []*Query{{Func: "$re"}, {Func: "null"}}}}}}, {Name: "capture", Args: []string{"$re", "$flags"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{{Func: "$re"}, {Func: "$flags"}}}}}, Op: OpPipe, Right: &Query{Func: "_capture"}}}},
+ "combinations": {{Name: "combinations", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "length"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}, Else: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, SuffixList: []*Suffix{{Iter: true}, {Bind: &Bind{Patterns: []*Pattern{{Name: "$x"}}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "$x"}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}, IsSlice: true}}}, Op: OpPipe, Right: &Query{Func: "combinations"}}}}}}}}}}}}}}, {Name: "combinations", Args: []string{"n"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "limit", Args: []*Query{{Func: "n"}, {Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "repeat", Args: []*Query{{Func: "."}}}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "combinations"}}}},
+ "debug": {{Name: "debug", Args: []string{"f"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "f"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "debug"}, Op: OpPipe, Right: &Query{Func: "empty"}}}}}, Op: OpComma, Right: &Query{Func: "."}}}},
+ "del": {{Name: "del", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "delpaths", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{{Func: "f"}}}}}}}}}}}}}},
+ "finites": {{Name: "finites", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Func: "isfinite"}}}}}}},
+ "first": {{Name: "first", Body: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}, {Name: "first", Args: []string{"g"}, Body: &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{Ident: "$out", Body: &Query{Left: &Query{Func: "g"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeBreak, Break: "$out"}}}}}}}}},
+ "fromdate": {{Name: "fromdate", Body: &Query{Func: "fromdateiso8601"}}},
+ "fromdateiso8601": {{Name: "fromdateiso8601", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "strptime", Args: []*Query{{Term: &Term{Type: TermTypeString, Str: &String{Str: "%Y-%m-%dT%H:%M:%S%z"}}}}}}}, Op: OpPipe, Right: &Query{Func: "mktime"}}}},
+ "fromstream": {{Name: "fromstream", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{KeyVals: []*ObjectKeyVal{{Key: "x", Val: &ObjectVal{Queries: []*Query{{Func: "null"}}}}, {Key: "e", Val: &ObjectVal{Queries: []*Query{{Func: "false"}}}}}}, SuffixList: []*Suffix{{Bind: &Bind{Patterns: []*Pattern{{Name: "$init"}}, Body: &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "f"}}, Pattern: &Pattern{Name: "$i"}, Start: &Query{Func: "$init"}, Update: &Query{Left: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "e"}}}, Then: &Query{Func: "$init"}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "$i"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "2"}}}}, Then: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "e"}}}}}}, {Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$i"}, SuffixList: []*Suffix{{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{{Left: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "x"}}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$i"}, SuffixList: []*Suffix{{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}}}, {Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$i"}, SuffixList: []*Suffix{{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}}}}}}, Else: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "e"}}}}}}, {Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$i"}, SuffixList: []*Suffix{{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}}}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}}}}}}, Extract: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "e"}}}, Then: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "x"}}}, Else: &Query{Func: "empty"}}}}}}}}}}}}}},
+ "group_by": {{Name: "group_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_group_by", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}}}}}}}}}}},
+ "gsub": {{Name: "gsub", Args: []string{"$re", "str"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "sub", Args: []*Query{{Func: "$re"}, {Func: "str"}, {Term: &Term{Type: TermTypeString, Str: &String{Str: "g"}}}}}}}}, {Name: "gsub", Args: []string{"$re", "str", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "sub", Args: []*Query{{Func: "$re"}, {Func: "str"}, {Left: &Query{Func: "$flags"}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "g"}}}}}}}}}},
+ "in": {{Name: "in", Args: []string{"xs"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Bind: &Bind{Patterns: []*Pattern{{Name: "$x"}}, Body: &Query{Left: &Query{Func: "xs"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "has", Args: []*Query{{Func: "$x"}}}}}}}}}}}}},
+ "inputs": {{Name: "inputs", Body: &Query{Term: &Term{Type: TermTypeTry, Try: &Try{Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "repeat", Args: []*Query{{Func: "input"}}}}}, Catch: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "break"}}}}, Then: &Query{Func: "empty"}, Else: &Query{Func: "error"}}}}}}}}},
+ "inside": {{Name: "inside", Args: []string{"xs"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Bind: &Bind{Patterns: []*Pattern{{Name: "$x"}}, Body: &Query{Left: &Query{Func: "xs"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "contains", Args: []*Query{{Func: "$x"}}}}}}}}}}}}},
+ "isempty": {{Name: "isempty", Args: []string{"g"}, Body: &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{Ident: "$out", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "g"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "false"}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeBreak, Break: "$out"}}}}}}, Op: OpComma, Right: &Query{Func: "true"}}}}}}},
+ "iterables": {{Name: "iterables", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "type"}, Op: OpPipe, Right: &Query{Left: &Query{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}}, Op: OpOr, Right: &Query{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}}}}}}}}}},
+ "last": {{Name: "last", Body: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeUnary, Unary: &Unary{Op: OpSub, Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}}, {Name: "last", Args: []string{"g"}, Body: &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "g"}}, Pattern: &Pattern{Name: "$item"}, Start: &Query{Func: "null"}, Update: &Query{Func: "$item"}}}}}},
+ "limit": {{Name: "limit", Args: []string{"$n", "g"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "$n"}, Op: OpGt, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{Ident: "$out", Body: &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "g"}}, Pattern: &Pattern{Name: "$item"}, Start: &Query{Func: "$n"}, Update: &Query{Left: &Query{Func: "."}, Op: OpSub, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}, Extract: &Query{Left: &Query{Func: "$item"}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "."}, Op: OpLe, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Term: &Term{Type: TermTypeBreak, Break: "$out"}}, Else: &Query{Func: "empty"}}}}}}}}}}}, Elif: []*IfElif{{Cond: &Query{Left: &Query{Func: "$n"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Func: "empty"}}}, Else: &Query{Func: "g"}}}}}},
+ "map": {{Name: "map", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}}, Op: OpPipe, Right: &Query{Func: "f"}}}}}}},
+ "map_values": {{Name: "map_values", Args: []string{"f"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}}, Op: OpModify, Right: &Query{Func: "f"}}}},
+ "match": {{Name: "match", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{{Func: "$re"}, {Func: "null"}}}}}}, {Name: "match", Args: []string{"$re", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_match", Args: []*Query{{Func: "$re"}, {Func: "$flags"}, {Func: "false"}}}, SuffixList: []*Suffix{{Iter: true}}}}}},
+ "max_by": {{Name: "max_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_max_by", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}}}}}}}}}}},
+ "min_by": {{Name: "min_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_min_by", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}}}}}}}}}}},
+ "normals": {{Name: "normals", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Func: "isnormal"}}}}}}},
+ "not": {{Name: "not", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Func: "."}, Then: &Query{Func: "false"}, Else: &Query{Func: "true"}}}}}},
+ "nth": {{Name: "nth", Args: []string{"$n"}, Body: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Func: "$n"}}}}}, {Name: "nth", Args: []string{"$n", "g"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "$n"}, Op: OpLt, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "error", Args: []*Query{{Term: &Term{Type: TermTypeString, Str: &String{Str: "nth doesn't support negative indices"}}}}}}}, Else: &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{Ident: "$out", Body: &Query{Term: &Term{Type: TermTypeForeach, Foreach: &Foreach{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "g"}}, Pattern: &Pattern{Name: "$item"}, Start: &Query{Left: &Query{Func: "$n"}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}, Update: &Query{Left: &Query{Func: "."}, Op: OpSub, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "1"}}}, Extract: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "."}, Op: OpLe, Right: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}, Then: &Query{Left: &Query{Func: "$item"}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeBreak, Break: "$out"}}}, Else: &Query{Func: "empty"}}}}}}}}}}}}}}},
+ "nulls": {{Name: "nulls", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "."}, Op: OpEq, Right: &Query{Func: "null"}}}}}}}},
+ "numbers": {{Name: "numbers", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "number"}}}}}}}}}},
+ "objects": {{Name: "objects", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}}}}}}}},
+ "paths": {{Name: "paths", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{{Func: ".."}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "."}, Op: OpNe, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}}}}}}}}, {Name: "paths", Args: []string{"f"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{{Left: &Query{Func: ".."}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Func: "f"}}}}}}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "."}, Op: OpNe, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}}}}}}}}},
+ "pick": {{Name: "pick", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Bind: &Bind{Patterns: []*Pattern{{Name: "$v"}}, Body: &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{{Func: "f"}}}}, Pattern: &Pattern{Name: "$p"}, Start: &Query{Func: "null"}, Update: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "setpath", Args: []*Query{{Func: "$p"}, {Left: &Query{Func: "$v"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "getpath", Args: []*Query{{Func: "$p"}}}}}}}}}}}}}}}}}}}},
+ "range": {{Name: "range", Args: []string{"$end"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_range", Args: []*Query{{Term: &Term{Type: TermTypeNumber, Number: "0"}}, {Func: "$end"}, {Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}, {Name: "range", Args: []string{"$start", "$end"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_range", Args: []*Query{{Func: "$start"}, {Func: "$end"}, {Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}}, {Name: "range", Args: []string{"$start", "$end", "$step"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_range", Args: []*Query{{Func: "$start"}, {Func: "$end"}, {Func: "$step"}}}}}}},
+ "recurse": {{Name: "recurse", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "recurse", Args: []*Query{{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}, {Optional: true}}}}}}}}}, {Name: "recurse", Args: []string{"f"}, Body: &Query{FuncDefs: []*FuncDef{{Name: "r", Body: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "f"}, Op: OpPipe, Right: &Query{Func: "r"}}}}}}}, Func: "r"}}, {Name: "recurse", Args: []string{"f", "cond"}, Body: &Query{FuncDefs: []*FuncDef{{Name: "r", Body: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "f"}, Op: OpPipe, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Func: "cond"}}}}}, Op: OpPipe, Right: &Query{Func: "r"}}}}}}}}, Func: "r"}}},
+ "repeat": {{Name: "repeat", Args: []string{"f"}, Body: &Query{FuncDefs: []*FuncDef{{Name: "_repeat", Body: &Query{Left: &Query{Func: "f"}, Op: OpComma, Right: &Query{Func: "_repeat"}}}}, Func: "_repeat"}}},
+ "scalars": {{Name: "scalars", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "type"}, Op: OpPipe, Right: &Query{Left: &Query{Left: &Query{Func: "."}, Op: OpNe, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}}, Op: OpAnd, Right: &Query{Left: &Query{Func: "."}, Op: OpNe, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}}}}}}}}}},
+ "scan": {{Name: "scan", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "scan", Args: []*Query{{Func: "$re"}, {Func: "null"}}}}}}, {Name: "scan", Args: []string{"$re", "$flags"}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{{Func: "$re"}, {Left: &Query{Func: "$flags"}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "g"}}}}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "captures"}}}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}}, Then: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "string"}}}, Else: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "captures"}, SuffixList: []*Suffix{{Iter: true}, {Index: &Index{Name: "string"}}}}}}}}}}}}}},
+ "select": {{Name: "select", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Func: "f"}, Then: &Query{Func: "."}, Else: &Query{Func: "empty"}}}}}},
+ "sort_by": {{Name: "sort_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_sort_by", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}}}}}}}}}}},
+ "splits": {{Name: "splits", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "splits", Args: []*Query{{Func: "$re"}, {Func: "null"}}}}}}, {Name: "splits", Args: []string{"$re", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "split", Args: []*Query{{Func: "$re"}, {Func: "$flags"}}}, SuffixList: []*Suffix{{Iter: true}}}}}},
+ "strings": {{Name: "strings", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "string"}}}}}}}}}},
+ "sub": {{Name: "sub", Args: []string{"$re", "str"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "sub", Args: []*Query{{Func: "$re"}, {Func: "str"}, {Func: "null"}}}}}}, {Name: "sub", Args: []string{"$re", "str", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Bind: &Bind{Patterns: []*Pattern{{Name: "$str"}}, Body: &Query{FuncDefs: []*FuncDef{{Name: "_sub", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "matches"}}}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{}}}}, Then: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$str"}, SuffixList: []*Suffix{{Index: &Index{End: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "offset"}}}, IsSlice: true}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "string"}}}}, Else: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "matches"}, SuffixList: []*Suffix{{Index: &Index{Start: &Query{Term: &Term{Type: TermTypeUnary, Unary: &Unary{Op: OpSub, Term: &Term{Type: TermTypeNumber, Number: "1"}}}}}}, {Bind: &Bind{Patterns: []*Pattern{{Name: "$r"}}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{KeyVals: []*ObjectKeyVal{{Key: "string", Val: &ObjectVal{Queries: []*Query{{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Left: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "$r"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "_capture"}, Op: OpPipe, Right: &Query{Func: "str"}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$str"}, SuffixList: []*Suffix{{Index: &Index{Start: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$r"}, SuffixList: []*Suffix{{Index: &Index{Name: "offset"}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$r"}, SuffixList: []*Suffix{{Index: &Index{Name: "length"}}}}}}, End: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "offset"}}}, IsSlice: true}}}}}}, Op: OpAdd, Right: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "string"}}}}}}}}}, {Key: "offset", Val: &ObjectVal{Queries: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "$r"}, SuffixList: []*Suffix{{Index: &Index{Name: "offset"}}}}}}}}, {Key: "matches", Val: &ObjectVal{Queries: []*Query{{Term: &Term{Type: TermTypeIndex, Index: &Index{Name: "matches"}, SuffixList: []*Suffix{{Index: &Index{End: &Query{Term: &Term{Type: TermTypeUnary, Unary: &Unary{Op: OpSub, Term: &Term{Type: TermTypeNumber, Number: "1"}}}}, IsSlice: true}}}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "_sub"}}}}}}}}}}}}, Left: &Query{Term: &Term{Type: TermTypeObject, Object: &Object{KeyVals: []*ObjectKeyVal{{Key: "string", Val: &ObjectVal{Queries: []*Query{{Term: &Term{Type: TermTypeString, Str: &String{}}}}}}, {Key: "matches", Val: &ObjectVal{Queries: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "match", Args: []*Query{{Func: "$re"}, {Func: "$flags"}}}}}}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "_sub"}}}}}}}}},
+ "test": {{Name: "test", Args: []string{"$re"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "test", Args: []*Query{{Func: "$re"}, {Func: "null"}}}}}}, {Name: "test", Args: []string{"$re", "$flags"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_match", Args: []*Query{{Func: "$re"}, {Func: "$flags"}, {Func: "true"}}}}}}},
+ "todate": {{Name: "todate", Body: &Query{Func: "todateiso8601"}}},
+ "todateiso8601": {{Name: "todateiso8601", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "strftime", Args: []*Query{{Term: &Term{Type: TermTypeString, Str: &String{Str: "%Y-%m-%dT%H:%M:%SZ"}}}}}}}}},
+ "tostream": {{Name: "tostream", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{{FuncDefs: []*FuncDef{{Name: "r", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}, {Optional: true}}}}, Op: OpPipe, Right: &Query{Func: "r"}}}}, Op: OpComma, Right: &Query{Func: "."}}}}, Func: "r"}}}, SuffixList: []*Suffix{{Bind: &Bind{Patterns: []*Pattern{{Name: "$p"}}, Body: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "getpath", Args: []*Query{{Func: "$p"}}}}}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeReduce, Reduce: &Reduce{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "path", Args: []*Query{{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}, {Optional: true}}}}}}}, Pattern: &Pattern{Name: "$q"}, Start: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "$p"}, Op: OpComma, Right: &Query{Func: "."}}}}}, Update: &Query{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Left: &Query{Func: "$p"}, Op: OpAdd, Right: &Query{Func: "$q"}}}}}}}}}}}}}}}},
+ "truncate_stream": {{Name: "truncate_stream", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Bind: &Bind{Patterns: []*Pattern{{Name: "$n"}}, Body: &Query{Left: &Query{Func: "null"}, Op: OpPipe, Right: &Query{Left: &Query{Func: "f"}, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}, Op: OpPipe, Right: &Query{Left: &Query{Func: "length"}, Op: OpGt, Right: &Query{Func: "$n"}}}, Then: &Query{Left: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Term: &Term{Type: TermTypeNumber, Number: "0"}}}}}, Op: OpModify, Right: &Query{Term: &Term{Type: TermTypeIndex, Index: &Index{Start: &Query{Func: "$n"}, IsSlice: true}}}}, Else: &Query{Func: "empty"}}}}}}}}}}}}},
+ "unique_by": {{Name: "unique_by", Args: []string{"f"}, Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "_unique_by", Args: []*Query{{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Term: &Term{Type: TermTypeArray, Array: &Array{Query: &Query{Func: "f"}}}}}}}}}}}}}},
+ "until": {{Name: "until", Args: []string{"cond", "next"}, Body: &Query{FuncDefs: []*FuncDef{{Name: "_until", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Func: "cond"}, Then: &Query{Func: "."}, Else: &Query{Left: &Query{Func: "next"}, Op: OpPipe, Right: &Query{Func: "_until"}}}}}}}, Func: "_until"}}},
+ "values": {{Name: "values", Body: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "select", Args: []*Query{{Left: &Query{Func: "."}, Op: OpNe, Right: &Query{Func: "null"}}}}}}}},
+ "walk": {{Name: "walk", Args: []string{"f"}, Body: &Query{FuncDefs: []*FuncDef{{Name: "_walk", Body: &Query{Left: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "array"}}}}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Func: "_walk"}}}}}, Elif: []*IfElif{{Cond: &Query{Left: &Query{Func: "type"}, Op: OpEq, Right: &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: "object"}}}}, Then: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map_values", Args: []*Query{{Func: "_walk"}}}}}}}}}}, Op: OpPipe, Right: &Query{Func: "f"}}}}, Func: "_walk"}}},
+ "while": {{Name: "while", Args: []string{"cond", "update"}, Body: &Query{FuncDefs: []*FuncDef{{Name: "_while", Body: &Query{Term: &Term{Type: TermTypeIf, If: &If{Cond: &Query{Func: "cond"}, Then: &Query{Left: &Query{Func: "."}, Op: OpComma, Right: &Query{Term: &Term{Type: TermTypeQuery, Query: &Query{Left: &Query{Func: "update"}, Op: OpPipe, Right: &Query{Func: "_while"}}}}}, Else: &Query{Func: "empty"}}}}}}, Func: "_while"}}},
+ "with_entries": {{Name: "with_entries", Args: []string{"f"}, Body: &Query{Left: &Query{Func: "to_entries"}, Op: OpPipe, Right: &Query{Left: &Query{Term: &Term{Type: TermTypeFunc, Func: &Func{Name: "map", Args: []*Query{{Func: "f"}}}}}, Op: OpPipe, Right: &Query{Func: "from_entries"}}}}},
+ }
+}
diff --git a/vendor/github.com/itchyny/gojq/builtin.jq b/vendor/github.com/itchyny/gojq/builtin.jq
new file mode 100644
index 000000000..24c972900
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/builtin.jq
@@ -0,0 +1,181 @@
+def not: if . then false else true end;
+def in(xs): . as $x | xs | has($x);
+def map(f): [.[] | f];
+def with_entries(f): to_entries | map(f) | from_entries;
+def select(f): if f then . else empty end;
+def recurse: recurse(.[]?);
+def recurse(f): def r: ., (f | r); r;
+def recurse(f; cond): def r: ., (f | select(cond) | r); r;
+
+def while(cond; update):
+ def _while: if cond then ., (update | _while) else empty end;
+ _while;
+def until(cond; next):
+ def _until: if cond then . else next | _until end;
+ _until;
+def repeat(f):
+ def _repeat: f, _repeat;
+ _repeat;
+def range($end): _range(0; $end; 1);
+def range($start; $end): _range($start; $end; 1);
+def range($start; $end; $step): _range($start; $end; $step);
+
+def min_by(f): _min_by(map([f]));
+def max_by(f): _max_by(map([f]));
+def sort_by(f): _sort_by(map([f]));
+def group_by(f): _group_by(map([f]));
+def unique_by(f): _unique_by(map([f]));
+
+def arrays: select(type == "array");
+def objects: select(type == "object");
+def iterables: select(type | . == "array" or . == "object");
+def booleans: select(type == "boolean");
+def numbers: select(type == "number");
+def finites: select(isfinite);
+def normals: select(isnormal);
+def strings: select(type == "string");
+def nulls: select(. == null);
+def values: select(. != null);
+def scalars: select(type | . != "array" and . != "object");
+
+def inside(xs): . as $x | xs | contains($x);
+def combinations:
+ if length == 0 then
+ []
+ else
+ .[0][] as $x | [$x] + (.[1:] | combinations)
+ end;
+def combinations(n): [limit(n; repeat(.))] | combinations;
+def walk(f):
+ def _walk:
+ if type == "array" then
+ map(_walk)
+ elif type == "object" then
+ map_values(_walk)
+ end | f;
+ _walk;
+
+def first: .[0];
+def first(g): label $out | g | ., break $out;
+def last: .[-1];
+def last(g): reduce g as $item (null; $item);
+def isempty(g): label $out | (g | false, break $out), true;
+def all: all(.);
+def all(y): all(.[]; y);
+def all(g; y): isempty(g | select(y | not));
+def any: any(.);
+def any(y): any(.[]; y);
+def any(g; y): isempty(g | select(y)) | not;
+def limit($n; g):
+ if $n > 0 then
+ label $out |
+ foreach g as $item (
+ $n;
+ . - 1;
+ $item, if . <= 0 then break $out else empty end
+ )
+ elif $n == 0 then
+ empty
+ else
+ g
+ end;
+def nth($n): .[$n];
+def nth($n; g):
+ if $n < 0 then
+ error("nth doesn't support negative indices")
+ else
+ label $out |
+ foreach g as $item (
+ $n + 1;
+ . - 1;
+ if . <= 0 then $item, break $out else empty end
+ )
+ end;
+
+def truncate_stream(f):
+ . as $n | null | f |
+ if .[0] | length > $n then .[0] |= .[$n:] else empty end;
+def fromstream(f):
+ { x: null, e: false } as $init |
+ foreach f as $i (
+ $init;
+ if .e then $init end |
+ if $i | length == 2 then
+ setpath(["e"]; $i[0] | length == 0) |
+ setpath(["x"] + $i[0]; $i[1])
+ else
+ setpath(["e"]; $i[0] | length == 1)
+ end;
+ if .e then .x else empty end
+ );
+def tostream:
+ path(def r: (.[]? | r), .; r) as $p |
+ getpath($p) |
+ reduce path(.[]?) as $q ([$p, .]; [$p + $q]);
+
+def map_values(f): .[] |= f;
+def del(f): delpaths([path(f)]);
+def paths: path(..) | select(. != []);
+def paths(f): path(.. | select(f)) | select(. != []);
+def pick(f): . as $v |
+ reduce path(f) as $p (null; setpath($p; $v | getpath($p)));
+
+def fromdateiso8601: strptime("%Y-%m-%dT%H:%M:%S%z") | mktime;
+def todateiso8601: strftime("%Y-%m-%dT%H:%M:%SZ");
+def fromdate: fromdateiso8601;
+def todate: todateiso8601;
+
+def match($re): match($re; null);
+def match($re; $flags): _match($re; $flags; false)[];
+def test($re): test($re; null);
+def test($re; $flags): _match($re; $flags; true);
+def capture($re): capture($re; null);
+def capture($re; $flags): match($re; $flags) | _capture;
+def scan($re): scan($re; null);
+def scan($re; $flags):
+ match($re; $flags + "g") |
+ if .captures == [] then
+ .string
+ else
+ [.captures[].string]
+ end;
+def splits($re): splits($re; null);
+def splits($re; $flags): split($re; $flags)[];
+def sub($re; str): sub($re; str; null);
+def sub($re; str; $flags):
+ . as $str |
+ def _sub:
+ if .matches == [] then
+ $str[:.offset] + .string
+ else
+ .matches[-1] as $r |
+ {
+ string: (($r | _capture | str) + $str[$r.offset+$r.length:.offset] + .string),
+ offset: $r.offset,
+ matches: .matches[:-1],
+ } |
+ _sub
+ end;
+ { string: "", matches: [match($re; $flags)] } | _sub;
+def gsub($re; str): sub($re; str; "g");
+def gsub($re; str; $flags): sub($re; str; $flags + "g");
+
+def debug(f): (f | debug | empty), .;
+def inputs:
+ try
+ repeat(input)
+ catch
+ if . == "break" then empty else error end;
+
+def INDEX(stream; idx_expr):
+ reduce stream as $row ({}; .[$row | idx_expr | tostring] = $row);
+def INDEX(idx_expr):
+ INDEX(.[]; idx_expr);
+def JOIN($idx; idx_expr):
+ [.[] | [., $idx[idx_expr]]];
+def JOIN($idx; stream; idx_expr):
+ stream | [., $idx[idx_expr]];
+def JOIN($idx; stream; idx_expr; join_expr):
+ stream | [., $idx[idx_expr]] | join_expr;
+def IN(s): any(s == .; .);
+def IN(src; s): any(src == s; .);
diff --git a/vendor/github.com/itchyny/gojq/code.go b/vendor/github.com/itchyny/gojq/code.go
new file mode 100644
index 000000000..33505bde0
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/code.go
@@ -0,0 +1,108 @@
+package gojq
+
+type code struct {
+ v any
+ op opcode
+}
+
+type opcode int
+
+const (
+ opnop opcode = iota
+ oppush
+ oppop
+ opdup
+ opconst
+ opload
+ opstore
+ opobject
+ opappend
+ opfork
+ opforktrybegin
+ opforktryend
+ opforkalt
+ opforklabel
+ opbacktrack
+ opjump
+ opjumpifnot
+ opindex
+ opindexarray
+ opcall
+ opcallrec
+ oppushpc
+ opcallpc
+ opscope
+ opret
+ opiter
+ opexpbegin
+ opexpend
+ oppathbegin
+ oppathend
+)
+
+func (op opcode) String() string {
+ switch op {
+ case opnop:
+ return "nop"
+ case oppush:
+ return "push"
+ case oppop:
+ return "pop"
+ case opdup:
+ return "dup"
+ case opconst:
+ return "const"
+ case opload:
+ return "load"
+ case opstore:
+ return "store"
+ case opobject:
+ return "object"
+ case opappend:
+ return "append"
+ case opfork:
+ return "fork"
+ case opforktrybegin:
+ return "forktrybegin"
+ case opforktryend:
+ return "forktryend"
+ case opforkalt:
+ return "forkalt"
+ case opforklabel:
+ return "forklabel"
+ case opbacktrack:
+ return "backtrack"
+ case opjump:
+ return "jump"
+ case opjumpifnot:
+ return "jumpifnot"
+ case opindex:
+ return "index"
+ case opindexarray:
+ return "indexarray"
+ case opcall:
+ return "call"
+ case opcallrec:
+ return "callrec"
+ case oppushpc:
+ return "pushpc"
+ case opcallpc:
+ return "callpc"
+ case opscope:
+ return "scope"
+ case opret:
+ return "ret"
+ case opiter:
+ return "iter"
+ case opexpbegin:
+ return "expbegin"
+ case opexpend:
+ return "expend"
+ case oppathbegin:
+ return "pathbegin"
+ case oppathend:
+ return "pathend"
+ default:
+ panic(op)
+ }
+}
diff --git a/vendor/github.com/itchyny/gojq/compare.go b/vendor/github.com/itchyny/gojq/compare.go
new file mode 100644
index 000000000..e70c1fbbb
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/compare.go
@@ -0,0 +1,100 @@
+package gojq
+
+import (
+ "math"
+ "math/big"
+)
+
+// Compare l and r, and returns jq-flavored comparison value.
+// The result will be 0 if l == r, -1 if l < r, and +1 if l > r.
+// This comparison is used by built-in operators and functions.
+func Compare(l, r any) int {
+ return compare(l, r)
+}
+
+func compare(l, r any) int {
+ return binopTypeSwitch(l, r,
+ compareInt,
+ func(l, r float64) any {
+ switch {
+ case l < r || math.IsNaN(l):
+ return -1
+ case l == r:
+ return 0
+ default:
+ return 1
+ }
+ },
+ func(l, r *big.Int) any {
+ return l.Cmp(r)
+ },
+ func(l, r string) any {
+ switch {
+ case l < r:
+ return -1
+ case l == r:
+ return 0
+ default:
+ return 1
+ }
+ },
+ func(l, r []any) any {
+ n := len(l)
+ if len(r) < n {
+ n = len(r)
+ }
+ for i := 0; i < n; i++ {
+ if cmp := compare(l[i], r[i]); cmp != 0 {
+ return cmp
+ }
+ }
+ return compareInt(len(l), len(r))
+ },
+ func(l, r map[string]any) any {
+ lk, rk := funcKeys(l), funcKeys(r)
+ if cmp := compare(lk, rk); cmp != 0 {
+ return cmp
+ }
+ for _, k := range lk.([]any) {
+ if cmp := compare(l[k.(string)], r[k.(string)]); cmp != 0 {
+ return cmp
+ }
+ }
+ return 0
+ },
+ func(l, r any) any {
+ return compareInt(typeIndex(l), typeIndex(r))
+ },
+ ).(int)
+}
+
+func compareInt(l, r int) any {
+ switch {
+ case l < r:
+ return -1
+ case l == r:
+ return 0
+ default:
+ return 1
+ }
+}
+
+func typeIndex(v any) int {
+ switch v := v.(type) {
+ default:
+ return 0
+ case bool:
+ if !v {
+ return 1
+ }
+ return 2
+ case int, float64, *big.Int:
+ return 3
+ case string:
+ return 4
+ case []any:
+ return 5
+ case map[string]any:
+ return 6
+ }
+}
diff --git a/vendor/github.com/itchyny/gojq/compiler.go b/vendor/github.com/itchyny/gojq/compiler.go
new file mode 100644
index 000000000..d114f27ba
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/compiler.go
@@ -0,0 +1,1672 @@
+package gojq
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "sort"
+ "strconv"
+ "strings"
+)
+
+type compiler struct {
+ moduleLoader ModuleLoader
+ environLoader func() []string
+ variables []string
+ customFuncs map[string]function
+ inputIter Iter
+ codes []*code
+ codeinfos []codeinfo
+ builtinScope *scopeinfo
+ scopes []*scopeinfo
+ scopecnt int
+}
+
+// Code is a compiled jq query.
+type Code struct {
+ variables []string
+ codes []*code
+ codeinfos []codeinfo
+}
+
+// Run runs the code with the variable values (which should be in the
+// same order as the given variables using [WithVariables]) and returns
+// a result iterator.
+//
+// It is safe to call this method in goroutines, to reuse a compiled [*Code].
+// But for arguments, do not give values sharing same data between goroutines.
+func (c *Code) Run(v any, values ...any) Iter {
+ return c.RunWithContext(context.Background(), v, values...)
+}
+
+// RunWithContext runs the code with context.
+func (c *Code) RunWithContext(ctx context.Context, v any, values ...any) Iter {
+ if len(values) > len(c.variables) {
+ return NewIter(&tooManyVariableValuesError{})
+ } else if len(values) < len(c.variables) {
+ return NewIter(&expectedVariableError{c.variables[len(values)]})
+ }
+ for i, v := range values {
+ values[i] = normalizeNumbers(v)
+ }
+ return newEnv(ctx).execute(c, normalizeNumbers(v), values...)
+}
+
+type scopeinfo struct {
+ variables []*varinfo
+ funcs []*funcinfo
+ id int
+ depth int
+ variablecnt int
+}
+
+type varinfo struct {
+ name string
+ index [2]int
+ depth int
+}
+
+type funcinfo struct {
+ name string
+ pc int
+ argcnt int
+}
+
+// Compile compiles a query.
+func Compile(q *Query, options ...CompilerOption) (*Code, error) {
+ c := &compiler{}
+ for _, opt := range options {
+ opt(c)
+ }
+ c.builtinScope = c.newScope()
+ scope := c.newScope()
+ c.scopes = []*scopeinfo{scope}
+ setscope := c.lazy(func() *code {
+ return &code{op: opscope, v: [3]int{scope.id, scope.variablecnt, 0}}
+ })
+ for _, name := range c.variables {
+ if !newLexer(name).validVarName() {
+ return nil, &variableNameError{name}
+ }
+ c.appendCodeInfo(name)
+ c.append(&code{op: opstore, v: c.pushVariable(name)})
+ }
+ if c.moduleLoader != nil {
+ if moduleLoader, ok := c.moduleLoader.(interface {
+ LoadInitModules() ([]*Query, error)
+ }); ok {
+ qs, err := moduleLoader.LoadInitModules()
+ if err != nil {
+ return nil, err
+ }
+ for _, q := range qs {
+ if err := c.compileModule(q, ""); err != nil {
+ return nil, err
+ }
+ }
+ }
+ }
+ if err := c.compile(q); err != nil {
+ return nil, err
+ }
+ setscope()
+ c.optimizeTailRec()
+ c.optimizeCodeOps()
+ return &Code{
+ variables: c.variables,
+ codes: c.codes,
+ codeinfos: c.codeinfos,
+ }, nil
+}
+
+func (c *compiler) compile(q *Query) error {
+ for _, i := range q.Imports {
+ if err := c.compileImport(i); err != nil {
+ return err
+ }
+ }
+ if err := c.compileQuery(q); err != nil {
+ return err
+ }
+ c.append(&code{op: opret})
+ return nil
+}
+
+func (c *compiler) compileImport(i *Import) error {
+ var path, alias string
+ var err error
+ if i.ImportPath != "" {
+ path, alias = i.ImportPath, i.ImportAlias
+ } else {
+ path = i.IncludePath
+ }
+ if c.moduleLoader == nil {
+ return fmt.Errorf("cannot load module: %q", path)
+ }
+ if strings.HasPrefix(alias, "$") {
+ var vals any
+ if moduleLoader, ok := c.moduleLoader.(interface {
+ LoadJSONWithMeta(string, map[string]any) (any, error)
+ }); ok {
+ if vals, err = moduleLoader.LoadJSONWithMeta(path, i.Meta.ToValue()); err != nil {
+ return err
+ }
+ } else if moduleLoader, ok := c.moduleLoader.(interface {
+ LoadJSON(string) (any, error)
+ }); ok {
+ if vals, err = moduleLoader.LoadJSON(path); err != nil {
+ return err
+ }
+ } else {
+ return fmt.Errorf("module not found: %q", path)
+ }
+ vals = normalizeNumbers(vals)
+ c.append(&code{op: oppush, v: vals})
+ c.append(&code{op: opstore, v: c.pushVariable(alias)})
+ c.append(&code{op: oppush, v: vals})
+ c.append(&code{op: opstore, v: c.pushVariable(alias + "::" + alias[1:])})
+ return nil
+ }
+ var q *Query
+ if moduleLoader, ok := c.moduleLoader.(interface {
+ LoadModuleWithMeta(string, map[string]any) (*Query, error)
+ }); ok {
+ if q, err = moduleLoader.LoadModuleWithMeta(path, i.Meta.ToValue()); err != nil {
+ return err
+ }
+ } else if moduleLoader, ok := c.moduleLoader.(interface {
+ LoadModule(string) (*Query, error)
+ }); ok {
+ if q, err = moduleLoader.LoadModule(path); err != nil {
+ return err
+ }
+ }
+ c.appendCodeInfo("module " + path)
+ if err = c.compileModule(q, alias); err != nil {
+ return err
+ }
+ c.appendCodeInfo("end of module " + path)
+ return nil
+}
+
+func (c *compiler) compileModule(q *Query, alias string) error {
+ scope := c.scopes[len(c.scopes)-1]
+ scope.depth++
+ defer func(l int) {
+ scope.depth--
+ scope.variables = scope.variables[:l]
+ }(len(scope.variables))
+ if alias != "" {
+ defer func(l int) {
+ for _, f := range scope.funcs[l:] {
+ f.name = alias + "::" + f.name
+ }
+ }(len(scope.funcs))
+ }
+ for _, i := range q.Imports {
+ if err := c.compileImport(i); err != nil {
+ return err
+ }
+ }
+ for _, fd := range q.FuncDefs {
+ if err := c.compileFuncDef(fd, false); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (c *compiler) newVariable() [2]int {
+ return c.createVariable("")
+}
+
+func (c *compiler) pushVariable(name string) [2]int {
+ s := c.scopes[len(c.scopes)-1]
+ for _, v := range s.variables {
+ if v.name == name && v.depth == s.depth {
+ return v.index
+ }
+ }
+ return c.createVariable(name)
+}
+
+func (c *compiler) createVariable(name string) [2]int {
+ s := c.scopes[len(c.scopes)-1]
+ v := [2]int{s.id, s.variablecnt}
+ s.variablecnt++
+ s.variables = append(s.variables, &varinfo{name, v, s.depth})
+ return v
+}
+
+func (c *compiler) lookupVariable(name string) ([2]int, error) {
+ for i := len(c.scopes) - 1; i >= 0; i-- {
+ s := c.scopes[i]
+ for j := len(s.variables) - 1; j >= 0; j-- {
+ if w := s.variables[j]; w.name == name {
+ return w.index, nil
+ }
+ }
+ }
+ return [2]int{}, &variableNotFoundError{name}
+}
+
+func (c *compiler) lookupFuncOrVariable(name string) (*funcinfo, *varinfo) {
+ for i, isFunc := len(c.scopes)-1, name[0] != '$'; i >= 0; i-- {
+ s := c.scopes[i]
+ if isFunc {
+ for j := len(s.funcs) - 1; j >= 0; j-- {
+ if f := s.funcs[j]; f.name == name && f.argcnt == 0 {
+ return f, nil
+ }
+ }
+ }
+ for j := len(s.variables) - 1; j >= 0; j-- {
+ if v := s.variables[j]; v.name == name {
+ return nil, v
+ }
+ }
+ }
+ return nil, nil
+}
+
+func (c *compiler) lookupBuiltin(name string, argcnt int) *funcinfo {
+ s := c.builtinScope
+ for i := len(s.funcs) - 1; i >= 0; i-- {
+ if f := s.funcs[i]; f.name == name && f.argcnt == argcnt {
+ return f
+ }
+ }
+ return nil
+}
+
+func (c *compiler) appendBuiltin(name string, argcnt int) func() {
+ setjump := c.lazy(func() *code {
+ return &code{op: opjump, v: len(c.codes)}
+ })
+ c.appendCodeInfo(name)
+ c.builtinScope.funcs = append(
+ c.builtinScope.funcs,
+ &funcinfo{name, len(c.codes), argcnt},
+ )
+ return func() {
+ setjump()
+ c.appendCodeInfo("end of " + name)
+ }
+}
+
+func (c *compiler) newScope() *scopeinfo {
+ i := c.scopecnt // do not use len(c.scopes) because it pops
+ c.scopecnt++
+ return &scopeinfo{id: i}
+}
+
+func (c *compiler) newScopeDepth() func() {
+ scope := c.scopes[len(c.scopes)-1]
+ l, m := len(scope.variables), len(scope.funcs)
+ scope.depth++
+ return func() {
+ scope.depth--
+ scope.variables = scope.variables[:l]
+ scope.funcs = scope.funcs[:m]
+ }
+}
+
+func (c *compiler) compileFuncDef(e *FuncDef, builtin bool) error {
+ var scope *scopeinfo
+ if builtin {
+ scope = c.builtinScope
+ } else {
+ scope = c.scopes[len(c.scopes)-1]
+ }
+ defer c.lazy(func() *code {
+ return &code{op: opjump, v: len(c.codes)}
+ })()
+ c.appendCodeInfo(e.Name)
+ scope.funcs = append(scope.funcs, &funcinfo{e.Name, len(c.codes), len(e.Args)})
+ defer func(scopes []*scopeinfo, variables []string) {
+ c.scopes, c.variables = scopes, variables
+ }(c.scopes, c.variables)
+ c.variables = c.variables[len(c.variables):]
+ scope = c.newScope()
+ if builtin {
+ c.scopes = []*scopeinfo{c.builtinScope, scope}
+ } else {
+ c.scopes = append(c.scopes, scope)
+ }
+ defer c.lazy(func() *code {
+ return &code{op: opscope, v: [3]int{scope.id, scope.variablecnt, len(e.Args)}}
+ })()
+ if len(e.Args) > 0 {
+ type varIndex struct {
+ name string
+ index [2]int
+ }
+ vis := make([]varIndex, 0, len(e.Args))
+ v := c.newVariable()
+ c.append(&code{op: opstore, v: v})
+ for _, arg := range e.Args {
+ if arg[0] == '$' {
+ c.appendCodeInfo(arg[1:])
+ w := c.createVariable(arg[1:])
+ c.append(&code{op: opstore, v: w})
+ vis = append(vis, varIndex{arg, w})
+ } else {
+ c.appendCodeInfo(arg)
+ c.append(&code{op: opstore, v: c.createVariable(arg)})
+ }
+ }
+ for _, w := range vis {
+ c.append(&code{op: opload, v: v})
+ c.append(&code{op: opexpbegin})
+ c.append(&code{op: opload, v: w.index})
+ c.append(&code{op: opcallpc})
+ c.appendCodeInfo(w.name)
+ c.append(&code{op: opstore, v: c.pushVariable(w.name)})
+ c.append(&code{op: opexpend})
+ }
+ c.append(&code{op: opload, v: v})
+ }
+ if err := c.compile(e.Body); err != nil {
+ return err
+ }
+ c.appendCodeInfo("end of " + e.Name)
+ return nil
+}
+
+func (c *compiler) compileQuery(e *Query) error {
+ for _, fd := range e.FuncDefs {
+ if err := c.compileFuncDef(fd, false); err != nil {
+ return err
+ }
+ }
+ if e.Func != "" {
+ switch e.Func {
+ case ".":
+ return c.compileTerm(&Term{Type: TermTypeIdentity})
+ case "..":
+ return c.compileTerm(&Term{Type: TermTypeRecurse})
+ case "null":
+ return c.compileTerm(&Term{Type: TermTypeNull})
+ case "true":
+ return c.compileTerm(&Term{Type: TermTypeTrue})
+ case "false":
+ return c.compileTerm(&Term{Type: TermTypeFalse})
+ default:
+ return c.compileFunc(&Func{Name: e.Func})
+ }
+ } else if e.Term != nil {
+ return c.compileTerm(e.Term)
+ }
+ switch e.Op {
+ case OpPipe:
+ if err := c.compileQuery(e.Left); err != nil {
+ return err
+ }
+ return c.compileQuery(e.Right)
+ case OpComma:
+ return c.compileComma(e.Left, e.Right)
+ case OpAlt:
+ return c.compileAlt(e.Left, e.Right)
+ case OpAssign, OpModify, OpUpdateAdd, OpUpdateSub,
+ OpUpdateMul, OpUpdateDiv, OpUpdateMod, OpUpdateAlt:
+ return c.compileQueryUpdate(e.Left, e.Right, e.Op)
+ case OpOr:
+ return c.compileIf(
+ &If{
+ Cond: e.Left,
+ Then: &Query{Term: &Term{Type: TermTypeTrue}},
+ Else: &Query{Term: &Term{Type: TermTypeIf, If: &If{
+ Cond: e.Right,
+ Then: &Query{Term: &Term{Type: TermTypeTrue}},
+ Else: &Query{Term: &Term{Type: TermTypeFalse}},
+ }}},
+ },
+ )
+ case OpAnd:
+ return c.compileIf(
+ &If{
+ Cond: e.Left,
+ Then: &Query{Term: &Term{Type: TermTypeIf, If: &If{
+ Cond: e.Right,
+ Then: &Query{Term: &Term{Type: TermTypeTrue}},
+ Else: &Query{Term: &Term{Type: TermTypeFalse}},
+ }}},
+ Else: &Query{Term: &Term{Type: TermTypeFalse}},
+ },
+ )
+ default:
+ return c.compileCall(
+ e.Op.getFunc(),
+ []*Query{e.Left, e.Right},
+ )
+ }
+}
+
+func (c *compiler) compileComma(l, r *Query) error {
+ setfork := c.lazy(func() *code {
+ return &code{op: opfork, v: len(c.codes)}
+ })
+ if err := c.compileQuery(l); err != nil {
+ return err
+ }
+ defer c.lazy(func() *code {
+ return &code{op: opjump, v: len(c.codes)}
+ })()
+ setfork()
+ return c.compileQuery(r)
+}
+
+func (c *compiler) compileAlt(l, r *Query) error {
+ c.append(&code{op: oppush, v: false})
+ found := c.newVariable()
+ c.append(&code{op: opstore, v: found})
+ setfork := c.lazy(func() *code {
+ return &code{op: opfork, v: len(c.codes)} // opload found
+ })
+ if err := c.compileQuery(l); err != nil {
+ return err
+ }
+ c.append(&code{op: opdup})
+ c.append(&code{op: opjumpifnot, v: len(c.codes) + 4}) // oppop
+ c.append(&code{op: oppush, v: true}) // found some value
+ c.append(&code{op: opstore, v: found})
+ defer c.lazy(func() *code {
+ return &code{op: opjump, v: len(c.codes)}
+ })()
+ c.append(&code{op: oppop})
+ c.append(&code{op: opbacktrack})
+ setfork()
+ c.append(&code{op: opload, v: found})
+ c.append(&code{op: opjumpifnot, v: len(c.codes) + 3})
+ c.append(&code{op: opbacktrack}) // if found, backtrack
+ c.append(&code{op: oppop})
+ return c.compileQuery(r)
+}
+
+func (c *compiler) compileQueryUpdate(l, r *Query, op Operator) error {
+ switch op {
+ case OpAssign:
+ // optimize assignment operator with constant indexing and slicing
+ // .foo.[0].[1:2] = f => setpath(["foo",0,{"start":1,"end":2}]; f)
+ if xs := l.toIndices(nil); xs != nil {
+ // ref: compileCall
+ v := c.newVariable()
+ c.append(&code{op: opstore, v: v})
+ c.append(&code{op: opload, v: v})
+ if err := c.compileQuery(r); err != nil {
+ return err
+ }
+ c.append(&code{op: oppush, v: xs})
+ c.append(&code{op: opload, v: v})
+ c.append(&code{op: opcall, v: [3]any{internalFuncs["setpath"].callback, 2, "setpath"}})
+ return nil
+ }
+ fallthrough
+ case OpModify:
+ return c.compileFunc(
+ &Func{
+ Name: op.getFunc(),
+ Args: []*Query{l, r},
+ },
+ )
+ default:
+ name := "$%0"
+ c.append(&code{op: opdup})
+ if err := c.compileQuery(r); err != nil {
+ return err
+ }
+ c.append(&code{op: opstore, v: c.pushVariable(name)})
+ return c.compileFunc(
+ &Func{
+ Name: "_modify",
+ Args: []*Query{
+ l,
+ {Term: &Term{
+ Type: TermTypeFunc,
+ Func: &Func{
+ Name: op.getFunc(),
+ Args: []*Query{
+ {Term: &Term{Type: TermTypeIdentity}},
+ {Func: name},
+ },
+ },
+ }},
+ },
+ },
+ )
+ }
+}
+
+func (c *compiler) compileBind(e *Term, b *Bind) error {
+ defer c.newScopeDepth()()
+ c.append(&code{op: opdup})
+ c.append(&code{op: opexpbegin})
+ if err := c.compileTerm(e); err != nil {
+ return err
+ }
+ var pc int
+ var vs [][2]int
+ for i, p := range b.Patterns {
+ var pcc int
+ var err error
+ if i < len(b.Patterns)-1 {
+ defer c.lazy(func() *code {
+ return &code{op: opforkalt, v: pcc}
+ })()
+ }
+ if 0 < i {
+ for _, v := range vs {
+ c.append(&code{op: oppush, v: nil})
+ c.append(&code{op: opstore, v: v})
+ }
+ }
+ if vs, err = c.compilePattern(vs[:0], p); err != nil {
+ return err
+ }
+ if i < len(b.Patterns)-1 {
+ defer c.lazy(func() *code {
+ return &code{op: opjump, v: pc}
+ })()
+ pcc = len(c.codes)
+ }
+ }
+ if len(b.Patterns) > 1 {
+ pc = len(c.codes)
+ }
+ if len(b.Patterns) == 1 && c.codes[len(c.codes)-2].op == opexpbegin {
+ c.codes[len(c.codes)-2].op = opnop
+ } else {
+ c.append(&code{op: opexpend})
+ }
+ return c.compileQuery(b.Body)
+}
+
+func (c *compiler) compilePattern(vs [][2]int, p *Pattern) ([][2]int, error) {
+ var err error
+ c.appendCodeInfo(p)
+ if p.Name != "" {
+ v := c.pushVariable(p.Name)
+ c.append(&code{op: opstore, v: v})
+ return append(vs, v), nil
+ } else if len(p.Array) > 0 {
+ v := c.newVariable()
+ c.append(&code{op: opstore, v: v})
+ for i, p := range p.Array {
+ c.append(&code{op: opload, v: v})
+ c.append(&code{op: opindexarray, v: i})
+ if vs, err = c.compilePattern(vs, p); err != nil {
+ return nil, err
+ }
+ }
+ return vs, nil
+ } else if len(p.Object) > 0 {
+ v := c.newVariable()
+ c.append(&code{op: opstore, v: v})
+ for _, kv := range p.Object {
+ var key, name string
+ c.append(&code{op: opload, v: v})
+ if key = kv.Key; key != "" {
+ if key[0] == '$' {
+ key, name = key[1:], key
+ }
+ } else if kv.KeyString != nil {
+ if key = kv.KeyString.Str; key == "" {
+ if err := c.compileString(kv.KeyString, nil); err != nil {
+ return nil, err
+ }
+ }
+ } else if kv.KeyQuery != nil {
+ if err := c.compileQuery(kv.KeyQuery); err != nil {
+ return nil, err
+ }
+ }
+ if key != "" {
+ c.append(&code{op: opindex, v: key})
+ } else {
+ c.append(&code{op: opload, v: v})
+ c.append(&code{op: oppush, v: nil})
+ // ref: compileCall
+ c.append(&code{op: opcall, v: [3]any{internalFuncs["_index"].callback, 2, "_index"}})
+ }
+ if name != "" {
+ if kv.Val != nil {
+ c.append(&code{op: opdup})
+ }
+ if vs, err = c.compilePattern(vs, &Pattern{Name: name}); err != nil {
+ return nil, err
+ }
+ }
+ if kv.Val != nil {
+ if vs, err = c.compilePattern(vs, kv.Val); err != nil {
+ return nil, err
+ }
+ }
+ }
+ return vs, nil
+ } else {
+ return nil, fmt.Errorf("invalid pattern: %s", p)
+ }
+}
+
+func (c *compiler) compileIf(e *If) error {
+ c.appendCodeInfo(e)
+ c.append(&code{op: opdup}) // duplicate the value for then or else clause
+ c.append(&code{op: opexpbegin})
+ pc := len(c.codes)
+ f := c.newScopeDepth()
+ if err := c.compileQuery(e.Cond); err != nil {
+ return err
+ }
+ f()
+ if pc == len(c.codes) {
+ c.codes = c.codes[:pc-1]
+ } else {
+ c.append(&code{op: opexpend})
+ }
+ pcc := len(c.codes)
+ setjumpifnot := c.lazy(func() *code {
+ return &code{op: opjumpifnot, v: len(c.codes)} // skip then clause
+ })
+ f = c.newScopeDepth()
+ if err := c.compileQuery(e.Then); err != nil {
+ return err
+ }
+ f()
+ defer c.lazy(func() *code {
+ return &code{op: opjump, v: len(c.codes)}
+ })()
+ setjumpifnot()
+ if len(e.Elif) > 0 {
+ return c.compileIf(&If{e.Elif[0].Cond, e.Elif[0].Then, e.Elif[1:], e.Else})
+ }
+ if e.Else != nil {
+ defer c.newScopeDepth()()
+ defer func() {
+ // optimize constant results
+ // opdup, ..., opjumpifnot, opconst, opjump, opconst
+ // => opnop, ..., opjumpifnot, oppush, opjump, oppush
+ if pcc+4 == len(c.codes) &&
+ c.codes[pcc+1] != nil && c.codes[pcc+1].op == opconst &&
+ c.codes[pcc+3] != nil && c.codes[pcc+3].op == opconst {
+ c.codes[pc-2].op = opnop
+ c.codes[pcc+1].op = oppush
+ c.codes[pcc+3].op = oppush
+ }
+ }()
+ return c.compileQuery(e.Else)
+ }
+ return nil
+}
+
+func (c *compiler) compileTry(e *Try) error {
+ c.appendCodeInfo(e)
+ setforktrybegin := c.lazy(func() *code {
+ return &code{op: opforktrybegin, v: len(c.codes)}
+ })
+ f := c.newScopeDepth()
+ if err := c.compileQuery(e.Body); err != nil {
+ return err
+ }
+ f()
+ c.append(&code{op: opforktryend})
+ defer c.lazy(func() *code {
+ return &code{op: opjump, v: len(c.codes)}
+ })()
+ setforktrybegin()
+ if e.Catch != nil {
+ defer c.newScopeDepth()()
+ return c.compileQuery(e.Catch)
+ }
+ c.append(&code{op: opbacktrack})
+ return nil
+}
+
+func (c *compiler) compileReduce(e *Reduce) error {
+ c.appendCodeInfo(e)
+ defer c.newScopeDepth()()
+ setfork := c.lazy(func() *code {
+ return &code{op: opfork, v: len(c.codes)}
+ })
+ c.append(&code{op: opdup})
+ v := c.newVariable()
+ f := c.newScopeDepth()
+ if err := c.compileQuery(e.Start); err != nil {
+ return err
+ }
+ f()
+ c.append(&code{op: opstore, v: v})
+ if err := c.compileTerm(e.Term); err != nil {
+ return err
+ }
+ if _, err := c.compilePattern(nil, e.Pattern); err != nil {
+ return err
+ }
+ c.append(&code{op: opload, v: v})
+ f = c.newScopeDepth()
+ if err := c.compileQuery(e.Update); err != nil {
+ return err
+ }
+ f()
+ c.append(&code{op: opstore, v: v})
+ c.append(&code{op: opbacktrack})
+ setfork()
+ c.append(&code{op: oppop})
+ c.append(&code{op: opload, v: v})
+ return nil
+}
+
+func (c *compiler) compileForeach(e *Foreach) error {
+ c.appendCodeInfo(e)
+ defer c.newScopeDepth()()
+ c.append(&code{op: opdup})
+ v := c.newVariable()
+ f := c.newScopeDepth()
+ if err := c.compileQuery(e.Start); err != nil {
+ return err
+ }
+ f()
+ c.append(&code{op: opstore, v: v})
+ if err := c.compileTerm(e.Term); err != nil {
+ return err
+ }
+ if _, err := c.compilePattern(nil, e.Pattern); err != nil {
+ return err
+ }
+ c.append(&code{op: opload, v: v})
+ f = c.newScopeDepth()
+ if err := c.compileQuery(e.Update); err != nil {
+ return err
+ }
+ f()
+ c.append(&code{op: opdup})
+ c.append(&code{op: opstore, v: v})
+ if e.Extract != nil {
+ defer c.newScopeDepth()()
+ return c.compileQuery(e.Extract)
+ }
+ return nil
+}
+
+func (c *compiler) compileLabel(e *Label) error {
+ c.appendCodeInfo(e)
+ v := c.pushVariable("$%" + e.Ident[1:])
+ c.append(&code{op: opforklabel, v: v})
+ return c.compileQuery(e.Body)
+}
+
+func (c *compiler) compileBreak(label string) error {
+ v, err := c.lookupVariable("$%" + label[1:])
+ if err != nil {
+ return &breakError{label, nil}
+ }
+ c.append(&code{op: oppop})
+ c.append(&code{op: opload, v: v})
+ c.append(&code{op: opcall, v: [3]any{funcBreak(label), 0, "_break"}})
+ return nil
+}
+
+func funcBreak(label string) func(any, []any) any {
+ return func(v any, _ []any) any {
+ return &breakError{label, v}
+ }
+}
+
+func (c *compiler) compileTerm(e *Term) error {
+ if len(e.SuffixList) > 0 {
+ s := e.SuffixList[len(e.SuffixList)-1]
+ t := *e // clone without changing e
+ t.SuffixList = t.SuffixList[:len(e.SuffixList)-1]
+ return c.compileTermSuffix(&t, s)
+ }
+ switch e.Type {
+ case TermTypeIdentity:
+ return nil
+ case TermTypeRecurse:
+ return c.compileFunc(&Func{Name: "recurse"})
+ case TermTypeNull:
+ c.append(&code{op: opconst, v: nil})
+ return nil
+ case TermTypeTrue:
+ c.append(&code{op: opconst, v: true})
+ return nil
+ case TermTypeFalse:
+ c.append(&code{op: opconst, v: false})
+ return nil
+ case TermTypeIndex:
+ return c.compileIndex(&Term{Type: TermTypeIdentity}, e.Index)
+ case TermTypeFunc:
+ return c.compileFunc(e.Func)
+ case TermTypeObject:
+ return c.compileObject(e.Object)
+ case TermTypeArray:
+ return c.compileArray(e.Array)
+ case TermTypeNumber:
+ c.append(&code{op: opconst, v: toNumber(e.Number)})
+ return nil
+ case TermTypeUnary:
+ return c.compileUnary(e.Unary)
+ case TermTypeFormat:
+ return c.compileFormat(e.Format, e.Str)
+ case TermTypeString:
+ return c.compileString(e.Str, nil)
+ case TermTypeIf:
+ return c.compileIf(e.If)
+ case TermTypeTry:
+ return c.compileTry(e.Try)
+ case TermTypeReduce:
+ return c.compileReduce(e.Reduce)
+ case TermTypeForeach:
+ return c.compileForeach(e.Foreach)
+ case TermTypeLabel:
+ return c.compileLabel(e.Label)
+ case TermTypeBreak:
+ return c.compileBreak(e.Break)
+ case TermTypeQuery:
+ defer c.newScopeDepth()()
+ return c.compileQuery(e.Query)
+ default:
+ panic("invalid term: " + e.String())
+ }
+}
+
+func (c *compiler) compileIndex(e *Term, x *Index) error {
+ if k := x.toIndexKey(); k != nil {
+ if err := c.compileTerm(e); err != nil {
+ return err
+ }
+ c.appendCodeInfo(x)
+ c.append(&code{op: opindex, v: k})
+ return nil
+ }
+ c.appendCodeInfo(x)
+ if x.Str != nil {
+ return c.compileCall("_index", []*Query{{Term: e}, {Term: &Term{Type: TermTypeString, Str: x.Str}}})
+ }
+ if !x.IsSlice {
+ return c.compileCall("_index", []*Query{{Term: e}, x.Start})
+ }
+ if x.Start == nil {
+ return c.compileCall("_slice", []*Query{{Term: e}, x.End, {Term: &Term{Type: TermTypeNull}}})
+ }
+ if x.End == nil {
+ return c.compileCall("_slice", []*Query{{Term: e}, {Term: &Term{Type: TermTypeNull}}, x.Start})
+ }
+ return c.compileCall("_slice", []*Query{{Term: e}, x.End, x.Start})
+}
+
+func (c *compiler) compileFunc(e *Func) error {
+ if len(e.Args) == 0 {
+ if f, v := c.lookupFuncOrVariable(e.Name); f != nil {
+ return c.compileCallPc(f, e.Args)
+ } else if v != nil {
+ if e.Name[0] == '$' {
+ c.append(&code{op: oppop})
+ c.append(&code{op: opload, v: v.index})
+ } else {
+ c.append(&code{op: opload, v: v.index})
+ c.append(&code{op: opcallpc})
+ }
+ return nil
+ } else if e.Name == "$ENV" || e.Name == "env" {
+ env := make(map[string]any)
+ if c.environLoader != nil {
+ for _, kv := range c.environLoader() {
+ if i := strings.IndexByte(kv, '='); i > 0 {
+ env[kv[:i]] = kv[i+1:]
+ }
+ }
+ }
+ c.append(&code{op: opconst, v: env})
+ return nil
+ } else if e.Name[0] == '$' {
+ return &variableNotFoundError{e.Name}
+ }
+ } else {
+ for i := len(c.scopes) - 1; i >= 0; i-- {
+ s := c.scopes[i]
+ for j := len(s.funcs) - 1; j >= 0; j-- {
+ if f := s.funcs[j]; f.name == e.Name && f.argcnt == len(e.Args) {
+ return c.compileCallPc(f, e.Args)
+ }
+ }
+ }
+ }
+ if f := c.lookupBuiltin(e.Name, len(e.Args)); f != nil {
+ return c.compileCallPc(f, e.Args)
+ }
+ if fds, ok := builtinFuncDefs[e.Name]; ok {
+ for _, fd := range fds {
+ if len(fd.Args) == len(e.Args) {
+ if err := c.compileFuncDef(fd, true); err != nil {
+ return err
+ }
+ break
+ }
+ }
+ if len(fds) == 0 {
+ switch e.Name {
+ case "_assign":
+ c.compileAssign()
+ case "_modify":
+ c.compileModify()
+ }
+ }
+ if f := c.lookupBuiltin(e.Name, len(e.Args)); f != nil {
+ return c.compileCallPc(f, e.Args)
+ }
+ }
+ if fn, ok := internalFuncs[e.Name]; ok && fn.accept(len(e.Args)) {
+ switch e.Name {
+ case "empty":
+ c.append(&code{op: opbacktrack})
+ return nil
+ case "path":
+ c.append(&code{op: oppathbegin})
+ if err := c.compileCall(e.Name, e.Args); err != nil {
+ return err
+ }
+ c.codes[len(c.codes)-1] = &code{op: oppathend}
+ return nil
+ case "builtins":
+ return c.compileCallInternal(
+ [3]any{c.funcBuiltins, 0, e.Name},
+ e.Args,
+ true,
+ -1,
+ )
+ case "input":
+ if c.inputIter == nil {
+ return &inputNotAllowedError{}
+ }
+ return c.compileCallInternal(
+ [3]any{c.funcInput, 0, e.Name},
+ e.Args,
+ true,
+ -1,
+ )
+ case "modulemeta":
+ return c.compileCallInternal(
+ [3]any{c.funcModulemeta, 0, e.Name},
+ e.Args,
+ true,
+ -1,
+ )
+ default:
+ return c.compileCall(e.Name, e.Args)
+ }
+ }
+ if fn, ok := c.customFuncs[e.Name]; ok && fn.accept(len(e.Args)) {
+ if err := c.compileCallInternal(
+ [3]any{fn.callback, len(e.Args), e.Name},
+ e.Args,
+ true,
+ -1,
+ ); err != nil {
+ return err
+ }
+ if fn.iter {
+ c.append(&code{op: opiter})
+ }
+ return nil
+ }
+ return &funcNotFoundError{e}
+}
+
+// Appends the compiled code for the assignment operator (`=`) to maximize
+// performance. Originally the operator was implemented as follows.
+//
+// def _assign(p; $x): reduce path(p) as $q (.; setpath($q; $x));
+//
+// To overcome the difficulty of reducing allocations on `setpath`, we use the
+// `allocator` type and track the allocated addresses during the reduction.
+func (c *compiler) compileAssign() {
+ defer c.appendBuiltin("_assign", 2)()
+ scope := c.newScope()
+ v, p := [2]int{scope.id, 0}, [2]int{scope.id, 1}
+ x, a := [2]int{scope.id, 2}, [2]int{scope.id, 3}
+ // Cannot reuse v, p due to backtracking in x.
+ w, q := [2]int{scope.id, 4}, [2]int{scope.id, 5}
+ c.appends(
+ &code{op: opscope, v: [3]int{scope.id, 6, 2}},
+ &code{op: opstore, v: v}, // def _assign(p; $x):
+ &code{op: opstore, v: p},
+ &code{op: opstore, v: x},
+ &code{op: opload, v: v},
+ &code{op: opexpbegin},
+ &code{op: opload, v: x},
+ &code{op: opcallpc},
+ &code{op: opstore, v: x},
+ &code{op: opexpend},
+ &code{op: oppush, v: nil},
+ &code{op: opcall, v: [3]any{funcAllocator, 0, "_allocator"}},
+ &code{op: opstore, v: a},
+ &code{op: opload, v: v},
+ &code{op: opfork, v: len(c.codes) + 30}, // reduce [L1]
+ &code{op: opdup},
+ &code{op: opstore, v: w},
+ &code{op: oppathbegin}, // path(p)
+ &code{op: opload, v: p},
+ &code{op: opcallpc},
+ &code{op: opload, v: w},
+ &code{op: oppathend},
+ &code{op: opstore, v: q}, // as $q (.;
+ &code{op: opload, v: a}, // setpath($q; $x)
+ &code{op: opload, v: x},
+ &code{op: opload, v: q},
+ &code{op: opload, v: w},
+ &code{op: opcall, v: [3]any{funcSetpathWithAllocator, 3, "_setpath"}},
+ &code{op: opstore, v: w},
+ &code{op: opbacktrack}, // );
+ &code{op: oppop}, // [L1]
+ &code{op: opload, v: w},
+ &code{op: opret},
+ )
+}
+
+// Appends the compiled code for the update-assignment operator (`|=`) to
+// maximize performance. We use the `allocator` type, just like `_assign/2`.
+func (c *compiler) compileModify() {
+ defer c.appendBuiltin("_modify", 2)()
+ scope := c.newScope()
+ v, p := [2]int{scope.id, 0}, [2]int{scope.id, 1}
+ f, d := [2]int{scope.id, 2}, [2]int{scope.id, 3}
+ a, l := [2]int{scope.id, 4}, [2]int{scope.id, 5}
+ c.appends(
+ &code{op: opscope, v: [3]int{scope.id, 6, 2}},
+ &code{op: opstore, v: v}, // def _modify(p; f):
+ &code{op: opstore, v: p},
+ &code{op: opstore, v: f},
+ &code{op: oppush, v: []any{}},
+ &code{op: opstore, v: d},
+ &code{op: oppush, v: nil},
+ &code{op: opcall, v: [3]any{funcAllocator, 0, "_allocator"}},
+ &code{op: opstore, v: a},
+ &code{op: opload, v: v},
+ &code{op: opfork, v: len(c.codes) + 39}, // reduce [L1]
+ &code{op: oppathbegin}, // path(p)
+ &code{op: opload, v: p},
+ &code{op: opcallpc},
+ &code{op: opload, v: v},
+ &code{op: oppathend},
+ &code{op: opstore, v: p}, // as $p (.;
+ &code{op: opforklabel, v: l}, // label $l |
+ &code{op: opload, v: v}, //
+ &code{op: opfork, v: len(c.codes) + 36}, // [L2]
+ &code{op: oppop}, // (getpath($p) |
+ &code{op: opload, v: a},
+ &code{op: opload, v: p},
+ &code{op: opload, v: v},
+ &code{op: opcall, v: [3]any{internalFuncs["getpath"].callback, 1, "getpath"}},
+ &code{op: opload, v: f}, // f)
+ &code{op: opcallpc},
+ &code{op: opload, v: p}, // setpath($p; ...)
+ &code{op: opload, v: v},
+ &code{op: opcall, v: [3]any{funcSetpathWithAllocator, 3, "_setpath"}},
+ &code{op: opstore, v: v},
+ &code{op: opload, v: v}, // ., break $l
+ &code{op: opfork, v: len(c.codes) + 34}, // [L4]
+ &code{op: opjump, v: len(c.codes) + 38}, // [L3]
+ &code{op: opload, v: l}, // [L4]
+ &code{op: opcall, v: [3]any{funcBreak(""), 0, "_break"}},
+ &code{op: opload, v: p}, // append $p to $d [L2]
+ &code{op: opappend, v: d}, //
+ &code{op: opbacktrack}, // ) | [L3]
+ &code{op: oppop}, // delpaths($d); [L1]
+ &code{op: opload, v: a},
+ &code{op: opload, v: d},
+ &code{op: opload, v: v},
+ &code{op: opcall, v: [3]any{funcDelpathsWithAllocator, 2, "_delpaths"}},
+ &code{op: opret},
+ )
+}
+
+func (c *compiler) funcBuiltins(any, []any) any {
+ type funcNameArity struct {
+ name string
+ arity int
+ }
+ var xs []*funcNameArity
+ for _, fds := range builtinFuncDefs {
+ for _, fd := range fds {
+ if fd.Name[0] != '_' {
+ xs = append(xs, &funcNameArity{fd.Name, len(fd.Args)})
+ }
+ }
+ }
+ for name, fn := range internalFuncs {
+ if name[0] != '_' {
+ for i, cnt := 0, fn.argcount; cnt > 0; i, cnt = i+1, cnt>>1 {
+ if cnt&1 > 0 {
+ xs = append(xs, &funcNameArity{name, i})
+ }
+ }
+ }
+ }
+ for name, fn := range c.customFuncs {
+ if name[0] != '_' {
+ for i, cnt := 0, fn.argcount; cnt > 0; i, cnt = i+1, cnt>>1 {
+ if cnt&1 > 0 {
+ xs = append(xs, &funcNameArity{name, i})
+ }
+ }
+ }
+ }
+ sort.Slice(xs, func(i, j int) bool {
+ return xs[i].name < xs[j].name ||
+ xs[i].name == xs[j].name && xs[i].arity < xs[j].arity
+ })
+ ys := make([]any, len(xs))
+ for i, x := range xs {
+ ys[i] = x.name + "/" + strconv.Itoa(x.arity)
+ }
+ return ys
+}
+
+func (c *compiler) funcInput(any, []any) any {
+ v, ok := c.inputIter.Next()
+ if !ok {
+ return errors.New("break")
+ }
+ return normalizeNumbers(v)
+}
+
+func (c *compiler) funcModulemeta(v any, _ []any) any {
+ s, ok := v.(string)
+ if !ok {
+ return &func0TypeError{"modulemeta", v}
+ }
+ if c.moduleLoader == nil {
+ return fmt.Errorf("cannot load module: %q", s)
+ }
+ var q *Query
+ var err error
+ if moduleLoader, ok := c.moduleLoader.(interface {
+ LoadModuleWithMeta(string, map[string]any) (*Query, error)
+ }); ok {
+ if q, err = moduleLoader.LoadModuleWithMeta(s, nil); err != nil {
+ return err
+ }
+ } else if moduleLoader, ok := c.moduleLoader.(interface {
+ LoadModule(string) (*Query, error)
+ }); ok {
+ if q, err = moduleLoader.LoadModule(s); err != nil {
+ return err
+ }
+ }
+ meta := q.Meta.ToValue()
+ if meta == nil {
+ meta = make(map[string]any)
+ }
+ meta["defs"] = listModuleDefs(q)
+ meta["deps"] = listModuleDeps(q)
+ return meta
+}
+
+func listModuleDefs(q *Query) []any {
+ type funcNameArity struct {
+ name string
+ arity int
+ }
+ var xs []*funcNameArity
+ for _, fd := range q.FuncDefs {
+ if fd.Name[0] != '_' {
+ xs = append(xs, &funcNameArity{fd.Name, len(fd.Args)})
+ }
+ }
+ sort.Slice(xs, func(i, j int) bool {
+ return xs[i].name < xs[j].name ||
+ xs[i].name == xs[j].name && xs[i].arity < xs[j].arity
+ })
+ defs := make([]any, len(xs))
+ for i, x := range xs {
+ defs[i] = x.name + "/" + strconv.Itoa(x.arity)
+ }
+ return defs
+}
+
+func listModuleDeps(q *Query) []any {
+ deps := make([]any, len(q.Imports))
+ for j, i := range q.Imports {
+ v := i.Meta.ToValue()
+ if v == nil {
+ v = make(map[string]any)
+ }
+ relpath := i.ImportPath
+ if relpath == "" {
+ relpath = i.IncludePath
+ }
+ v["relpath"] = relpath
+ if i.ImportAlias != "" {
+ v["as"] = strings.TrimPrefix(i.ImportAlias, "$")
+ }
+ v["is_data"] = strings.HasPrefix(i.ImportAlias, "$")
+ deps[j] = v
+ }
+ return deps
+}
+
+func (c *compiler) compileObject(e *Object) error {
+ c.appendCodeInfo(e)
+ if len(e.KeyVals) == 0 {
+ c.append(&code{op: opconst, v: map[string]any{}})
+ return nil
+ }
+ defer c.newScopeDepth()()
+ v := c.newVariable()
+ c.append(&code{op: opstore, v: v})
+ pc := len(c.codes)
+ for _, kv := range e.KeyVals {
+ if err := c.compileObjectKeyVal(v, kv); err != nil {
+ return err
+ }
+ }
+ c.append(&code{op: opobject, v: len(e.KeyVals)})
+ // optimize constant objects
+ l := len(e.KeyVals)
+ if pc+l*3+1 != len(c.codes) {
+ return nil
+ }
+ for i := 0; i < l; i++ {
+ if c.codes[pc+i*3].op != oppush ||
+ c.codes[pc+i*3+1].op != opload ||
+ c.codes[pc+i*3+2].op != opconst {
+ return nil
+ }
+ }
+ w := make(map[string]any, l)
+ for i := 0; i < l; i++ {
+ w[c.codes[pc+i*3].v.(string)] = c.codes[pc+i*3+2].v
+ }
+ c.codes[pc-1] = &code{op: opconst, v: w}
+ c.codes = c.codes[:pc]
+ return nil
+}
+
+func (c *compiler) compileObjectKeyVal(v [2]int, kv *ObjectKeyVal) error {
+ if key := kv.Key; key != "" {
+ if key[0] == '$' {
+ if kv.Val == nil { // {$foo} == {foo:$foo}
+ c.append(&code{op: oppush, v: key[1:]})
+ }
+ c.append(&code{op: opload, v: v})
+ if err := c.compileFunc(&Func{Name: key}); err != nil {
+ return err
+ }
+ } else {
+ c.append(&code{op: oppush, v: key})
+ if kv.Val == nil { // {foo} == {foo:.foo}
+ c.append(&code{op: opload, v: v})
+ c.append(&code{op: opindex, v: key})
+ }
+ }
+ } else if key := kv.KeyString; key != nil {
+ if key.Queries == nil {
+ c.append(&code{op: oppush, v: key.Str})
+ if kv.Val == nil { // {"foo"} == {"foo":.["foo"]}
+ c.append(&code{op: opload, v: v})
+ c.append(&code{op: opindex, v: key.Str})
+ }
+ } else {
+ c.append(&code{op: opload, v: v})
+ if err := c.compileString(key, nil); err != nil {
+ return err
+ }
+ if kv.Val == nil {
+ c.append(&code{op: opdup})
+ c.append(&code{op: opload, v: v})
+ c.append(&code{op: oppush, v: nil})
+ // ref: compileCall
+ c.append(&code{op: opcall, v: [3]any{internalFuncs["_index"].callback, 2, "_index"}})
+ }
+ }
+ } else if kv.KeyQuery != nil {
+ c.append(&code{op: opload, v: v})
+ f := c.newScopeDepth()
+ if err := c.compileQuery(kv.KeyQuery); err != nil {
+ return err
+ }
+ f()
+ }
+ if kv.Val != nil {
+ c.append(&code{op: opload, v: v})
+ for _, e := range kv.Val.Queries {
+ if err := c.compileQuery(e); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+func (c *compiler) compileArray(e *Array) error {
+ c.appendCodeInfo(e)
+ if e.Query == nil {
+ c.append(&code{op: opconst, v: []any{}})
+ return nil
+ }
+ c.append(&code{op: oppush, v: []any{}})
+ arr := c.newVariable()
+ c.append(&code{op: opstore, v: arr})
+ pc := len(c.codes)
+ setfork := c.lazy(func() *code {
+ return &code{op: opfork, v: len(c.codes)}
+ })
+ defer c.newScopeDepth()()
+ if err := c.compileQuery(e.Query); err != nil {
+ return err
+ }
+ c.append(&code{op: opappend, v: arr})
+ c.append(&code{op: opbacktrack})
+ setfork()
+ c.append(&code{op: oppop})
+ c.append(&code{op: opload, v: arr})
+ if e.Query.Op == OpPipe {
+ return nil
+ }
+ // optimize constant arrays
+ if (len(c.codes)-pc)%3 != 0 {
+ return nil
+ }
+ l := (len(c.codes) - pc - 3) / 3
+ for i := 0; i < l; i++ {
+ if c.codes[pc+i].op != opfork ||
+ c.codes[pc+i*2+l].op != opconst ||
+ (i < l-1 && c.codes[pc+i*2+l+1].op != opjump) {
+ return nil
+ }
+ }
+ v := make([]any, l)
+ for i := 0; i < l; i++ {
+ v[i] = c.codes[pc+i*2+l].v
+ }
+ c.codes[pc-2] = &code{op: opconst, v: v}
+ c.codes = c.codes[:pc-1]
+ return nil
+}
+
+func (c *compiler) compileUnary(e *Unary) error {
+ c.appendCodeInfo(e)
+ if v := e.toNumber(); v != nil {
+ c.append(&code{op: opconst, v: v})
+ return nil
+ }
+ if err := c.compileTerm(e.Term); err != nil {
+ return err
+ }
+ switch e.Op {
+ case OpAdd:
+ return c.compileCall("_plus", nil)
+ case OpSub:
+ return c.compileCall("_negate", nil)
+ default:
+ return fmt.Errorf("unexpected operator in Unary: %s", e.Op)
+ }
+}
+
+func (c *compiler) compileFormat(format string, str *String) error {
+ f := formatToFunc(format)
+ if f == nil {
+ f = &Func{
+ Name: "format",
+ Args: []*Query{{Term: &Term{Type: TermTypeString, Str: &String{Str: format[1:]}}}},
+ }
+ }
+ if str == nil {
+ return c.compileFunc(f)
+ }
+ return c.compileString(str, f)
+}
+
+func formatToFunc(format string) *Func {
+ switch format {
+ case "@text":
+ return &Func{Name: "tostring"}
+ case "@json":
+ return &Func{Name: "tojson"}
+ case "@html":
+ return &Func{Name: "_tohtml"}
+ case "@uri":
+ return &Func{Name: "_touri"}
+ case "@urid":
+ return &Func{Name: "_tourid"}
+ case "@csv":
+ return &Func{Name: "_tocsv"}
+ case "@tsv":
+ return &Func{Name: "_totsv"}
+ case "@sh":
+ return &Func{Name: "_tosh"}
+ case "@base64":
+ return &Func{Name: "_tobase64"}
+ case "@base64d":
+ return &Func{Name: "_tobase64d"}
+ default:
+ return nil
+ }
+}
+
+func (c *compiler) compileString(s *String, f *Func) error {
+ if s.Queries == nil {
+ c.append(&code{op: opconst, v: s.Str})
+ return nil
+ }
+ if f == nil {
+ f = &Func{Name: "tostring"}
+ }
+ var q *Query
+ for _, e := range s.Queries {
+ if e.Term.Str == nil {
+ e = &Query{Left: e, Op: OpPipe, Right: &Query{Term: &Term{Type: TermTypeFunc, Func: f}}}
+ }
+ if q == nil {
+ q = e
+ } else {
+ q = &Query{Left: q, Op: OpAdd, Right: e}
+ }
+ }
+ return c.compileQuery(q)
+}
+
+func (c *compiler) compileTermSuffix(e *Term, s *Suffix) error {
+ if s.Index != nil {
+ return c.compileIndex(e, s.Index)
+ } else if s.Iter {
+ if err := c.compileTerm(e); err != nil {
+ return err
+ }
+ c.append(&code{op: opiter})
+ return nil
+ } else if s.Optional {
+ if len(e.SuffixList) > 0 {
+ if u := e.SuffixList[len(e.SuffixList)-1].toTerm(); u != nil {
+ // no need to clone (ref: compileTerm)
+ e.SuffixList = e.SuffixList[:len(e.SuffixList)-1]
+ if err := c.compileTerm(e); err != nil {
+ return err
+ }
+ e = u
+ }
+ }
+ return c.compileTry(&Try{Body: &Query{Term: e}})
+ } else if s.Bind != nil {
+ return c.compileBind(e, s.Bind)
+ } else {
+ return fmt.Errorf("invalid suffix: %s", s)
+ }
+}
+
+func (c *compiler) compileCall(name string, args []*Query) error {
+ fn := internalFuncs[name]
+ var indexing int
+ switch name {
+ case "_index", "_slice":
+ indexing = 1
+ case "getpath":
+ indexing = 0
+ default:
+ indexing = -1
+ }
+ if err := c.compileCallInternal(
+ [3]any{fn.callback, len(args), name},
+ args,
+ true,
+ indexing,
+ ); err != nil {
+ return err
+ }
+ if fn.iter {
+ c.append(&code{op: opiter})
+ }
+ return nil
+}
+
+func (c *compiler) compileCallPc(fn *funcinfo, args []*Query) error {
+ return c.compileCallInternal(fn.pc, args, false, -1)
+}
+
+func (c *compiler) compileCallInternal(
+ fn any, args []*Query, internal bool, indexing int,
+) error {
+ if len(args) == 0 {
+ c.append(&code{op: opcall, v: fn})
+ return nil
+ }
+ v := c.newVariable()
+ c.append(&code{op: opstore, v: v})
+ if indexing >= 0 {
+ c.append(&code{op: opexpbegin})
+ }
+ for i := len(args) - 1; i >= 0; i-- {
+ pc := len(c.codes) + 1 // skip opjump (ref: compileFuncDef)
+ name := "lambda:" + strconv.Itoa(pc)
+ if err := c.compileFuncDef(&FuncDef{Name: name, Body: args[i]}, false); err != nil {
+ return err
+ }
+ if internal {
+ switch len(c.codes) - pc {
+ case 2: // optimize identity argument (opscope, opret)
+ j := len(c.codes) - 3
+ c.codes[j] = &code{op: opload, v: v}
+ c.codes = c.codes[:j+1]
+ s := c.scopes[len(c.scopes)-1]
+ s.funcs = s.funcs[:len(s.funcs)-1]
+ c.deleteCodeInfo(name)
+ case 3: // optimize one instruction argument (opscope, opX, opret)
+ j := len(c.codes) - 4
+ if c.codes[j+2].op == opconst {
+ c.codes[j] = &code{op: oppush, v: c.codes[j+2].v}
+ c.codes = c.codes[:j+1]
+ } else {
+ c.codes[j] = &code{op: opload, v: v}
+ c.codes[j+1] = c.codes[j+2]
+ c.codes = c.codes[:j+2]
+ }
+ s := c.scopes[len(c.scopes)-1]
+ s.funcs = s.funcs[:len(s.funcs)-1]
+ c.deleteCodeInfo(name)
+ default:
+ c.append(&code{op: opload, v: v})
+ c.append(&code{op: oppushpc, v: pc})
+ c.append(&code{op: opcallpc})
+ }
+ } else {
+ c.append(&code{op: oppushpc, v: pc})
+ }
+ if i == indexing {
+ if c.codes[len(c.codes)-2].op == opexpbegin {
+ c.codes[len(c.codes)-2] = c.codes[len(c.codes)-1]
+ c.codes = c.codes[:len(c.codes)-1]
+ } else {
+ c.append(&code{op: opexpend})
+ }
+ }
+ }
+ if indexing > 0 {
+ c.append(&code{op: oppush, v: nil})
+ } else {
+ c.append(&code{op: opload, v: v})
+ }
+ c.append(&code{op: opcall, v: fn})
+ return nil
+}
+
+func (c *compiler) append(code *code) {
+ c.codes = append(c.codes, code)
+}
+
+func (c *compiler) appends(codes ...*code) {
+ c.codes = append(c.codes, codes...)
+}
+
+func (c *compiler) lazy(f func() *code) func() {
+ i := len(c.codes)
+ c.codes = append(c.codes, nil)
+ return func() { c.codes[i] = f() }
+}
+
+func (c *compiler) optimizeTailRec() {
+ var pcs []int
+ scopes := map[int]bool{}
+L:
+ for i, l := 0, len(c.codes); i < l; i++ {
+ switch c.codes[i].op {
+ case opscope:
+ pcs = append(pcs, i)
+ if v := c.codes[i].v.([3]int); v[2] == 0 {
+ scopes[i] = v[1] == 0
+ }
+ case opcall:
+ var canjump bool
+ if j, ok := c.codes[i].v.(int); !ok ||
+ len(pcs) == 0 || pcs[len(pcs)-1] != j {
+ break
+ } else if canjump, ok = scopes[j]; !ok {
+ break
+ }
+ for j := i + 1; j < l; {
+ switch c.codes[j].op {
+ case opjump:
+ j = c.codes[j].v.(int)
+ case opret:
+ if canjump {
+ c.codes[i].op = opjump
+ c.codes[i].v = pcs[len(pcs)-1] + 1
+ } else {
+ c.codes[i].op = opcallrec
+ }
+ continue L
+ default:
+ continue L
+ }
+ }
+ case opret:
+ if len(pcs) == 0 {
+ break L
+ }
+ pcs = pcs[:len(pcs)-1]
+ }
+ }
+}
+
+func (c *compiler) optimizeCodeOps() {
+ for i, next := len(c.codes)-1, (*code)(nil); i >= 0; i-- {
+ code := c.codes[i]
+ switch code.op {
+ case oppush, opdup, opload:
+ switch next.op {
+ case oppop:
+ code.op = opnop
+ next.op = opnop
+ case opconst:
+ code.op = opnop
+ next.op = oppush
+ }
+ case opjump, opjumpifnot:
+ if j := code.v.(int); j-1 == i {
+ code.op = opnop
+ } else if next = c.codes[j]; next.op == opjump {
+ code.v = next.v
+ }
+ }
+ next = code
+ }
+}
diff --git a/vendor/github.com/itchyny/gojq/debug.go b/vendor/github.com/itchyny/gojq/debug.go
new file mode 100644
index 000000000..236982809
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/debug.go
@@ -0,0 +1,209 @@
+//go:build gojq_debug
+// +build gojq_debug
+
+package gojq
+
+import (
+ "fmt"
+ "io"
+ "os"
+ "strconv"
+ "strings"
+)
+
+var (
+ debug bool
+ debugOut io.Writer
+)
+
+func init() {
+ if out := os.Getenv("GOJQ_DEBUG"); out != "" {
+ debug = true
+ if out == "stdout" {
+ debugOut = os.Stdout
+ } else {
+ debugOut = os.Stderr
+ }
+ }
+}
+
+type codeinfo struct {
+ name string
+ pc int
+}
+
+func (c *compiler) appendCodeInfo(x any) {
+ if !debug {
+ return
+ }
+ var name string
+ switch x := x.(type) {
+ case string:
+ name = x
+ default:
+ name = fmt.Sprint(x)
+ }
+ var diff int
+ if c.codes[len(c.codes)-1] != nil && c.codes[len(c.codes)-1].op == opret && strings.HasPrefix(name, "end of ") {
+ diff = -1
+ }
+ c.codeinfos = append(c.codeinfos, codeinfo{name, len(c.codes) + diff})
+}
+
+func (c *compiler) deleteCodeInfo(name string) {
+ for i := 0; i < len(c.codeinfos); i++ {
+ if strings.HasSuffix(c.codeinfos[i].name, name) {
+ copy(c.codeinfos[i:], c.codeinfos[i+1:])
+ c.codeinfos = c.codeinfos[:len(c.codeinfos)-1]
+ i--
+ }
+ }
+}
+
+func (env *env) lookupInfoName(pc int) string {
+ var name string
+ for _, ci := range env.codeinfos {
+ if ci.pc == pc {
+ if name != "" {
+ name += ", "
+ }
+ name += ci.name
+ }
+ }
+ return name
+}
+
+func (env *env) debugCodes() {
+ if !debug {
+ return
+ }
+ for i, c := range env.codes {
+ pc := i
+ switch c.op {
+ case opcall, opcallrec:
+ if x, ok := c.v.(int); ok {
+ pc = x
+ }
+ case opjump:
+ x := c.v.(int)
+ if x > 0 && env.codes[x-1].op == opscope {
+ pc = x - 1
+ }
+ }
+ var s string
+ if name := env.lookupInfoName(pc); name != "" {
+ switch c.op {
+ case opcall, opcallrec, opjump:
+ if !strings.HasPrefix(name, "module ") {
+ s = "\t## call " + name
+ break
+ }
+ fallthrough
+ default:
+ s = "\t## " + name
+ }
+ }
+ fmt.Fprintf(debugOut, "\t%d\t%-*s%s%s\n", i, 25, c.op, debugOperand(c), s)
+ }
+ fmt.Fprintln(debugOut, "\t"+strings.Repeat("-", 40)+"+")
+}
+
+func (env *env) debugState(pc int, backtrack bool) {
+ if !debug {
+ return
+ }
+ var sb strings.Builder
+ c := env.codes[pc]
+ op := c.op.String()
+ if backtrack {
+ op += " "
+ }
+ fmt.Fprintf(&sb, "\t%d\t%-*s%s\t|", pc, 25, op, debugOperand(c))
+ var xs []int
+ for i := env.stack.index; i >= 0; i = env.stack.data[i].next {
+ xs = append(xs, i)
+ }
+ for i := len(xs) - 1; i >= 0; i-- {
+ sb.WriteString("\t")
+ sb.WriteString(debugValue(env.stack.data[xs[i]].value))
+ }
+ switch c.op {
+ case opcall, opcallrec:
+ if x, ok := c.v.(int); ok {
+ pc = x
+ }
+ case opjump:
+ x := c.v.(int)
+ if x > 0 && env.codes[x-1].op == opscope {
+ pc = x - 1
+ }
+ }
+ if name := env.lookupInfoName(pc); name != "" {
+ switch c.op {
+ case opcall, opcallrec, opjump:
+ if !strings.HasPrefix(name, "module ") {
+ sb.WriteString("\t\t\t## call " + name)
+ break
+ }
+ fallthrough
+ default:
+ sb.WriteString("\t\t\t## " + name)
+ }
+ }
+ fmt.Fprintln(debugOut, sb.String())
+}
+
+func (env *env) debugForks(pc int, op string) {
+ if !debug {
+ return
+ }
+ var sb strings.Builder
+ for i, v := range env.forks {
+ if i > 0 {
+ sb.WriteByte('\t')
+ }
+ if i == len(env.forks)-1 {
+ sb.WriteByte('<')
+ }
+ fmt.Fprintf(&sb, "%d, %s", v.pc, debugValue(env.stack.data[v.stackindex].value))
+ if i == len(env.forks)-1 {
+ sb.WriteByte('>')
+ }
+ }
+ fmt.Fprintf(debugOut, "\t-\t%-*s%d\t|\t%s\n", 25, op, pc, sb.String())
+}
+
+func debugOperand(c *code) string {
+ switch c.op {
+ case opcall, opcallrec:
+ switch v := c.v.(type) {
+ case int:
+ return strconv.Itoa(v)
+ case [3]any:
+ return fmt.Sprintf("%s/%d", v[2], v[1])
+ default:
+ panic(c)
+ }
+ default:
+ return debugValue(c.v)
+ }
+}
+
+func debugValue(v any) string {
+ switch v := v.(type) {
+ case Iter:
+ return fmt.Sprintf("gojq.Iter(%#v)", v)
+ case []pathValue:
+ return fmt.Sprintf("[]gojq.pathValue(%v)", v)
+ case [2]int:
+ return fmt.Sprintf("[%d,%d]", v[0], v[1])
+ case [3]int:
+ return fmt.Sprintf("[%d,%d,%d]", v[0], v[1], v[2])
+ case [3]any:
+ return fmt.Sprintf("[%v,%v,%v]", v[0], v[1], v[2])
+ case allocator:
+ return fmt.Sprintf("%v", v)
+ default:
+ return Preview(v)
+ }
+}
diff --git a/vendor/github.com/itchyny/gojq/encoder.go b/vendor/github.com/itchyny/gojq/encoder.go
new file mode 100644
index 000000000..3233e8a95
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/encoder.go
@@ -0,0 +1,193 @@
+package gojq
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "math"
+ "math/big"
+ "sort"
+ "strconv"
+ "strings"
+ "unicode/utf8"
+)
+
+// Marshal returns the jq-flavored JSON encoding of v.
+//
+// This method accepts only limited types (nil, bool, int, float64, *big.Int,
+// string, []any, and map[string]any) because these are the possible types a
+// gojq iterator can emit. This method marshals NaN to null, truncates
+// infinities to (+|-) math.MaxFloat64, uses \b and \f in strings, and does not
+// escape '<', '>', '&', '\u2028', and '\u2029'. These behaviors are based on
+// the marshaler of jq command, and different from json.Marshal in the Go
+// standard library. Note that the result is not safe to embed in HTML.
+func Marshal(v any) ([]byte, error) {
+ var b bytes.Buffer
+ (&encoder{w: &b}).encode(v)
+ return b.Bytes(), nil
+}
+
+func jsonMarshal(v any) string {
+ var sb strings.Builder
+ (&encoder{w: &sb}).encode(v)
+ return sb.String()
+}
+
+func jsonEncodeString(sb *strings.Builder, v string) {
+ (&encoder{w: sb}).encodeString(v)
+}
+
+type encoder struct {
+ w interface {
+ io.Writer
+ io.ByteWriter
+ io.StringWriter
+ }
+ buf [64]byte
+}
+
+func (e *encoder) encode(v any) {
+ switch v := v.(type) {
+ case nil:
+ e.w.WriteString("null")
+ case bool:
+ if v {
+ e.w.WriteString("true")
+ } else {
+ e.w.WriteString("false")
+ }
+ case int:
+ e.w.Write(strconv.AppendInt(e.buf[:0], int64(v), 10))
+ case float64:
+ e.encodeFloat64(v)
+ case *big.Int:
+ e.w.Write(v.Append(e.buf[:0], 10))
+ case string:
+ e.encodeString(v)
+ case []any:
+ e.encodeArray(v)
+ case map[string]any:
+ e.encodeObject(v)
+ default:
+ panic(fmt.Sprintf("invalid type: %[1]T (%[1]v)", v))
+ }
+}
+
+// ref: floatEncoder in encoding/json
+func (e *encoder) encodeFloat64(f float64) {
+ if math.IsNaN(f) {
+ e.w.WriteString("null")
+ return
+ }
+ if f >= math.MaxFloat64 {
+ f = math.MaxFloat64
+ } else if f <= -math.MaxFloat64 {
+ f = -math.MaxFloat64
+ }
+ format := byte('f')
+ if x := math.Abs(f); x != 0 && x < 1e-6 || x >= 1e21 {
+ format = 'e'
+ }
+ buf := strconv.AppendFloat(e.buf[:0], f, format, -1, 64)
+ if format == 'e' {
+ // clean up e-09 to e-9
+ if n := len(buf); n >= 4 && buf[n-4] == 'e' && buf[n-3] == '-' && buf[n-2] == '0' {
+ buf[n-2] = buf[n-1]
+ buf = buf[:n-1]
+ }
+ }
+ e.w.Write(buf)
+}
+
+// ref: encodeState#string in encoding/json
+func (e *encoder) encodeString(s string) {
+ e.w.WriteByte('"')
+ start := 0
+ for i := 0; i < len(s); {
+ if b := s[i]; b < utf8.RuneSelf {
+ if ' ' <= b && b <= '~' && b != '"' && b != '\\' {
+ i++
+ continue
+ }
+ if start < i {
+ e.w.WriteString(s[start:i])
+ }
+ switch b {
+ case '"':
+ e.w.WriteString(`\"`)
+ case '\\':
+ e.w.WriteString(`\\`)
+ case '\b':
+ e.w.WriteString(`\b`)
+ case '\f':
+ e.w.WriteString(`\f`)
+ case '\n':
+ e.w.WriteString(`\n`)
+ case '\r':
+ e.w.WriteString(`\r`)
+ case '\t':
+ e.w.WriteString(`\t`)
+ default:
+ const hex = "0123456789abcdef"
+ e.w.WriteString(`\u00`)
+ e.w.WriteByte(hex[b>>4])
+ e.w.WriteByte(hex[b&0xF])
+ }
+ i++
+ start = i
+ continue
+ }
+ c, size := utf8.DecodeRuneInString(s[i:])
+ if c == utf8.RuneError && size == 1 {
+ if start < i {
+ e.w.WriteString(s[start:i])
+ }
+ e.w.WriteString(`\ufffd`)
+ i += size
+ start = i
+ continue
+ }
+ i += size
+ }
+ if start < len(s) {
+ e.w.WriteString(s[start:])
+ }
+ e.w.WriteByte('"')
+}
+
+func (e *encoder) encodeArray(vs []any) {
+ e.w.WriteByte('[')
+ for i, v := range vs {
+ if i > 0 {
+ e.w.WriteByte(',')
+ }
+ e.encode(v)
+ }
+ e.w.WriteByte(']')
+}
+
+func (e *encoder) encodeObject(vs map[string]any) {
+ e.w.WriteByte('{')
+ type keyVal struct {
+ key string
+ val any
+ }
+ kvs := make([]keyVal, len(vs))
+ var i int
+ for k, v := range vs {
+ kvs[i] = keyVal{k, v}
+ i++
+ }
+ sort.Slice(kvs, func(i, j int) bool {
+ return kvs[i].key < kvs[j].key
+ })
+ for i, kv := range kvs {
+ if i > 0 {
+ e.w.WriteByte(',')
+ }
+ e.encodeString(kv.key)
+ e.w.WriteByte(':')
+ e.encode(kv.val)
+ }
+ e.w.WriteByte('}')
+}
diff --git a/vendor/github.com/itchyny/gojq/env.go b/vendor/github.com/itchyny/gojq/env.go
new file mode 100644
index 000000000..bf058eda8
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/env.go
@@ -0,0 +1,48 @@
+package gojq
+
+import "context"
+
+type env struct {
+ pc int
+ stack *stack
+ paths *stack
+ scopes *scopeStack
+ values []any
+ codes []*code
+ codeinfos []codeinfo
+ forks []fork
+ backtrack bool
+ offset int
+ expdepth int
+ label int
+ args [32]any // len(env.args) > maxarity
+ ctx context.Context
+}
+
+func newEnv(ctx context.Context) *env {
+ return &env{
+ stack: newStack(),
+ paths: newStack(),
+ scopes: newScopeStack(),
+ ctx: ctx,
+ }
+}
+
+type scope struct {
+ id int
+ offset int
+ pc int
+ saveindex int
+ outerindex int
+}
+
+type fork struct {
+ pc int
+ stackindex int
+ stacklimit int
+ scopeindex int
+ scopelimit int
+ pathindex int
+ pathlimit int
+ expdepth int
+}
diff --git a/vendor/github.com/itchyny/gojq/error.go b/vendor/github.com/itchyny/gojq/error.go
new file mode 100644
index 000000000..09a70d392
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/error.go
@@ -0,0 +1,382 @@
+package gojq
+
+import "strconv"
+
+// ValueError is an interface for errors with a value for internal function.
+// Return an error implementing this interface when you want to catch error
+// values (not error messages) by try-catch, just like built-in error function.
+// Refer to [WithFunction] to add a custom internal function.
+type ValueError interface {
+ error
+ Value() any
+}
+
+type expectedObjectError struct {
+ v any
+}
+
+func (err *expectedObjectError) Error() string {
+ return "expected an object but got: " + typeErrorPreview(err.v)
+}
+
+type expectedArrayError struct {
+ v any
+}
+
+func (err *expectedArrayError) Error() string {
+ return "expected an array but got: " + typeErrorPreview(err.v)
+}
+
+type iteratorError struct {
+ v any
+}
+
+func (err *iteratorError) Error() string {
+ return "cannot iterate over: " + typeErrorPreview(err.v)
+}
+
+type arrayIndexNegativeError struct {
+ v int
+}
+
+func (err *arrayIndexNegativeError) Error() string {
+ return "array index should not be negative: " + Preview(err.v)
+}
+
+type arrayIndexTooLargeError struct {
+ v any
+}
+
+func (err *arrayIndexTooLargeError) Error() string {
+ return "array index too large: " + Preview(err.v)
+}
+
+type objectKeyNotStringError struct {
+ v any
+}
+
+func (err *objectKeyNotStringError) Error() string {
+ return "expected a string for object key but got: " + typeErrorPreview(err.v)
+}
+
+type arrayIndexNotNumberError struct {
+ v any
+}
+
+func (err *arrayIndexNotNumberError) Error() string {
+ return "expected a number for indexing an array but got: " + typeErrorPreview(err.v)
+}
+
+type stringIndexNotNumberError struct {
+ v any
+}
+
+func (err *stringIndexNotNumberError) Error() string {
+ return "expected a number for indexing a string but got: " + typeErrorPreview(err.v)
+}
+
+type expectedStartEndError struct {
+ v any
+}
+
+func (err *expectedStartEndError) Error() string {
+ return `expected "start" and "end" for slicing but got: ` + typeErrorPreview(err.v)
+}
+
+type lengthMismatchError struct{}
+
+func (err *lengthMismatchError) Error() string {
+ return "length mismatch"
+}
+
+type inputNotAllowedError struct{}
+
+func (*inputNotAllowedError) Error() string {
+ return "input(s)/0 is not allowed"
+}
+
+type funcNotFoundError struct {
+ f *Func
+}
+
+func (err *funcNotFoundError) Error() string {
+ return "function not defined: " + err.f.Name + "/" + strconv.Itoa(len(err.f.Args))
+}
+
+type func0TypeError struct {
+ name string
+ v any
+}
+
+func (err *func0TypeError) Error() string {
+ return err.name + " cannot be applied to: " + typeErrorPreview(err.v)
+}
+
+type func1TypeError struct {
+ name string
+ v, w any
+}
+
+func (err *func1TypeError) Error() string {
+ return err.name + "(" + Preview(err.w) + ") cannot be applied to: " + typeErrorPreview(err.v)
+}
+
+type func2TypeError struct {
+ name string
+ v, w, x any
+}
+
+func (err *func2TypeError) Error() string {
+ return err.name + "(" + Preview(err.w) + "; " + Preview(err.x) + ") cannot be applied to: " + typeErrorPreview(err.v)
+}
+
+type func0WrapError struct {
+ name string
+ v any
+ err error
+}
+
+func (err *func0WrapError) Error() string {
+ return err.name + " cannot be applied to " + Preview(err.v) + ": " + err.err.Error()
+}
+
+type func1WrapError struct {
+ name string
+ v, w any
+ err error
+}
+
+func (err *func1WrapError) Error() string {
+ return err.name + "(" + Preview(err.w) + ") cannot be applied to " + Preview(err.v) + ": " + err.err.Error()
+}
+
+type func2WrapError struct {
+ name string
+ v, w, x any
+ err error
+}
+
+func (err *func2WrapError) Error() string {
+ return err.name + "(" + Preview(err.w) + "; " + Preview(err.x) + ") cannot be applied to " + Preview(err.v) + ": " + err.err.Error()
+}
+
+type exitCodeError struct {
+ value any
+ code int
+}
+
+func (err *exitCodeError) Error() string {
+ if s, ok := err.value.(string); ok {
+ return "error: " + s
+ }
+ return "error: " + jsonMarshal(err.value)
+}
+
+func (err *exitCodeError) Value() any {
+ return err.value
+}
+
+func (err *exitCodeError) ExitCode() int {
+ return err.code
+}
+
+// HaltError is an error emitted by halt and halt_error functions.
+// It implements [ValueError], and if the value is nil, discard the error
+// and stop the iteration. Consider a query like "1, halt, 2";
+// the first value is 1, and the second value is a HaltError with nil value.
+// You might think the iterator should not emit an error this case, but it
+// should so that we can recognize the halt error to stop the outer loop
+// of iterating input values; echo 1 2 3 | gojq "., halt".
+type HaltError exitCodeError
+
+func (err *HaltError) Error() string {
+ return "halt " + (*exitCodeError)(err).Error()
+}
+
+// Value returns the value of the error. This implements [ValueError],
+// but halt error is not catchable by try-catch.
+func (err *HaltError) Value() any {
+ return (*exitCodeError)(err).Value()
+}
+
+// ExitCode returns the exit code of the error.
+func (err *HaltError) ExitCode() int {
+ return (*exitCodeError)(err).ExitCode()
+}
+
+type flattenDepthError struct {
+ v float64
+}
+
+func (err *flattenDepthError) Error() string {
+ return "flatten depth should not be negative: " + Preview(err.v)
+}
+
+type joinTypeError struct {
+ v any
+}
+
+func (err *joinTypeError) Error() string {
+ return "join cannot be applied to an array including: " + typeErrorPreview(err.v)
+}
+
+type timeArrayError struct{}
+
+func (err *timeArrayError) Error() string {
+ return "expected an array of 8 numbers"
+}
+
+type unaryTypeError struct {
+ name string
+ v any
+}
+
+func (err *unaryTypeError) Error() string {
+ return "cannot " + err.name + ": " + typeErrorPreview(err.v)
+}
+
+type binopTypeError struct {
+ name string
+ l, r any
+}
+
+func (err *binopTypeError) Error() string {
+ return "cannot " + err.name + ": " + typeErrorPreview(err.l) + " and " + typeErrorPreview(err.r)
+}
+
+type zeroDivisionError struct {
+ l, r any
+}
+
+func (err *zeroDivisionError) Error() string {
+ return "cannot divide " + typeErrorPreview(err.l) + " by: " + typeErrorPreview(err.r)
+}
+
+type zeroModuloError struct {
+ l, r any
+}
+
+func (err *zeroModuloError) Error() string {
+ return "cannot modulo " + typeErrorPreview(err.l) + " by: " + typeErrorPreview(err.r)
+}
+
+type formatNotFoundError struct {
+ n string
+}
+
+func (err *formatNotFoundError) Error() string {
+ return "format not defined: " + err.n
+}
+
+type formatRowError struct {
+ typ string
+ v any
+}
+
+func (err *formatRowError) Error() string {
+ return "@" + err.typ + " cannot format an array including: " + typeErrorPreview(err.v)
+}
+
+type tooManyVariableValuesError struct{}
+
+func (err *tooManyVariableValuesError) Error() string {
+ return "too many variable values provided"
+}
+
+type expectedVariableError struct {
+ n string
+}
+
+func (err *expectedVariableError) Error() string {
+ return "variable defined but not bound: " + err.n
+}
+
+type variableNotFoundError struct {
+ n string
+}
+
+func (err *variableNotFoundError) Error() string {
+ return "variable not defined: " + err.n
+}
+
+type variableNameError struct {
+ n string
+}
+
+func (err *variableNameError) Error() string {
+ return "invalid variable name: " + err.n
+}
+
+type breakError struct {
+ n string
+ v any
+}
+
+func (err *breakError) Error() string {
+ return "label not defined: " + err.n
+}
+
+func (err *breakError) ExitCode() int {
+ return 3
+}
+
+type tryEndError struct {
+ err error
+}
+
+func (err *tryEndError) Error() string {
+ return err.err.Error()
+}
+
+type invalidPathError struct {
+ v any
+}
+
+func (err *invalidPathError) Error() string {
+ return "invalid path against: " + typeErrorPreview(err.v)
+}
+
+type invalidPathIterError struct {
+ v any
+}
+
+func (err *invalidPathIterError) Error() string {
+ return "invalid path on iterating against: " + typeErrorPreview(err.v)
+}
+
+type queryParseError struct {
+ fname, contents string
+ err error
+}
+
+func (err *queryParseError) QueryParseError() (string, string, error) {
+ return err.fname, err.contents, err.err
+}
+
+func (err *queryParseError) Error() string {
+ return "invalid query: " + err.fname + ": " + err.err.Error()
+}
+
+type jsonParseError struct {
+ fname, contents string
+ err error
+}
+
+func (err *jsonParseError) JSONParseError() (string, string, error) {
+ return err.fname, err.contents, err.err
+}
+
+func (err *jsonParseError) Error() string {
+ return "invalid json: " + err.fname + ": " + err.err.Error()
+}
+
+func typeErrorPreview(v any) string {
+ switch v.(type) {
+ case nil:
+ return "null"
+ case Iter:
+ return "gojq.Iter"
+ default:
+ return TypeOf(v) + " (" + Preview(v) + ")"
+ }
+}
diff --git a/vendor/github.com/itchyny/gojq/execute.go b/vendor/github.com/itchyny/gojq/execute.go
new file mode 100644
index 000000000..344d8a3c5
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/execute.go
@@ -0,0 +1,443 @@
+package gojq
+
+import (
+ "context"
+ "math"
+ "reflect"
+ "sort"
+)
+
+func (env *env) execute(bc *Code, v any, vars ...any) Iter {
+ env.codes = bc.codes
+ env.codeinfos = bc.codeinfos
+ env.push(v)
+ for i := len(vars) - 1; i >= 0; i-- {
+ env.push(vars[i])
+ }
+ env.debugCodes()
+ return env
+}
+
+func (env *env) Next() (any, bool) {
+ var err error
+ pc, callpc, index := env.pc, len(env.codes)-1, -1
+ backtrack, hasCtx := env.backtrack, env.ctx != context.Background()
+ defer func() { env.pc, env.backtrack = pc, true }()
+loop:
+ for ; pc < len(env.codes); pc++ {
+ env.debugState(pc, backtrack)
+ code := env.codes[pc]
+ if hasCtx {
+ select {
+ case <-env.ctx.Done():
+ pc, env.forks = len(env.codes), nil
+ return env.ctx.Err(), true
+ default:
+ }
+ }
+ switch code.op {
+ case opnop:
+ // nop
+ case oppush:
+ env.push(code.v)
+ case oppop:
+ env.pop()
+ case opdup:
+ v := env.pop()
+ env.push(v)
+ env.push(v)
+ case opconst:
+ env.pop()
+ env.push(code.v)
+ case opload:
+ env.push(env.values[env.index(code.v.([2]int))])
+ case opstore:
+ env.values[env.index(code.v.([2]int))] = env.pop()
+ case opobject:
+ if backtrack {
+ break loop
+ }
+ n := code.v.(int)
+ m := make(map[string]any, n)
+ for i := 0; i < n; i++ {
+ v, k := env.pop(), env.pop()
+ s, ok := k.(string)
+ if !ok {
+ err = &objectKeyNotStringError{k}
+ break loop
+ }
+ if _, ok := m[s]; !ok {
+ m[s] = v
+ }
+ }
+ env.push(m)
+ case opappend:
+ i := env.index(code.v.([2]int))
+ env.values[i] = append(env.values[i].([]any), env.pop())
+ case opfork:
+ if backtrack {
+ if err != nil {
+ break loop
+ }
+ pc, backtrack = code.v.(int), false
+ goto loop
+ }
+ env.pushfork(pc)
+ case opforktrybegin:
+ if backtrack {
+ if err == nil {
+ break loop
+ }
+ switch e := err.(type) {
+ case *tryEndError:
+ err = e.err
+ break loop
+ case *breakError, *HaltError:
+ break loop
+ case ValueError:
+ env.pop()
+ env.push(e.Value())
+ default:
+ env.pop()
+ env.push(err.Error())
+ }
+ pc, backtrack, err = code.v.(int), false, nil
+ goto loop
+ }
+ env.pushfork(pc)
+ case opforktryend:
+ if backtrack {
+ if err != nil {
+ err = &tryEndError{err}
+ }
+ break loop
+ }
+ env.pushfork(pc)
+ case opforkalt:
+ if backtrack {
+ if err == nil {
+ break loop
+ }
+ pc, backtrack, err = code.v.(int), false, nil
+ goto loop
+ }
+ env.pushfork(pc)
+ case opforklabel:
+ if backtrack {
+ label := env.pop()
+ if e, ok := err.(*breakError); ok && e.v == label {
+ err = nil
+ }
+ break loop
+ }
+ env.push(env.label)
+ env.pushfork(pc)
+ env.pop()
+ env.values[env.index(code.v.([2]int))] = env.label
+ env.label++
+ case opbacktrack:
+ break loop
+ case opjump:
+ pc = code.v.(int)
+ goto loop
+ case opjumpifnot:
+ if v := env.pop(); v == nil || v == false {
+ pc = code.v.(int)
+ goto loop
+ }
+ case opindex, opindexarray:
+ if backtrack {
+ break loop
+ }
+ p, v := code.v, env.pop()
+ if code.op == opindexarray && v != nil {
+ if _, ok := v.([]any); !ok {
+ err = &expectedArrayError{v}
+ break loop
+ }
+ }
+ w := funcIndex2(nil, v, p)
+ if e, ok := w.(error); ok {
+ err = e
+ break loop
+ }
+ env.push(w)
+ if !env.paths.empty() && env.expdepth == 0 {
+ if !env.pathIntact(v) {
+ err = &invalidPathError{v}
+ break loop
+ }
+ env.paths.push(pathValue{path: p, value: w})
+ }
+ case opcall:
+ if backtrack {
+ break loop
+ }
+ switch v := code.v.(type) {
+ case int:
+ pc, callpc, index = v, pc, env.scopes.index
+ goto loop
+ case [3]any:
+ argcnt := v[1].(int)
+ x, args := env.pop(), env.args[:argcnt]
+ for i := 0; i < argcnt; i++ {
+ args[i] = env.pop()
+ }
+ w := v[0].(func(any, []any) any)(x, args)
+ if e, ok := w.(error); ok {
+ err = e
+ break loop
+ }
+ env.push(w)
+ if !env.paths.empty() && env.expdepth == 0 {
+ switch v[2].(string) {
+ case "_index":
+ if x = args[0]; !env.pathIntact(x) {
+ err = &invalidPathError{x}
+ break loop
+ }
+ env.paths.push(pathValue{path: args[1], value: w})
+ case "_slice":
+ if x = args[0]; !env.pathIntact(x) {
+ err = &invalidPathError{x}
+ break loop
+ }
+ env.paths.push(pathValue{
+ path: map[string]any{"start": args[2], "end": args[1]},
+ value: w,
+ })
+ case "getpath":
+ if !env.pathIntact(x) {
+ err = &invalidPathError{x}
+ break loop
+ }
+ for _, p := range args[0].([]any) {
+ env.paths.push(pathValue{path: p, value: w})
+ }
+ }
+ }
+ default:
+ panic(v)
+ }
+ case opcallrec:
+ pc, callpc, index = code.v.(int), -1, env.scopes.index
+ goto loop
+ case oppushpc:
+ env.push([2]int{code.v.(int), env.scopes.index})
+ case opcallpc:
+ xs := env.pop().([2]int)
+ pc, callpc, index = xs[0], pc, xs[1]
+ goto loop
+ case opscope:
+ xs := code.v.([3]int)
+ var saveindex, outerindex int
+ if index == env.scopes.index {
+ if callpc >= 0 {
+ saveindex = index
+ } else {
+ callpc, saveindex = env.popscope()
+ }
+ } else {
+ saveindex, _ = env.scopes.save()
+ env.scopes.index = index
+ }
+ if outerindex = index; outerindex >= 0 {
+ if s := env.scopes.data[outerindex].value; s.id == xs[0] {
+ outerindex = s.outerindex
+ }
+ }
+ env.scopes.push(scope{xs[0], env.offset, callpc, saveindex, outerindex})
+ env.offset += xs[1]
+ if env.offset > len(env.values) {
+ vs := make([]any, env.offset*2)
+ copy(vs, env.values)
+ env.values = vs
+ }
+ case opret:
+ if backtrack {
+ break loop
+ }
+ pc, env.scopes.index = env.popscope()
+ if env.scopes.empty() {
+ return env.pop(), true
+ }
+ case opiter:
+ if err != nil {
+ break loop
+ }
+ backtrack = false
+ var xs []pathValue
+ switch v := env.pop().(type) {
+ case []pathValue:
+ xs = v
+ case []any:
+ if !env.paths.empty() && env.expdepth == 0 && !env.pathIntact(v) {
+ err = &invalidPathIterError{v}
+ break loop
+ }
+ if len(v) == 0 {
+ break loop
+ }
+ xs = make([]pathValue, len(v))
+ for i, v := range v {
+ xs[i] = pathValue{path: i, value: v}
+ }
+ case map[string]any:
+ if !env.paths.empty() && env.expdepth == 0 && !env.pathIntact(v) {
+ err = &invalidPathIterError{v}
+ break loop
+ }
+ if len(v) == 0 {
+ break loop
+ }
+ xs = make([]pathValue, len(v))
+ var i int
+ for k, v := range v {
+ xs[i] = pathValue{path: k, value: v}
+ i++
+ }
+ sort.Slice(xs, func(i, j int) bool {
+ return xs[i].path.(string) < xs[j].path.(string)
+ })
+ case Iter:
+ if w, ok := v.Next(); ok {
+ env.push(v)
+ env.pushfork(pc)
+ env.pop()
+ if e, ok := w.(error); ok {
+ err = e
+ break loop
+ }
+ env.push(w)
+ continue
+ }
+ break loop
+ default:
+ err = &iteratorError{v}
+ env.push(emptyIter{})
+ break loop
+ }
+ if len(xs) > 1 {
+ env.push(xs[1:])
+ env.pushfork(pc)
+ env.pop()
+ }
+ env.push(xs[0].value)
+ if !env.paths.empty() && env.expdepth == 0 {
+ env.paths.push(xs[0])
+ }
+ case opexpbegin:
+ env.expdepth++
+ case opexpend:
+ env.expdepth--
+ case oppathbegin:
+ env.paths.push(env.expdepth)
+ env.paths.push(pathValue{value: env.stack.top()})
+ env.expdepth = 0
+ case oppathend:
+ if backtrack {
+ break loop
+ }
+ env.pop()
+ if v := env.pop(); !env.pathIntact(v) {
+ err = &invalidPathError{v}
+ break loop
+ }
+ env.push(env.poppaths())
+ env.expdepth = env.paths.pop().(int)
+ default:
+ panic(code.op)
+ }
+ }
+ if len(env.forks) > 0 {
+ pc, backtrack = env.popfork(), true
+ goto loop
+ }
+ if err != nil {
+ return err, true
+ }
+ return nil, false
+}
+
+func (env *env) push(v any) {
+ env.stack.push(v)
+}
+
+func (env *env) pop() any {
+ return env.stack.pop()
+}
+
+func (env *env) popscope() (int, int) {
+ free := env.scopes.index > env.scopes.limit
+ s := env.scopes.pop()
+ if free {
+ env.offset = s.offset
+ }
+ return s.pc, s.saveindex
+}
+
+func (env *env) pushfork(pc int) {
+ f := fork{pc: pc, expdepth: env.expdepth}
+ f.stackindex, f.stacklimit = env.stack.save()
+ f.scopeindex, f.scopelimit = env.scopes.save()
+ f.pathindex, f.pathlimit = env.paths.save()
+ env.forks = append(env.forks, f)
+ env.debugForks(pc, ">>>")
+}
+
+func (env *env) popfork() int {
+ f := env.forks[len(env.forks)-1]
+ env.debugForks(f.pc, "<<<")
+ env.forks, env.expdepth = env.forks[:len(env.forks)-1], f.expdepth
+ env.stack.restore(f.stackindex, f.stacklimit)
+ env.scopes.restore(f.scopeindex, f.scopelimit)
+ env.paths.restore(f.pathindex, f.pathlimit)
+ return f.pc
+}
+
+func (env *env) index(v [2]int) int {
+ for id, i := v[0], env.scopes.index; i >= 0; {
+ s := env.scopes.data[i].value
+ if s.id == id {
+ return s.offset + v[1]
+ }
+ i = s.outerindex
+ }
+ panic("env.index")
+}
+
+type pathValue struct {
+ path, value any
+}
+
+func (env *env) pathIntact(v any) bool {
+ w := env.paths.top().(pathValue).value
+ switch v := v.(type) {
+ case []any, map[string]any:
+ switch w.(type) {
+ case []any, map[string]any:
+ v, w := reflect.ValueOf(v), reflect.ValueOf(w)
+ return v.Pointer() == w.Pointer() && v.Len() == w.Len()
+ }
+ case float64:
+ if w, ok := w.(float64); ok {
+ return v == w || math.IsNaN(v) && math.IsNaN(w)
+ }
+ }
+ return v == w
+}
+
+func (env *env) poppaths() []any {
+ xs := []any{}
+ for {
+ p := env.paths.pop().(pathValue)
+ if p.path == nil {
+ break
+ }
+ xs = append(xs, p.path)
+ }
+ for i, j := 0, len(xs)-1; i < j; i, j = i+1, j-1 {
+ xs[i], xs[j] = xs[j], xs[i]
+ }
+ return xs
+}
diff --git a/vendor/github.com/itchyny/gojq/func.go b/vendor/github.com/itchyny/gojq/func.go
new file mode 100644
index 000000000..165690a4f
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/func.go
@@ -0,0 +1,2168 @@
+package gojq
+
+import (
+ "encoding/base64"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "math"
+ "math/big"
+ "net/url"
+ "reflect"
+ "regexp"
+ "sort"
+ "strconv"
+ "strings"
+ "time"
+ "unicode"
+ "unicode/utf8"
+
+ "github.com/itchyny/timefmt-go"
+)
+
+//go:generate go run -modfile=go.dev.mod _tools/gen_builtin.go -i builtin.jq -o builtin.go
+var builtinFuncDefs map[string][]*FuncDef
+
+const (
+ argcount0 = 1 << iota
+ argcount1
+ argcount2
+ argcount3
+)
+
+type function struct {
+ argcount int
+ iter bool
+ callback func(any, []any) any
+}
+
+func (fn function) accept(cnt int) bool {
+ return fn.argcount&(1<= 0 {
+ return v
+ }
+ return -v
+ case float64:
+ return math.Abs(v)
+ case *big.Int:
+ if v.Sign() >= 0 {
+ return v
+ }
+ return new(big.Int).Abs(v)
+ default:
+ return &func0TypeError{"abs", v}
+ }
+}
+
+func funcLength(v any) any {
+ switch v := v.(type) {
+ case nil:
+ return 0
+ case int:
+ if v >= 0 {
+ return v
+ }
+ return -v
+ case float64:
+ return math.Abs(v)
+ case *big.Int:
+ if v.Sign() >= 0 {
+ return v
+ }
+ return new(big.Int).Abs(v)
+ case string:
+ return len([]rune(v))
+ case []any:
+ return len(v)
+ case map[string]any:
+ return len(v)
+ default:
+ return &func0TypeError{"length", v}
+ }
+}
+
+func funcUtf8ByteLength(v any) any {
+ s, ok := v.(string)
+ if !ok {
+ return &func0TypeError{"utf8bytelength", v}
+ }
+ return len(s)
+}
+
+func funcKeys(v any) any {
+ switch v := v.(type) {
+ case []any:
+ w := make([]any, len(v))
+ for i := range v {
+ w[i] = i
+ }
+ return w
+ case map[string]any:
+ w := make([]any, len(v))
+ for i, k := range keys(v) {
+ w[i] = k
+ }
+ return w
+ default:
+ return &func0TypeError{"keys", v}
+ }
+}
+
+func keys(v map[string]any) []string {
+ w := make([]string, len(v))
+ var i int
+ for k := range v {
+ w[i] = k
+ i++
+ }
+ sort.Strings(w)
+ return w
+}
+
+func values(v any) ([]any, bool) {
+ switch v := v.(type) {
+ case []any:
+ return v, true
+ case map[string]any:
+ vs := make([]any, len(v))
+ for i, k := range keys(v) {
+ vs[i] = v[k]
+ }
+ return vs, true
+ default:
+ return nil, false
+ }
+}
+
+func funcHas(v, x any) any {
+ switch v := v.(type) {
+ case []any:
+ if x, ok := toInt(x); ok {
+ return 0 <= x && x < len(v)
+ }
+ case map[string]any:
+ if x, ok := x.(string); ok {
+ _, ok := v[x]
+ return ok
+ }
+ case nil:
+ return false
+ }
+ return &func1TypeError{"has", v, x}
+}
+
+func funcToEntries(v any) any {
+ switch v := v.(type) {
+ case []any:
+ w := make([]any, len(v))
+ for i, x := range v {
+ w[i] = map[string]any{"key": i, "value": x}
+ }
+ return w
+ case map[string]any:
+ w := make([]any, len(v))
+ for i, k := range keys(v) {
+ w[i] = map[string]any{"key": k, "value": v[k]}
+ }
+ return w
+ default:
+ return &func0TypeError{"to_entries", v}
+ }
+}
+
+func funcFromEntries(v any) any {
+ vs, ok := v.([]any)
+ if !ok {
+ return &func0TypeError{"from_entries", v}
+ }
+ w := make(map[string]any, len(vs))
+ for _, v := range vs {
+ switch v := v.(type) {
+ case map[string]any:
+ var (
+ key string
+ value any
+ ok bool
+ )
+ for _, k := range [4]string{"key", "Key", "name", "Name"} {
+ if k := v[k]; k != nil && k != false {
+ if key, ok = k.(string); !ok {
+ return &func0WrapError{"from_entries", vs, &objectKeyNotStringError{k}}
+ }
+ break
+ }
+ }
+ if !ok {
+ return &func0WrapError{"from_entries", vs, &objectKeyNotStringError{nil}}
+ }
+ for _, k := range [2]string{"value", "Value"} {
+ if value, ok = v[k]; ok {
+ break
+ }
+ }
+ w[key] = value
+ default:
+ return &func0TypeError{"from_entries", v}
+ }
+ }
+ return w
+}
+
+func funcAdd(v any) any {
+ vs, ok := values(v)
+ if !ok {
+ return &func0TypeError{"add", v}
+ }
+ v = nil
+ for _, x := range vs {
+ switch x := x.(type) {
+ case nil:
+ continue
+ case string:
+ switch w := v.(type) {
+ case nil:
+ var sb strings.Builder
+ sb.WriteString(x)
+ v = &sb
+ continue
+ case *strings.Builder:
+ w.WriteString(x)
+ continue
+ }
+ case []any:
+ switch w := v.(type) {
+ case nil:
+ s := make([]any, len(x))
+ copy(s, x)
+ v = s
+ continue
+ case []any:
+ v = append(w, x...)
+ continue
+ }
+ case map[string]any:
+ switch w := v.(type) {
+ case nil:
+ m := make(map[string]any, len(x))
+ for k, e := range x {
+ m[k] = e
+ }
+ v = m
+ continue
+ case map[string]any:
+ for k, e := range x {
+ w[k] = e
+ }
+ continue
+ }
+ }
+ if sb, ok := v.(*strings.Builder); ok {
+ v = sb.String()
+ }
+ v = funcOpAdd(nil, v, x)
+ if err, ok := v.(error); ok {
+ return err
+ }
+ }
+ if sb, ok := v.(*strings.Builder); ok {
+ v = sb.String()
+ }
+ return v
+}
+
+func funcToNumber(v any) any {
+ switch v := v.(type) {
+ case int, float64, *big.Int:
+ return v
+ case string:
+ if !newLexer(v).validNumber() {
+ return &func0WrapError{"tonumber", v, errors.New("invalid number")}
+ }
+ return toNumber(v)
+ default:
+ return &func0TypeError{"tonumber", v}
+ }
+}
+
+func toNumber(v string) any {
+ return normalizeNumber(json.Number(v))
+}
+
+func funcToString(v any) any {
+ if s, ok := v.(string); ok {
+ return s
+ }
+ return funcToJSON(v)
+}
+
+func funcType(v any) any {
+ return TypeOf(v)
+}
+
+func funcReverse(v any) any {
+ vs, ok := v.([]any)
+ if !ok {
+ return &func0TypeError{"reverse", v}
+ }
+ ws := make([]any, len(vs))
+ for i, v := range vs {
+ ws[len(ws)-i-1] = v
+ }
+ return ws
+}
+
+func funcContains(v, x any) any {
+ return binopTypeSwitch(v, x,
+ func(l, r int) any { return l == r },
+ func(l, r float64) any { return l == r },
+ func(l, r *big.Int) any { return l.Cmp(r) == 0 },
+ func(l, r string) any { return strings.Contains(l, r) },
+ func(l, r []any) any {
+ R:
+ for _, r := range r {
+ for _, l := range l {
+ if funcContains(l, r) == true {
+ continue R
+ }
+ }
+ return false
+ }
+ return true
+ },
+ func(l, r map[string]any) any {
+ if len(l) < len(r) {
+ return false
+ }
+ for k, r := range r {
+ if l, ok := l[k]; !ok || funcContains(l, r) != true {
+ return false
+ }
+ }
+ return true
+ },
+ func(l, r any) any {
+ if l == r {
+ return true
+ }
+ return &func1TypeError{"contains", l, r}
+ },
+ )
+}
+
+func funcIndices(v, x any) any {
+ return indexFunc("indices", v, x, indices)
+}
+
+func indices(vs, xs []any) any {
+ rs := []any{}
+ if len(xs) == 0 {
+ return rs
+ }
+ for i := 0; i <= len(vs)-len(xs); i++ {
+ if compare(vs[i:i+len(xs)], xs) == 0 {
+ rs = append(rs, i)
+ }
+ }
+ return rs
+}
+
+func funcIndex(v, x any) any {
+ return indexFunc("index", v, x, func(vs, xs []any) any {
+ if len(xs) == 0 {
+ return nil
+ }
+ for i := 0; i <= len(vs)-len(xs); i++ {
+ if compare(vs[i:i+len(xs)], xs) == 0 {
+ return i
+ }
+ }
+ return nil
+ })
+}
+
+func funcRindex(v, x any) any {
+ return indexFunc("rindex", v, x, func(vs, xs []any) any {
+ if len(xs) == 0 {
+ return nil
+ }
+ for i := len(vs) - len(xs); i >= 0; i-- {
+ if compare(vs[i:i+len(xs)], xs) == 0 {
+ return i
+ }
+ }
+ return nil
+ })
+}
+
+func indexFunc(name string, v, x any, f func(_, _ []any) any) any {
+ switch v := v.(type) {
+ case nil:
+ return nil
+ case []any:
+ switch x := x.(type) {
+ case []any:
+ return f(v, x)
+ default:
+ return f(v, []any{x})
+ }
+ case string:
+ if x, ok := x.(string); ok {
+ return f(explode(v), explode(x))
+ }
+ return &func1TypeError{name, v, x}
+ default:
+ return &func1TypeError{name, v, x}
+ }
+}
+
+func funcStartsWith(v, x any) any {
+ s, ok := v.(string)
+ if !ok {
+ return &func1TypeError{"startswith", v, x}
+ }
+ t, ok := x.(string)
+ if !ok {
+ return &func1TypeError{"startswith", v, x}
+ }
+ return strings.HasPrefix(s, t)
+}
+
+func funcEndsWith(v, x any) any {
+ s, ok := v.(string)
+ if !ok {
+ return &func1TypeError{"endswith", v, x}
+ }
+ t, ok := x.(string)
+ if !ok {
+ return &func1TypeError{"endswith", v, x}
+ }
+ return strings.HasSuffix(s, t)
+}
+
+func funcLtrimstr(v, x any) any {
+ s, ok := v.(string)
+ if !ok {
+ return &func1TypeError{"ltrimstr", v, x}
+ }
+ t, ok := x.(string)
+ if !ok {
+ return &func1TypeError{"ltrimstr", v, x}
+ }
+ return strings.TrimPrefix(s, t)
+}
+
+func funcRtrimstr(v, x any) any {
+ s, ok := v.(string)
+ if !ok {
+ return &func1TypeError{"rtrimstr", v, x}
+ }
+ t, ok := x.(string)
+ if !ok {
+ return &func1TypeError{"rtrimstr", v, x}
+ }
+ return strings.TrimSuffix(s, t)
+}
+
+func funcLtrim(v any) any {
+ s, ok := v.(string)
+ if !ok {
+ return &func0TypeError{"ltrim", v}
+ }
+ return strings.TrimLeftFunc(s, unicode.IsSpace)
+}
+
+func funcRtrim(v any) any {
+ s, ok := v.(string)
+ if !ok {
+ return &func0TypeError{"rtrim", v}
+ }
+ return strings.TrimRightFunc(s, unicode.IsSpace)
+}
+
+func funcTrim(v any) any {
+ s, ok := v.(string)
+ if !ok {
+ return &func0TypeError{"trim", v}
+ }
+ return strings.TrimSpace(s)
+}
+
+func funcExplode(v any) any {
+ s, ok := v.(string)
+ if !ok {
+ return &func0TypeError{"explode", v}
+ }
+ return explode(s)
+}
+
+func explode(s string) []any {
+ xs := make([]any, len([]rune(s)))
+ var i int
+ for _, r := range s {
+ xs[i] = int(r)
+ i++
+ }
+ return xs
+}
+
+func funcImplode(v any) any {
+ vs, ok := v.([]any)
+ if !ok {
+ return &func0TypeError{"implode", v}
+ }
+ var sb strings.Builder
+ sb.Grow(len(vs))
+ for _, v := range vs {
+ if r, ok := toInt(v); ok {
+ if 0 <= r && r <= utf8.MaxRune {
+ sb.WriteRune(rune(r))
+ } else {
+ sb.WriteRune(utf8.RuneError)
+ }
+ } else {
+ return &func0TypeError{"implode", vs}
+ }
+ }
+ return sb.String()
+}
+
+func funcSplit(v any, args []any) any {
+ s, ok := v.(string)
+ if !ok {
+ return &func0TypeError{"split", v}
+ }
+ x, ok := args[0].(string)
+ if !ok {
+ return &func0TypeError{"split", x}
+ }
+ var ss []string
+ if len(args) == 1 {
+ ss = strings.Split(s, x)
+ } else {
+ var flags string
+ if args[1] != nil {
+ v, ok := args[1].(string)
+ if !ok {
+ return &func0TypeError{"split", args[1]}
+ }
+ flags = v
+ }
+ r, err := compileRegexp(x, flags)
+ if err != nil {
+ return err
+ }
+ ss = r.Split(s, -1)
+ }
+ xs := make([]any, len(ss))
+ for i, s := range ss {
+ xs[i] = s
+ }
+ return xs
+}
+
+func funcASCIIDowncase(v any) any {
+ s, ok := v.(string)
+ if !ok {
+ return &func0TypeError{"ascii_downcase", v}
+ }
+ return strings.Map(func(r rune) rune {
+ if 'A' <= r && r <= 'Z' {
+ return r + ('a' - 'A')
+ }
+ return r
+ }, s)
+}
+
+func funcASCIIUpcase(v any) any {
+ s, ok := v.(string)
+ if !ok {
+ return &func0TypeError{"ascii_upcase", v}
+ }
+ return strings.Map(func(r rune) rune {
+ if 'a' <= r && r <= 'z' {
+ return r - ('a' - 'A')
+ }
+ return r
+ }, s)
+}
+
+func funcToJSON(v any) any {
+ return jsonMarshal(v)
+}
+
+func funcFromJSON(v any) any {
+ s, ok := v.(string)
+ if !ok {
+ return &func0TypeError{"fromjson", v}
+ }
+ var w any
+ dec := json.NewDecoder(strings.NewReader(s))
+ dec.UseNumber()
+ if err := dec.Decode(&w); err != nil {
+ return &func0WrapError{"fromjson", v, err}
+ }
+ if _, err := dec.Token(); err != io.EOF {
+ return &func0TypeError{"fromjson", v}
+ }
+ return normalizeNumbers(w)
+}
+
+func funcFormat(v, x any) any {
+ s, ok := x.(string)
+ if !ok {
+ return &func0TypeError{"format", x}
+ }
+ format := "@" + s
+ f := formatToFunc(format)
+ if f == nil {
+ return &formatNotFoundError{format}
+ }
+ return internalFuncs[f.Name].callback(v, nil)
+}
+
+var htmlEscaper = strings.NewReplacer(
+ `<`, "<",
+ `>`, ">",
+ `&`, "&",
+ `'`, "'",
+ `"`, """,
+)
+
+func funcToHTML(v any) any {
+ switch x := funcToString(v).(type) {
+ case string:
+ return htmlEscaper.Replace(x)
+ default:
+ return x
+ }
+}
+
+func funcToURI(v any) any {
+ switch x := funcToString(v).(type) {
+ case string:
+ return url.QueryEscape(x)
+ default:
+ return x
+ }
+}
+
+func funcToURId(v any) any {
+ switch x := funcToString(v).(type) {
+ case string:
+ x, err := url.QueryUnescape(x)
+ if err != nil {
+ return &func0WrapError{"@urid", v, err}
+ }
+ return x
+ default:
+ return x
+ }
+}
+
+var csvEscaper = strings.NewReplacer(
+ `"`, `""`,
+ "\x00", `\0`,
+)
+
+func funcToCSV(v any) any {
+ return formatJoin("csv", v, ",", func(s string) string {
+ return `"` + csvEscaper.Replace(s) + `"`
+ })
+}
+
+var tsvEscaper = strings.NewReplacer(
+ "\t", `\t`,
+ "\r", `\r`,
+ "\n", `\n`,
+ "\\", `\\`,
+ "\x00", `\0`,
+)
+
+func funcToTSV(v any) any {
+ return formatJoin("tsv", v, "\t", tsvEscaper.Replace)
+}
+
+var shEscaper = strings.NewReplacer(
+ "'", `'\''`,
+ "\x00", `\0`,
+)
+
+func funcToSh(v any) any {
+ if _, ok := v.([]any); !ok {
+ v = []any{v}
+ }
+ return formatJoin("sh", v, " ", func(s string) string {
+ return "'" + shEscaper.Replace(s) + "'"
+ })
+}
+
+func formatJoin(typ string, v any, sep string, escape func(string) string) any {
+ vs, ok := v.([]any)
+ if !ok {
+ return &func0TypeError{"@" + typ, v}
+ }
+ ss := make([]string, len(vs))
+ for i, v := range vs {
+ switch v := v.(type) {
+ case []any, map[string]any:
+ return &formatRowError{typ, v}
+ case string:
+ ss[i] = escape(v)
+ default:
+ if s := jsonMarshal(v); s != "null" || typ == "sh" {
+ ss[i] = s
+ }
+ }
+ }
+ return strings.Join(ss, sep)
+}
+
+func funcToBase64(v any) any {
+ switch x := funcToString(v).(type) {
+ case string:
+ return base64.StdEncoding.EncodeToString([]byte(x))
+ default:
+ return x
+ }
+}
+
+func funcToBase64d(v any) any {
+ switch x := funcToString(v).(type) {
+ case string:
+ if i := strings.IndexRune(x, base64.StdPadding); i >= 0 {
+ x = x[:i]
+ }
+ y, err := base64.RawStdEncoding.DecodeString(x)
+ if err != nil {
+ return &func0WrapError{"@base64d", v, err}
+ }
+ return string(y)
+ default:
+ return x
+ }
+}
+
+func funcIndex2(_, v, x any) any {
+ switch x := x.(type) {
+ case string:
+ switch v := v.(type) {
+ case nil:
+ return nil
+ case map[string]any:
+ return v[x]
+ default:
+ return &expectedObjectError{v}
+ }
+ case int, float64, *big.Int:
+ i, _ := toInt(x)
+ switch v := v.(type) {
+ case nil:
+ return nil
+ case []any:
+ return index(v, i)
+ case string:
+ return indexString(v, i)
+ default:
+ return &expectedArrayError{v}
+ }
+ case []any:
+ switch v := v.(type) {
+ case nil:
+ return nil
+ case []any:
+ return indices(v, x)
+ default:
+ return &expectedArrayError{v}
+ }
+ case map[string]any:
+ if v == nil {
+ return nil
+ }
+ start, ok := x["start"]
+ if !ok {
+ return &expectedStartEndError{x}
+ }
+ end, ok := x["end"]
+ if !ok {
+ return &expectedStartEndError{x}
+ }
+ return funcSlice(nil, v, end, start)
+ default:
+ switch v.(type) {
+ case []any:
+ return &arrayIndexNotNumberError{x}
+ case string:
+ return &stringIndexNotNumberError{x}
+ default:
+ return &objectKeyNotStringError{x}
+ }
+ }
+}
+
+func index(vs []any, i int) any {
+ i = clampIndex(i, -1, len(vs))
+ if 0 <= i && i < len(vs) {
+ return vs[i]
+ }
+ return nil
+}
+
+func indexString(s string, i int) any {
+ l := len([]rune(s))
+ i = clampIndex(i, -1, l)
+ if 0 <= i && i < l {
+ for _, r := range s {
+ if i--; i < 0 {
+ return string(r)
+ }
+ }
+ }
+ return nil
+}
+
+func funcSlice(_, v, e, s any) (r any) {
+ switch v := v.(type) {
+ case nil:
+ return nil
+ case []any:
+ return slice(v, e, s)
+ case string:
+ return sliceString(v, e, s)
+ default:
+ return &expectedArrayError{v}
+ }
+}
+
+func slice(vs []any, e, s any) any {
+ var start, end int
+ if s != nil {
+ if i, ok := toInt(s); ok {
+ start = clampIndex(i, 0, len(vs))
+ } else {
+ return &arrayIndexNotNumberError{s}
+ }
+ }
+ if e != nil {
+ if i, ok := toInt(e); ok {
+ end = clampIndex(i, start, len(vs))
+ } else {
+ return &arrayIndexNotNumberError{e}
+ }
+ } else {
+ end = len(vs)
+ }
+ return vs[start:end]
+}
+
+func sliceString(v string, e, s any) any {
+ var start, end int
+ l := len([]rune(v))
+ if s != nil {
+ if i, ok := toInt(s); ok {
+ start = clampIndex(i, 0, l)
+ } else {
+ return &stringIndexNotNumberError{s}
+ }
+ }
+ if e != nil {
+ if i, ok := toInt(e); ok {
+ end = clampIndex(i, start, l)
+ } else {
+ return &stringIndexNotNumberError{e}
+ }
+ } else {
+ end = l
+ }
+ if start < l {
+ for i := range v {
+ if start--; start < 0 {
+ start = i
+ break
+ }
+ }
+ } else {
+ start = len(v)
+ }
+ if end < l {
+ for i := range v {
+ if end--; end < 0 {
+ end = i
+ break
+ }
+ }
+ } else {
+ end = len(v)
+ }
+ return v[start:end]
+}
+
+func clampIndex(i, min, max int) int {
+ if i < 0 {
+ i += max
+ }
+ if i < min {
+ return min
+ } else if i < max {
+ return i
+ } else {
+ return max
+ }
+}
+
+func funcFlatten(v any, args []any) any {
+ vs, ok := values(v)
+ if !ok {
+ return &func0TypeError{"flatten", v}
+ }
+ var depth float64
+ if len(args) == 0 {
+ depth = -1
+ } else {
+ depth, ok = toFloat(args[0])
+ if !ok {
+ return &func0TypeError{"flatten", args[0]}
+ }
+ if depth < 0 {
+ return &flattenDepthError{depth}
+ }
+ }
+ return flatten([]any{}, vs, depth)
+}
+
+func flatten(xs, vs []any, depth float64) []any {
+ for _, v := range vs {
+ if vs, ok := v.([]any); ok && depth != 0 {
+ xs = flatten(xs, vs, depth-1)
+ } else {
+ xs = append(xs, v)
+ }
+ }
+ return xs
+}
+
+type rangeIter struct {
+ value, end, step any
+}
+
+func (iter *rangeIter) Next() (any, bool) {
+ if compare(iter.step, 0)*compare(iter.value, iter.end) >= 0 {
+ return nil, false
+ }
+ v := iter.value
+ iter.value = funcOpAdd(nil, v, iter.step)
+ return v, true
+}
+
+func funcRange(_ any, xs []any) any {
+ for _, x := range xs {
+ switch x.(type) {
+ case int, float64, *big.Int:
+ default:
+ return &func0TypeError{"range", x}
+ }
+ }
+ return &rangeIter{xs[0], xs[1], xs[2]}
+}
+
+func funcMin(v any) any {
+ vs, ok := v.([]any)
+ if !ok {
+ return &func0TypeError{"min", v}
+ }
+ return minMaxBy(vs, vs, true)
+}
+
+func funcMinBy(v, x any) any {
+ vs, ok := v.([]any)
+ if !ok {
+ return &func1TypeError{"min_by", v, x}
+ }
+ xs, ok := x.([]any)
+ if !ok {
+ return &func1TypeError{"min_by", v, x}
+ }
+ if len(vs) != len(xs) {
+ return &func1WrapError{"min_by", v, x, &lengthMismatchError{}}
+ }
+ return minMaxBy(vs, xs, true)
+}
+
+func funcMax(v any) any {
+ vs, ok := v.([]any)
+ if !ok {
+ return &func0TypeError{"max", v}
+ }
+ return minMaxBy(vs, vs, false)
+}
+
+func funcMaxBy(v, x any) any {
+ vs, ok := v.([]any)
+ if !ok {
+ return &func1TypeError{"max_by", v, x}
+ }
+ xs, ok := x.([]any)
+ if !ok {
+ return &func1TypeError{"max_by", v, x}
+ }
+ if len(vs) != len(xs) {
+ return &func1WrapError{"max_by", v, x, &lengthMismatchError{}}
+ }
+ return minMaxBy(vs, xs, false)
+}
+
+func minMaxBy(vs, xs []any, isMin bool) any {
+ if len(vs) == 0 {
+ return nil
+ }
+ i, j, x := 0, 0, xs[0]
+ for i++; i < len(xs); i++ {
+ if compare(x, xs[i]) > 0 == isMin {
+ j, x = i, xs[i]
+ }
+ }
+ return vs[j]
+}
+
+type sortItem struct {
+ value, key any
+}
+
+func sortItems(name string, v, x any) ([]*sortItem, error) {
+ vs, ok := v.([]any)
+ if !ok {
+ if strings.HasSuffix(name, "_by") {
+ return nil, &func1TypeError{name, v, x}
+ }
+ return nil, &func0TypeError{name, v}
+ }
+ xs, ok := x.([]any)
+ if !ok {
+ return nil, &func1TypeError{name, v, x}
+ }
+ if len(vs) != len(xs) {
+ return nil, &func1WrapError{name, v, x, &lengthMismatchError{}}
+ }
+ items := make([]*sortItem, len(vs))
+ for i, v := range vs {
+ items[i] = &sortItem{v, xs[i]}
+ }
+ sort.SliceStable(items, func(i, j int) bool {
+ return compare(items[i].key, items[j].key) < 0
+ })
+ return items, nil
+}
+
+func funcSort(v any) any {
+ return sortBy("sort", v, v)
+}
+
+func funcSortBy(v, x any) any {
+ return sortBy("sort_by", v, x)
+}
+
+func sortBy(name string, v, x any) any {
+ items, err := sortItems(name, v, x)
+ if err != nil {
+ return err
+ }
+ rs := make([]any, len(items))
+ for i, x := range items {
+ rs[i] = x.value
+ }
+ return rs
+}
+
+func funcGroupBy(v, x any) any {
+ items, err := sortItems("group_by", v, x)
+ if err != nil {
+ return err
+ }
+ rs := []any{}
+ var last any
+ for i, r := range items {
+ if i == 0 || compare(last, r.key) != 0 {
+ rs, last = append(rs, []any{r.value}), r.key
+ } else {
+ rs[len(rs)-1] = append(rs[len(rs)-1].([]any), r.value)
+ }
+ }
+ return rs
+}
+
+func funcUnique(v any) any {
+ return uniqueBy("unique", v, v)
+}
+
+func funcUniqueBy(v, x any) any {
+ return uniqueBy("unique_by", v, x)
+}
+
+func uniqueBy(name string, v, x any) any {
+ items, err := sortItems(name, v, x)
+ if err != nil {
+ return err
+ }
+ rs := []any{}
+ var last any
+ for i, r := range items {
+ if i == 0 || compare(last, r.key) != 0 {
+ rs, last = append(rs, r.value), r.key
+ }
+ }
+ return rs
+}
+
+func funcJoin(v, x any) any {
+ vs, ok := values(v)
+ if !ok {
+ return &func1TypeError{"join", v, x}
+ }
+ if len(vs) == 0 {
+ return ""
+ }
+ sep, ok := x.(string)
+ if len(vs) > 1 && !ok {
+ return &func1TypeError{"join", v, x}
+ }
+ ss := make([]string, len(vs))
+ for i, v := range vs {
+ switch v := v.(type) {
+ case nil:
+ case string:
+ ss[i] = v
+ case bool:
+ if v {
+ ss[i] = "true"
+ } else {
+ ss[i] = "false"
+ }
+ case int, float64, *big.Int:
+ ss[i] = jsonMarshal(v)
+ default:
+ return &joinTypeError{v}
+ }
+ }
+ return strings.Join(ss, sep)
+}
+
+func funcSignificand(v float64) float64 {
+ if math.IsNaN(v) || math.IsInf(v, 0) || v == 0.0 {
+ return v
+ }
+ return math.Float64frombits((math.Float64bits(v) & 0x800fffffffffffff) | 0x3ff0000000000000)
+}
+
+func funcExp10(v float64) float64 {
+ return math.Pow(10, v)
+}
+
+func funcFrexp(v any) any {
+ x, ok := toFloat(v)
+ if !ok {
+ return &func0TypeError{"frexp", v}
+ }
+ f, e := math.Frexp(x)
+ return []any{f, e}
+}
+
+func funcModf(v any) any {
+ x, ok := toFloat(v)
+ if !ok {
+ return &func0TypeError{"modf", v}
+ }
+ i, f := math.Modf(x)
+ return []any{f, i}
+}
+
+func funcLgamma(v float64) float64 {
+ v, _ = math.Lgamma(v)
+ return v
+}
+
+func funcDrem(l, r float64) float64 {
+ x := math.Remainder(l, r)
+ if x == 0.0 {
+ return math.Copysign(x, l)
+ }
+ return x
+}
+
+func funcJn(l, r float64) float64 {
+ return math.Jn(int(l), r)
+}
+
+func funcLdexp(l, r float64) float64 {
+ return math.Ldexp(l, int(r))
+}
+
+func funcYn(l, r float64) float64 {
+ return math.Yn(int(l), r)
+}
+
+func funcInfinite(any) any {
+ return math.Inf(1)
+}
+
+func funcIsfinite(v any) any {
+ x, ok := toFloat(v)
+ return ok && !math.IsInf(x, 0)
+}
+
+func funcIsinfinite(v any) any {
+ x, ok := toFloat(v)
+ return ok && math.IsInf(x, 0)
+}
+
+func funcNan(any) any {
+ return math.NaN()
+}
+
+func funcIsnan(v any) any {
+ x, ok := toFloat(v)
+ if !ok {
+ if v == nil {
+ return false
+ }
+ return &func0TypeError{"isnan", v}
+ }
+ return math.IsNaN(x)
+}
+
+func funcIsnormal(v any) any {
+ if v, ok := toFloat(v); ok {
+ e := math.Float64bits(v) & 0x7ff0000000000000 >> 52
+ return 0 < e && e < 0x7ff
+ }
+ return false
+}
+
+// An `allocator` creates new maps and slices, stores the allocated addresses.
+// This allocator is used to reduce allocations on assignment operator (`=`),
+// update-assignment operator (`|=`), and the `map_values`, `del`, `delpaths`
+// functions.
+type allocator map[uintptr]struct{}
+
+func funcAllocator(any, []any) any {
+ return allocator{}
+}
+
+func (a allocator) allocated(v any) bool {
+ _, ok := a[reflect.ValueOf(v).Pointer()]
+ return ok
+}
+
+func (a allocator) makeObject(l int) map[string]any {
+ v := make(map[string]any, l)
+ if a != nil {
+ a[reflect.ValueOf(v).Pointer()] = struct{}{}
+ }
+ return v
+}
+
+func (a allocator) makeArray(l, c int) []any {
+ if c < l {
+ c = l
+ }
+ v := make([]any, l, c)
+ if a != nil {
+ a[reflect.ValueOf(v).Pointer()] = struct{}{}
+ }
+ return v
+}
+
+func funcSetpath(v, p, n any) any {
+ // There is no need to use an allocator on a single update.
+ return setpath(v, p, n, nil)
+}
+
+// Used in compiler#compileAssign and compiler#compileModify.
+func funcSetpathWithAllocator(v any, args []any) any {
+ return setpath(v, args[0], args[1], args[2].(allocator))
+}
+
+func setpath(v, p, n any, a allocator) any {
+ path, ok := p.([]any)
+ if !ok {
+ return &func1TypeError{"setpath", v, p}
+ }
+ u, err := update(v, path, n, a)
+ if err != nil {
+ return &func2WrapError{"setpath", v, p, n, err}
+ }
+ return u
+}
+
+func funcDelpaths(v, p any) any {
+ return delpaths(v, p, allocator{})
+}
+
+// Used in compiler#compileAssign and compiler#compileModify.
+func funcDelpathsWithAllocator(v any, args []any) any {
+ return delpaths(v, args[0], args[1].(allocator))
+}
+
+func delpaths(v, p any, a allocator) any {
+ paths, ok := p.([]any)
+ if !ok {
+ return &func1TypeError{"delpaths", v, p}
+ }
+ if len(paths) == 0 {
+ return v
+ }
+ // Fills the paths with an empty value and then delete them. We cannot delete
+ // in each loop because array indices should not change. For example,
+ // jq -n "[0, 1, 2, 3] | delpaths([[1], [2]])" #=> [0, 3].
+ var empty struct{}
+ var err error
+ u := v
+ for _, q := range paths {
+ path, ok := q.([]any)
+ if !ok {
+ return &func1WrapError{"delpaths", v, p, &expectedArrayError{q}}
+ }
+ u, err = update(u, path, empty, a)
+ if err != nil {
+ return &func1WrapError{"delpaths", v, p, err}
+ }
+ }
+ return deleteEmpty(u)
+}
+
+func update(v any, path []any, n any, a allocator) (any, error) {
+ if len(path) == 0 {
+ return n, nil
+ }
+ switch p := path[0].(type) {
+ case string:
+ switch v := v.(type) {
+ case nil:
+ return updateObject(nil, p, path[1:], n, a)
+ case map[string]any:
+ return updateObject(v, p, path[1:], n, a)
+ case struct{}:
+ return v, nil
+ default:
+ return nil, &expectedObjectError{v}
+ }
+ case int, float64, *big.Int:
+ i, _ := toInt(p)
+ switch v := v.(type) {
+ case nil:
+ return updateArrayIndex(nil, i, path[1:], n, a)
+ case []any:
+ return updateArrayIndex(v, i, path[1:], n, a)
+ case struct{}:
+ return v, nil
+ default:
+ return nil, &expectedArrayError{v}
+ }
+ case map[string]any:
+ switch v := v.(type) {
+ case nil:
+ return updateArraySlice(nil, p, path[1:], n, a)
+ case []any:
+ return updateArraySlice(v, p, path[1:], n, a)
+ case struct{}:
+ return v, nil
+ default:
+ return nil, &expectedArrayError{v}
+ }
+ default:
+ switch v.(type) {
+ case []any:
+ return nil, &arrayIndexNotNumberError{p}
+ default:
+ return nil, &objectKeyNotStringError{p}
+ }
+ }
+}
+
+func updateObject(v map[string]any, k string, path []any, n any, a allocator) (any, error) {
+ x, ok := v[k]
+ if !ok && n == struct{}{} {
+ return v, nil
+ }
+ u, err := update(x, path, n, a)
+ if err != nil {
+ return nil, err
+ }
+ if a.allocated(v) {
+ v[k] = u
+ return v, nil
+ }
+ w := a.makeObject(len(v) + 1)
+ for k, v := range v {
+ w[k] = v
+ }
+ w[k] = u
+ return w, nil
+}
+
+func updateArrayIndex(v []any, i int, path []any, n any, a allocator) (any, error) {
+ var x any
+ if j := clampIndex(i, -1, len(v)); j < 0 {
+ if n == struct{}{} {
+ return v, nil
+ }
+ return nil, &arrayIndexNegativeError{i}
+ } else if j < len(v) {
+ i = j
+ x = v[i]
+ } else {
+ if n == struct{}{} {
+ return v, nil
+ }
+ if i >= 0x8000000 {
+ return nil, &arrayIndexTooLargeError{i}
+ }
+ }
+ u, err := update(x, path, n, a)
+ if err != nil {
+ return nil, err
+ }
+ l, c := len(v), cap(v)
+ if a.allocated(v) {
+ if i < c {
+ if i >= l {
+ v = v[:i+1]
+ }
+ v[i] = u
+ return v, nil
+ }
+ c *= 2
+ }
+ if i >= l {
+ l = i + 1
+ }
+ w := a.makeArray(l, c)
+ copy(w, v)
+ w[i] = u
+ return w, nil
+}
+
+func updateArraySlice(v []any, m map[string]any, path []any, n any, a allocator) (any, error) {
+ s, ok := m["start"]
+ if !ok {
+ return nil, &expectedStartEndError{m}
+ }
+ e, ok := m["end"]
+ if !ok {
+ return nil, &expectedStartEndError{m}
+ }
+ var start, end int
+ if i, ok := toInt(s); ok {
+ start = clampIndex(i, 0, len(v))
+ }
+ if i, ok := toInt(e); ok {
+ end = clampIndex(i, start, len(v))
+ } else {
+ end = len(v)
+ }
+ if start == end && n == struct{}{} {
+ return v, nil
+ }
+ u, err := update(v[start:end], path, n, a)
+ if err != nil {
+ return nil, err
+ }
+ switch u := u.(type) {
+ case []any:
+ var w []any
+ if len(u) == end-start && a.allocated(v) {
+ w = v
+ } else {
+ w = a.makeArray(len(v)-(end-start)+len(u), 0)
+ copy(w, v[:start])
+ copy(w[start+len(u):], v[end:])
+ }
+ copy(w[start:], u)
+ return w, nil
+ case struct{}:
+ var w []any
+ if a.allocated(v) {
+ w = v
+ } else {
+ w = a.makeArray(len(v), 0)
+ copy(w, v)
+ }
+ for i := start; i < end; i++ {
+ w[i] = u
+ }
+ return w, nil
+ default:
+ return nil, &expectedArrayError{u}
+ }
+}
+
+func deleteEmpty(v any) any {
+ switch v := v.(type) {
+ case struct{}:
+ return nil
+ case map[string]any:
+ for k, w := range v {
+ if w == struct{}{} {
+ delete(v, k)
+ } else {
+ v[k] = deleteEmpty(w)
+ }
+ }
+ return v
+ case []any:
+ var j int
+ for _, w := range v {
+ if w != struct{}{} {
+ v[j] = deleteEmpty(w)
+ j++
+ }
+ }
+ for i := j; i < len(v); i++ {
+ v[i] = nil
+ }
+ return v[:j]
+ default:
+ return v
+ }
+}
+
+func funcGetpath(v, p any) any {
+ path, ok := p.([]any)
+ if !ok {
+ return &func1TypeError{"getpath", v, p}
+ }
+ u := v
+ for _, x := range path {
+ switch v.(type) {
+ case nil, []any, map[string]any:
+ v = funcIndex2(nil, v, x)
+ if err, ok := v.(error); ok {
+ return &func1WrapError{"getpath", u, p, err}
+ }
+ default:
+ return &func1TypeError{"getpath", u, p}
+ }
+ }
+ return v
+}
+
+func funcTranspose(v any) any {
+ vss, ok := v.([]any)
+ if !ok {
+ return &func0TypeError{"transpose", v}
+ }
+ if len(vss) == 0 {
+ return []any{}
+ }
+ var l int
+ for _, vs := range vss {
+ vs, ok := vs.([]any)
+ if !ok {
+ return &func0TypeError{"transpose", v}
+ }
+ if k := len(vs); l < k {
+ l = k
+ }
+ }
+ wss := make([][]any, l)
+ xs := make([]any, l)
+ for i, k := 0, len(vss); i < l; i++ {
+ s := make([]any, k)
+ wss[i] = s
+ xs[i] = s
+ }
+ for i, vs := range vss {
+ for j, v := range vs.([]any) {
+ wss[j][i] = v
+ }
+ }
+ return xs
+}
+
+func funcBsearch(v, t any) any {
+ vs, ok := v.([]any)
+ if !ok {
+ return &func1TypeError{"bsearch", v, t}
+ }
+ i := sort.Search(len(vs), func(i int) bool {
+ return compare(vs[i], t) >= 0
+ })
+ if i < len(vs) && compare(vs[i], t) == 0 {
+ return i
+ }
+ return -i - 1
+}
+
+func funcGmtime(v any) any {
+ if v, ok := toFloat(v); ok {
+ return epochToArray(v, time.UTC)
+ }
+ return &func0TypeError{"gmtime", v}
+}
+
+func funcLocaltime(v any) any {
+ if v, ok := toFloat(v); ok {
+ return epochToArray(v, time.Local)
+ }
+ return &func0TypeError{"localtime", v}
+}
+
+func epochToArray(v float64, loc *time.Location) []any {
+ t := time.Unix(int64(v), int64((v-math.Floor(v))*1e9)).In(loc)
+ return []any{
+ t.Year(),
+ int(t.Month()) - 1,
+ t.Day(),
+ t.Hour(),
+ t.Minute(),
+ float64(t.Second()) + float64(t.Nanosecond())/1e9,
+ int(t.Weekday()),
+ t.YearDay() - 1,
+ }
+}
+
+func funcMktime(v any) any {
+ a, ok := v.([]any)
+ if !ok {
+ return &func0TypeError{"mktime", v}
+ }
+ t, err := arrayToTime(a, time.UTC)
+ if err != nil {
+ return &func0WrapError{"mktime", v, err}
+ }
+ return timeToEpoch(t)
+}
+
+func timeToEpoch(t time.Time) float64 {
+ return float64(t.Unix()) + float64(t.Nanosecond())/1e9
+}
+
+func funcStrftime(v, x any) any {
+ if w, ok := toFloat(v); ok {
+ v = epochToArray(w, time.UTC)
+ }
+ a, ok := v.([]any)
+ if !ok {
+ return &func1TypeError{"strftime", v, x}
+ }
+ format, ok := x.(string)
+ if !ok {
+ return &func1TypeError{"strftime", v, x}
+ }
+ t, err := arrayToTime(a, time.UTC)
+ if err != nil {
+ return &func1WrapError{"strftime", v, x, err}
+ }
+ return timefmt.Format(t, format)
+}
+
+func funcStrflocaltime(v, x any) any {
+ if w, ok := toFloat(v); ok {
+ v = epochToArray(w, time.Local)
+ }
+ a, ok := v.([]any)
+ if !ok {
+ return &func1TypeError{"strflocaltime", v, x}
+ }
+ format, ok := x.(string)
+ if !ok {
+ return &func1TypeError{"strflocaltime", v, x}
+ }
+ t, err := arrayToTime(a, time.Local)
+ if err != nil {
+ return &func1WrapError{"strflocaltime", v, x, err}
+ }
+ return timefmt.Format(t, format)
+}
+
+func funcStrptime(v, x any) any {
+ s, ok := v.(string)
+ if !ok {
+ return &func1TypeError{"strptime", v, x}
+ }
+ format, ok := x.(string)
+ if !ok {
+ return &func1TypeError{"strptime", v, x}
+ }
+ t, err := timefmt.Parse(s, format)
+ if err != nil {
+ return &func1WrapError{"strptime", v, x, err}
+ }
+ var u time.Time
+ if t == u {
+ return &func1TypeError{"strptime", v, x}
+ }
+ return epochToArray(timeToEpoch(t), time.UTC)
+}
+
+func arrayToTime(a []any, loc *time.Location) (time.Time, error) {
+ var t time.Time
+ if len(a) != 8 {
+ return t, &timeArrayError{}
+ }
+ var y, m, d, h, min, sec, nsec int
+ var ok bool
+ if y, ok = toInt(a[0]); !ok {
+ return t, &timeArrayError{}
+ }
+ if m, ok = toInt(a[1]); ok {
+ m++
+ } else {
+ return t, &timeArrayError{}
+ }
+ if d, ok = toInt(a[2]); !ok {
+ return t, &timeArrayError{}
+ }
+ if h, ok = toInt(a[3]); !ok {
+ return t, &timeArrayError{}
+ }
+ if min, ok = toInt(a[4]); !ok {
+ return t, &timeArrayError{}
+ }
+ if x, ok := toFloat(a[5]); ok {
+ sec = int(x)
+ nsec = int((x - math.Floor(x)) * 1e9)
+ } else {
+ return t, &timeArrayError{}
+ }
+ if _, ok = toFloat(a[6]); !ok {
+ return t, &timeArrayError{}
+ }
+ if _, ok = toFloat(a[7]); !ok {
+ return t, &timeArrayError{}
+ }
+ return time.Date(y, time.Month(m), d, h, min, sec, nsec, loc), nil
+}
+
+func funcNow(any) any {
+ return timeToEpoch(time.Now())
+}
+
+func funcMatch(v, re, fs, testing any) any {
+ name := "match"
+ if testing == true {
+ name = "test"
+ }
+ var flags string
+ if fs != nil {
+ v, ok := fs.(string)
+ if !ok {
+ return &func2TypeError{name, v, re, fs}
+ }
+ flags = v
+ }
+ s, ok := v.(string)
+ if !ok {
+ return &func2TypeError{name, v, re, fs}
+ }
+ restr, ok := re.(string)
+ if !ok {
+ return &func2TypeError{name, v, re, fs}
+ }
+ r, err := compileRegexp(restr, flags)
+ if err != nil {
+ return err
+ }
+ var xs [][]int
+ if strings.ContainsRune(flags, 'g') && testing != true {
+ xs = r.FindAllStringSubmatchIndex(s, -1)
+ } else {
+ got := r.FindStringSubmatchIndex(s)
+ if testing == true {
+ return got != nil
+ }
+ if got != nil {
+ xs = [][]int{got}
+ }
+ }
+ res, names := make([]any, len(xs)), r.SubexpNames()
+ for i, x := range xs {
+ captures := make([]any, (len(x)-2)/2)
+ for j := 1; j < len(x)/2; j++ {
+ var name any
+ if n := names[j]; n != "" {
+ name = n
+ }
+ if x[j*2] < 0 {
+ captures[j-1] = map[string]any{
+ "name": name,
+ "offset": -1,
+ "length": 0,
+ "string": nil,
+ }
+ continue
+ }
+ captures[j-1] = map[string]any{
+ "name": name,
+ "offset": len([]rune(s[:x[j*2]])),
+ "length": len([]rune(s[:x[j*2+1]])) - len([]rune(s[:x[j*2]])),
+ "string": s[x[j*2]:x[j*2+1]],
+ }
+ }
+ res[i] = map[string]any{
+ "offset": len([]rune(s[:x[0]])),
+ "length": len([]rune(s[:x[1]])) - len([]rune(s[:x[0]])),
+ "string": s[x[0]:x[1]],
+ "captures": captures,
+ }
+ }
+ return res
+}
+
+func compileRegexp(re, flags string) (*regexp.Regexp, error) {
+ if strings.IndexFunc(flags, func(r rune) bool {
+ return r != 'g' && r != 'i' && r != 'm'
+ }) >= 0 {
+ return nil, fmt.Errorf("unsupported regular expression flag: %q", flags)
+ }
+ re = strings.ReplaceAll(re, "(?<", "(?P<")
+ if strings.ContainsRune(flags, 'i') {
+ re = "(?i)" + re
+ }
+ if strings.ContainsRune(flags, 'm') {
+ re = "(?s)" + re
+ }
+ r, err := regexp.Compile(re)
+ if err != nil {
+ return nil, fmt.Errorf("invalid regular expression %q: %s", re, err)
+ }
+ return r, nil
+}
+
+func funcCapture(v any) any {
+ vs, ok := v.(map[string]any)
+ if !ok {
+ return &expectedObjectError{v}
+ }
+ v = vs["captures"]
+ captures, ok := v.([]any)
+ if !ok {
+ return &expectedArrayError{v}
+ }
+ w := make(map[string]any, len(captures))
+ for _, capture := range captures {
+ if capture, ok := capture.(map[string]any); ok {
+ if name, ok := capture["name"].(string); ok {
+ w[name] = capture["string"]
+ }
+ }
+ }
+ return w
+}
+
+func funcError(v any, args []any) any {
+ if len(args) > 0 {
+ v = args[0]
+ }
+ return &exitCodeError{v, 5}
+}
+
+func funcHalt(any) any {
+ return &HaltError{nil, 0}
+}
+
+func funcHaltError(v any, args []any) any {
+ code := 5
+ if len(args) > 0 {
+ var ok bool
+ if code, ok = toInt(args[0]); !ok {
+ return &func0TypeError{"halt_error", args[0]}
+ }
+ }
+ return &HaltError{v, code}
+}
+
+func toInt(x any) (int, bool) {
+ switch x := x.(type) {
+ case int:
+ return x, true
+ case float64:
+ return floatToInt(x), true
+ case *big.Int:
+ if x.IsInt64() {
+ if i := x.Int64(); math.MinInt <= i && i <= math.MaxInt {
+ return int(i), true
+ }
+ }
+ if x.Sign() > 0 {
+ return math.MaxInt, true
+ }
+ return math.MinInt, true
+ default:
+ return 0, false
+ }
+}
+
+func floatToInt(x float64) int {
+ if math.MinInt <= x && x <= math.MaxInt {
+ return int(x)
+ }
+ if x > 0 {
+ return math.MaxInt
+ }
+ return math.MinInt
+}
+
+func toFloat(x any) (float64, bool) {
+ switch x := x.(type) {
+ case int:
+ return float64(x), true
+ case float64:
+ return x, true
+ case *big.Int:
+ return bigToFloat(x), true
+ default:
+ return 0.0, false
+ }
+}
+
+func bigToFloat(x *big.Int) float64 {
+ if x.IsInt64() {
+ return float64(x.Int64())
+ }
+ if f, err := strconv.ParseFloat(x.String(), 64); err == nil {
+ return f
+ }
+ return math.Inf(x.Sign())
+}
diff --git a/vendor/github.com/itchyny/gojq/go.dev.mod b/vendor/github.com/itchyny/gojq/go.dev.mod
new file mode 100644
index 000000000..2c1e43401
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/go.dev.mod
@@ -0,0 +1,8 @@
+module github.com/itchyny/gojq
+
+go 1.20
+
+require (
+ github.com/itchyny/astgen-go v0.0.0-20231113225122-e1c22b9aaf7b // indirect
+ github.com/itchyny/timefmt-go v0.1.5 // indirect
+)
diff --git a/vendor/github.com/itchyny/gojq/go.dev.sum b/vendor/github.com/itchyny/gojq/go.dev.sum
new file mode 100644
index 000000000..5c52eab2e
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/go.dev.sum
@@ -0,0 +1,4 @@
+github.com/itchyny/astgen-go v0.0.0-20231113225122-e1c22b9aaf7b h1:72fDU7wad+r3iQObaxhlXVIpAIMRUIUMrNa3go1vb8s=
+github.com/itchyny/astgen-go v0.0.0-20231113225122-e1c22b9aaf7b/go.mod h1:Zp6xzEWVc2pQ/ObfLD6t/M6gDegsJWKdGKJSiT7qlu0=
+github.com/itchyny/timefmt-go v0.1.5 h1:G0INE2la8S6ru/ZI5JecgyzbbJNs5lG1RcBqa7Jm6GE=
+github.com/itchyny/timefmt-go v0.1.5/go.mod h1:nEP7L+2YmAbT2kZ2HfSs1d8Xtw9LY8D2stDBckWakZ8=
diff --git a/vendor/github.com/itchyny/gojq/gojq.go b/vendor/github.com/itchyny/gojq/gojq.go
new file mode 100644
index 000000000..e078c8090
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/gojq.go
@@ -0,0 +1,5 @@
+// Package gojq provides the parser and the interpreter of gojq.
+// Please refer to [Usage as a library] for introduction.
+//
+// [Usage as a library]: https://github.com/itchyny/gojq#usage-as-a-library
+package gojq
diff --git a/vendor/github.com/itchyny/gojq/iter.go b/vendor/github.com/itchyny/gojq/iter.go
new file mode 100644
index 000000000..d0bed9606
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/iter.go
@@ -0,0 +1,49 @@
+package gojq
+
+// Iter is an interface for an iterator.
+type Iter interface {
+ Next() (any, bool)
+}
+
+// NewIter creates a new [Iter] from values.
+func NewIter(values ...any) Iter {
+ switch len(values) {
+ case 0:
+ return emptyIter{}
+ case 1:
+ return &unitIter{value: values[0]}
+ default:
+ iter := sliceIter(values)
+ return &iter
+ }
+}
+
+type emptyIter struct{}
+
+func (emptyIter) Next() (any, bool) {
+ return nil, false
+}
+
+type unitIter struct {
+ value any
+ done bool
+}
+
+func (iter *unitIter) Next() (any, bool) {
+ if iter.done {
+ return nil, false
+ }
+ iter.done = true
+ return iter.value, true
+}
+
+type sliceIter []any
+
+func (iter *sliceIter) Next() (any, bool) {
+ if len(*iter) == 0 {
+ return nil, false
+ }
+ value := (*iter)[0]
+ *iter = (*iter)[1:]
+ return value, true
+}
diff --git a/vendor/github.com/itchyny/gojq/lexer.go b/vendor/github.com/itchyny/gojq/lexer.go
new file mode 100644
index 000000000..509d60c65
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/lexer.go
@@ -0,0 +1,577 @@
+package gojq
+
+import (
+ "encoding/json"
+ "unicode/utf8"
+)
+
+type lexer struct {
+ source string
+ offset int
+ result *Query
+ token string
+ tokenType int
+ inString bool
+ err error
+}
+
+func newLexer(src string) *lexer {
+ return &lexer{source: src}
+}
+
+const eof = -1
+
+var keywords = map[string]int{
+ "or": tokOrOp,
+ "and": tokAndOp,
+ "module": tokModule,
+ "import": tokImport,
+ "include": tokInclude,
+ "def": tokDef,
+ "as": tokAs,
+ "label": tokLabel,
+ "break": tokBreak,
+ "null": tokNull,
+ "true": tokTrue,
+ "false": tokFalse,
+ "if": tokIf,
+ "then": tokThen,
+ "elif": tokElif,
+ "else": tokElse,
+ "end": tokEnd,
+ "try": tokTry,
+ "catch": tokCatch,
+ "reduce": tokReduce,
+ "foreach": tokForeach,
+}
+
+func (l *lexer) Lex(lval *yySymType) (tokenType int) {
+ defer func() { l.tokenType = tokenType }()
+ if len(l.source) == l.offset {
+ l.token = ""
+ return eof
+ }
+ if l.inString {
+ tok, str := l.scanString(l.offset)
+ lval.token = str
+ return tok
+ }
+ ch, iseof := l.next()
+ if iseof {
+ l.token = ""
+ return eof
+ }
+ switch {
+ case isIdent(ch, false):
+ i := l.offset - 1
+ j, isModule := l.scanIdentOrModule()
+ l.token = l.source[i:j]
+ lval.token = l.token
+ if isModule {
+ return tokModuleIdent
+ }
+ if tok, ok := keywords[l.token]; ok {
+ return tok
+ }
+ return tokIdent
+ case isNumber(ch):
+ i := l.offset - 1
+ j := l.scanNumber(numberStateLead)
+ if j < 0 {
+ l.token = l.source[i:-j]
+ return tokInvalid
+ }
+ l.token = l.source[i:j]
+ lval.token = l.token
+ return tokNumber
+ }
+ switch ch {
+ case '.':
+ ch := l.peek()
+ switch {
+ case ch == '.':
+ l.offset++
+ l.token = ".."
+ return tokRecurse
+ case isIdent(ch, false):
+ l.token = l.source[l.offset-1 : l.scanIdent()]
+ lval.token = l.token[1:]
+ return tokIndex
+ case isNumber(ch):
+ i := l.offset - 1
+ j := l.scanNumber(numberStateFloat)
+ if j < 0 {
+ l.token = l.source[i:-j]
+ return tokInvalid
+ }
+ l.token = l.source[i:j]
+ lval.token = l.token
+ return tokNumber
+ default:
+ return '.'
+ }
+ case '$':
+ if isIdent(l.peek(), false) {
+ i := l.offset - 1
+ j, isModule := l.scanIdentOrModule()
+ l.token = l.source[i:j]
+ lval.token = l.token
+ if isModule {
+ return tokModuleVariable
+ }
+ return tokVariable
+ }
+ case '|':
+ if l.peek() == '=' {
+ l.offset++
+ l.token = "|="
+ lval.operator = OpModify
+ return tokUpdateOp
+ }
+ case '?':
+ if l.peek() == '/' {
+ l.offset++
+ if l.peek() == '/' {
+ l.offset++
+ l.token = "?//"
+ return tokDestAltOp
+ }
+ l.offset--
+ }
+ case '+':
+ if l.peek() == '=' {
+ l.offset++
+ l.token = "+="
+ lval.operator = OpUpdateAdd
+ return tokUpdateOp
+ }
+ case '-':
+ if l.peek() == '=' {
+ l.offset++
+ l.token = "-="
+ lval.operator = OpUpdateSub
+ return tokUpdateOp
+ }
+ case '*':
+ if l.peek() == '=' {
+ l.offset++
+ l.token = "*="
+ lval.operator = OpUpdateMul
+ return tokUpdateOp
+ }
+ case '/':
+ switch l.peek() {
+ case '=':
+ l.offset++
+ l.token = "/="
+ lval.operator = OpUpdateDiv
+ return tokUpdateOp
+ case '/':
+ l.offset++
+ if l.peek() == '=' {
+ l.offset++
+ l.token = "//="
+ lval.operator = OpUpdateAlt
+ return tokUpdateOp
+ }
+ l.token = "//"
+ lval.operator = OpAlt
+ return tokAltOp
+ }
+ case '%':
+ if l.peek() == '=' {
+ l.offset++
+ l.token = "%="
+ lval.operator = OpUpdateMod
+ return tokUpdateOp
+ }
+ case '=':
+ if l.peek() == '=' {
+ l.offset++
+ l.token = "=="
+ lval.operator = OpEq
+ return tokCompareOp
+ }
+ l.token = "="
+ lval.operator = OpAssign
+ return tokUpdateOp
+ case '!':
+ if l.peek() == '=' {
+ l.offset++
+ l.token = "!="
+ lval.operator = OpNe
+ return tokCompareOp
+ }
+ case '>':
+ if l.peek() == '=' {
+ l.offset++
+ l.token = ">="
+ lval.operator = OpGe
+ return tokCompareOp
+ }
+ l.token = ">"
+ lval.operator = OpGt
+ return tokCompareOp
+ case '<':
+ if l.peek() == '=' {
+ l.offset++
+ l.token = "<="
+ lval.operator = OpLe
+ return tokCompareOp
+ }
+ l.token = "<"
+ lval.operator = OpLt
+ return tokCompareOp
+ case '@':
+ if isIdent(l.peek(), true) {
+ l.token = l.source[l.offset-1 : l.scanIdent()]
+ lval.token = l.token
+ return tokFormat
+ }
+ case '"':
+ tok, str := l.scanString(l.offset - 1)
+ lval.token = str
+ return tok
+ default:
+ if ch >= utf8.RuneSelf {
+ r, size := utf8.DecodeRuneInString(l.source[l.offset-1:])
+ l.offset += size
+ l.token = string(r)
+ }
+ }
+ return int(ch)
+}
+
+func (l *lexer) next() (byte, bool) {
+ for {
+ ch := l.source[l.offset]
+ l.offset++
+ if ch == '#' {
+ if l.skipComment() {
+ return 0, true
+ }
+ } else if !isWhite(ch) {
+ return ch, false
+ } else if len(l.source) == l.offset {
+ return 0, true
+ }
+ }
+}
+
+func (l *lexer) skipComment() bool {
+ for {
+ switch l.peek() {
+ case 0:
+ return true
+ case '\\':
+ switch l.offset++; l.peek() {
+ case '\\', '\n':
+ l.offset++
+ case '\r':
+ if l.offset++; l.peek() == '\n' {
+ l.offset++
+ }
+ }
+ case '\n', '\r':
+ return false
+ default:
+ l.offset++
+ }
+ }
+}
+
+func (l *lexer) peek() byte {
+ if len(l.source) == l.offset {
+ return 0
+ }
+ return l.source[l.offset]
+}
+
+func (l *lexer) scanIdent() int {
+ for isIdent(l.peek(), true) {
+ l.offset++
+ }
+ return l.offset
+}
+
+func (l *lexer) scanIdentOrModule() (int, bool) {
+ index := l.scanIdent()
+ var isModule bool
+ if l.peek() == ':' {
+ l.offset++
+ if l.peek() == ':' {
+ l.offset++
+ if isIdent(l.peek(), false) {
+ l.offset++
+ index = l.scanIdent()
+ isModule = true
+ } else {
+ l.offset -= 2
+ }
+ } else {
+ l.offset--
+ }
+ }
+ return index, isModule
+}
+
+func (l *lexer) validVarName() bool {
+ if l.peek() != '$' {
+ return false
+ }
+ l.offset++
+ return isIdent(l.peek(), false) && l.scanIdent() == len(l.source)
+}
+
+const (
+ numberStateLead = iota
+ numberStateFloat
+ numberStateExpLead
+ numberStateExp
+)
+
+func (l *lexer) scanNumber(state int) int {
+ for {
+ switch state {
+ case numberStateLead, numberStateFloat:
+ if ch := l.peek(); isNumber(ch) {
+ l.offset++
+ } else {
+ switch ch {
+ case '.':
+ if state != numberStateLead {
+ l.offset++
+ return -l.offset
+ }
+ l.offset++
+ state = numberStateFloat
+ case 'e', 'E':
+ l.offset++
+ switch l.peek() {
+ case '-', '+':
+ l.offset++
+ }
+ state = numberStateExpLead
+ default:
+ if isIdent(ch, false) {
+ l.offset++
+ return -l.offset
+ }
+ return l.offset
+ }
+ }
+ case numberStateExpLead, numberStateExp:
+ if ch := l.peek(); !isNumber(ch) {
+ if isIdent(ch, false) {
+ l.offset++
+ return -l.offset
+ }
+ if state == numberStateExpLead {
+ return -l.offset
+ }
+ return l.offset
+ }
+ l.offset++
+ state = numberStateExp
+ default:
+ panic(state)
+ }
+ }
+}
+
+func (l *lexer) validNumber() bool {
+ ch := l.peek()
+ switch ch {
+ case '+', '-':
+ l.offset++
+ ch = l.peek()
+ }
+ state := numberStateLead
+ if ch == '.' {
+ l.offset++
+ ch = l.peek()
+ state = numberStateFloat
+ }
+ return isNumber(ch) && l.scanNumber(state) == len(l.source)
+}
+
+func (l *lexer) scanString(start int) (int, string) {
+ var decode bool
+ var controls int
+ unquote := func(src string, quote bool) (string, error) {
+ if !decode {
+ if quote {
+ return src, nil
+ }
+ return src[1 : len(src)-1], nil
+ }
+ var buf []byte
+ if !quote && controls == 0 {
+ buf = []byte(src)
+ } else {
+ buf = quoteAndEscape(src, quote, controls)
+ }
+ if err := json.Unmarshal(buf, &src); err != nil {
+ return "", err
+ }
+ return src, nil
+ }
+ for i := l.offset; i < len(l.source); i++ {
+ ch := l.source[i]
+ switch ch {
+ case '\\':
+ if i++; i >= len(l.source) {
+ break
+ }
+ switch l.source[i] {
+ case 'u':
+ for j := 1; j <= 4; j++ {
+ if i+j >= len(l.source) || !isHex(l.source[i+j]) {
+ l.offset = i + j
+ l.token = l.source[i-1 : l.offset]
+ return tokInvalidEscapeSequence, ""
+ }
+ }
+ i += 4
+ fallthrough
+ case '"', '/', '\\', 'b', 'f', 'n', 'r', 't':
+ decode = true
+ case '(':
+ if !l.inString {
+ l.inString = true
+ return tokStringStart, ""
+ }
+ if i == l.offset+1 {
+ l.offset += 2
+ l.inString = false
+ return tokStringQuery, ""
+ }
+ l.offset = i - 1
+ l.token = l.source[start:l.offset]
+ str, err := unquote(l.token, true)
+ if err != nil {
+ return tokInvalid, ""
+ }
+ return tokString, str
+ default:
+ l.offset = i + 1
+ l.token = l.source[l.offset-2 : l.offset]
+ return tokInvalidEscapeSequence, ""
+ }
+ case '"':
+ if !l.inString {
+ l.offset = i + 1
+ l.token = l.source[start:l.offset]
+ str, err := unquote(l.token, false)
+ if err != nil {
+ return tokInvalid, ""
+ }
+ return tokString, str
+ }
+ if i > l.offset {
+ l.offset = i
+ l.token = l.source[start:l.offset]
+ str, err := unquote(l.token, true)
+ if err != nil {
+ return tokInvalid, ""
+ }
+ return tokString, str
+ }
+ l.inString = false
+ l.offset = i + 1
+ return tokStringEnd, ""
+ default:
+ if !decode {
+ decode = ch > '~'
+ }
+ if ch < ' ' { // ref: unquoteBytes in encoding/json
+ controls++
+ }
+ }
+ }
+ l.offset = len(l.source)
+ l.token = ""
+ return tokUnterminatedString, ""
+}
+
+func quoteAndEscape(src string, quote bool, controls int) []byte {
+ size := len(src) + controls*5
+ if quote {
+ size += 2
+ }
+ buf := make([]byte, size)
+ var j int
+ if quote {
+ buf[0] = '"'
+ buf[len(buf)-1] = '"'
+ j++
+ }
+ for i := 0; i < len(src); i++ {
+ if ch := src[i]; ch < ' ' {
+ const hex = "0123456789abcdef"
+ copy(buf[j:], `\u00`)
+ buf[j+4] = hex[ch>>4]
+ buf[j+5] = hex[ch&0xF]
+ j += 6
+ } else {
+ buf[j] = ch
+ j++
+ }
+ }
+ return buf
+}
+
+// ParseError represents a description of a query parsing error.
+type ParseError struct {
+ Offset int // the error occurred after reading Offset bytes
+ Token string // the Token that caused the error (may be empty)
+ tokenType int
+}
+
+func (err *ParseError) Error() string {
+ switch err.tokenType {
+ case eof:
+ return "unexpected EOF"
+ case tokInvalid:
+ return "invalid token " + jsonMarshal(err.Token)
+ case tokInvalidEscapeSequence:
+ return `invalid escape sequence "` + err.Token + `" in string literal`
+ case tokUnterminatedString:
+ return "unterminated string literal"
+ default:
+ return "unexpected token " + jsonMarshal(err.Token)
+ }
+}
+
+func (l *lexer) Error(string) {
+ offset, token := l.offset, l.token
+ if l.tokenType != eof && l.tokenType < utf8.RuneSelf {
+ token = string(rune(l.tokenType))
+ }
+ l.err = &ParseError{offset, token, l.tokenType}
+}
+
+func isWhite(ch byte) bool {
+ switch ch {
+ case '\t', '\n', '\r', ' ':
+ return true
+ default:
+ return false
+ }
+}
+
+func isIdent(ch byte, tail bool) bool {
+ return 'a' <= ch && ch <= 'z' ||
+ 'A' <= ch && ch <= 'Z' || ch == '_' ||
+ tail && isNumber(ch)
+}
+
+func isHex(ch byte) bool {
+ return 'a' <= ch && ch <= 'f' ||
+ 'A' <= ch && ch <= 'F' ||
+ isNumber(ch)
+}
+
+func isNumber(ch byte) bool {
+ return '0' <= ch && ch <= '9'
+}
diff --git a/vendor/github.com/itchyny/gojq/module_loader.go b/vendor/github.com/itchyny/gojq/module_loader.go
new file mode 100644
index 000000000..0a73ba05b
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/module_loader.go
@@ -0,0 +1,182 @@
+package gojq
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "os"
+ "path/filepath"
+ "strings"
+)
+
+// ModuleLoader is the interface for loading modules.
+//
+// Implement following optional methods. Use [NewModuleLoader] to load local modules.
+//
+// LoadInitModules() ([]*Query, error)
+// LoadModule(string) (*Query, error)
+// LoadModuleWithMeta(string, map[string]any) (*Query, error)
+// LoadJSON(string) (any, error)
+// LoadJSONWithMeta(string, map[string]any) (any, error)
+type ModuleLoader any
+
+// NewModuleLoader creates a new [ModuleLoader] loading local modules in the paths.
+// Note that user can load modules outside the paths using "search" path of metadata.
+// Empty paths are ignored, so specify "." for the current working directory.
+func NewModuleLoader(paths []string) ModuleLoader {
+ ps := make([]string, 0, len(paths))
+ for _, path := range paths {
+ if path = resolvePath(path, ""); path != "" {
+ ps = append(ps, path)
+ }
+ }
+ return &moduleLoader{ps}
+}
+
+type moduleLoader struct {
+ paths []string
+}
+
+func (l *moduleLoader) LoadInitModules() ([]*Query, error) {
+ var qs []*Query
+ for _, path := range l.paths {
+ if filepath.Base(path) != ".jq" {
+ continue
+ }
+ fi, err := os.Stat(path)
+ if err != nil {
+ if os.IsNotExist(err) {
+ continue
+ }
+ return nil, err
+ }
+ if fi.IsDir() {
+ continue
+ }
+ cnt, err := os.ReadFile(path)
+ if err != nil {
+ return nil, err
+ }
+ q, err := parseModule(string(cnt), filepath.Dir(path))
+ if err != nil {
+ return nil, &queryParseError{path, string(cnt), err}
+ }
+ qs = append(qs, q)
+ }
+ return qs, nil
+}
+
+func (l *moduleLoader) LoadModuleWithMeta(name string, meta map[string]any) (*Query, error) {
+ path, err := l.lookupModule(name, ".jq", meta)
+ if err != nil {
+ return nil, err
+ }
+ cnt, err := os.ReadFile(path)
+ if err != nil {
+ return nil, err
+ }
+ q, err := parseModule(string(cnt), filepath.Dir(path))
+ if err != nil {
+ return nil, &queryParseError{path, string(cnt), err}
+ }
+ return q, nil
+}
+
+func (l *moduleLoader) LoadJSONWithMeta(name string, meta map[string]any) (any, error) {
+ path, err := l.lookupModule(name, ".json", meta)
+ if err != nil {
+ return nil, err
+ }
+ f, err := os.Open(path)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+ vals := []any{}
+ dec := json.NewDecoder(f)
+ dec.UseNumber()
+ for {
+ var val any
+ if err := dec.Decode(&val); err != nil {
+ if err == io.EOF {
+ break
+ }
+ if _, err := f.Seek(0, io.SeekStart); err != nil {
+ return nil, err
+ }
+ cnt, er := io.ReadAll(f)
+ if er != nil {
+ return nil, er
+ }
+ return nil, &jsonParseError{path, string(cnt), err}
+ }
+ vals = append(vals, val)
+ }
+ return vals, nil
+}
+
+func (l *moduleLoader) lookupModule(name, extension string, meta map[string]any) (string, error) {
+ paths := l.paths
+ if path, ok := meta["search"].(string); ok {
+ paths = append([]string{path}, paths...)
+ }
+ for _, base := range paths {
+ path := filepath.Join(base, name+extension)
+ if _, err := os.Stat(path); err == nil {
+ return path, err
+ }
+ path = filepath.Join(base, name, filepath.Base(name)+extension)
+ if _, err := os.Stat(path); err == nil {
+ return path, err
+ }
+ }
+ return "", fmt.Errorf("module not found: %q", name)
+}
+
+func parseModule(cnt, dir string) (*Query, error) {
+ q, err := Parse(cnt)
+ if err != nil {
+ return nil, err
+ }
+ for _, i := range q.Imports {
+ if i.Meta != nil {
+ for _, e := range i.Meta.KeyVals {
+ if e.Key == "search" || e.KeyString == "search" {
+ if path, ok := e.Val.toString(); ok {
+ if path = resolvePath(path, dir); path != "" {
+ e.Val.Str = path
+ } else {
+ e.Val.Null = true
+ }
+ }
+ }
+ }
+ }
+ }
+ return q, nil
+}
+
+func resolvePath(path, dir string) string {
+ switch {
+ case filepath.IsAbs(path):
+ return path
+ case strings.HasPrefix(path, "~/"):
+ dir, err := os.UserHomeDir()
+ if err != nil {
+ return ""
+ }
+ return filepath.Join(dir, path[2:])
+ case strings.HasPrefix(path, "$ORIGIN/"):
+ exe, err := os.Executable()
+ if err != nil {
+ return ""
+ }
+ exe, err = filepath.EvalSymlinks(exe)
+ if err != nil {
+ return ""
+ }
+ return filepath.Join(filepath.Dir(exe), path[8:])
+ default:
+ return filepath.Join(dir, path)
+ }
+}
diff --git a/vendor/github.com/itchyny/gojq/normalize.go b/vendor/github.com/itchyny/gojq/normalize.go
new file mode 100644
index 000000000..2bfcd2156
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/normalize.go
@@ -0,0 +1,84 @@
+package gojq
+
+import (
+ "encoding/json"
+ "math"
+ "math/big"
+ "strings"
+)
+
+func normalizeNumber(v json.Number) any {
+ if i, err := v.Int64(); err == nil && math.MinInt <= i && i <= math.MaxInt {
+ return int(i)
+ }
+ if strings.ContainsAny(v.String(), ".eE") {
+ if f, err := v.Float64(); err == nil {
+ return f
+ }
+ }
+ if bi, ok := new(big.Int).SetString(v.String(), 10); ok {
+ return bi
+ }
+ if strings.HasPrefix(v.String(), "-") {
+ return math.Inf(-1)
+ }
+ return math.Inf(1)
+}
+
+func normalizeNumbers(v any) any {
+ switch v := v.(type) {
+ case json.Number:
+ return normalizeNumber(v)
+ case *big.Int:
+ if v.IsInt64() {
+ if i := v.Int64(); math.MinInt <= i && i <= math.MaxInt {
+ return int(i)
+ }
+ }
+ return v
+ case int64:
+ if math.MinInt <= v && v <= math.MaxInt {
+ return int(v)
+ }
+ return big.NewInt(v)
+ case int32:
+ return int(v)
+ case int16:
+ return int(v)
+ case int8:
+ return int(v)
+ case uint:
+ if v <= math.MaxInt {
+ return int(v)
+ }
+ return new(big.Int).SetUint64(uint64(v))
+ case uint64:
+ if v <= math.MaxInt {
+ return int(v)
+ }
+ return new(big.Int).SetUint64(v)
+ case uint32:
+ if uint64(v) <= math.MaxInt {
+ return int(v)
+ }
+ return new(big.Int).SetUint64(uint64(v))
+ case uint16:
+ return int(v)
+ case uint8:
+ return int(v)
+ case float32:
+ return float64(v)
+ case []any:
+ for i, x := range v {
+ v[i] = normalizeNumbers(x)
+ }
+ return v
+ case map[string]any:
+ for k, x := range v {
+ v[k] = normalizeNumbers(x)
+ }
+ return v
+ default:
+ return v
+ }
+}
diff --git a/vendor/github.com/itchyny/gojq/operator.go b/vendor/github.com/itchyny/gojq/operator.go
new file mode 100644
index 000000000..513dbfadc
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/operator.go
@@ -0,0 +1,549 @@
+package gojq
+
+import (
+ "math"
+ "math/big"
+ "strings"
+)
+
+// Operator ...
+type Operator int
+
+// Operators ...
+const (
+ OpPipe Operator = iota + 1
+ OpComma
+ OpAdd
+ OpSub
+ OpMul
+ OpDiv
+ OpMod
+ OpEq
+ OpNe
+ OpGt
+ OpLt
+ OpGe
+ OpLe
+ OpAnd
+ OpOr
+ OpAlt
+ OpAssign
+ OpModify
+ OpUpdateAdd
+ OpUpdateSub
+ OpUpdateMul
+ OpUpdateDiv
+ OpUpdateMod
+ OpUpdateAlt
+)
+
+// String implements [fmt.Stringer].
+func (op Operator) String() string {
+ switch op {
+ case OpPipe:
+ return "|"
+ case OpComma:
+ return ","
+ case OpAdd:
+ return "+"
+ case OpSub:
+ return "-"
+ case OpMul:
+ return "*"
+ case OpDiv:
+ return "/"
+ case OpMod:
+ return "%"
+ case OpEq:
+ return "=="
+ case OpNe:
+ return "!="
+ case OpGt:
+ return ">"
+ case OpLt:
+ return "<"
+ case OpGe:
+ return ">="
+ case OpLe:
+ return "<="
+ case OpAnd:
+ return "and"
+ case OpOr:
+ return "or"
+ case OpAlt:
+ return "//"
+ case OpAssign:
+ return "="
+ case OpModify:
+ return "|="
+ case OpUpdateAdd:
+ return "+="
+ case OpUpdateSub:
+ return "-="
+ case OpUpdateMul:
+ return "*="
+ case OpUpdateDiv:
+ return "/="
+ case OpUpdateMod:
+ return "%="
+ case OpUpdateAlt:
+ return "//="
+ default:
+ panic(op)
+ }
+}
+
+// GoString implements [fmt.GoStringer].
+func (op Operator) GoString() (str string) {
+ defer func() { str = "gojq." + str }()
+ switch op {
+ case Operator(0):
+ return "Operator(0)"
+ case OpPipe:
+ return "OpPipe"
+ case OpComma:
+ return "OpComma"
+ case OpAdd:
+ return "OpAdd"
+ case OpSub:
+ return "OpSub"
+ case OpMul:
+ return "OpMul"
+ case OpDiv:
+ return "OpDiv"
+ case OpMod:
+ return "OpMod"
+ case OpEq:
+ return "OpEq"
+ case OpNe:
+ return "OpNe"
+ case OpGt:
+ return "OpGt"
+ case OpLt:
+ return "OpLt"
+ case OpGe:
+ return "OpGe"
+ case OpLe:
+ return "OpLe"
+ case OpAnd:
+ return "OpAnd"
+ case OpOr:
+ return "OpOr"
+ case OpAlt:
+ return "OpAlt"
+ case OpAssign:
+ return "OpAssign"
+ case OpModify:
+ return "OpModify"
+ case OpUpdateAdd:
+ return "OpUpdateAdd"
+ case OpUpdateSub:
+ return "OpUpdateSub"
+ case OpUpdateMul:
+ return "OpUpdateMul"
+ case OpUpdateDiv:
+ return "OpUpdateDiv"
+ case OpUpdateMod:
+ return "OpUpdateMod"
+ case OpUpdateAlt:
+ return "OpUpdateAlt"
+ default:
+ panic(op)
+ }
+}
+
+func (op Operator) getFunc() string {
+ switch op {
+ case OpPipe:
+ panic("unreachable")
+ case OpComma:
+ panic("unreachable")
+ case OpAdd:
+ return "_add"
+ case OpSub:
+ return "_subtract"
+ case OpMul:
+ return "_multiply"
+ case OpDiv:
+ return "_divide"
+ case OpMod:
+ return "_modulo"
+ case OpEq:
+ return "_equal"
+ case OpNe:
+ return "_notequal"
+ case OpGt:
+ return "_greater"
+ case OpLt:
+ return "_less"
+ case OpGe:
+ return "_greatereq"
+ case OpLe:
+ return "_lesseq"
+ case OpAnd:
+ panic("unreachable")
+ case OpOr:
+ panic("unreachable")
+ case OpAlt:
+ panic("unreachable")
+ case OpAssign:
+ return "_assign"
+ case OpModify:
+ return "_modify"
+ case OpUpdateAdd:
+ return "_add"
+ case OpUpdateSub:
+ return "_subtract"
+ case OpUpdateMul:
+ return "_multiply"
+ case OpUpdateDiv:
+ return "_divide"
+ case OpUpdateMod:
+ return "_modulo"
+ case OpUpdateAlt:
+ return "_alternative"
+ default:
+ panic(op)
+ }
+}
+
+func binopTypeSwitch(
+ l, r any,
+ callbackInts func(_, _ int) any,
+ callbackFloats func(_, _ float64) any,
+ callbackBigInts func(_, _ *big.Int) any,
+ callbackStrings func(_, _ string) any,
+ callbackArrays func(_, _ []any) any,
+ callbackMaps func(_, _ map[string]any) any,
+ fallback func(_, _ any) any) any {
+ switch l := l.(type) {
+ case int:
+ switch r := r.(type) {
+ case int:
+ return callbackInts(l, r)
+ case float64:
+ return callbackFloats(float64(l), r)
+ case *big.Int:
+ return callbackBigInts(big.NewInt(int64(l)), r)
+ default:
+ return fallback(l, r)
+ }
+ case float64:
+ switch r := r.(type) {
+ case int:
+ return callbackFloats(l, float64(r))
+ case float64:
+ return callbackFloats(l, r)
+ case *big.Int:
+ return callbackFloats(l, bigToFloat(r))
+ default:
+ return fallback(l, r)
+ }
+ case *big.Int:
+ switch r := r.(type) {
+ case int:
+ return callbackBigInts(l, big.NewInt(int64(r)))
+ case float64:
+ return callbackFloats(bigToFloat(l), r)
+ case *big.Int:
+ return callbackBigInts(l, r)
+ default:
+ return fallback(l, r)
+ }
+ case string:
+ switch r := r.(type) {
+ case string:
+ return callbackStrings(l, r)
+ default:
+ return fallback(l, r)
+ }
+ case []any:
+ switch r := r.(type) {
+ case []any:
+ return callbackArrays(l, r)
+ default:
+ return fallback(l, r)
+ }
+ case map[string]any:
+ switch r := r.(type) {
+ case map[string]any:
+ return callbackMaps(l, r)
+ default:
+ return fallback(l, r)
+ }
+ default:
+ return fallback(l, r)
+ }
+}
+
+func funcOpPlus(v any) any {
+ switch v := v.(type) {
+ case int:
+ return v
+ case float64:
+ return v
+ case *big.Int:
+ return v
+ default:
+ return &unaryTypeError{"plus", v}
+ }
+}
+
+func funcOpNegate(v any) any {
+ switch v := v.(type) {
+ case int:
+ return -v
+ case float64:
+ return -v
+ case *big.Int:
+ return new(big.Int).Neg(v)
+ default:
+ return &unaryTypeError{"negate", v}
+ }
+}
+
+func funcOpAdd(_, l, r any) any {
+ return binopTypeSwitch(l, r,
+ func(l, r int) any {
+ if v := l + r; (v >= l) == (r >= 0) {
+ return v
+ }
+ x, y := big.NewInt(int64(l)), big.NewInt(int64(r))
+ return x.Add(x, y)
+ },
+ func(l, r float64) any { return l + r },
+ func(l, r *big.Int) any { return new(big.Int).Add(l, r) },
+ func(l, r string) any { return l + r },
+ func(l, r []any) any {
+ if len(l) == 0 {
+ return r
+ }
+ if len(r) == 0 {
+ return l
+ }
+ v := make([]any, len(l)+len(r))
+ copy(v, l)
+ copy(v[len(l):], r)
+ return v
+ },
+ func(l, r map[string]any) any {
+ if len(l) == 0 {
+ return r
+ }
+ if len(r) == 0 {
+ return l
+ }
+ m := make(map[string]any, len(l)+len(r))
+ for k, v := range l {
+ m[k] = v
+ }
+ for k, v := range r {
+ m[k] = v
+ }
+ return m
+ },
+ func(l, r any) any {
+ if l == nil {
+ return r
+ }
+ if r == nil {
+ return l
+ }
+ return &binopTypeError{"add", l, r}
+ },
+ )
+}
+
+func funcOpSub(_, l, r any) any {
+ return binopTypeSwitch(l, r,
+ func(l, r int) any {
+ if v := l - r; (v <= l) == (r >= 0) {
+ return v
+ }
+ x, y := big.NewInt(int64(l)), big.NewInt(int64(r))
+ return x.Sub(x, y)
+ },
+ func(l, r float64) any { return l - r },
+ func(l, r *big.Int) any { return new(big.Int).Sub(l, r) },
+ func(l, r string) any { return &binopTypeError{"subtract", l, r} },
+ func(l, r []any) any {
+ v := make([]any, 0, len(l))
+ L:
+ for _, l := range l {
+ for _, r := range r {
+ if compare(l, r) == 0 {
+ continue L
+ }
+ }
+ v = append(v, l)
+ }
+ return v
+ },
+ func(l, r map[string]any) any { return &binopTypeError{"subtract", l, r} },
+ func(l, r any) any { return &binopTypeError{"subtract", l, r} },
+ )
+}
+
+func funcOpMul(_, l, r any) any {
+ return binopTypeSwitch(l, r,
+ func(l, r int) any {
+ if v := l * r; r == 0 || v/r == l {
+ return v
+ }
+ x, y := big.NewInt(int64(l)), big.NewInt(int64(r))
+ return x.Mul(x, y)
+ },
+ func(l, r float64) any { return l * r },
+ func(l, r *big.Int) any { return new(big.Int).Mul(l, r) },
+ func(l, r string) any { return &binopTypeError{"multiply", l, r} },
+ func(l, r []any) any { return &binopTypeError{"multiply", l, r} },
+ deepMergeObjects,
+ func(l, r any) any {
+ if l, ok := l.(string); ok {
+ if r, ok := toFloat(r); ok {
+ return repeatString(l, r)
+ }
+ }
+ if r, ok := r.(string); ok {
+ if l, ok := toFloat(l); ok {
+ return repeatString(r, l)
+ }
+ }
+ return &binopTypeError{"multiply", l, r}
+ },
+ )
+}
+
+func deepMergeObjects(l, r map[string]any) any {
+ m := make(map[string]any, len(l)+len(r))
+ for k, v := range l {
+ m[k] = v
+ }
+ for k, v := range r {
+ if mk, ok := m[k]; ok {
+ if mk, ok := mk.(map[string]any); ok {
+ if w, ok := v.(map[string]any); ok {
+ v = deepMergeObjects(mk, w)
+ }
+ }
+ }
+ m[k] = v
+ }
+ return m
+}
+
+func repeatString(s string, n float64) any {
+ if n < 0.0 || len(s) > 0 && n > float64(0x10000000/len(s)) || math.IsNaN(n) {
+ return nil
+ }
+ if s == "" {
+ return ""
+ }
+ return strings.Repeat(s, int(n))
+}
+
+func funcOpDiv(_, l, r any) any {
+ return binopTypeSwitch(l, r,
+ func(l, r int) any {
+ if r == 0 {
+ return &zeroDivisionError{l, r}
+ }
+ if l%r == 0 {
+ return l / r
+ }
+ return float64(l) / float64(r)
+ },
+ func(l, r float64) any {
+ if r == 0.0 {
+ return &zeroDivisionError{l, r}
+ }
+ return l / r
+ },
+ func(l, r *big.Int) any {
+ if r.Sign() == 0 {
+ return &zeroDivisionError{l, r}
+ }
+ d, m := new(big.Int).DivMod(l, r, new(big.Int))
+ if m.Sign() == 0 {
+ return d
+ }
+ return bigToFloat(l) / bigToFloat(r)
+ },
+ func(l, r string) any {
+ if l == "" {
+ return []any{}
+ }
+ xs := strings.Split(l, r)
+ vs := make([]any, len(xs))
+ for i, x := range xs {
+ vs[i] = x
+ }
+ return vs
+ },
+ func(l, r []any) any { return &binopTypeError{"divide", l, r} },
+ func(l, r map[string]any) any { return &binopTypeError{"divide", l, r} },
+ func(l, r any) any { return &binopTypeError{"divide", l, r} },
+ )
+}
+
+func funcOpMod(_, l, r any) any {
+ return binopTypeSwitch(l, r,
+ func(l, r int) any {
+ if r == 0 {
+ return &zeroModuloError{l, r}
+ }
+ return l % r
+ },
+ func(l, r float64) any {
+ ri := floatToInt(r)
+ if ri == 0 {
+ return &zeroModuloError{l, r}
+ }
+ if math.IsNaN(l) || math.IsNaN(r) {
+ return math.NaN()
+ }
+ return floatToInt(l) % ri
+ },
+ func(l, r *big.Int) any {
+ if r.Sign() == 0 {
+ return &zeroModuloError{l, r}
+ }
+ return new(big.Int).Rem(l, r)
+ },
+ func(l, r string) any { return &binopTypeError{"modulo", l, r} },
+ func(l, r []any) any { return &binopTypeError{"modulo", l, r} },
+ func(l, r map[string]any) any { return &binopTypeError{"modulo", l, r} },
+ func(l, r any) any { return &binopTypeError{"modulo", l, r} },
+ )
+}
+
+func funcOpAlt(_, l, r any) any {
+ if l == nil || l == false {
+ return r
+ }
+ return l
+}
+
+func funcOpEq(_, l, r any) any {
+ return compare(l, r) == 0
+}
+
+func funcOpNe(_, l, r any) any {
+ return compare(l, r) != 0
+}
+
+func funcOpGt(_, l, r any) any {
+ return compare(l, r) > 0
+}
+
+func funcOpLt(_, l, r any) any {
+ return compare(l, r) < 0
+}
+
+func funcOpGe(_, l, r any) any {
+ return compare(l, r) >= 0
+}
+
+func funcOpLe(_, l, r any) any {
+ return compare(l, r) <= 0
+}
diff --git a/vendor/github.com/itchyny/gojq/option.go b/vendor/github.com/itchyny/gojq/option.go
new file mode 100644
index 000000000..f1a110fae
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/option.go
@@ -0,0 +1,96 @@
+package gojq
+
+import "fmt"
+
+// CompilerOption is a compiler option.
+type CompilerOption func(*compiler)
+
+// WithModuleLoader is a compiler option for module loader.
+// If you want to load modules from the filesystem, use [NewModuleLoader].
+func WithModuleLoader(moduleLoader ModuleLoader) CompilerOption {
+ return func(c *compiler) {
+ c.moduleLoader = moduleLoader
+ }
+}
+
+// WithEnvironLoader is a compiler option for environment variables loader.
+// The OS environment variables are not accessible by default due to security
+// reasons. You can specify [os.Environ] as argument if you allow to access.
+func WithEnvironLoader(environLoader func() []string) CompilerOption {
+ return func(c *compiler) {
+ c.environLoader = environLoader
+ }
+}
+
+// WithVariables is a compiler option for variable names. The variables can be
+// used in the query. You have to give the values to [*Code.Run] in the same order.
+func WithVariables(variables []string) CompilerOption {
+ return func(c *compiler) {
+ c.variables = variables
+ }
+}
+
+// WithFunction is a compiler option for adding a custom internal function.
+// Specify the minimum and maximum count of the function arguments. These
+// values should satisfy 0 <= minarity <= maxarity <= 30, otherwise panics.
+// On handling numbers, you should take account to int, float64 and *big.Int.
+// These are the number types you are allowed to return, so do not return int64.
+// Refer to [ValueError] to return a value error just like built-in error
+// function. If you want to emit multiple values, call the empty function,
+// accept a filter for its argument, or call another built-in function, then
+// use LoadInitModules of the module loader.
+func WithFunction(name string, minarity, maxarity int, f func(any, []any) any) CompilerOption {
+ return withFunction(name, minarity, maxarity, false, f)
+}
+
+// WithIterFunction is a compiler option for adding a custom iterator function.
+// This is like the [WithFunction] option, but you can add a function which
+// returns an Iter to emit multiple values. You cannot define both iterator and
+// non-iterator functions of the same name (with possibly different arities).
+// See also [NewIter], which can be used to convert values or an error to an Iter.
+func WithIterFunction(name string, minarity, maxarity int, f func(any, []any) Iter) CompilerOption {
+ return withFunction(name, minarity, maxarity, true,
+ func(v any, args []any) any {
+ return f(v, args)
+ },
+ )
+}
+
+func withFunction(name string, minarity, maxarity int, iter bool, f func(any, []any) any) CompilerOption {
+ if !(0 <= minarity && minarity <= maxarity && maxarity <= 30) {
+ panic(fmt.Sprintf("invalid arity for %q: %d, %d", name, minarity, maxarity))
+ }
+ argcount := 1<<(maxarity+1) - 1<= 1 && c-1 < len(yyToknames) {
+ if yyToknames[c-1] != "" {
+ return yyToknames[c-1]
+ }
+ }
+ return __yyfmt__.Sprintf("tok-%v", c)
+}
+
+func yyStatname(s int) string {
+ if s >= 0 && s < len(yyStatenames) {
+ if yyStatenames[s] != "" {
+ return yyStatenames[s]
+ }
+ }
+ return __yyfmt__.Sprintf("state-%v", s)
+}
+
+func yyErrorMessage(state, lookAhead int) string {
+ const TOKSTART = 4
+
+ if !yyErrorVerbose {
+ return "syntax error"
+ }
+
+ for _, e := range yyErrorMessages {
+ if e.state == state && e.token == lookAhead {
+ return "syntax error: " + e.msg
+ }
+ }
+
+ res := "syntax error: unexpected " + yyTokname(lookAhead)
+
+ // To match Bison, suggest at most four expected tokens.
+ expected := make([]int, 0, 4)
+
+ // Look for shiftable tokens.
+ base := int(yyPact[state])
+ for tok := TOKSTART; tok-1 < len(yyToknames); tok++ {
+ if n := base + tok; n >= 0 && n < yyLast && int(yyChk[int(yyAct[n])]) == tok {
+ if len(expected) == cap(expected) {
+ return res
+ }
+ expected = append(expected, tok)
+ }
+ }
+
+ if yyDef[state] == -2 {
+ i := 0
+ for yyExca[i] != -1 || int(yyExca[i+1]) != state {
+ i += 2
+ }
+
+ // Look for tokens that we accept or reduce.
+ for i += 2; yyExca[i] >= 0; i += 2 {
+ tok := int(yyExca[i])
+ if tok < TOKSTART || yyExca[i+1] == 0 {
+ continue
+ }
+ if len(expected) == cap(expected) {
+ return res
+ }
+ expected = append(expected, tok)
+ }
+
+ // If the default action is to accept or reduce, give up.
+ if yyExca[i+1] != 0 {
+ return res
+ }
+ }
+
+ for i, tok := range expected {
+ if i == 0 {
+ res += ", expecting "
+ } else {
+ res += " or "
+ }
+ res += yyTokname(tok)
+ }
+ return res
+}
+
+func yylex1(lex yyLexer, lval *yySymType) (char, token int) {
+ token = 0
+ char = lex.Lex(lval)
+ if char <= 0 {
+ token = int(yyTok1[0])
+ goto out
+ }
+ if char < len(yyTok1) {
+ token = int(yyTok1[char])
+ goto out
+ }
+ if char >= yyPrivate {
+ if char < yyPrivate+len(yyTok2) {
+ token = int(yyTok2[char-yyPrivate])
+ goto out
+ }
+ }
+ for i := 0; i < len(yyTok3); i += 2 {
+ token = int(yyTok3[i+0])
+ if token == char {
+ token = int(yyTok3[i+1])
+ goto out
+ }
+ }
+
+out:
+ if token == 0 {
+ token = int(yyTok2[1]) /* unknown char */
+ }
+ if yyDebug >= 3 {
+ __yyfmt__.Printf("lex %s(%d)\n", yyTokname(token), uint(char))
+ }
+ return char, token
+}
+
+func yyParse(yylex yyLexer) int {
+ return yyNewParser().Parse(yylex)
+}
+
+func (yyrcvr *yyParserImpl) Parse(yylex yyLexer) int {
+ var yyn int
+ var yyVAL yySymType
+ var yyDollar []yySymType
+ _ = yyDollar // silence set and not used
+ yyS := yyrcvr.stack[:]
+
+ Nerrs := 0 /* number of errors */
+ Errflag := 0 /* error recovery flag */
+ yystate := 0
+ yyrcvr.char = -1
+ yytoken := -1 // yyrcvr.char translated into internal numbering
+ defer func() {
+ // Make sure we report no lookahead when not parsing.
+ yystate = -1
+ yyrcvr.char = -1
+ yytoken = -1
+ }()
+ yyp := -1
+ goto yystack
+
+ret0:
+ return 0
+
+ret1:
+ return 1
+
+yystack:
+ /* put a state and value onto the stack */
+ if yyDebug >= 4 {
+ __yyfmt__.Printf("char %v in %v\n", yyTokname(yytoken), yyStatname(yystate))
+ }
+
+ yyp++
+ if yyp >= len(yyS) {
+ nyys := make([]yySymType, len(yyS)*2)
+ copy(nyys, yyS)
+ yyS = nyys
+ }
+ yyS[yyp] = yyVAL
+ yyS[yyp].yys = yystate
+
+yynewstate:
+ yyn = int(yyPact[yystate])
+ if yyn <= yyFlag {
+ goto yydefault /* simple state */
+ }
+ if yyrcvr.char < 0 {
+ yyrcvr.char, yytoken = yylex1(yylex, &yyrcvr.lval)
+ }
+ yyn += yytoken
+ if yyn < 0 || yyn >= yyLast {
+ goto yydefault
+ }
+ yyn = int(yyAct[yyn])
+ if int(yyChk[yyn]) == yytoken { /* valid shift */
+ yyrcvr.char = -1
+ yytoken = -1
+ yyVAL = yyrcvr.lval
+ yystate = yyn
+ if Errflag > 0 {
+ Errflag--
+ }
+ goto yystack
+ }
+
+yydefault:
+ /* default state action */
+ yyn = int(yyDef[yystate])
+ if yyn == -2 {
+ if yyrcvr.char < 0 {
+ yyrcvr.char, yytoken = yylex1(yylex, &yyrcvr.lval)
+ }
+
+ /* look through exception table */
+ xi := 0
+ for {
+ if yyExca[xi+0] == -1 && int(yyExca[xi+1]) == yystate {
+ break
+ }
+ xi += 2
+ }
+ for xi += 2; ; xi += 2 {
+ yyn = int(yyExca[xi+0])
+ if yyn < 0 || yyn == yytoken {
+ break
+ }
+ }
+ yyn = int(yyExca[xi+1])
+ if yyn < 0 {
+ goto ret0
+ }
+ }
+ if yyn == 0 {
+ /* error ... attempt to resume parsing */
+ switch Errflag {
+ case 0: /* brand new error */
+ yylex.Error(yyErrorMessage(yystate, yytoken))
+ Nerrs++
+ if yyDebug >= 1 {
+ __yyfmt__.Printf("%s", yyStatname(yystate))
+ __yyfmt__.Printf(" saw %s\n", yyTokname(yytoken))
+ }
+ fallthrough
+
+ case 1, 2: /* incompletely recovered error ... try again */
+ Errflag = 3
+
+ /* find a state where "error" is a legal shift action */
+ for yyp >= 0 {
+ yyn = int(yyPact[yyS[yyp].yys]) + yyErrCode
+ if yyn >= 0 && yyn < yyLast {
+ yystate = int(yyAct[yyn]) /* simulate a shift of "error" */
+ if int(yyChk[yystate]) == yyErrCode {
+ goto yystack
+ }
+ }
+
+ /* the current p has no shift on "error", pop stack */
+ if yyDebug >= 2 {
+ __yyfmt__.Printf("error recovery pops state %d\n", yyS[yyp].yys)
+ }
+ yyp--
+ }
+ /* there is no state on the stack with an error shift ... abort */
+ goto ret1
+
+ case 3: /* no shift yet; clobber input char */
+ if yyDebug >= 2 {
+ __yyfmt__.Printf("error recovery discards %s\n", yyTokname(yytoken))
+ }
+ if yytoken == yyEofCode {
+ goto ret1
+ }
+ yyrcvr.char = -1
+ yytoken = -1
+ goto yynewstate /* try again in the same state */
+ }
+ }
+
+ /* reduction by production yyn */
+ if yyDebug >= 2 {
+ __yyfmt__.Printf("reduce %v in:\n\t%v\n", yyn, yyStatname(yystate))
+ }
+
+ yynt := yyn
+ yypt := yyp
+ _ = yypt // guard against "declared and not used"
+
+ yyp -= int(yyR2[yyn])
+ // yyp is now the index of $0. Perform the default action. Iff the
+ // reduced production is ε, $1 is possibly out of range.
+ if yyp+1 >= len(yyS) {
+ nyys := make([]yySymType, len(yyS)*2)
+ copy(nyys, yyS)
+ yyS = nyys
+ }
+ yyVAL = yyS[yyp+1]
+
+ /* consult goto table to find next state */
+ yyn = int(yyR1[yyn])
+ yyg := int(yyPgo[yyn])
+ yyj := yyg + yyS[yyp].yys + 1
+
+ if yyj >= yyLast {
+ yystate = int(yyAct[yyg])
+ } else {
+ yystate = int(yyAct[yyj])
+ if int(yyChk[yystate]) != -yyn {
+ yystate = int(yyAct[yyg])
+ }
+ }
+ // dummy call; replaced with literal code
+ switch yynt {
+
+ case 1:
+ yyDollar = yyS[yypt-2 : yypt+1]
+//line parser.go.y:59
+ {
+ if yyDollar[1].value != nil {
+ yyDollar[2].value.(*Query).Meta = yyDollar[1].value.(*ConstObject)
+ }
+ yylex.(*lexer).result = yyDollar[2].value.(*Query)
+ }
+ case 2:
+ yyDollar = yyS[yypt-0 : yypt+1]
+//line parser.go.y:66
+ {
+ yyVAL.value = nil
+ }
+ case 3:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:70
+ {
+ yyVAL.value = yyDollar[2].value
+ }
+ case 4:
+ yyDollar = yyS[yypt-2 : yypt+1]
+//line parser.go.y:76
+ {
+ yyVAL.value = &Query{Imports: yyDollar[1].value.([]*Import), FuncDefs: reverseFuncDef(yyDollar[2].value.([]*FuncDef)), Term: &Term{Type: TermTypeIdentity}}
+ }
+ case 5:
+ yyDollar = yyS[yypt-2 : yypt+1]
+//line parser.go.y:80
+ {
+ if yyDollar[1].value != nil {
+ yyDollar[2].value.(*Query).Imports = yyDollar[1].value.([]*Import)
+ }
+ yyVAL.value = yyDollar[2].value
+ }
+ case 6:
+ yyDollar = yyS[yypt-0 : yypt+1]
+//line parser.go.y:87
+ {
+ yyVAL.value = []*Import(nil)
+ }
+ case 7:
+ yyDollar = yyS[yypt-2 : yypt+1]
+//line parser.go.y:91
+ {
+ yyVAL.value = append(yyDollar[1].value.([]*Import), yyDollar[2].value.(*Import))
+ }
+ case 8:
+ yyDollar = yyS[yypt-6 : yypt+1]
+//line parser.go.y:97
+ {
+ yyVAL.value = &Import{ImportPath: yyDollar[2].token, ImportAlias: yyDollar[4].token, Meta: yyDollar[5].value.(*ConstObject)}
+ }
+ case 9:
+ yyDollar = yyS[yypt-4 : yypt+1]
+//line parser.go.y:101
+ {
+ yyVAL.value = &Import{IncludePath: yyDollar[2].token, Meta: yyDollar[3].value.(*ConstObject)}
+ }
+ case 10:
+ yyDollar = yyS[yypt-0 : yypt+1]
+//line parser.go.y:107
+ {
+ yyVAL.value = (*ConstObject)(nil)
+ }
+ case 11:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:110
+ {
+ }
+ case 12:
+ yyDollar = yyS[yypt-0 : yypt+1]
+//line parser.go.y:114
+ {
+ yyVAL.value = []*FuncDef(nil)
+ }
+ case 13:
+ yyDollar = yyS[yypt-2 : yypt+1]
+//line parser.go.y:118
+ {
+ yyVAL.value = append(yyDollar[2].value.([]*FuncDef), yyDollar[1].value.(*FuncDef))
+ }
+ case 14:
+ yyDollar = yyS[yypt-5 : yypt+1]
+//line parser.go.y:124
+ {
+ yyVAL.value = &FuncDef{Name: yyDollar[2].token, Body: yyDollar[4].value.(*Query)}
+ }
+ case 15:
+ yyDollar = yyS[yypt-8 : yypt+1]
+//line parser.go.y:128
+ {
+ yyVAL.value = &FuncDef{yyDollar[2].token, yyDollar[4].value.([]string), yyDollar[7].value.(*Query)}
+ }
+ case 16:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:134
+ {
+ yyVAL.value = []string{yyDollar[1].token}
+ }
+ case 17:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:138
+ {
+ yyVAL.value = append(yyDollar[1].value.([]string), yyDollar[3].token)
+ }
+ case 18:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:143
+ {
+ }
+ case 19:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:144
+ {
+ }
+ case 20:
+ yyDollar = yyS[yypt-2 : yypt+1]
+//line parser.go.y:148
+ {
+ yyDollar[2].value.(*Query).FuncDefs = prependFuncDef(yyDollar[2].value.(*Query).FuncDefs, yyDollar[1].value.(*FuncDef))
+ yyVAL.value = yyDollar[2].value
+ }
+ case 21:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:153
+ {
+ yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpPipe, Right: yyDollar[3].value.(*Query)}
+ }
+ case 22:
+ yyDollar = yyS[yypt-5 : yypt+1]
+//line parser.go.y:157
+ {
+ yyDollar[1].value.(*Term).SuffixList = append(yyDollar[1].value.(*Term).SuffixList, &Suffix{Bind: &Bind{yyDollar[3].value.([]*Pattern), yyDollar[5].value.(*Query)}})
+ yyVAL.value = &Query{Term: yyDollar[1].value.(*Term)}
+ }
+ case 23:
+ yyDollar = yyS[yypt-4 : yypt+1]
+//line parser.go.y:162
+ {
+ yyVAL.value = &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{yyDollar[2].token, yyDollar[4].value.(*Query)}}}
+ }
+ case 24:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:166
+ {
+ yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpComma, Right: yyDollar[3].value.(*Query)}
+ }
+ case 25:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:170
+ {
+ yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: yyDollar[2].operator, Right: yyDollar[3].value.(*Query)}
+ }
+ case 26:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:174
+ {
+ yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: yyDollar[2].operator, Right: yyDollar[3].value.(*Query)}
+ }
+ case 27:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:178
+ {
+ yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpOr, Right: yyDollar[3].value.(*Query)}
+ }
+ case 28:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:182
+ {
+ yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpAnd, Right: yyDollar[3].value.(*Query)}
+ }
+ case 29:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:186
+ {
+ yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: yyDollar[2].operator, Right: yyDollar[3].value.(*Query)}
+ }
+ case 30:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:190
+ {
+ yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpAdd, Right: yyDollar[3].value.(*Query)}
+ }
+ case 31:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:194
+ {
+ yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpSub, Right: yyDollar[3].value.(*Query)}
+ }
+ case 32:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:198
+ {
+ yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpMul, Right: yyDollar[3].value.(*Query)}
+ }
+ case 33:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:202
+ {
+ yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpDiv, Right: yyDollar[3].value.(*Query)}
+ }
+ case 34:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:206
+ {
+ yyVAL.value = &Query{Left: yyDollar[1].value.(*Query), Op: OpMod, Right: yyDollar[3].value.(*Query)}
+ }
+ case 35:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:210
+ {
+ yyVAL.value = &Query{Term: yyDollar[1].value.(*Term)}
+ }
+ case 36:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:216
+ {
+ yyVAL.value = []*Pattern{yyDollar[1].value.(*Pattern)}
+ }
+ case 37:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:220
+ {
+ yyVAL.value = append(yyDollar[1].value.([]*Pattern), yyDollar[3].value.(*Pattern))
+ }
+ case 38:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:226
+ {
+ yyVAL.value = &Pattern{Name: yyDollar[1].token}
+ }
+ case 39:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:230
+ {
+ yyVAL.value = &Pattern{Array: yyDollar[2].value.([]*Pattern)}
+ }
+ case 40:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:234
+ {
+ yyVAL.value = &Pattern{Object: yyDollar[2].value.([]*PatternObject)}
+ }
+ case 41:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:240
+ {
+ yyVAL.value = []*Pattern{yyDollar[1].value.(*Pattern)}
+ }
+ case 42:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:244
+ {
+ yyVAL.value = append(yyDollar[1].value.([]*Pattern), yyDollar[3].value.(*Pattern))
+ }
+ case 43:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:250
+ {
+ yyVAL.value = []*PatternObject{yyDollar[1].value.(*PatternObject)}
+ }
+ case 44:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:254
+ {
+ yyVAL.value = append(yyDollar[1].value.([]*PatternObject), yyDollar[3].value.(*PatternObject))
+ }
+ case 45:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:260
+ {
+ yyVAL.value = &PatternObject{Key: yyDollar[1].token, Val: yyDollar[3].value.(*Pattern)}
+ }
+ case 46:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:264
+ {
+ yyVAL.value = &PatternObject{KeyString: yyDollar[1].value.(*String), Val: yyDollar[3].value.(*Pattern)}
+ }
+ case 47:
+ yyDollar = yyS[yypt-5 : yypt+1]
+//line parser.go.y:268
+ {
+ yyVAL.value = &PatternObject{KeyQuery: yyDollar[2].value.(*Query), Val: yyDollar[5].value.(*Pattern)}
+ }
+ case 48:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:272
+ {
+ yyVAL.value = &PatternObject{Key: yyDollar[1].token}
+ }
+ case 49:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:278
+ {
+ yyVAL.value = &Term{Type: TermTypeIdentity}
+ }
+ case 50:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:282
+ {
+ yyVAL.value = &Term{Type: TermTypeRecurse}
+ }
+ case 51:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:286
+ {
+ yyVAL.value = &Term{Type: TermTypeIndex, Index: &Index{Name: yyDollar[1].token}}
+ }
+ case 52:
+ yyDollar = yyS[yypt-2 : yypt+1]
+//line parser.go.y:290
+ {
+ if yyDollar[2].value.(*Suffix).Iter {
+ yyVAL.value = &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{yyDollar[2].value.(*Suffix)}}
+ } else {
+ yyVAL.value = &Term{Type: TermTypeIndex, Index: yyDollar[2].value.(*Suffix).Index}
+ }
+ }
+ case 53:
+ yyDollar = yyS[yypt-2 : yypt+1]
+//line parser.go.y:298
+ {
+ yyVAL.value = &Term{Type: TermTypeIndex, Index: &Index{Str: yyDollar[2].value.(*String)}}
+ }
+ case 54:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:302
+ {
+ yyVAL.value = &Term{Type: TermTypeNull}
+ }
+ case 55:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:306
+ {
+ yyVAL.value = &Term{Type: TermTypeTrue}
+ }
+ case 56:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:310
+ {
+ yyVAL.value = &Term{Type: TermTypeFalse}
+ }
+ case 57:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:314
+ {
+ yyVAL.value = &Term{Type: TermTypeFunc, Func: &Func{Name: yyDollar[1].token}}
+ }
+ case 58:
+ yyDollar = yyS[yypt-4 : yypt+1]
+//line parser.go.y:318
+ {
+ yyVAL.value = &Term{Type: TermTypeFunc, Func: &Func{Name: yyDollar[1].token, Args: yyDollar[3].value.([]*Query)}}
+ }
+ case 59:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:322
+ {
+ yyVAL.value = &Term{Type: TermTypeFunc, Func: &Func{Name: yyDollar[1].token}}
+ }
+ case 60:
+ yyDollar = yyS[yypt-2 : yypt+1]
+//line parser.go.y:326
+ {
+ yyVAL.value = &Term{Type: TermTypeObject, Object: &Object{}}
+ }
+ case 61:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:330
+ {
+ yyVAL.value = &Term{Type: TermTypeObject, Object: &Object{yyDollar[2].value.([]*ObjectKeyVal)}}
+ }
+ case 62:
+ yyDollar = yyS[yypt-4 : yypt+1]
+//line parser.go.y:334
+ {
+ yyVAL.value = &Term{Type: TermTypeObject, Object: &Object{yyDollar[2].value.([]*ObjectKeyVal)}}
+ }
+ case 63:
+ yyDollar = yyS[yypt-2 : yypt+1]
+//line parser.go.y:338
+ {
+ yyVAL.value = &Term{Type: TermTypeArray, Array: &Array{}}
+ }
+ case 64:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:342
+ {
+ yyVAL.value = &Term{Type: TermTypeArray, Array: &Array{yyDollar[2].value.(*Query)}}
+ }
+ case 65:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:346
+ {
+ yyVAL.value = &Term{Type: TermTypeNumber, Number: yyDollar[1].token}
+ }
+ case 66:
+ yyDollar = yyS[yypt-2 : yypt+1]
+//line parser.go.y:350
+ {
+ yyVAL.value = &Term{Type: TermTypeUnary, Unary: &Unary{OpAdd, yyDollar[2].value.(*Term)}}
+ }
+ case 67:
+ yyDollar = yyS[yypt-2 : yypt+1]
+//line parser.go.y:354
+ {
+ yyVAL.value = &Term{Type: TermTypeUnary, Unary: &Unary{OpSub, yyDollar[2].value.(*Term)}}
+ }
+ case 68:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:358
+ {
+ yyVAL.value = &Term{Type: TermTypeFormat, Format: yyDollar[1].token}
+ }
+ case 69:
+ yyDollar = yyS[yypt-2 : yypt+1]
+//line parser.go.y:362
+ {
+ yyVAL.value = &Term{Type: TermTypeFormat, Format: yyDollar[1].token, Str: yyDollar[2].value.(*String)}
+ }
+ case 70:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:366
+ {
+ yyVAL.value = &Term{Type: TermTypeString, Str: yyDollar[1].value.(*String)}
+ }
+ case 71:
+ yyDollar = yyS[yypt-7 : yypt+1]
+//line parser.go.y:370
+ {
+ yyVAL.value = &Term{Type: TermTypeIf, If: &If{yyDollar[2].value.(*Query), yyDollar[4].value.(*Query), yyDollar[5].value.([]*IfElif), yyDollar[6].value.(*Query)}}
+ }
+ case 72:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:374
+ {
+ yyVAL.value = &Term{Type: TermTypeTry, Try: &Try{yyDollar[2].value.(*Query), yyDollar[3].value.(*Query)}}
+ }
+ case 73:
+ yyDollar = yyS[yypt-9 : yypt+1]
+//line parser.go.y:378
+ {
+ yyVAL.value = &Term{Type: TermTypeReduce, Reduce: &Reduce{yyDollar[2].value.(*Term), yyDollar[4].value.(*Pattern), yyDollar[6].value.(*Query), yyDollar[8].value.(*Query)}}
+ }
+ case 74:
+ yyDollar = yyS[yypt-9 : yypt+1]
+//line parser.go.y:382
+ {
+ yyVAL.value = &Term{Type: TermTypeForeach, Foreach: &Foreach{yyDollar[2].value.(*Term), yyDollar[4].value.(*Pattern), yyDollar[6].value.(*Query), yyDollar[8].value.(*Query), nil}}
+ }
+ case 75:
+ yyDollar = yyS[yypt-11 : yypt+1]
+//line parser.go.y:386
+ {
+ yyVAL.value = &Term{Type: TermTypeForeach, Foreach: &Foreach{yyDollar[2].value.(*Term), yyDollar[4].value.(*Pattern), yyDollar[6].value.(*Query), yyDollar[8].value.(*Query), yyDollar[10].value.(*Query)}}
+ }
+ case 76:
+ yyDollar = yyS[yypt-2 : yypt+1]
+//line parser.go.y:390
+ {
+ yyVAL.value = &Term{Type: TermTypeBreak, Break: yyDollar[2].token}
+ }
+ case 77:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:394
+ {
+ yyVAL.value = &Term{Type: TermTypeQuery, Query: yyDollar[2].value.(*Query)}
+ }
+ case 78:
+ yyDollar = yyS[yypt-2 : yypt+1]
+//line parser.go.y:398
+ {
+ yyDollar[1].value.(*Term).SuffixList = append(yyDollar[1].value.(*Term).SuffixList, &Suffix{Index: &Index{Name: yyDollar[2].token}})
+ }
+ case 79:
+ yyDollar = yyS[yypt-2 : yypt+1]
+//line parser.go.y:402
+ {
+ yyDollar[1].value.(*Term).SuffixList = append(yyDollar[1].value.(*Term).SuffixList, yyDollar[2].value.(*Suffix))
+ }
+ case 80:
+ yyDollar = yyS[yypt-2 : yypt+1]
+//line parser.go.y:406
+ {
+ yyDollar[1].value.(*Term).SuffixList = append(yyDollar[1].value.(*Term).SuffixList, &Suffix{Optional: true})
+ }
+ case 81:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:410
+ {
+ yyDollar[1].value.(*Term).SuffixList = append(yyDollar[1].value.(*Term).SuffixList, yyDollar[3].value.(*Suffix))
+ }
+ case 82:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:414
+ {
+ yyDollar[1].value.(*Term).SuffixList = append(yyDollar[1].value.(*Term).SuffixList, &Suffix{Index: &Index{Str: yyDollar[3].value.(*String)}})
+ }
+ case 83:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:420
+ {
+ yyVAL.value = &String{Str: yyDollar[1].token}
+ }
+ case 84:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:424
+ {
+ yyVAL.value = &String{Queries: yyDollar[2].value.([]*Query)}
+ }
+ case 85:
+ yyDollar = yyS[yypt-0 : yypt+1]
+//line parser.go.y:430
+ {
+ yyVAL.value = []*Query{}
+ }
+ case 86:
+ yyDollar = yyS[yypt-2 : yypt+1]
+//line parser.go.y:434
+ {
+ yyVAL.value = append(yyDollar[1].value.([]*Query), &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: yyDollar[2].token}}})
+ }
+ case 87:
+ yyDollar = yyS[yypt-4 : yypt+1]
+//line parser.go.y:438
+ {
+ yylex.(*lexer).inString = true
+ yyVAL.value = append(yyDollar[1].value.([]*Query), &Query{Term: &Term{Type: TermTypeQuery, Query: yyDollar[3].value.(*Query)}})
+ }
+ case 88:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:444
+ {
+ }
+ case 89:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:445
+ {
+ }
+ case 90:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:448
+ {
+ }
+ case 91:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:449
+ {
+ }
+ case 92:
+ yyDollar = yyS[yypt-2 : yypt+1]
+//line parser.go.y:453
+ {
+ yyVAL.value = &Suffix{Iter: true}
+ }
+ case 93:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:457
+ {
+ yyVAL.value = &Suffix{Index: &Index{Start: yyDollar[2].value.(*Query)}}
+ }
+ case 94:
+ yyDollar = yyS[yypt-4 : yypt+1]
+//line parser.go.y:461
+ {
+ yyVAL.value = &Suffix{Index: &Index{Start: yyDollar[2].value.(*Query), IsSlice: true}}
+ }
+ case 95:
+ yyDollar = yyS[yypt-4 : yypt+1]
+//line parser.go.y:465
+ {
+ yyVAL.value = &Suffix{Index: &Index{End: yyDollar[3].value.(*Query), IsSlice: true}}
+ }
+ case 96:
+ yyDollar = yyS[yypt-5 : yypt+1]
+//line parser.go.y:469
+ {
+ yyVAL.value = &Suffix{Index: &Index{Start: yyDollar[2].value.(*Query), End: yyDollar[4].value.(*Query), IsSlice: true}}
+ }
+ case 97:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:475
+ {
+ yyVAL.value = []*Query{yyDollar[1].value.(*Query)}
+ }
+ case 98:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:479
+ {
+ yyVAL.value = append(yyDollar[1].value.([]*Query), yyDollar[3].value.(*Query))
+ }
+ case 99:
+ yyDollar = yyS[yypt-0 : yypt+1]
+//line parser.go.y:485
+ {
+ yyVAL.value = []*IfElif(nil)
+ }
+ case 100:
+ yyDollar = yyS[yypt-5 : yypt+1]
+//line parser.go.y:489
+ {
+ yyVAL.value = append(yyDollar[1].value.([]*IfElif), &IfElif{yyDollar[3].value.(*Query), yyDollar[5].value.(*Query)})
+ }
+ case 101:
+ yyDollar = yyS[yypt-0 : yypt+1]
+//line parser.go.y:495
+ {
+ yyVAL.value = (*Query)(nil)
+ }
+ case 102:
+ yyDollar = yyS[yypt-2 : yypt+1]
+//line parser.go.y:499
+ {
+ yyVAL.value = yyDollar[2].value
+ }
+ case 103:
+ yyDollar = yyS[yypt-0 : yypt+1]
+//line parser.go.y:505
+ {
+ yyVAL.value = (*Query)(nil)
+ }
+ case 104:
+ yyDollar = yyS[yypt-2 : yypt+1]
+//line parser.go.y:509
+ {
+ yyVAL.value = yyDollar[2].value
+ }
+ case 105:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:515
+ {
+ yyVAL.value = []*ObjectKeyVal{yyDollar[1].value.(*ObjectKeyVal)}
+ }
+ case 106:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:519
+ {
+ yyVAL.value = append(yyDollar[1].value.([]*ObjectKeyVal), yyDollar[3].value.(*ObjectKeyVal))
+ }
+ case 107:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:525
+ {
+ yyVAL.value = &ObjectKeyVal{Key: yyDollar[1].token, Val: yyDollar[3].value.(*ObjectVal)}
+ }
+ case 108:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:529
+ {
+ yyVAL.value = &ObjectKeyVal{KeyString: yyDollar[1].value.(*String), Val: yyDollar[3].value.(*ObjectVal)}
+ }
+ case 109:
+ yyDollar = yyS[yypt-5 : yypt+1]
+//line parser.go.y:533
+ {
+ yyVAL.value = &ObjectKeyVal{KeyQuery: yyDollar[2].value.(*Query), Val: yyDollar[5].value.(*ObjectVal)}
+ }
+ case 110:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:537
+ {
+ yyVAL.value = &ObjectKeyVal{Key: yyDollar[1].token}
+ }
+ case 111:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:541
+ {
+ yyVAL.value = &ObjectKeyVal{KeyString: yyDollar[1].value.(*String)}
+ }
+ case 112:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:546
+ {
+ }
+ case 113:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:547
+ {
+ }
+ case 114:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:548
+ {
+ }
+ case 115:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:552
+ {
+ yyVAL.value = &ObjectVal{[]*Query{{Term: yyDollar[1].value.(*Term)}}}
+ }
+ case 116:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:556
+ {
+ yyVAL.value = &ObjectVal{append(yyDollar[1].value.(*ObjectVal).Queries, &Query{Term: yyDollar[3].value.(*Term)})}
+ }
+ case 117:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:562
+ {
+ yyVAL.value = &ConstTerm{Object: yyDollar[1].value.(*ConstObject)}
+ }
+ case 118:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:566
+ {
+ yyVAL.value = &ConstTerm{Array: yyDollar[1].value.(*ConstArray)}
+ }
+ case 119:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:570
+ {
+ yyVAL.value = &ConstTerm{Number: yyDollar[1].token}
+ }
+ case 120:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:574
+ {
+ yyVAL.value = &ConstTerm{Str: yyDollar[1].token}
+ }
+ case 121:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:578
+ {
+ yyVAL.value = &ConstTerm{Null: true}
+ }
+ case 122:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:582
+ {
+ yyVAL.value = &ConstTerm{True: true}
+ }
+ case 123:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:586
+ {
+ yyVAL.value = &ConstTerm{False: true}
+ }
+ case 124:
+ yyDollar = yyS[yypt-2 : yypt+1]
+//line parser.go.y:592
+ {
+ yyVAL.value = &ConstObject{}
+ }
+ case 125:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:596
+ {
+ yyVAL.value = &ConstObject{yyDollar[2].value.([]*ConstObjectKeyVal)}
+ }
+ case 126:
+ yyDollar = yyS[yypt-4 : yypt+1]
+//line parser.go.y:600
+ {
+ yyVAL.value = &ConstObject{yyDollar[2].value.([]*ConstObjectKeyVal)}
+ }
+ case 127:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:606
+ {
+ yyVAL.value = []*ConstObjectKeyVal{yyDollar[1].value.(*ConstObjectKeyVal)}
+ }
+ case 128:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:610
+ {
+ yyVAL.value = append(yyDollar[1].value.([]*ConstObjectKeyVal), yyDollar[3].value.(*ConstObjectKeyVal))
+ }
+ case 129:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:616
+ {
+ yyVAL.value = &ConstObjectKeyVal{Key: yyDollar[1].token, Val: yyDollar[3].value.(*ConstTerm)}
+ }
+ case 130:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:620
+ {
+ yyVAL.value = &ConstObjectKeyVal{Key: yyDollar[1].token, Val: yyDollar[3].value.(*ConstTerm)}
+ }
+ case 131:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:624
+ {
+ yyVAL.value = &ConstObjectKeyVal{KeyString: yyDollar[1].token, Val: yyDollar[3].value.(*ConstTerm)}
+ }
+ case 132:
+ yyDollar = yyS[yypt-2 : yypt+1]
+//line parser.go.y:630
+ {
+ yyVAL.value = &ConstArray{}
+ }
+ case 133:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:634
+ {
+ yyVAL.value = &ConstArray{yyDollar[2].value.([]*ConstTerm)}
+ }
+ case 134:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:640
+ {
+ yyVAL.value = []*ConstTerm{yyDollar[1].value.(*ConstTerm)}
+ }
+ case 135:
+ yyDollar = yyS[yypt-3 : yypt+1]
+//line parser.go.y:644
+ {
+ yyVAL.value = append(yyDollar[1].value.([]*ConstTerm), yyDollar[3].value.(*ConstTerm))
+ }
+ case 136:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:649
+ {
+ }
+ case 137:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:650
+ {
+ }
+ case 138:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:651
+ {
+ }
+ case 139:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:652
+ {
+ }
+ case 140:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:653
+ {
+ }
+ case 141:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:654
+ {
+ }
+ case 142:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:655
+ {
+ }
+ case 143:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:656
+ {
+ }
+ case 144:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:657
+ {
+ }
+ case 145:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:658
+ {
+ }
+ case 146:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:659
+ {
+ }
+ case 147:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:660
+ {
+ }
+ case 148:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:661
+ {
+ }
+ case 149:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:662
+ {
+ }
+ case 150:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:663
+ {
+ }
+ case 151:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:664
+ {
+ }
+ case 152:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:665
+ {
+ }
+ case 153:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:666
+ {
+ }
+ case 154:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:667
+ {
+ }
+ case 155:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:668
+ {
+ }
+ case 156:
+ yyDollar = yyS[yypt-1 : yypt+1]
+//line parser.go.y:669
+ {
+ }
+ }
+ goto yystack /* stack new state and value */
+}
diff --git a/vendor/github.com/itchyny/gojq/parser.go.y b/vendor/github.com/itchyny/gojq/parser.go.y
new file mode 100644
index 000000000..e100a842e
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/parser.go.y
@@ -0,0 +1,671 @@
+%{
+package gojq
+
+func reverseFuncDef(xs []*FuncDef) []*FuncDef {
+ for i, j := 0, len(xs)-1; i < j; i, j = i+1, j-1 {
+ xs[i], xs[j] = xs[j], xs[i]
+ }
+ return xs
+}
+
+func prependFuncDef(xs []*FuncDef, x *FuncDef) []*FuncDef {
+ xs = append(xs, nil)
+ copy(xs[1:], xs)
+ xs[0] = x
+ return xs
+}
+%}
+
+%union {
+ value any
+ token string
+ operator Operator
+}
+
+%type program moduleheader programbody imports import metaopt funcdefs funcdef funcdefargs query
+%type bindpatterns pattern arraypatterns objectpatterns objectpattern
+%type term string stringparts suffix args ifelifs ifelse trycatch
+%type objectkeyvals objectkeyval objectval
+%type constterm constobject constobjectkeyvals constobjectkeyval constarray constarrayelems
+%type tokIdentVariable tokIdentModuleIdent tokVariableModuleVariable tokKeyword objectkey
+%token tokAltOp tokUpdateOp tokDestAltOp tokOrOp tokAndOp tokCompareOp
+%token tokModule tokImport tokInclude tokDef tokAs tokLabel tokBreak
+%token tokNull tokTrue tokFalse
+%token tokIdent tokVariable tokModuleIdent tokModuleVariable
+%token tokIndex tokNumber tokFormat
+%token tokString tokStringStart tokStringQuery tokStringEnd
+%token tokIf tokThen tokElif tokElse tokEnd
+%token tokTry tokCatch tokReduce tokForeach
+%token tokRecurse tokFuncDefPost tokTermPost tokEmptyCatch
+%token tokInvalid tokInvalidEscapeSequence tokUnterminatedString
+
+%nonassoc tokFuncDefPost tokTermPost
+%right '|'
+%left ','
+%right tokAltOp
+%nonassoc tokUpdateOp
+%left tokOrOp
+%left tokAndOp
+%nonassoc tokCompareOp
+%left '+' '-'
+%left '*' '/' '%'
+%nonassoc tokAs tokIndex '.' '?' tokEmptyCatch
+%nonassoc '[' tokTry tokCatch
+
+%%
+
+program
+ : moduleheader programbody
+ {
+ if $1 != nil { $2.(*Query).Meta = $1.(*ConstObject) }
+ yylex.(*lexer).result = $2.(*Query)
+ }
+
+moduleheader
+ :
+ {
+ $$ = nil
+ }
+ | tokModule constobject ';'
+ {
+ $$ = $2;
+ }
+
+programbody
+ : imports funcdefs
+ {
+ $$ = &Query{Imports: $1.([]*Import), FuncDefs: reverseFuncDef($2.([]*FuncDef)), Term: &Term{Type: TermTypeIdentity}}
+ }
+ | imports query
+ {
+ if $1 != nil { $2.(*Query).Imports = $1.([]*Import) }
+ $$ = $2
+ }
+
+imports
+ :
+ {
+ $$ = []*Import(nil)
+ }
+ | imports import
+ {
+ $$ = append($1.([]*Import), $2.(*Import))
+ }
+
+import
+ : tokImport tokString tokAs tokIdentVariable metaopt ';'
+ {
+ $$ = &Import{ImportPath: $2, ImportAlias: $4, Meta: $5.(*ConstObject)}
+ }
+ | tokInclude tokString metaopt ';'
+ {
+ $$ = &Import{IncludePath: $2, Meta: $3.(*ConstObject)}
+ }
+
+metaopt
+ :
+ {
+ $$ = (*ConstObject)(nil)
+ }
+ | constobject {}
+
+funcdefs
+ :
+ {
+ $$ = []*FuncDef(nil)
+ }
+ | funcdef funcdefs
+ {
+ $$ = append($2.([]*FuncDef), $1.(*FuncDef))
+ }
+
+funcdef
+ : tokDef tokIdent ':' query ';'
+ {
+ $$ = &FuncDef{Name: $2, Body: $4.(*Query)}
+ }
+ | tokDef tokIdent '(' funcdefargs ')' ':' query ';'
+ {
+ $$ = &FuncDef{$2, $4.([]string), $7.(*Query)}
+ }
+
+funcdefargs
+ : tokIdentVariable
+ {
+ $$ = []string{$1}
+ }
+ | funcdefargs ';' tokIdentVariable
+ {
+ $$ = append($1.([]string), $3)
+ }
+
+tokIdentVariable
+ : tokIdent {}
+ | tokVariable {}
+
+query
+ : funcdef query %prec tokFuncDefPost
+ {
+ $2.(*Query).FuncDefs = prependFuncDef($2.(*Query).FuncDefs, $1.(*FuncDef))
+ $$ = $2
+ }
+ | query '|' query
+ {
+ $$ = &Query{Left: $1.(*Query), Op: OpPipe, Right: $3.(*Query)}
+ }
+ | term tokAs bindpatterns '|' query
+ {
+ $1.(*Term).SuffixList = append($1.(*Term).SuffixList, &Suffix{Bind: &Bind{$3.([]*Pattern), $5.(*Query)}})
+ $$ = &Query{Term: $1.(*Term)}
+ }
+ | tokLabel tokVariable '|' query
+ {
+ $$ = &Query{Term: &Term{Type: TermTypeLabel, Label: &Label{$2, $4.(*Query)}}}
+ }
+ | query ',' query
+ {
+ $$ = &Query{Left: $1.(*Query), Op: OpComma, Right: $3.(*Query)}
+ }
+ | query tokAltOp query
+ {
+ $$ = &Query{Left: $1.(*Query), Op: $2, Right: $3.(*Query)}
+ }
+ | query tokUpdateOp query
+ {
+ $$ = &Query{Left: $1.(*Query), Op: $2, Right: $3.(*Query)}
+ }
+ | query tokOrOp query
+ {
+ $$ = &Query{Left: $1.(*Query), Op: OpOr, Right: $3.(*Query)}
+ }
+ | query tokAndOp query
+ {
+ $$ = &Query{Left: $1.(*Query), Op: OpAnd, Right: $3.(*Query)}
+ }
+ | query tokCompareOp query
+ {
+ $$ = &Query{Left: $1.(*Query), Op: $2, Right: $3.(*Query)}
+ }
+ | query '+' query
+ {
+ $$ = &Query{Left: $1.(*Query), Op: OpAdd, Right: $3.(*Query)}
+ }
+ | query '-' query
+ {
+ $$ = &Query{Left: $1.(*Query), Op: OpSub, Right: $3.(*Query)}
+ }
+ | query '*' query
+ {
+ $$ = &Query{Left: $1.(*Query), Op: OpMul, Right: $3.(*Query)}
+ }
+ | query '/' query
+ {
+ $$ = &Query{Left: $1.(*Query), Op: OpDiv, Right: $3.(*Query)}
+ }
+ | query '%' query
+ {
+ $$ = &Query{Left: $1.(*Query), Op: OpMod, Right: $3.(*Query)}
+ }
+ | term %prec tokTermPost
+ {
+ $$ = &Query{Term: $1.(*Term)}
+ }
+
+bindpatterns
+ : pattern
+ {
+ $$ = []*Pattern{$1.(*Pattern)}
+ }
+ | bindpatterns tokDestAltOp pattern
+ {
+ $$ = append($1.([]*Pattern), $3.(*Pattern))
+ }
+
+pattern
+ : tokVariable
+ {
+ $$ = &Pattern{Name: $1}
+ }
+ | '[' arraypatterns ']'
+ {
+ $$ = &Pattern{Array: $2.([]*Pattern)}
+ }
+ | '{' objectpatterns '}'
+ {
+ $$ = &Pattern{Object: $2.([]*PatternObject)}
+ }
+
+arraypatterns
+ : pattern
+ {
+ $$ = []*Pattern{$1.(*Pattern)}
+ }
+ | arraypatterns ',' pattern
+ {
+ $$ = append($1.([]*Pattern), $3.(*Pattern))
+ }
+
+objectpatterns
+ : objectpattern
+ {
+ $$ = []*PatternObject{$1.(*PatternObject)}
+ }
+ | objectpatterns ',' objectpattern
+ {
+ $$ = append($1.([]*PatternObject), $3.(*PatternObject))
+ }
+
+objectpattern
+ : objectkey ':' pattern
+ {
+ $$ = &PatternObject{Key: $1, Val: $3.(*Pattern)}
+ }
+ | string ':' pattern
+ {
+ $$ = &PatternObject{KeyString: $1.(*String), Val: $3.(*Pattern)}
+ }
+ | '(' query ')' ':' pattern
+ {
+ $$ = &PatternObject{KeyQuery: $2.(*Query), Val: $5.(*Pattern)}
+ }
+ | tokVariable
+ {
+ $$ = &PatternObject{Key: $1}
+ }
+
+term
+ : '.'
+ {
+ $$ = &Term{Type: TermTypeIdentity}
+ }
+ | tokRecurse
+ {
+ $$ = &Term{Type: TermTypeRecurse}
+ }
+ | tokIndex
+ {
+ $$ = &Term{Type: TermTypeIndex, Index: &Index{Name: $1}}
+ }
+ | '.' suffix
+ {
+ if $2.(*Suffix).Iter {
+ $$ = &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{$2.(*Suffix)}}
+ } else {
+ $$ = &Term{Type: TermTypeIndex, Index: $2.(*Suffix).Index}
+ }
+ }
+ | '.' string
+ {
+ $$ = &Term{Type: TermTypeIndex, Index: &Index{Str: $2.(*String)}}
+ }
+ | tokNull
+ {
+ $$ = &Term{Type: TermTypeNull}
+ }
+ | tokTrue
+ {
+ $$ = &Term{Type: TermTypeTrue}
+ }
+ | tokFalse
+ {
+ $$ = &Term{Type: TermTypeFalse}
+ }
+ | tokIdentModuleIdent
+ {
+ $$ = &Term{Type: TermTypeFunc, Func: &Func{Name: $1}}
+ }
+ | tokIdentModuleIdent '(' args ')'
+ {
+ $$ = &Term{Type: TermTypeFunc, Func: &Func{Name: $1, Args: $3.([]*Query)}}
+ }
+ | tokVariableModuleVariable
+ {
+ $$ = &Term{Type: TermTypeFunc, Func: &Func{Name: $1}}
+ }
+ | '{' '}'
+ {
+ $$ = &Term{Type: TermTypeObject, Object: &Object{}}
+ }
+ | '{' objectkeyvals '}'
+ {
+ $$ = &Term{Type: TermTypeObject, Object: &Object{$2.([]*ObjectKeyVal)}}
+ }
+ | '{' objectkeyvals ',' '}'
+ {
+ $$ = &Term{Type: TermTypeObject, Object: &Object{$2.([]*ObjectKeyVal)}}
+ }
+ | '[' ']'
+ {
+ $$ = &Term{Type: TermTypeArray, Array: &Array{}}
+ }
+ | '[' query ']'
+ {
+ $$ = &Term{Type: TermTypeArray, Array: &Array{$2.(*Query)}}
+ }
+ | tokNumber
+ {
+ $$ = &Term{Type: TermTypeNumber, Number: $1}
+ }
+ | '+' term
+ {
+ $$ = &Term{Type: TermTypeUnary, Unary: &Unary{OpAdd, $2.(*Term)}}
+ }
+ | '-' term
+ {
+ $$ = &Term{Type: TermTypeUnary, Unary: &Unary{OpSub, $2.(*Term)}}
+ }
+ | tokFormat
+ {
+ $$ = &Term{Type: TermTypeFormat, Format: $1}
+ }
+ | tokFormat string
+ {
+ $$ = &Term{Type: TermTypeFormat, Format: $1, Str: $2.(*String)}
+ }
+ | string
+ {
+ $$ = &Term{Type: TermTypeString, Str: $1.(*String)}
+ }
+ | tokIf query tokThen query ifelifs ifelse tokEnd
+ {
+ $$ = &Term{Type: TermTypeIf, If: &If{$2.(*Query), $4.(*Query), $5.([]*IfElif), $6.(*Query)}}
+ }
+ | tokTry query trycatch
+ {
+ $$ = &Term{Type: TermTypeTry, Try: &Try{$2.(*Query), $3.(*Query)}}
+ }
+ | tokReduce term tokAs pattern '(' query ';' query ')'
+ {
+ $$ = &Term{Type: TermTypeReduce, Reduce: &Reduce{$2.(*Term), $4.(*Pattern), $6.(*Query), $8.(*Query)}}
+ }
+ | tokForeach term tokAs pattern '(' query ';' query ')'
+ {
+ $$ = &Term{Type: TermTypeForeach, Foreach: &Foreach{$2.(*Term), $4.(*Pattern), $6.(*Query), $8.(*Query), nil}}
+ }
+ | tokForeach term tokAs pattern '(' query ';' query ';' query ')'
+ {
+ $$ = &Term{Type: TermTypeForeach, Foreach: &Foreach{$2.(*Term), $4.(*Pattern), $6.(*Query), $8.(*Query), $10.(*Query)}}
+ }
+ | tokBreak tokVariable
+ {
+ $$ = &Term{Type: TermTypeBreak, Break: $2}
+ }
+ | '(' query ')'
+ {
+ $$ = &Term{Type: TermTypeQuery, Query: $2.(*Query)}
+ }
+ | term tokIndex
+ {
+ $1.(*Term).SuffixList = append($1.(*Term).SuffixList, &Suffix{Index: &Index{Name: $2}})
+ }
+ | term suffix
+ {
+ $1.(*Term).SuffixList = append($1.(*Term).SuffixList, $2.(*Suffix))
+ }
+ | term '?'
+ {
+ $1.(*Term).SuffixList = append($1.(*Term).SuffixList, &Suffix{Optional: true})
+ }
+ | term '.' suffix
+ {
+ $1.(*Term).SuffixList = append($1.(*Term).SuffixList, $3.(*Suffix))
+ }
+ | term '.' string
+ {
+ $1.(*Term).SuffixList = append($1.(*Term).SuffixList, &Suffix{Index: &Index{Str: $3.(*String)}})
+ }
+
+string
+ : tokString
+ {
+ $$ = &String{Str: $1}
+ }
+ | tokStringStart stringparts tokStringEnd
+ {
+ $$ = &String{Queries: $2.([]*Query)}
+ }
+
+stringparts
+ :
+ {
+ $$ = []*Query{}
+ }
+ | stringparts tokString
+ {
+ $$ = append($1.([]*Query), &Query{Term: &Term{Type: TermTypeString, Str: &String{Str: $2}}})
+ }
+ | stringparts tokStringQuery query ')'
+ {
+ yylex.(*lexer).inString = true
+ $$ = append($1.([]*Query), &Query{Term: &Term{Type: TermTypeQuery, Query: $3.(*Query)}})
+ }
+
+tokIdentModuleIdent
+ : tokIdent {}
+ | tokModuleIdent {}
+
+tokVariableModuleVariable
+ : tokVariable {}
+ | tokModuleVariable {}
+
+suffix
+ : '[' ']'
+ {
+ $$ = &Suffix{Iter: true}
+ }
+ | '[' query ']'
+ {
+ $$ = &Suffix{Index: &Index{Start: $2.(*Query)}}
+ }
+ | '[' query ':' ']'
+ {
+ $$ = &Suffix{Index: &Index{Start: $2.(*Query), IsSlice: true}}
+ }
+ | '[' ':' query ']'
+ {
+ $$ = &Suffix{Index: &Index{End: $3.(*Query), IsSlice: true}}
+ }
+ | '[' query ':' query ']'
+ {
+ $$ = &Suffix{Index: &Index{Start: $2.(*Query), End: $4.(*Query), IsSlice: true}}
+ }
+
+args
+ : query
+ {
+ $$ = []*Query{$1.(*Query)}
+ }
+ | args ';' query
+ {
+ $$ = append($1.([]*Query), $3.(*Query))
+ }
+
+ifelifs
+ :
+ {
+ $$ = []*IfElif(nil)
+ }
+ | ifelifs tokElif query tokThen query
+ {
+ $$ = append($1.([]*IfElif), &IfElif{$3.(*Query), $5.(*Query)})
+ }
+
+ifelse
+ :
+ {
+ $$ = (*Query)(nil)
+ }
+ | tokElse query
+ {
+ $$ = $2
+ }
+
+trycatch
+ : %prec tokEmptyCatch
+ {
+ $$ = (*Query)(nil)
+ }
+ | tokCatch query
+ {
+ $$ = $2
+ }
+
+objectkeyvals
+ : objectkeyval
+ {
+ $$ = []*ObjectKeyVal{$1.(*ObjectKeyVal)}
+ }
+ | objectkeyvals ',' objectkeyval
+ {
+ $$ = append($1.([]*ObjectKeyVal), $3.(*ObjectKeyVal))
+ }
+
+objectkeyval
+ : objectkey ':' objectval
+ {
+ $$ = &ObjectKeyVal{Key: $1, Val: $3.(*ObjectVal)}
+ }
+ | string ':' objectval
+ {
+ $$ = &ObjectKeyVal{KeyString: $1.(*String), Val: $3.(*ObjectVal)}
+ }
+ | '(' query ')' ':' objectval
+ {
+ $$ = &ObjectKeyVal{KeyQuery: $2.(*Query), Val: $5.(*ObjectVal)}
+ }
+ | objectkey
+ {
+ $$ = &ObjectKeyVal{Key: $1}
+ }
+ | string
+ {
+ $$ = &ObjectKeyVal{KeyString: $1.(*String)}
+ }
+
+objectkey
+ : tokIdent {}
+ | tokVariable {}
+ | tokKeyword {}
+
+objectval
+ : term
+ {
+ $$ = &ObjectVal{[]*Query{{Term: $1.(*Term)}}}
+ }
+ | objectval '|' term
+ {
+ $$ = &ObjectVal{append($1.(*ObjectVal).Queries, &Query{Term: $3.(*Term)})}
+ }
+
+constterm
+ : constobject
+ {
+ $$ = &ConstTerm{Object: $1.(*ConstObject)}
+ }
+ | constarray
+ {
+ $$ = &ConstTerm{Array: $1.(*ConstArray)}
+ }
+ | tokNumber
+ {
+ $$ = &ConstTerm{Number: $1}
+ }
+ | tokString
+ {
+ $$ = &ConstTerm{Str: $1}
+ }
+ | tokNull
+ {
+ $$ = &ConstTerm{Null: true}
+ }
+ | tokTrue
+ {
+ $$ = &ConstTerm{True: true}
+ }
+ | tokFalse
+ {
+ $$ = &ConstTerm{False: true}
+ }
+
+constobject
+ : '{' '}'
+ {
+ $$ = &ConstObject{}
+ }
+ | '{' constobjectkeyvals '}'
+ {
+ $$ = &ConstObject{$2.([]*ConstObjectKeyVal)}
+ }
+ | '{' constobjectkeyvals ',' '}'
+ {
+ $$ = &ConstObject{$2.([]*ConstObjectKeyVal)}
+ }
+
+constobjectkeyvals
+ : constobjectkeyval
+ {
+ $$ = []*ConstObjectKeyVal{$1.(*ConstObjectKeyVal)}
+ }
+ | constobjectkeyvals ',' constobjectkeyval
+ {
+ $$ = append($1.([]*ConstObjectKeyVal), $3.(*ConstObjectKeyVal))
+ }
+
+constobjectkeyval
+ : tokIdent ':' constterm
+ {
+ $$ = &ConstObjectKeyVal{Key: $1, Val: $3.(*ConstTerm)}
+ }
+ | tokKeyword ':' constterm
+ {
+ $$ = &ConstObjectKeyVal{Key: $1, Val: $3.(*ConstTerm)}
+ }
+ | tokString ':' constterm
+ {
+ $$ = &ConstObjectKeyVal{KeyString: $1, Val: $3.(*ConstTerm)}
+ }
+
+constarray
+ : '[' ']'
+ {
+ $$ = &ConstArray{}
+ }
+ | '[' constarrayelems ']'
+ {
+ $$ = &ConstArray{$2.([]*ConstTerm)}
+ }
+
+constarrayelems
+ : constterm
+ {
+ $$ = []*ConstTerm{$1.(*ConstTerm)}
+ }
+ | constarrayelems ',' constterm
+ {
+ $$ = append($1.([]*ConstTerm), $3.(*ConstTerm))
+ }
+
+tokKeyword
+ : tokOrOp {}
+ | tokAndOp {}
+ | tokModule {}
+ | tokImport {}
+ | tokInclude {}
+ | tokDef {}
+ | tokAs {}
+ | tokLabel {}
+ | tokBreak {}
+ | tokNull {}
+ | tokTrue {}
+ | tokFalse {}
+ | tokIf {}
+ | tokThen {}
+ | tokElif {}
+ | tokElse {}
+ | tokEnd {}
+ | tokTry {}
+ | tokCatch {}
+ | tokReduce {}
+ | tokForeach {}
+
+%%
diff --git a/vendor/github.com/itchyny/gojq/preview.go b/vendor/github.com/itchyny/gojq/preview.go
new file mode 100644
index 000000000..e082eb561
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/preview.go
@@ -0,0 +1,77 @@
+package gojq
+
+import "unicode/utf8"
+
+// Preview returns the preview string of v. The preview string is basically the
+// same as the jq-flavored JSON encoding returned by [Marshal], but is truncated
+// by 30 bytes, and more efficient than truncating the result of [Marshal].
+//
+// This method is used by error messages of built-in operators and functions,
+// and accepts only limited types (nil, bool, int, float64, *big.Int, string,
+// []any, and map[string]any). Note that the maximum width and trailing strings
+// on truncation may be changed in the future.
+func Preview(v any) string {
+ bs := jsonLimitedMarshal(v, 32)
+ if l := 30; len(bs) > l {
+ var trailing string
+ switch v.(type) {
+ case string:
+ trailing = ` ..."`
+ case []any:
+ trailing = " ...]"
+ case map[string]any:
+ trailing = " ...}"
+ default:
+ trailing = " ..."
+ }
+ for len(bs) > l-len(trailing) {
+ _, size := utf8.DecodeLastRune(bs)
+ bs = bs[:len(bs)-size]
+ }
+ bs = append(bs, trailing...)
+ }
+ return string(bs)
+}
+
+func jsonLimitedMarshal(v any, n int) (bs []byte) {
+ w := &limitedWriter{buf: make([]byte, n)}
+ defer func() {
+ _ = recover()
+ bs = w.Bytes()
+ }()
+ (&encoder{w: w}).encode(v)
+ return
+}
+
+type limitedWriter struct {
+ buf []byte
+ off int
+}
+
+func (w *limitedWriter) Write(bs []byte) (int, error) {
+ n := copy(w.buf[w.off:], bs)
+ if w.off += n; w.off == len(w.buf) {
+ panic(struct{}{})
+ }
+ return n, nil
+}
+
+func (w *limitedWriter) WriteByte(b byte) error {
+ w.buf[w.off] = b
+ if w.off++; w.off == len(w.buf) {
+ panic(struct{}{})
+ }
+ return nil
+}
+
+func (w *limitedWriter) WriteString(s string) (int, error) {
+ n := copy(w.buf[w.off:], s)
+ if w.off += n; w.off == len(w.buf) {
+ panic(struct{}{})
+ }
+ return n, nil
+}
+
+func (w *limitedWriter) Bytes() []byte {
+ return w.buf[:w.off]
+}
diff --git a/vendor/github.com/itchyny/gojq/query.go b/vendor/github.com/itchyny/gojq/query.go
new file mode 100644
index 000000000..7038b9dd5
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/query.go
@@ -0,0 +1,1193 @@
+package gojq
+
+import (
+ "context"
+ "strings"
+)
+
+// Parse a query string, and returns the query struct.
+//
+// If parsing failed, it returns an error of type [*ParseError], which has
+// the byte offset and the invalid token. The byte offset is the scanned bytes
+// when the error occurred. The token is empty if the error occurred after
+// scanning the entire query string.
+func Parse(src string) (*Query, error) {
+ l := newLexer(src)
+ if yyParse(l) > 0 {
+ return nil, l.err
+ }
+ return l.result, nil
+}
+
+// Query represents the abstract syntax tree of a jq query.
+type Query struct {
+ Meta *ConstObject
+ Imports []*Import
+ FuncDefs []*FuncDef
+ Term *Term
+ Left *Query
+ Op Operator
+ Right *Query
+ Func string
+}
+
+// Run the query.
+//
+// It is safe to call this method in goroutines, to reuse a parsed [*Query].
+// But for arguments, do not give values sharing same data between goroutines.
+func (e *Query) Run(v any) Iter {
+ return e.RunWithContext(context.Background(), v)
+}
+
+// RunWithContext runs the query with context.
+func (e *Query) RunWithContext(ctx context.Context, v any) Iter {
+ code, err := Compile(e)
+ if err != nil {
+ return NewIter(err)
+ }
+ return code.RunWithContext(ctx, v)
+}
+
+func (e *Query) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *Query) writeTo(s *strings.Builder) {
+ if e.Meta != nil {
+ s.WriteString("module ")
+ e.Meta.writeTo(s)
+ s.WriteString(";\n")
+ }
+ for _, im := range e.Imports {
+ im.writeTo(s)
+ }
+ for i, fd := range e.FuncDefs {
+ if i > 0 {
+ s.WriteByte(' ')
+ }
+ fd.writeTo(s)
+ }
+ if len(e.FuncDefs) > 0 {
+ s.WriteByte(' ')
+ }
+ if e.Func != "" {
+ s.WriteString(e.Func)
+ } else if e.Term != nil {
+ e.Term.writeTo(s)
+ } else if e.Right != nil {
+ e.Left.writeTo(s)
+ if e.Op == OpComma {
+ s.WriteString(", ")
+ } else {
+ s.WriteByte(' ')
+ s.WriteString(e.Op.String())
+ s.WriteByte(' ')
+ }
+ e.Right.writeTo(s)
+ }
+}
+
+func (e *Query) minify() {
+ for _, e := range e.FuncDefs {
+ e.Minify()
+ }
+ if e.Term != nil {
+ if name := e.Term.toFunc(); name != "" {
+ e.Term = nil
+ e.Func = name
+ } else {
+ e.Term.minify()
+ }
+ } else if e.Right != nil {
+ e.Left.minify()
+ e.Right.minify()
+ }
+}
+
+func (e *Query) toIndexKey() any {
+ if e.Term == nil {
+ return nil
+ }
+ return e.Term.toIndexKey()
+}
+
+func (e *Query) toIndices(xs []any) []any {
+ if e.Term == nil {
+ return nil
+ }
+ return e.Term.toIndices(xs)
+}
+
+// Import ...
+type Import struct {
+ ImportPath string
+ ImportAlias string
+ IncludePath string
+ Meta *ConstObject
+}
+
+func (e *Import) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *Import) writeTo(s *strings.Builder) {
+ if e.ImportPath != "" {
+ s.WriteString("import ")
+ jsonEncodeString(s, e.ImportPath)
+ s.WriteString(" as ")
+ s.WriteString(e.ImportAlias)
+ } else {
+ s.WriteString("include ")
+ jsonEncodeString(s, e.IncludePath)
+ }
+ if e.Meta != nil {
+ s.WriteByte(' ')
+ e.Meta.writeTo(s)
+ }
+ s.WriteString(";\n")
+}
+
+// FuncDef ...
+type FuncDef struct {
+ Name string
+ Args []string
+ Body *Query
+}
+
+func (e *FuncDef) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *FuncDef) writeTo(s *strings.Builder) {
+ s.WriteString("def ")
+ s.WriteString(e.Name)
+ if len(e.Args) > 0 {
+ s.WriteByte('(')
+ for i, e := range e.Args {
+ if i > 0 {
+ s.WriteString("; ")
+ }
+ s.WriteString(e)
+ }
+ s.WriteByte(')')
+ }
+ s.WriteString(": ")
+ e.Body.writeTo(s)
+ s.WriteByte(';')
+}
+
+// Minify ...
+func (e *FuncDef) Minify() {
+ e.Body.minify()
+}
+
+// Term ...
+type Term struct {
+ Type TermType
+ Index *Index
+ Func *Func
+ Object *Object
+ Array *Array
+ Number string
+ Unary *Unary
+ Format string
+ Str *String
+ If *If
+ Try *Try
+ Reduce *Reduce
+ Foreach *Foreach
+ Label *Label
+ Break string
+ Query *Query
+ SuffixList []*Suffix
+}
+
+func (e *Term) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *Term) writeTo(s *strings.Builder) {
+ switch e.Type {
+ case TermTypeIdentity:
+ s.WriteByte('.')
+ case TermTypeRecurse:
+ s.WriteString("..")
+ case TermTypeNull:
+ s.WriteString("null")
+ case TermTypeTrue:
+ s.WriteString("true")
+ case TermTypeFalse:
+ s.WriteString("false")
+ case TermTypeIndex:
+ e.Index.writeTo(s)
+ case TermTypeFunc:
+ e.Func.writeTo(s)
+ case TermTypeObject:
+ e.Object.writeTo(s)
+ case TermTypeArray:
+ e.Array.writeTo(s)
+ case TermTypeNumber:
+ s.WriteString(e.Number)
+ case TermTypeUnary:
+ e.Unary.writeTo(s)
+ case TermTypeFormat:
+ s.WriteString(e.Format)
+ if e.Str != nil {
+ s.WriteByte(' ')
+ e.Str.writeTo(s)
+ }
+ case TermTypeString:
+ e.Str.writeTo(s)
+ case TermTypeIf:
+ e.If.writeTo(s)
+ case TermTypeTry:
+ e.Try.writeTo(s)
+ case TermTypeReduce:
+ e.Reduce.writeTo(s)
+ case TermTypeForeach:
+ e.Foreach.writeTo(s)
+ case TermTypeLabel:
+ e.Label.writeTo(s)
+ case TermTypeBreak:
+ s.WriteString("break ")
+ s.WriteString(e.Break)
+ case TermTypeQuery:
+ s.WriteByte('(')
+ e.Query.writeTo(s)
+ s.WriteByte(')')
+ }
+ for _, e := range e.SuffixList {
+ e.writeTo(s)
+ }
+}
+
+func (e *Term) minify() {
+ switch e.Type {
+ case TermTypeIndex:
+ e.Index.minify()
+ case TermTypeFunc:
+ e.Func.minify()
+ case TermTypeObject:
+ e.Object.minify()
+ case TermTypeArray:
+ e.Array.minify()
+ case TermTypeUnary:
+ e.Unary.minify()
+ case TermTypeFormat:
+ if e.Str != nil {
+ e.Str.minify()
+ }
+ case TermTypeString:
+ e.Str.minify()
+ case TermTypeIf:
+ e.If.minify()
+ case TermTypeTry:
+ e.Try.minify()
+ case TermTypeReduce:
+ e.Reduce.minify()
+ case TermTypeForeach:
+ e.Foreach.minify()
+ case TermTypeLabel:
+ e.Label.minify()
+ case TermTypeQuery:
+ e.Query.minify()
+ }
+ for _, e := range e.SuffixList {
+ e.minify()
+ }
+}
+
+func (e *Term) toFunc() string {
+ if len(e.SuffixList) != 0 {
+ return ""
+ }
+ // ref: compiler#compileQuery
+ switch e.Type {
+ case TermTypeIdentity:
+ return "."
+ case TermTypeRecurse:
+ return ".."
+ case TermTypeNull:
+ return "null"
+ case TermTypeTrue:
+ return "true"
+ case TermTypeFalse:
+ return "false"
+ case TermTypeFunc:
+ return e.Func.toFunc()
+ default:
+ return ""
+ }
+}
+
+func (e *Term) toIndexKey() any {
+ switch e.Type {
+ case TermTypeNumber:
+ return toNumber(e.Number)
+ case TermTypeUnary:
+ return e.Unary.toNumber()
+ case TermTypeString:
+ if e.Str.Queries == nil {
+ return e.Str.Str
+ }
+ return nil
+ default:
+ return nil
+ }
+}
+
+func (e *Term) toIndices(xs []any) []any {
+ switch e.Type {
+ case TermTypeIndex:
+ if xs = e.Index.toIndices(xs); xs == nil {
+ return nil
+ }
+ case TermTypeQuery:
+ if xs = e.Query.toIndices(xs); xs == nil {
+ return nil
+ }
+ default:
+ return nil
+ }
+ for _, s := range e.SuffixList {
+ if xs = s.toIndices(xs); xs == nil {
+ return nil
+ }
+ }
+ return xs
+}
+
+func (e *Term) toNumber() any {
+ if e.Type == TermTypeNumber {
+ return toNumber(e.Number)
+ }
+ return nil
+}
+
+// Unary ...
+type Unary struct {
+ Op Operator
+ Term *Term
+}
+
+func (e *Unary) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *Unary) writeTo(s *strings.Builder) {
+ s.WriteString(e.Op.String())
+ e.Term.writeTo(s)
+}
+
+func (e *Unary) minify() {
+ e.Term.minify()
+}
+
+func (e *Unary) toNumber() any {
+ v := e.Term.toNumber()
+ if v != nil && e.Op == OpSub {
+ v = funcOpNegate(v)
+ }
+ return v
+}
+
+// Pattern ...
+type Pattern struct {
+ Name string
+ Array []*Pattern
+ Object []*PatternObject
+}
+
+func (e *Pattern) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *Pattern) writeTo(s *strings.Builder) {
+ if e.Name != "" {
+ s.WriteString(e.Name)
+ } else if len(e.Array) > 0 {
+ s.WriteByte('[')
+ for i, e := range e.Array {
+ if i > 0 {
+ s.WriteString(", ")
+ }
+ e.writeTo(s)
+ }
+ s.WriteByte(']')
+ } else if len(e.Object) > 0 {
+ s.WriteByte('{')
+ for i, e := range e.Object {
+ if i > 0 {
+ s.WriteString(", ")
+ }
+ e.writeTo(s)
+ }
+ s.WriteByte('}')
+ }
+}
+
+// PatternObject ...
+type PatternObject struct {
+ Key string
+ KeyString *String
+ KeyQuery *Query
+ Val *Pattern
+}
+
+func (e *PatternObject) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *PatternObject) writeTo(s *strings.Builder) {
+ if e.Key != "" {
+ s.WriteString(e.Key)
+ } else if e.KeyString != nil {
+ e.KeyString.writeTo(s)
+ } else if e.KeyQuery != nil {
+ s.WriteByte('(')
+ e.KeyQuery.writeTo(s)
+ s.WriteByte(')')
+ }
+ if e.Val != nil {
+ s.WriteString(": ")
+ e.Val.writeTo(s)
+ }
+}
+
+// Index ...
+type Index struct {
+ Name string
+ Str *String
+ Start *Query
+ End *Query
+ IsSlice bool
+}
+
+func (e *Index) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *Index) writeTo(s *strings.Builder) {
+ if l := s.Len(); l > 0 {
+ // ". .x" != "..x" and "0 .x" != "0.x"
+ if c := s.String()[l-1]; c == '.' || '0' <= c && c <= '9' {
+ s.WriteByte(' ')
+ }
+ }
+ s.WriteByte('.')
+ e.writeSuffixTo(s)
+}
+
+func (e *Index) writeSuffixTo(s *strings.Builder) {
+ if e.Name != "" {
+ s.WriteString(e.Name)
+ } else if e.Str != nil {
+ e.Str.writeTo(s)
+ } else {
+ s.WriteByte('[')
+ if e.IsSlice {
+ if e.Start != nil {
+ e.Start.writeTo(s)
+ }
+ s.WriteByte(':')
+ if e.End != nil {
+ e.End.writeTo(s)
+ }
+ } else {
+ e.Start.writeTo(s)
+ }
+ s.WriteByte(']')
+ }
+}
+
+func (e *Index) minify() {
+ if e.Str != nil {
+ e.Str.minify()
+ }
+ if e.Start != nil {
+ e.Start.minify()
+ }
+ if e.End != nil {
+ e.End.minify()
+ }
+}
+
+func (e *Index) toIndexKey() any {
+ if e.Name != "" {
+ return e.Name
+ } else if e.Str != nil {
+ if e.Str.Queries == nil {
+ return e.Str.Str
+ }
+ } else if !e.IsSlice {
+ return e.Start.toIndexKey()
+ } else {
+ var start, end any
+ ok := true
+ if e.Start != nil {
+ start = e.Start.toIndexKey()
+ ok = start != nil
+ }
+ if e.End != nil && ok {
+ end = e.End.toIndexKey()
+ ok = end != nil
+ }
+ if ok {
+ return map[string]any{"start": start, "end": end}
+ }
+ }
+ return nil
+}
+
+func (e *Index) toIndices(xs []any) []any {
+ if k := e.toIndexKey(); k != nil {
+ return append(xs, k)
+ }
+ return nil
+}
+
+// Func ...
+type Func struct {
+ Name string
+ Args []*Query
+}
+
+func (e *Func) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *Func) writeTo(s *strings.Builder) {
+ s.WriteString(e.Name)
+ if len(e.Args) > 0 {
+ s.WriteByte('(')
+ for i, e := range e.Args {
+ if i > 0 {
+ s.WriteString("; ")
+ }
+ e.writeTo(s)
+ }
+ s.WriteByte(')')
+ }
+}
+
+func (e *Func) minify() {
+ for _, x := range e.Args {
+ x.minify()
+ }
+}
+
+func (e *Func) toFunc() string {
+ if len(e.Args) != 0 {
+ return ""
+ }
+ return e.Name
+}
+
+// String ...
+type String struct {
+ Str string
+ Queries []*Query
+}
+
+func (e *String) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *String) writeTo(s *strings.Builder) {
+ if e.Queries == nil {
+ jsonEncodeString(s, e.Str)
+ return
+ }
+ s.WriteByte('"')
+ for _, e := range e.Queries {
+ if e.Term.Str == nil {
+ s.WriteString(`\`)
+ e.writeTo(s)
+ } else {
+ es := e.String()
+ s.WriteString(es[1 : len(es)-1])
+ }
+ }
+ s.WriteByte('"')
+}
+
+func (e *String) minify() {
+ for _, e := range e.Queries {
+ e.minify()
+ }
+}
+
+// Object ...
+type Object struct {
+ KeyVals []*ObjectKeyVal
+}
+
+func (e *Object) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *Object) writeTo(s *strings.Builder) {
+ if len(e.KeyVals) == 0 {
+ s.WriteString("{}")
+ return
+ }
+ s.WriteString("{ ")
+ for i, kv := range e.KeyVals {
+ if i > 0 {
+ s.WriteString(", ")
+ }
+ kv.writeTo(s)
+ }
+ s.WriteString(" }")
+}
+
+func (e *Object) minify() {
+ for _, e := range e.KeyVals {
+ e.minify()
+ }
+}
+
+// ObjectKeyVal ...
+type ObjectKeyVal struct {
+ Key string
+ KeyString *String
+ KeyQuery *Query
+ Val *ObjectVal
+}
+
+func (e *ObjectKeyVal) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *ObjectKeyVal) writeTo(s *strings.Builder) {
+ if e.Key != "" {
+ s.WriteString(e.Key)
+ } else if e.KeyString != nil {
+ e.KeyString.writeTo(s)
+ } else if e.KeyQuery != nil {
+ s.WriteByte('(')
+ e.KeyQuery.writeTo(s)
+ s.WriteByte(')')
+ }
+ if e.Val != nil {
+ s.WriteString(": ")
+ e.Val.writeTo(s)
+ }
+}
+
+func (e *ObjectKeyVal) minify() {
+ if e.KeyString != nil {
+ e.KeyString.minify()
+ } else if e.KeyQuery != nil {
+ e.KeyQuery.minify()
+ }
+ if e.Val != nil {
+ e.Val.minify()
+ }
+}
+
+// ObjectVal ...
+type ObjectVal struct {
+ Queries []*Query
+}
+
+func (e *ObjectVal) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *ObjectVal) writeTo(s *strings.Builder) {
+ for i, e := range e.Queries {
+ if i > 0 {
+ s.WriteString(" | ")
+ }
+ e.writeTo(s)
+ }
+}
+
+func (e *ObjectVal) minify() {
+ for _, e := range e.Queries {
+ e.minify()
+ }
+}
+
+// Array ...
+type Array struct {
+ Query *Query
+}
+
+func (e *Array) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *Array) writeTo(s *strings.Builder) {
+ s.WriteByte('[')
+ if e.Query != nil {
+ e.Query.writeTo(s)
+ }
+ s.WriteByte(']')
+}
+
+func (e *Array) minify() {
+ if e.Query != nil {
+ e.Query.minify()
+ }
+}
+
+// Suffix ...
+type Suffix struct {
+ Index *Index
+ Iter bool
+ Optional bool
+ Bind *Bind
+}
+
+func (e *Suffix) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *Suffix) writeTo(s *strings.Builder) {
+ if e.Index != nil {
+ if e.Index.Name != "" || e.Index.Str != nil {
+ e.Index.writeTo(s)
+ } else {
+ e.Index.writeSuffixTo(s)
+ }
+ } else if e.Iter {
+ s.WriteString("[]")
+ } else if e.Optional {
+ s.WriteByte('?')
+ } else if e.Bind != nil {
+ e.Bind.writeTo(s)
+ }
+}
+
+func (e *Suffix) minify() {
+ if e.Index != nil {
+ e.Index.minify()
+ } else if e.Bind != nil {
+ e.Bind.minify()
+ }
+}
+
+func (e *Suffix) toTerm() *Term {
+ if e.Index != nil {
+ return &Term{Type: TermTypeIndex, Index: e.Index}
+ } else if e.Iter {
+ return &Term{Type: TermTypeIdentity, SuffixList: []*Suffix{{Iter: true}}}
+ } else {
+ return nil
+ }
+}
+
+func (e *Suffix) toIndices(xs []any) []any {
+ if e.Index == nil {
+ return nil
+ }
+ return e.Index.toIndices(xs)
+}
+
+// Bind ...
+type Bind struct {
+ Patterns []*Pattern
+ Body *Query
+}
+
+func (e *Bind) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *Bind) writeTo(s *strings.Builder) {
+ for i, p := range e.Patterns {
+ if i == 0 {
+ s.WriteString(" as ")
+ p.writeTo(s)
+ s.WriteByte(' ')
+ } else {
+ s.WriteString("?// ")
+ p.writeTo(s)
+ s.WriteByte(' ')
+ }
+ }
+ s.WriteString("| ")
+ e.Body.writeTo(s)
+}
+
+func (e *Bind) minify() {
+ e.Body.minify()
+}
+
+// If ...
+type If struct {
+ Cond *Query
+ Then *Query
+ Elif []*IfElif
+ Else *Query
+}
+
+func (e *If) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *If) writeTo(s *strings.Builder) {
+ s.WriteString("if ")
+ e.Cond.writeTo(s)
+ s.WriteString(" then ")
+ e.Then.writeTo(s)
+ for _, e := range e.Elif {
+ s.WriteByte(' ')
+ e.writeTo(s)
+ }
+ if e.Else != nil {
+ s.WriteString(" else ")
+ e.Else.writeTo(s)
+ }
+ s.WriteString(" end")
+}
+
+func (e *If) minify() {
+ e.Cond.minify()
+ e.Then.minify()
+ for _, x := range e.Elif {
+ x.minify()
+ }
+ if e.Else != nil {
+ e.Else.minify()
+ }
+}
+
+// IfElif ...
+type IfElif struct {
+ Cond *Query
+ Then *Query
+}
+
+func (e *IfElif) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *IfElif) writeTo(s *strings.Builder) {
+ s.WriteString("elif ")
+ e.Cond.writeTo(s)
+ s.WriteString(" then ")
+ e.Then.writeTo(s)
+}
+
+func (e *IfElif) minify() {
+ e.Cond.minify()
+ e.Then.minify()
+}
+
+// Try ...
+type Try struct {
+ Body *Query
+ Catch *Query
+}
+
+func (e *Try) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *Try) writeTo(s *strings.Builder) {
+ s.WriteString("try ")
+ e.Body.writeTo(s)
+ if e.Catch != nil {
+ s.WriteString(" catch ")
+ e.Catch.writeTo(s)
+ }
+}
+
+func (e *Try) minify() {
+ e.Body.minify()
+ if e.Catch != nil {
+ e.Catch.minify()
+ }
+}
+
+// Reduce ...
+type Reduce struct {
+ Term *Term
+ Pattern *Pattern
+ Start *Query
+ Update *Query
+}
+
+func (e *Reduce) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *Reduce) writeTo(s *strings.Builder) {
+ s.WriteString("reduce ")
+ e.Term.writeTo(s)
+ s.WriteString(" as ")
+ e.Pattern.writeTo(s)
+ s.WriteString(" (")
+ e.Start.writeTo(s)
+ s.WriteString("; ")
+ e.Update.writeTo(s)
+ s.WriteByte(')')
+}
+
+func (e *Reduce) minify() {
+ e.Term.minify()
+ e.Start.minify()
+ e.Update.minify()
+}
+
+// Foreach ...
+type Foreach struct {
+ Term *Term
+ Pattern *Pattern
+ Start *Query
+ Update *Query
+ Extract *Query
+}
+
+func (e *Foreach) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *Foreach) writeTo(s *strings.Builder) {
+ s.WriteString("foreach ")
+ e.Term.writeTo(s)
+ s.WriteString(" as ")
+ e.Pattern.writeTo(s)
+ s.WriteString(" (")
+ e.Start.writeTo(s)
+ s.WriteString("; ")
+ e.Update.writeTo(s)
+ if e.Extract != nil {
+ s.WriteString("; ")
+ e.Extract.writeTo(s)
+ }
+ s.WriteByte(')')
+}
+
+func (e *Foreach) minify() {
+ e.Term.minify()
+ e.Start.minify()
+ e.Update.minify()
+ if e.Extract != nil {
+ e.Extract.minify()
+ }
+}
+
+// Label ...
+type Label struct {
+ Ident string
+ Body *Query
+}
+
+func (e *Label) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *Label) writeTo(s *strings.Builder) {
+ s.WriteString("label ")
+ s.WriteString(e.Ident)
+ s.WriteString(" | ")
+ e.Body.writeTo(s)
+}
+
+func (e *Label) minify() {
+ e.Body.minify()
+}
+
+// ConstTerm ...
+type ConstTerm struct {
+ Object *ConstObject
+ Array *ConstArray
+ Number string
+ Str string
+ Null bool
+ True bool
+ False bool
+}
+
+func (e *ConstTerm) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *ConstTerm) writeTo(s *strings.Builder) {
+ if e.Object != nil {
+ e.Object.writeTo(s)
+ } else if e.Array != nil {
+ e.Array.writeTo(s)
+ } else if e.Number != "" {
+ s.WriteString(e.Number)
+ } else if e.Null {
+ s.WriteString("null")
+ } else if e.True {
+ s.WriteString("true")
+ } else if e.False {
+ s.WriteString("false")
+ } else {
+ jsonEncodeString(s, e.Str)
+ }
+}
+
+func (e *ConstTerm) toValue() any {
+ if e.Object != nil {
+ return e.Object.ToValue()
+ } else if e.Array != nil {
+ return e.Array.toValue()
+ } else if e.Number != "" {
+ return toNumber(e.Number)
+ } else if e.Null {
+ return nil
+ } else if e.True {
+ return true
+ } else if e.False {
+ return false
+ } else {
+ return e.Str
+ }
+}
+
+func (e *ConstTerm) toString() (string, bool) {
+ if e.Object != nil || e.Array != nil ||
+ e.Number != "" || e.Null || e.True || e.False {
+ return "", false
+ }
+ return e.Str, true
+}
+
+// ConstObject ...
+type ConstObject struct {
+ KeyVals []*ConstObjectKeyVal
+}
+
+func (e *ConstObject) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *ConstObject) writeTo(s *strings.Builder) {
+ if len(e.KeyVals) == 0 {
+ s.WriteString("{}")
+ return
+ }
+ s.WriteString("{ ")
+ for i, kv := range e.KeyVals {
+ if i > 0 {
+ s.WriteString(", ")
+ }
+ kv.writeTo(s)
+ }
+ s.WriteString(" }")
+}
+
+// ToValue converts the object to map[string]any.
+func (e *ConstObject) ToValue() map[string]any {
+ if e == nil {
+ return nil
+ }
+ v := make(map[string]any, len(e.KeyVals))
+ for _, e := range e.KeyVals {
+ key := e.Key
+ if key == "" {
+ key = e.KeyString
+ }
+ v[key] = e.Val.toValue()
+ }
+ return v
+}
+
+// ConstObjectKeyVal ...
+type ConstObjectKeyVal struct {
+ Key string
+ KeyString string
+ Val *ConstTerm
+}
+
+func (e *ConstObjectKeyVal) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *ConstObjectKeyVal) writeTo(s *strings.Builder) {
+ if e.Key != "" {
+ s.WriteString(e.Key)
+ } else {
+ jsonEncodeString(s, e.KeyString)
+ }
+ s.WriteString(": ")
+ e.Val.writeTo(s)
+}
+
+// ConstArray ...
+type ConstArray struct {
+ Elems []*ConstTerm
+}
+
+func (e *ConstArray) String() string {
+ var s strings.Builder
+ e.writeTo(&s)
+ return s.String()
+}
+
+func (e *ConstArray) writeTo(s *strings.Builder) {
+ s.WriteByte('[')
+ for i, e := range e.Elems {
+ if i > 0 {
+ s.WriteString(", ")
+ }
+ e.writeTo(s)
+ }
+ s.WriteByte(']')
+}
+
+func (e *ConstArray) toValue() []any {
+ v := make([]any, len(e.Elems))
+ for i, e := range e.Elems {
+ v[i] = e.toValue()
+ }
+ return v
+}
diff --git a/vendor/github.com/itchyny/gojq/release.go b/vendor/github.com/itchyny/gojq/release.go
new file mode 100644
index 000000000..c34dfb45c
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/release.go
@@ -0,0 +1,16 @@
+//go:build !gojq_debug
+// +build !gojq_debug
+
+package gojq
+
+type codeinfo struct{}
+
+func (c *compiler) appendCodeInfo(any) {}
+
+func (c *compiler) deleteCodeInfo(string) {}
+
+func (env *env) debugCodes() {}
+
+func (env *env) debugState(int, bool) {}
+
+func (env *env) debugForks(int, string) {}
diff --git a/vendor/github.com/itchyny/gojq/scope_stack.go b/vendor/github.com/itchyny/gojq/scope_stack.go
new file mode 100644
index 000000000..e140ca15b
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/scope_stack.go
@@ -0,0 +1,52 @@
+package gojq
+
+type scopeStack struct {
+ data []scopeBlock
+ index int
+ limit int
+}
+
+type scopeBlock struct {
+ value scope
+ next int
+}
+
+func newScopeStack() *scopeStack {
+ return &scopeStack{index: -1, limit: -1}
+}
+
+func (s *scopeStack) push(v scope) {
+ b := scopeBlock{v, s.index}
+ i := s.index + 1
+ if i <= s.limit {
+ i = s.limit + 1
+ }
+ s.index = i
+ if i < len(s.data) {
+ s.data[i] = b
+ } else {
+ s.data = append(s.data, b)
+ }
+}
+
+func (s *scopeStack) pop() scope {
+ b := s.data[s.index]
+ s.index = b.next
+ return b.value
+}
+
+func (s *scopeStack) empty() bool {
+ return s.index < 0
+}
+
+func (s *scopeStack) save() (index, limit int) {
+ index, limit = s.index, s.limit
+ if s.index > s.limit {
+ s.limit = s.index
+ }
+ return
+}
+
+func (s *scopeStack) restore(index, limit int) {
+ s.index, s.limit = index, limit
+}
diff --git a/vendor/github.com/itchyny/gojq/stack.go b/vendor/github.com/itchyny/gojq/stack.go
new file mode 100644
index 000000000..a0e265c8c
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/stack.go
@@ -0,0 +1,56 @@
+package gojq
+
+type stack struct {
+ data []block
+ index int
+ limit int
+}
+
+type block struct {
+ value any
+ next int
+}
+
+func newStack() *stack {
+ return &stack{index: -1, limit: -1}
+}
+
+func (s *stack) push(v any) {
+ b := block{v, s.index}
+ i := s.index + 1
+ if i <= s.limit {
+ i = s.limit + 1
+ }
+ s.index = i
+ if i < len(s.data) {
+ s.data[i] = b
+ } else {
+ s.data = append(s.data, b)
+ }
+}
+
+func (s *stack) pop() any {
+ b := s.data[s.index]
+ s.index = b.next
+ return b.value
+}
+
+func (s *stack) top() any {
+ return s.data[s.index].value
+}
+
+func (s *stack) empty() bool {
+ return s.index < 0
+}
+
+func (s *stack) save() (index, limit int) {
+ index, limit = s.index, s.limit
+ if s.index > s.limit {
+ s.limit = s.index
+ }
+ return
+}
+
+func (s *stack) restore(index, limit int) {
+ s.index, s.limit = index, limit
+}
diff --git a/vendor/github.com/itchyny/gojq/term_type.go b/vendor/github.com/itchyny/gojq/term_type.go
new file mode 100644
index 000000000..941e7ba9c
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/term_type.go
@@ -0,0 +1,77 @@
+package gojq
+
+// TermType represents the type of [Term].
+type TermType int
+
+// TermType list.
+const (
+ TermTypeIdentity TermType = iota + 1
+ TermTypeRecurse
+ TermTypeNull
+ TermTypeTrue
+ TermTypeFalse
+ TermTypeIndex
+ TermTypeFunc
+ TermTypeObject
+ TermTypeArray
+ TermTypeNumber
+ TermTypeUnary
+ TermTypeFormat
+ TermTypeString
+ TermTypeIf
+ TermTypeTry
+ TermTypeReduce
+ TermTypeForeach
+ TermTypeLabel
+ TermTypeBreak
+ TermTypeQuery
+)
+
+// GoString implements [fmt.GoStringer].
+func (termType TermType) GoString() (str string) {
+ defer func() { str = "gojq." + str }()
+ switch termType {
+ case TermTypeIdentity:
+ return "TermTypeIdentity"
+ case TermTypeRecurse:
+ return "TermTypeRecurse"
+ case TermTypeNull:
+ return "TermTypeNull"
+ case TermTypeTrue:
+ return "TermTypeTrue"
+ case TermTypeFalse:
+ return "TermTypeFalse"
+ case TermTypeIndex:
+ return "TermTypeIndex"
+ case TermTypeFunc:
+ return "TermTypeFunc"
+ case TermTypeObject:
+ return "TermTypeObject"
+ case TermTypeArray:
+ return "TermTypeArray"
+ case TermTypeNumber:
+ return "TermTypeNumber"
+ case TermTypeUnary:
+ return "TermTypeUnary"
+ case TermTypeFormat:
+ return "TermTypeFormat"
+ case TermTypeString:
+ return "TermTypeString"
+ case TermTypeIf:
+ return "TermTypeIf"
+ case TermTypeTry:
+ return "TermTypeTry"
+ case TermTypeReduce:
+ return "TermTypeReduce"
+ case TermTypeForeach:
+ return "TermTypeForeach"
+ case TermTypeLabel:
+ return "TermTypeLabel"
+ case TermTypeBreak:
+ return "TermTypeBreak"
+ case TermTypeQuery:
+ return "TermTypeQuery"
+ default:
+ panic(termType)
+ }
+}
diff --git a/vendor/github.com/itchyny/gojq/type.go b/vendor/github.com/itchyny/gojq/type.go
new file mode 100644
index 000000000..bb388e20e
--- /dev/null
+++ b/vendor/github.com/itchyny/gojq/type.go
@@ -0,0 +1,29 @@
+package gojq
+
+import (
+ "fmt"
+ "math/big"
+)
+
+// TypeOf returns the jq-flavored type name of v.
+//
+// This method is used by built-in type/0 function, and accepts only limited
+// types (nil, bool, int, float64, *big.Int, string, []any, and map[string]any).
+func TypeOf(v any) string {
+ switch v.(type) {
+ case nil:
+ return "null"
+ case bool:
+ return "boolean"
+ case int, float64, *big.Int:
+ return "number"
+ case string:
+ return "string"
+ case []any:
+ return "array"
+ case map[string]any:
+ return "object"
+ default:
+ panic(fmt.Sprintf("invalid type: %[1]T (%[1]v)", v))
+ }
+}
diff --git a/vendor/github.com/itchyny/timefmt-go/CHANGELOG.md b/vendor/github.com/itchyny/timefmt-go/CHANGELOG.md
new file mode 100644
index 000000000..61a4e9dc4
--- /dev/null
+++ b/vendor/github.com/itchyny/timefmt-go/CHANGELOG.md
@@ -0,0 +1,21 @@
+# Changelog
+## [v0.1.5](https://github.com/itchyny/timefmt-go/compare/v0.1.4..v0.1.5) (2022-12-01)
+* support parsing time zone offset with name using both `%z` and `%Z`
+
+## [v0.1.4](https://github.com/itchyny/timefmt-go/compare/v0.1.3..v0.1.4) (2022-09-01)
+* improve documents
+* drop support for Go 1.16
+
+## [v0.1.3](https://github.com/itchyny/timefmt-go/compare/v0.1.2..v0.1.3) (2021-04-14)
+* implement `ParseInLocation` for configuring the default location
+
+## [v0.1.2](https://github.com/itchyny/timefmt-go/compare/v0.1.1..v0.1.2) (2021-02-22)
+* implement parsing/formatting time zone offset with colons (`%:z`, `%::z`, `%:::z`)
+* recognize `Z` as UTC on parsing time zone offset (`%z`)
+* fix padding on formatting time zone offset (`%z`)
+
+## [v0.1.1](https://github.com/itchyny/timefmt-go/compare/v0.1.0..v0.1.1) (2020-09-01)
+* fix overflow check in 32-bit architecture
+
+## [v0.1.0](https://github.com/itchyny/timefmt-go/compare/2c02364..v0.1.0) (2020-08-16)
+* initial implementation
diff --git a/vendor/github.com/itchyny/timefmt-go/LICENSE b/vendor/github.com/itchyny/timefmt-go/LICENSE
new file mode 100644
index 000000000..84d6cb033
--- /dev/null
+++ b/vendor/github.com/itchyny/timefmt-go/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2020-2022 itchyny
+
+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/itchyny/timefmt-go/Makefile b/vendor/github.com/itchyny/timefmt-go/Makefile
new file mode 100644
index 000000000..a87cb2864
--- /dev/null
+++ b/vendor/github.com/itchyny/timefmt-go/Makefile
@@ -0,0 +1,20 @@
+GOBIN ?= $(shell go env GOPATH)/bin
+
+.PHONY: all
+all: test
+
+.PHONY: test
+test:
+ go test -v -race ./...
+
+.PHONY: lint
+lint: $(GOBIN)/staticcheck
+ go vet ./...
+ staticcheck -checks all,-ST1000 ./...
+
+$(GOBIN)/staticcheck:
+ go install honnef.co/go/tools/cmd/staticcheck@latest
+
+.PHONY: clean
+clean:
+ go clean
diff --git a/vendor/github.com/itchyny/timefmt-go/README.md b/vendor/github.com/itchyny/timefmt-go/README.md
new file mode 100644
index 000000000..f01af9611
--- /dev/null
+++ b/vendor/github.com/itchyny/timefmt-go/README.md
@@ -0,0 +1,69 @@
+# timefmt-go
+[![CI Status](https://github.com/itchyny/timefmt-go/workflows/CI/badge.svg)](https://github.com/itchyny/timefmt-go/actions)
+[![Go Report Card](https://goreportcard.com/badge/github.com/itchyny/timefmt-go)](https://goreportcard.com/report/github.com/itchyny/timefmt-go)
+[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/itchyny/timefmt-go/blob/main/LICENSE)
+[![release](https://img.shields.io/github/release/itchyny/timefmt-go/all.svg)](https://github.com/itchyny/timefmt-go/releases)
+[![pkg.go.dev](https://pkg.go.dev/badge/github.com/itchyny/timefmt-go)](https://pkg.go.dev/github.com/itchyny/timefmt-go)
+
+### Efficient time formatting library (strftime, strptime) for Golang
+This is a Go language package for formatting and parsing date time strings.
+
+```go
+package main
+
+import (
+ "fmt"
+ "log"
+
+ "github.com/itchyny/timefmt-go"
+)
+
+func main() {
+ t, err := timefmt.Parse("2020/07/24 09:07:29", "%Y/%m/%d %H:%M:%S")
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Println(t) // 2020-07-24 09:07:29 +0000 UTC
+
+ str := timefmt.Format(t, "%Y/%m/%d %H:%M:%S")
+ fmt.Println(str) // 2020/07/24 09:07:29
+
+ str = timefmt.Format(t, "%a, %d %b %Y %T %z")
+ fmt.Println(str) // Fri, 24 Jul 2020 09:07:29 +0000
+}
+```
+
+Please refer to [`man 3 strftime`](https://linux.die.net/man/3/strftime) and
+[`man 3 strptime`](https://linux.die.net/man/3/strptime) for formatters.
+As an extension, `%f` directive is supported for zero-padded microseconds, which originates from Python.
+Note that `E` and `O` modifier characters are not supported.
+
+## Comparison to other libraries
+- This library
+ - provides both formatting and parsing functions in pure Go language,
+ - depends only on the Go standard libraries not to grow up dependency.
+- `Format` (`strftime`) implements glibc extensions including
+ - width specifier like `%6Y %10B %4Z` (limited to 1024 bytes),
+ - omitting padding modifier like `%-y-%-m-%-d`,
+ - space padding modifier like `%_y-%_m-%_d`,
+ - upper case modifier like `%^a %^b`,
+ - swapping case modifier like `%#Z`,
+ - time zone offset modifier like `%:z %::z %:::z`,
+ - and its performance is very good.
+- `AppendFormat` is provided for reducing allocations.
+- `Parse` (`strptime`) allows to parse
+ - composed directives like `%F %T`,
+ - century years like `%C %y`,
+ - week names like `%A` `%a` (parsed results are discarded).
+- `ParseInLocation` is provided for configuring the default location.
+
+![](https://user-images.githubusercontent.com/375258/88606920-de475c80-d0b8-11ea-8d40-cbfee9e35c2e.jpg)
+
+## Bug Tracker
+Report bug at [Issues・itchyny/timefmt-go - GitHub](https://github.com/itchyny/timefmt-go/issues).
+
+## Author
+itchyny (https://github.com/itchyny)
+
+## License
+This software is released under the MIT License, see LICENSE.
diff --git a/vendor/github.com/itchyny/timefmt-go/format.go b/vendor/github.com/itchyny/timefmt-go/format.go
new file mode 100644
index 000000000..eea976ee9
--- /dev/null
+++ b/vendor/github.com/itchyny/timefmt-go/format.go
@@ -0,0 +1,537 @@
+package timefmt
+
+import (
+ "math"
+ "strconv"
+ "time"
+)
+
+// Format time to string using the format.
+func Format(t time.Time, format string) string {
+ return string(AppendFormat(make([]byte, 0, 64), t, format))
+}
+
+// AppendFormat appends formatted time string to the buffer.
+func AppendFormat(buf []byte, t time.Time, format string) []byte {
+ year, month, day := t.Date()
+ hour, min, sec := t.Clock()
+ var width, colons int
+ var padding byte
+ var pending string
+ var upper, swap bool
+ for i := 0; i < len(format); i++ {
+ if b := format[i]; b == '%' {
+ if i++; i == len(format) {
+ buf = append(buf, '%')
+ break
+ }
+ b, width, padding, upper, swap = format[i], 0, '0', false, false
+ L:
+ switch b {
+ case '-':
+ if pending != "" {
+ buf = append(buf, '-')
+ break
+ }
+ if i++; i == len(format) {
+ goto K
+ }
+ padding = ^paddingMask
+ b = format[i]
+ goto L
+ case '_':
+ if i++; i == len(format) {
+ goto K
+ }
+ padding = ' ' | ^paddingMask
+ b = format[i]
+ goto L
+ case '^':
+ if i++; i == len(format) {
+ goto K
+ }
+ upper = true
+ b = format[i]
+ goto L
+ case '#':
+ if i++; i == len(format) {
+ goto K
+ }
+ swap = true
+ b = format[i]
+ goto L
+ case '0':
+ if i++; i == len(format) {
+ goto K
+ }
+ padding = '0' | ^paddingMask
+ b = format[i]
+ goto L
+ case '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ width = int(b & 0x0F)
+ const maxWidth = 1024
+ for i++; i < len(format); i++ {
+ b = format[i]
+ if b <= '9' && '0' <= b {
+ width = width*10 + int(b&0x0F)
+ if width >= math.MaxInt/10 {
+ width = maxWidth
+ }
+ } else {
+ break
+ }
+ }
+ if width > maxWidth {
+ width = maxWidth
+ }
+ if padding == ^paddingMask {
+ padding = ' ' | ^paddingMask
+ }
+ if i == len(format) {
+ goto K
+ }
+ goto L
+ case 'Y':
+ if width == 0 {
+ width = 4
+ }
+ buf = appendInt(buf, year, width, padding)
+ case 'y':
+ if width < 2 {
+ width = 2
+ }
+ buf = appendInt(buf, year%100, width, padding)
+ case 'C':
+ if width < 2 {
+ width = 2
+ }
+ buf = appendInt(buf, year/100, width, padding)
+ case 'g':
+ if width < 2 {
+ width = 2
+ }
+ year, _ := t.ISOWeek()
+ buf = appendInt(buf, year%100, width, padding)
+ case 'G':
+ if width == 0 {
+ width = 4
+ }
+ year, _ := t.ISOWeek()
+ buf = appendInt(buf, year, width, padding)
+ case 'm':
+ if width < 2 {
+ width = 2
+ }
+ buf = appendInt(buf, int(month), width, padding)
+ case 'B':
+ buf = appendString(buf, longMonthNames[month-1], width, padding, upper, swap)
+ case 'b', 'h':
+ buf = appendString(buf, shortMonthNames[month-1], width, padding, upper, swap)
+ case 'A':
+ buf = appendString(buf, longWeekNames[t.Weekday()], width, padding, upper, swap)
+ case 'a':
+ buf = appendString(buf, shortWeekNames[t.Weekday()], width, padding, upper, swap)
+ case 'w':
+ for ; width > 1; width-- {
+ buf = append(buf, padding&paddingMask)
+ }
+ buf = append(buf, '0'+byte(t.Weekday()))
+ case 'u':
+ w := int(t.Weekday())
+ if w == 0 {
+ w = 7
+ }
+ for ; width > 1; width-- {
+ buf = append(buf, padding&paddingMask)
+ }
+ buf = append(buf, '0'+byte(w))
+ case 'V':
+ if width < 2 {
+ width = 2
+ }
+ _, week := t.ISOWeek()
+ buf = appendInt(buf, week, width, padding)
+ case 'U':
+ if width < 2 {
+ width = 2
+ }
+ week := (t.YearDay() + 6 - int(t.Weekday())) / 7
+ buf = appendInt(buf, week, width, padding)
+ case 'W':
+ if width < 2 {
+ width = 2
+ }
+ week := t.YearDay()
+ if int(t.Weekday()) > 0 {
+ week -= int(t.Weekday()) - 7
+ }
+ week /= 7
+ buf = appendInt(buf, week, width, padding)
+ case 'e':
+ if padding < ^paddingMask {
+ padding = ' '
+ }
+ fallthrough
+ case 'd':
+ if width < 2 {
+ width = 2
+ }
+ buf = appendInt(buf, day, width, padding)
+ case 'j':
+ if width < 3 {
+ width = 3
+ }
+ buf = appendInt(buf, t.YearDay(), width, padding)
+ case 'k':
+ if padding < ^paddingMask {
+ padding = ' '
+ }
+ fallthrough
+ case 'H':
+ if width < 2 {
+ width = 2
+ }
+ buf = appendInt(buf, hour, width, padding)
+ case 'l':
+ if width < 2 {
+ width = 2
+ }
+ if padding < ^paddingMask {
+ padding = ' '
+ }
+ h := hour
+ if h > 12 {
+ h -= 12
+ }
+ buf = appendInt(buf, h, width, padding)
+ case 'I':
+ if width < 2 {
+ width = 2
+ }
+ h := hour
+ if h > 12 {
+ h -= 12
+ } else if h == 0 {
+ h = 12
+ }
+ buf = appendInt(buf, h, width, padding)
+ case 'p':
+ if hour < 12 {
+ buf = appendString(buf, "AM", width, padding, upper, swap)
+ } else {
+ buf = appendString(buf, "PM", width, padding, upper, swap)
+ }
+ case 'P':
+ if hour < 12 {
+ buf = appendString(buf, "am", width, padding, upper, swap)
+ } else {
+ buf = appendString(buf, "pm", width, padding, upper, swap)
+ }
+ case 'M':
+ if width < 2 {
+ width = 2
+ }
+ buf = appendInt(buf, min, width, padding)
+ case 'S':
+ if width < 2 {
+ width = 2
+ }
+ buf = appendInt(buf, sec, width, padding)
+ case 's':
+ if padding < ^paddingMask {
+ padding = ' '
+ }
+ buf = appendInt(buf, int(t.Unix()), width, padding)
+ case 'f':
+ if width == 0 {
+ width = 6
+ }
+ buf = appendInt(buf, t.Nanosecond()/1000, width, padding)
+ case 'Z', 'z':
+ name, offset := t.Zone()
+ if b == 'Z' && name != "" {
+ buf = appendString(buf, name, width, padding, upper, swap)
+ break
+ }
+ i := len(buf)
+ if padding != ^paddingMask {
+ for ; width > 1; width-- {
+ buf = append(buf, padding&paddingMask)
+ }
+ }
+ j := len(buf)
+ if offset < 0 {
+ buf = append(buf, '-')
+ offset = -offset
+ } else {
+ buf = append(buf, '+')
+ }
+ k := len(buf)
+ buf = appendInt(buf, offset/3600, 2, padding)
+ if buf[k] == ' ' {
+ buf[k-1], buf[k] = buf[k], buf[k-1]
+ }
+ if k = offset % 3600; colons <= 2 || k != 0 {
+ if colons != 0 {
+ buf = append(buf, ':')
+ }
+ buf = appendInt(buf, k/60, 2, '0')
+ if k %= 60; colons == 2 || colons == 3 && k != 0 {
+ buf = append(buf, ':')
+ buf = appendInt(buf, k, 2, '0')
+ }
+ }
+ colons = 0
+ if i != j {
+ l := len(buf)
+ k = j + 1 - (l - j)
+ if k < i {
+ l = j + 1 + i - k
+ k = i
+ } else {
+ l = j + 1
+ }
+ copy(buf[k:], buf[j:])
+ buf = buf[:l]
+ if padding&paddingMask == '0' {
+ for ; k > i; k-- {
+ buf[k-1], buf[k] = buf[k], buf[k-1]
+ }
+ }
+ }
+ case ':':
+ if pending != "" {
+ buf = append(buf, ':')
+ } else {
+ colons = 1
+ M:
+ for i++; i < len(format); i++ {
+ switch format[i] {
+ case ':':
+ colons++
+ case 'z':
+ if colons > 3 {
+ i++
+ break M
+ }
+ b = 'z'
+ goto L
+ default:
+ break M
+ }
+ }
+ buf = appendLast(buf, format[:i], width, padding)
+ i--
+ colons = 0
+ }
+ case 't':
+ buf = appendString(buf, "\t", width, padding, false, false)
+ case 'n':
+ buf = appendString(buf, "\n", width, padding, false, false)
+ case '%':
+ buf = appendString(buf, "%", width, padding, false, false)
+ default:
+ if pending == "" {
+ var ok bool
+ if pending, ok = compositions[b]; ok {
+ swap = false
+ break
+ }
+ buf = appendLast(buf, format[:i], width-1, padding)
+ }
+ buf = append(buf, b)
+ }
+ if pending != "" {
+ b, pending, width, padding = pending[0], pending[1:], 0, '0'
+ goto L
+ }
+ } else {
+ buf = append(buf, b)
+ }
+ }
+ return buf
+K:
+ return appendLast(buf, format, width, padding)
+}
+
+func appendInt(buf []byte, num, width int, padding byte) []byte {
+ if padding != ^paddingMask {
+ padding &= paddingMask
+ switch width {
+ case 2:
+ if num < 10 {
+ buf = append(buf, padding)
+ goto L1
+ } else if num < 100 {
+ goto L2
+ } else if num < 1000 {
+ goto L3
+ } else if num < 10000 {
+ goto L4
+ }
+ case 4:
+ if num < 1000 {
+ buf = append(buf, padding)
+ if num < 100 {
+ buf = append(buf, padding)
+ if num < 10 {
+ buf = append(buf, padding)
+ goto L1
+ }
+ goto L2
+ }
+ goto L3
+ } else if num < 10000 {
+ goto L4
+ }
+ default:
+ i := len(buf)
+ for ; width > 1; width-- {
+ buf = append(buf, padding)
+ }
+ j := len(buf)
+ buf = strconv.AppendInt(buf, int64(num), 10)
+ l := len(buf)
+ if j+1 == l || i == j {
+ return buf
+ }
+ k := j + 1 - (l - j)
+ if k < i {
+ l = j + 1 + i - k
+ k = i
+ } else {
+ l = j + 1
+ }
+ copy(buf[k:], buf[j:])
+ return buf[:l]
+ }
+ }
+ if num < 100 {
+ if num < 10 {
+ goto L1
+ }
+ goto L2
+ } else if num < 10000 {
+ if num < 1000 {
+ goto L3
+ }
+ goto L4
+ }
+ return strconv.AppendInt(buf, int64(num), 10)
+L4:
+ buf = append(buf, byte(num/1000)|'0')
+ num %= 1000
+L3:
+ buf = append(buf, byte(num/100)|'0')
+ num %= 100
+L2:
+ buf = append(buf, byte(num/10)|'0')
+ num %= 10
+L1:
+ return append(buf, byte(num)|'0')
+}
+
+func appendString(buf []byte, str string, width int, padding byte, upper, swap bool) []byte {
+ if width > len(str) && padding != ^paddingMask {
+ if padding < ^paddingMask {
+ padding = ' '
+ } else {
+ padding &= paddingMask
+ }
+ for width -= len(str); width > 0; width-- {
+ buf = append(buf, padding)
+ }
+ }
+ switch {
+ case swap:
+ if str[len(str)-1] < 'a' {
+ for _, b := range []byte(str) {
+ buf = append(buf, b|0x20)
+ }
+ break
+ }
+ fallthrough
+ case upper:
+ for _, b := range []byte(str) {
+ buf = append(buf, b&0x5F)
+ }
+ default:
+ buf = append(buf, str...)
+ }
+ return buf
+}
+
+func appendLast(buf []byte, format string, width int, padding byte) []byte {
+ for i := len(format) - 1; i >= 0; i-- {
+ if format[i] == '%' {
+ buf = appendString(buf, format[i:], width, padding, false, false)
+ break
+ }
+ }
+ return buf
+}
+
+const paddingMask byte = 0x7F
+
+var longMonthNames = []string{
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December",
+}
+
+var shortMonthNames = []string{
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec",
+}
+
+var longWeekNames = []string{
+ "Sunday",
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday",
+}
+
+var shortWeekNames = []string{
+ "Sun",
+ "Mon",
+ "Tue",
+ "Wed",
+ "Thu",
+ "Fri",
+ "Sat",
+}
+
+var compositions = map[byte]string{
+ 'c': "a b e H:M:S Y",
+ '+': "a b e H:M:S Z Y",
+ 'F': "Y-m-d",
+ 'D': "m/d/y",
+ 'x': "m/d/y",
+ 'v': "e-b-Y",
+ 'T': "H:M:S",
+ 'X': "H:M:S",
+ 'r': "I:M:S p",
+ 'R': "H:M",
+}
diff --git a/vendor/github.com/itchyny/timefmt-go/parse.go b/vendor/github.com/itchyny/timefmt-go/parse.go
new file mode 100644
index 000000000..83b0df2c4
--- /dev/null
+++ b/vendor/github.com/itchyny/timefmt-go/parse.go
@@ -0,0 +1,408 @@
+package timefmt
+
+import (
+ "errors"
+ "fmt"
+ "time"
+)
+
+// Parse time string using the format.
+func Parse(source, format string) (t time.Time, err error) {
+ return parse(source, format, time.UTC, time.Local)
+}
+
+// ParseInLocation parses time string with the default location.
+// The location is also used to parse the time zone name (%Z).
+func ParseInLocation(source, format string, loc *time.Location) (t time.Time, err error) {
+ return parse(source, format, loc, loc)
+}
+
+func parse(source, format string, loc, base *time.Location) (t time.Time, err error) {
+ year, month, day, hour, min, sec, nsec := 1900, 1, 1, 0, 0, 0, 0
+ defer func() {
+ if err != nil {
+ err = fmt.Errorf("failed to parse %q with %q: %w", source, format, err)
+ }
+ }()
+ var j, century, yday, colons int
+ var pm, hasZoneName, hasZoneOffset bool
+ var pending string
+ for i, l := 0, len(source); i < len(format); i++ {
+ if b := format[i]; b == '%' {
+ i++
+ if i == len(format) {
+ err = errors.New("stray %")
+ return
+ }
+ b = format[i]
+ L:
+ switch b {
+ case 'Y':
+ if year, j, err = parseNumber(source, j, 4, 'Y'); err != nil {
+ return
+ }
+ case 'y':
+ if year, j, err = parseNumber(source, j, 2, 'y'); err != nil {
+ return
+ }
+ if year < 69 {
+ year += 2000
+ } else {
+ year += 1900
+ }
+ case 'C':
+ if century, j, err = parseNumber(source, j, 2, 'C'); err != nil {
+ return
+ }
+ case 'g':
+ if year, j, err = parseNumber(source, j, 2, b); err != nil {
+ return
+ }
+ year += 2000
+ case 'G':
+ if year, j, err = parseNumber(source, j, 4, b); err != nil {
+ return
+ }
+ case 'm':
+ if month, j, err = parseNumber(source, j, 2, 'm'); err != nil {
+ return
+ }
+ case 'B':
+ if month, j, err = lookup(source, j, longMonthNames, 'B'); err != nil {
+ return
+ }
+ case 'b', 'h':
+ if month, j, err = lookup(source, j, shortMonthNames, b); err != nil {
+ return
+ }
+ case 'A':
+ if _, j, err = lookup(source, j, longWeekNames, 'A'); err != nil {
+ return
+ }
+ case 'a':
+ if _, j, err = lookup(source, j, shortWeekNames, 'a'); err != nil {
+ return
+ }
+ case 'w':
+ if j >= l || source[j] < '0' || '6' < source[j] {
+ err = parseFormatError(b)
+ return
+ }
+ j++
+ case 'u':
+ if j >= l || source[j] < '1' || '7' < source[j] {
+ err = parseFormatError(b)
+ return
+ }
+ j++
+ case 'V', 'U', 'W':
+ if _, j, err = parseNumber(source, j, 2, b); err != nil {
+ return
+ }
+ case 'e':
+ if j < l && source[j] == ' ' {
+ j++
+ }
+ fallthrough
+ case 'd':
+ if day, j, err = parseNumber(source, j, 2, b); err != nil {
+ return
+ }
+ case 'j':
+ if yday, j, err = parseNumber(source, j, 3, 'j'); err != nil {
+ return
+ }
+ case 'k':
+ if j < l && source[j] == ' ' {
+ j++
+ }
+ fallthrough
+ case 'H':
+ if hour, j, err = parseNumber(source, j, 2, b); err != nil {
+ return
+ }
+ case 'l':
+ if j < l && source[j] == ' ' {
+ j++
+ }
+ fallthrough
+ case 'I':
+ if hour, j, err = parseNumber(source, j, 2, b); err != nil {
+ return
+ }
+ if hour == 12 {
+ hour = 0
+ }
+ case 'p', 'P':
+ var ampm int
+ if ampm, j, err = lookup(source, j, []string{"AM", "PM"}, 'p'); err != nil {
+ return
+ }
+ pm = ampm == 2
+ case 'M':
+ if min, j, err = parseNumber(source, j, 2, 'M'); err != nil {
+ return
+ }
+ case 'S':
+ if sec, j, err = parseNumber(source, j, 2, 'S'); err != nil {
+ return
+ }
+ case 's':
+ var unix int
+ if unix, j, err = parseNumber(source, j, 10, 's'); err != nil {
+ return
+ }
+ t = time.Unix(int64(unix), 0).In(time.UTC)
+ var mon time.Month
+ year, mon, day = t.Date()
+ hour, min, sec = t.Clock()
+ month = int(mon)
+ case 'f':
+ var usec, k, d int
+ if usec, k, err = parseNumber(source, j, 6, 'f'); err != nil {
+ return
+ }
+ for j, d = k, k-j; d < 6; d++ {
+ usec *= 10
+ }
+ nsec = usec * 1000
+ case 'Z':
+ k := j
+ for ; k < l; k++ {
+ if c := source[k]; c < 'A' || 'Z' < c {
+ break
+ }
+ }
+ t, err = time.ParseInLocation("MST", source[j:k], base)
+ if err != nil {
+ err = fmt.Errorf(`cannot parse %q with "%%Z"`, source[j:k])
+ return
+ }
+ if hasZoneOffset {
+ name, _ := t.Zone()
+ _, offset := locationZone(loc)
+ loc = time.FixedZone(name, offset)
+ } else {
+ loc = t.Location()
+ }
+ hasZoneName = true
+ j = k
+ case 'z':
+ if j >= l {
+ err = parseZFormatError(colons)
+ return
+ }
+ sign := 1
+ switch source[j] {
+ case '-':
+ sign = -1
+ fallthrough
+ case '+':
+ var hour, min, sec, k int
+ if hour, k, _ = parseNumber(source, j+1, 2, 'z'); k != j+3 {
+ err = parseZFormatError(colons)
+ return
+ }
+ if j = k; j >= l || source[j] != ':' {
+ switch colons {
+ case 1:
+ err = errors.New("expected ':' for %:z")
+ return
+ case 2:
+ err = errors.New("expected ':' for %::z")
+ return
+ }
+ } else if j++; colons == 0 {
+ colons = 4
+ }
+ if min, k, _ = parseNumber(source, j, 2, 'z'); k != j+2 {
+ if colons == 0 {
+ k = j
+ } else {
+ err = parseZFormatError(colons & 3)
+ return
+ }
+ }
+ if j = k; colons > 1 {
+ if j >= l || source[j] != ':' {
+ if colons == 2 {
+ err = errors.New("expected ':' for %::z")
+ return
+ }
+ } else if sec, k, _ = parseNumber(source, j+1, 2, 'z'); k != j+3 {
+ if colons == 2 {
+ err = parseZFormatError(colons)
+ return
+ }
+ } else {
+ j = k
+ }
+ }
+ var name string
+ if hasZoneName {
+ name, _ = locationZone(loc)
+ }
+ loc, colons = time.FixedZone(name, sign*((hour*60+min)*60+sec)), 0
+ hasZoneOffset = true
+ case 'Z':
+ loc, colons, j = time.UTC, 0, j+1
+ default:
+ err = parseZFormatError(colons)
+ return
+ }
+ case ':':
+ if pending != "" {
+ if j >= l || source[j] != b {
+ err = expectedFormatError(b)
+ return
+ }
+ j++
+ } else {
+ if i++; i == len(format) {
+ err = errors.New(`expected 'z' after "%:"`)
+ return
+ } else if b = format[i]; b == 'z' {
+ colons = 1
+ } else if b != ':' {
+ err = errors.New(`expected 'z' after "%:"`)
+ return
+ } else if i++; i == len(format) {
+ err = errors.New(`expected 'z' after "%::"`)
+ return
+ } else if b = format[i]; b == 'z' {
+ colons = 2
+ } else {
+ err = errors.New(`expected 'z' after "%::"`)
+ return
+ }
+ goto L
+ }
+ case 't', 'n':
+ k := j
+ K:
+ for ; k < l; k++ {
+ switch source[k] {
+ case ' ', '\t', '\n', '\v', '\f', '\r':
+ default:
+ break K
+ }
+ }
+ if k == j {
+ err = fmt.Errorf("expected a space for %%%c", b)
+ return
+ }
+ j = k
+ case '%':
+ if j >= l || source[j] != b {
+ err = expectedFormatError(b)
+ return
+ }
+ j++
+ default:
+ if pending == "" {
+ var ok bool
+ if pending, ok = compositions[b]; ok {
+ break
+ }
+ err = fmt.Errorf(`unexpected format: "%%%c"`, b)
+ return
+ }
+ if j >= l || source[j] != b {
+ err = expectedFormatError(b)
+ return
+ }
+ j++
+ }
+ if pending != "" {
+ b, pending = pending[0], pending[1:]
+ goto L
+ }
+ } else if j >= len(source) || source[j] != b {
+ err = expectedFormatError(b)
+ return
+ } else {
+ j++
+ }
+ }
+ if j < len(source) {
+ err = fmt.Errorf("unconverted string: %q", source[j:])
+ return
+ }
+ if pm {
+ hour += 12
+ }
+ if century > 0 {
+ year = century*100 + year%100
+ }
+ if yday > 0 {
+ return time.Date(year, time.January, 1, hour, min, sec, nsec, loc).AddDate(0, 0, yday-1), nil
+ }
+ return time.Date(year, time.Month(month), day, hour, min, sec, nsec, loc), nil
+}
+
+func locationZone(loc *time.Location) (name string, offset int) {
+ return time.Date(2000, time.January, 1, 0, 0, 0, 0, loc).Zone()
+}
+
+type parseFormatError byte
+
+func (err parseFormatError) Error() string {
+ return fmt.Sprintf("cannot parse %%%c", byte(err))
+}
+
+type expectedFormatError byte
+
+func (err expectedFormatError) Error() string {
+ return fmt.Sprintf("expected %q", byte(err))
+}
+
+type parseZFormatError int
+
+func (err parseZFormatError) Error() string {
+ switch int(err) {
+ case 0:
+ return "cannot parse %z"
+ case 1:
+ return "cannot parse %:z"
+ default:
+ return "cannot parse %::z"
+ }
+}
+
+func parseNumber(source string, min, size int, format byte) (int, int, error) {
+ var val int
+ if l := len(source); min+size > l {
+ size = l
+ } else {
+ size += min
+ }
+ i := min
+ for ; i < size; i++ {
+ if b := source[i]; '0' <= b && b <= '9' {
+ val = val*10 + int(b&0x0F)
+ } else {
+ break
+ }
+ }
+ if i == min {
+ return 0, 0, parseFormatError(format)
+ }
+ return val, i, nil
+}
+
+func lookup(source string, min int, candidates []string, format byte) (int, int, error) {
+L:
+ for i, xs := range candidates {
+ j := min
+ for k := 0; k < len(xs); k, j = k+1, j+1 {
+ if j >= len(source) {
+ continue L
+ }
+ if x, y := xs[k], source[j]; x != y && x|('a'-'A') != y|('a'-'A') {
+ continue L
+ }
+ }
+ return i + 1, j, nil
+ }
+ return 0, 0, parseFormatError(format)
+}
diff --git a/vendor/github.com/itchyny/timefmt-go/timefmt.go b/vendor/github.com/itchyny/timefmt-go/timefmt.go
new file mode 100644
index 000000000..45bf6ae90
--- /dev/null
+++ b/vendor/github.com/itchyny/timefmt-go/timefmt.go
@@ -0,0 +1,2 @@
+// Package timefmt provides functions for formatting and parsing date time strings.
+package timefmt
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 000000000..0aa2c9228
--- /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 000000000..84f9c7b2c
--- /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 000000000..4e402a00e
--- /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 000000000..8b9bd4999
--- /dev/null
+++ b/vendor/github.com/lucasb-eyer/go-colorful/README.md
@@ -0,0 +1,482 @@
+go-colorful
+===========
+
+[![go reportcard](https://goreportcard.com/badge/github.com/lucasb-eyer/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)
+
+![Color distance comparison](doc/colordist/colordist.png)
+
+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:
+
+![Blending colors in different spaces.](doc/colorblend/colorblend.png)
+
+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`:
+
+![Invalid RGB colors may crop up when blending in CIE spaces.](doc/colorblend/invalid.png)
+
+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:
+
+![Fixing invalid RGB colors by clamping them to the valid range.](doc/colorblend/clamped.png)
+
+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:
+
+!["Spectral" colorbrewer gradient in HCL space.](doc/gradientgen/gradientgen.png)
+
+### 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.
+
+![Warm, fast warm, happy and fast happy random colors, respectively.](doc/colorgens/colorgens.png)
+
+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.
+
+![All example palettes](doc/palettegens/palettegens.png)
+
+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:
+
+![approximation quality](doc/approx-quality.png)
+
+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 000000000..2e2e49e19
--- /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 000000000..0d5bffe5d
--- /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 000000000..bb66dfa4f
--- /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 000000000..76f31d8f9
--- /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 000000000..16354abf5
--- /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 000000000..d19fb6443
--- /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 000000000..9f7bf6f7c
--- /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 000000000..00f42a5cc
--- /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/mattn/go-runewidth/LICENSE b/vendor/github.com/mattn/go-runewidth/LICENSE
new file mode 100644
index 000000000..91b5cef30
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Yasuhiro Matsumoto
+
+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/mattn/go-runewidth/README.md b/vendor/github.com/mattn/go-runewidth/README.md
new file mode 100644
index 000000000..5e2cfd98c
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/README.md
@@ -0,0 +1,27 @@
+go-runewidth
+============
+
+[![Build Status](https://github.com/mattn/go-runewidth/workflows/test/badge.svg?branch=master)](https://github.com/mattn/go-runewidth/actions?query=workflow%3Atest)
+[![Codecov](https://codecov.io/gh/mattn/go-runewidth/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-runewidth)
+[![GoDoc](https://godoc.org/github.com/mattn/go-runewidth?status.svg)](http://godoc.org/github.com/mattn/go-runewidth)
+[![Go Report Card](https://goreportcard.com/badge/github.com/mattn/go-runewidth)](https://goreportcard.com/report/github.com/mattn/go-runewidth)
+
+Provides functions to get fixed width of the character or string.
+
+Usage
+-----
+
+```go
+runewidth.StringWidth("つのだ☆HIRO") == 12
+```
+
+
+Author
+------
+
+Yasuhiro Matsumoto
+
+License
+-------
+
+under the MIT License: http://mattn.mit-license.org/2013
diff --git a/vendor/github.com/mattn/go-runewidth/runewidth.go b/vendor/github.com/mattn/go-runewidth/runewidth.go
new file mode 100644
index 000000000..7dfbb3be9
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/runewidth.go
@@ -0,0 +1,358 @@
+package runewidth
+
+import (
+ "os"
+ "strings"
+
+ "github.com/rivo/uniseg"
+)
+
+//go:generate go run script/generate.go
+
+var (
+ // EastAsianWidth will be set true if the current locale is CJK
+ EastAsianWidth bool
+
+ // StrictEmojiNeutral should be set false if handle broken fonts
+ StrictEmojiNeutral bool = true
+
+ // DefaultCondition is a condition in current locale
+ DefaultCondition = &Condition{
+ EastAsianWidth: false,
+ StrictEmojiNeutral: true,
+ }
+)
+
+func init() {
+ handleEnv()
+}
+
+func handleEnv() {
+ env := os.Getenv("RUNEWIDTH_EASTASIAN")
+ if env == "" {
+ EastAsianWidth = IsEastAsian()
+ } else {
+ EastAsianWidth = env == "1"
+ }
+ // update DefaultCondition
+ if DefaultCondition.EastAsianWidth != EastAsianWidth {
+ DefaultCondition.EastAsianWidth = EastAsianWidth
+ if len(DefaultCondition.combinedLut) > 0 {
+ DefaultCondition.combinedLut = DefaultCondition.combinedLut[:0]
+ CreateLUT()
+ }
+ }
+}
+
+type interval struct {
+ first rune
+ last rune
+}
+
+type table []interval
+
+func inTables(r rune, ts ...table) bool {
+ for _, t := range ts {
+ if inTable(r, t) {
+ return true
+ }
+ }
+ return false
+}
+
+func inTable(r rune, t table) bool {
+ if r < t[0].first {
+ return false
+ }
+
+ bot := 0
+ top := len(t) - 1
+ for top >= bot {
+ mid := (bot + top) >> 1
+
+ switch {
+ case t[mid].last < r:
+ bot = mid + 1
+ case t[mid].first > r:
+ top = mid - 1
+ default:
+ return true
+ }
+ }
+
+ return false
+}
+
+var private = table{
+ {0x00E000, 0x00F8FF}, {0x0F0000, 0x0FFFFD}, {0x100000, 0x10FFFD},
+}
+
+var nonprint = table{
+ {0x0000, 0x001F}, {0x007F, 0x009F}, {0x00AD, 0x00AD},
+ {0x070F, 0x070F}, {0x180B, 0x180E}, {0x200B, 0x200F},
+ {0x2028, 0x202E}, {0x206A, 0x206F}, {0xD800, 0xDFFF},
+ {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFE, 0xFFFF},
+}
+
+// Condition have flag EastAsianWidth whether the current locale is CJK or not.
+type Condition struct {
+ combinedLut []byte
+ EastAsianWidth bool
+ StrictEmojiNeutral bool
+}
+
+// NewCondition return new instance of Condition which is current locale.
+func NewCondition() *Condition {
+ return &Condition{
+ EastAsianWidth: EastAsianWidth,
+ StrictEmojiNeutral: StrictEmojiNeutral,
+ }
+}
+
+// RuneWidth returns the number of cells in r.
+// See http://www.unicode.org/reports/tr11/
+func (c *Condition) RuneWidth(r rune) int {
+ if r < 0 || r > 0x10FFFF {
+ return 0
+ }
+ if len(c.combinedLut) > 0 {
+ return int(c.combinedLut[r>>1]>>(uint(r&1)*4)) & 3
+ }
+ // optimized version, verified by TestRuneWidthChecksums()
+ if !c.EastAsianWidth {
+ switch {
+ case r < 0x20:
+ return 0
+ case (r >= 0x7F && r <= 0x9F) || r == 0xAD: // nonprint
+ return 0
+ case r < 0x300:
+ return 1
+ case inTable(r, narrow):
+ return 1
+ case inTables(r, nonprint, combining):
+ return 0
+ case inTable(r, doublewidth):
+ return 2
+ default:
+ return 1
+ }
+ } else {
+ switch {
+ case inTables(r, nonprint, combining):
+ return 0
+ case inTable(r, narrow):
+ return 1
+ case inTables(r, ambiguous, doublewidth):
+ return 2
+ case !c.StrictEmojiNeutral && inTables(r, ambiguous, emoji, narrow):
+ return 2
+ default:
+ return 1
+ }
+ }
+}
+
+// CreateLUT will create an in-memory lookup table of 557056 bytes for faster operation.
+// This should not be called concurrently with other operations on c.
+// If options in c is changed, CreateLUT should be called again.
+func (c *Condition) CreateLUT() {
+ const max = 0x110000
+ lut := c.combinedLut
+ if len(c.combinedLut) != 0 {
+ // Remove so we don't use it.
+ c.combinedLut = nil
+ } else {
+ lut = make([]byte, max/2)
+ }
+ for i := range lut {
+ i32 := int32(i * 2)
+ x0 := c.RuneWidth(i32)
+ x1 := c.RuneWidth(i32 + 1)
+ lut[i] = uint8(x0) | uint8(x1)<<4
+ }
+ c.combinedLut = lut
+}
+
+// StringWidth return width as you can see
+func (c *Condition) StringWidth(s string) (width int) {
+ g := uniseg.NewGraphemes(s)
+ for g.Next() {
+ var chWidth int
+ for _, r := range g.Runes() {
+ chWidth = c.RuneWidth(r)
+ if chWidth > 0 {
+ break // Our best guess at this point is to use the width of the first non-zero-width rune.
+ }
+ }
+ width += chWidth
+ }
+ return
+}
+
+// Truncate return string truncated with w cells
+func (c *Condition) Truncate(s string, w int, tail string) string {
+ if c.StringWidth(s) <= w {
+ return s
+ }
+ w -= c.StringWidth(tail)
+ var width int
+ pos := len(s)
+ g := uniseg.NewGraphemes(s)
+ for g.Next() {
+ var chWidth int
+ for _, r := range g.Runes() {
+ chWidth = c.RuneWidth(r)
+ if chWidth > 0 {
+ break // See StringWidth() for details.
+ }
+ }
+ if width+chWidth > w {
+ pos, _ = g.Positions()
+ break
+ }
+ width += chWidth
+ }
+ return s[:pos] + tail
+}
+
+// TruncateLeft cuts w cells from the beginning of the `s`.
+func (c *Condition) TruncateLeft(s string, w int, prefix string) string {
+ if c.StringWidth(s) <= w {
+ return prefix
+ }
+
+ var width int
+ pos := len(s)
+
+ g := uniseg.NewGraphemes(s)
+ for g.Next() {
+ var chWidth int
+ for _, r := range g.Runes() {
+ chWidth = c.RuneWidth(r)
+ if chWidth > 0 {
+ break // See StringWidth() for details.
+ }
+ }
+
+ if width+chWidth > w {
+ if width < w {
+ _, pos = g.Positions()
+ prefix += strings.Repeat(" ", width+chWidth-w)
+ } else {
+ pos, _ = g.Positions()
+ }
+
+ break
+ }
+
+ width += chWidth
+ }
+
+ return prefix + s[pos:]
+}
+
+// Wrap return string wrapped with w cells
+func (c *Condition) Wrap(s string, w int) string {
+ width := 0
+ out := ""
+ for _, r := range s {
+ cw := c.RuneWidth(r)
+ if r == '\n' {
+ out += string(r)
+ width = 0
+ continue
+ } else if width+cw > w {
+ out += "\n"
+ width = 0
+ out += string(r)
+ width += cw
+ continue
+ }
+ out += string(r)
+ width += cw
+ }
+ return out
+}
+
+// FillLeft return string filled in left by spaces in w cells
+func (c *Condition) FillLeft(s string, w int) string {
+ width := c.StringWidth(s)
+ count := w - width
+ if count > 0 {
+ b := make([]byte, count)
+ for i := range b {
+ b[i] = ' '
+ }
+ return string(b) + s
+ }
+ return s
+}
+
+// FillRight return string filled in left by spaces in w cells
+func (c *Condition) FillRight(s string, w int) string {
+ width := c.StringWidth(s)
+ count := w - width
+ if count > 0 {
+ b := make([]byte, count)
+ for i := range b {
+ b[i] = ' '
+ }
+ return s + string(b)
+ }
+ return s
+}
+
+// RuneWidth returns the number of cells in r.
+// See http://www.unicode.org/reports/tr11/
+func RuneWidth(r rune) int {
+ return DefaultCondition.RuneWidth(r)
+}
+
+// IsAmbiguousWidth returns whether is ambiguous width or not.
+func IsAmbiguousWidth(r rune) bool {
+ return inTables(r, private, ambiguous)
+}
+
+// IsNeutralWidth returns whether is neutral width or not.
+func IsNeutralWidth(r rune) bool {
+ return inTable(r, neutral)
+}
+
+// StringWidth return width as you can see
+func StringWidth(s string) (width int) {
+ return DefaultCondition.StringWidth(s)
+}
+
+// Truncate return string truncated with w cells
+func Truncate(s string, w int, tail string) string {
+ return DefaultCondition.Truncate(s, w, tail)
+}
+
+// TruncateLeft cuts w cells from the beginning of the `s`.
+func TruncateLeft(s string, w int, prefix string) string {
+ return DefaultCondition.TruncateLeft(s, w, prefix)
+}
+
+// Wrap return string wrapped with w cells
+func Wrap(s string, w int) string {
+ return DefaultCondition.Wrap(s, w)
+}
+
+// FillLeft return string filled in left by spaces in w cells
+func FillLeft(s string, w int) string {
+ return DefaultCondition.FillLeft(s, w)
+}
+
+// FillRight return string filled in left by spaces in w cells
+func FillRight(s string, w int) string {
+ return DefaultCondition.FillRight(s, w)
+}
+
+// CreateLUT will create an in-memory lookup table of 557055 bytes for faster operation.
+// This should not be called concurrently with other operations.
+func CreateLUT() {
+ if len(DefaultCondition.combinedLut) > 0 {
+ return
+ }
+ DefaultCondition.CreateLUT()
+}
diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_appengine.go b/vendor/github.com/mattn/go-runewidth/runewidth_appengine.go
new file mode 100644
index 000000000..84b6528df
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/runewidth_appengine.go
@@ -0,0 +1,9 @@
+//go:build appengine
+// +build appengine
+
+package runewidth
+
+// IsEastAsian return true if the current locale is CJK
+func IsEastAsian() bool {
+ return false
+}
diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_js.go b/vendor/github.com/mattn/go-runewidth/runewidth_js.go
new file mode 100644
index 000000000..c2abbc2db
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/runewidth_js.go
@@ -0,0 +1,9 @@
+//go:build js && !appengine
+// +build js,!appengine
+
+package runewidth
+
+func IsEastAsian() bool {
+ // TODO: Implement this for the web. Detect east asian in a compatible way, and return true.
+ return false
+}
diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_posix.go b/vendor/github.com/mattn/go-runewidth/runewidth_posix.go
new file mode 100644
index 000000000..5a31d738e
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/runewidth_posix.go
@@ -0,0 +1,81 @@
+//go:build !windows && !js && !appengine
+// +build !windows,!js,!appengine
+
+package runewidth
+
+import (
+ "os"
+ "regexp"
+ "strings"
+)
+
+var reLoc = regexp.MustCompile(`^[a-z][a-z][a-z]?(?:_[A-Z][A-Z])?\.(.+)`)
+
+var mblenTable = map[string]int{
+ "utf-8": 6,
+ "utf8": 6,
+ "jis": 8,
+ "eucjp": 3,
+ "euckr": 2,
+ "euccn": 2,
+ "sjis": 2,
+ "cp932": 2,
+ "cp51932": 2,
+ "cp936": 2,
+ "cp949": 2,
+ "cp950": 2,
+ "big5": 2,
+ "gbk": 2,
+ "gb2312": 2,
+}
+
+func isEastAsian(locale string) bool {
+ charset := strings.ToLower(locale)
+ r := reLoc.FindStringSubmatch(locale)
+ if len(r) == 2 {
+ charset = strings.ToLower(r[1])
+ }
+
+ if strings.HasSuffix(charset, "@cjk_narrow") {
+ return false
+ }
+
+ for pos, b := range []byte(charset) {
+ if b == '@' {
+ charset = charset[:pos]
+ break
+ }
+ }
+ max := 1
+ if m, ok := mblenTable[charset]; ok {
+ max = m
+ }
+ if max > 1 && (charset[0] != 'u' ||
+ strings.HasPrefix(locale, "ja") ||
+ strings.HasPrefix(locale, "ko") ||
+ strings.HasPrefix(locale, "zh")) {
+ return true
+ }
+ return false
+}
+
+// IsEastAsian return true if the current locale is CJK
+func IsEastAsian() bool {
+ locale := os.Getenv("LC_ALL")
+ if locale == "" {
+ locale = os.Getenv("LC_CTYPE")
+ }
+ if locale == "" {
+ locale = os.Getenv("LANG")
+ }
+
+ // ignore C locale
+ if locale == "POSIX" || locale == "C" {
+ return false
+ }
+ if len(locale) > 1 && locale[0] == 'C' && (locale[1] == '.' || locale[1] == '-') {
+ return false
+ }
+
+ return isEastAsian(locale)
+}
diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_table.go b/vendor/github.com/mattn/go-runewidth/runewidth_table.go
new file mode 100644
index 000000000..e5d890c26
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/runewidth_table.go
@@ -0,0 +1,439 @@
+// Code generated by script/generate.go. DO NOT EDIT.
+
+package runewidth
+
+var combining = table{
+ {0x0300, 0x036F}, {0x0483, 0x0489}, {0x07EB, 0x07F3},
+ {0x0C00, 0x0C00}, {0x0C04, 0x0C04}, {0x0D00, 0x0D01},
+ {0x135D, 0x135F}, {0x1A7F, 0x1A7F}, {0x1AB0, 0x1AC0},
+ {0x1B6B, 0x1B73}, {0x1DC0, 0x1DF9}, {0x1DFB, 0x1DFF},
+ {0x20D0, 0x20F0}, {0x2CEF, 0x2CF1}, {0x2DE0, 0x2DFF},
+ {0x3099, 0x309A}, {0xA66F, 0xA672}, {0xA674, 0xA67D},
+ {0xA69E, 0xA69F}, {0xA6F0, 0xA6F1}, {0xA8E0, 0xA8F1},
+ {0xFE20, 0xFE2F}, {0x101FD, 0x101FD}, {0x10376, 0x1037A},
+ {0x10EAB, 0x10EAC}, {0x10F46, 0x10F50}, {0x11300, 0x11301},
+ {0x1133B, 0x1133C}, {0x11366, 0x1136C}, {0x11370, 0x11374},
+ {0x16AF0, 0x16AF4}, {0x1D165, 0x1D169}, {0x1D16D, 0x1D172},
+ {0x1D17B, 0x1D182}, {0x1D185, 0x1D18B}, {0x1D1AA, 0x1D1AD},
+ {0x1D242, 0x1D244}, {0x1E000, 0x1E006}, {0x1E008, 0x1E018},
+ {0x1E01B, 0x1E021}, {0x1E023, 0x1E024}, {0x1E026, 0x1E02A},
+ {0x1E8D0, 0x1E8D6},
+}
+
+var doublewidth = table{
+ {0x1100, 0x115F}, {0x231A, 0x231B}, {0x2329, 0x232A},
+ {0x23E9, 0x23EC}, {0x23F0, 0x23F0}, {0x23F3, 0x23F3},
+ {0x25FD, 0x25FE}, {0x2614, 0x2615}, {0x2648, 0x2653},
+ {0x267F, 0x267F}, {0x2693, 0x2693}, {0x26A1, 0x26A1},
+ {0x26AA, 0x26AB}, {0x26BD, 0x26BE}, {0x26C4, 0x26C5},
+ {0x26CE, 0x26CE}, {0x26D4, 0x26D4}, {0x26EA, 0x26EA},
+ {0x26F2, 0x26F3}, {0x26F5, 0x26F5}, {0x26FA, 0x26FA},
+ {0x26FD, 0x26FD}, {0x2705, 0x2705}, {0x270A, 0x270B},
+ {0x2728, 0x2728}, {0x274C, 0x274C}, {0x274E, 0x274E},
+ {0x2753, 0x2755}, {0x2757, 0x2757}, {0x2795, 0x2797},
+ {0x27B0, 0x27B0}, {0x27BF, 0x27BF}, {0x2B1B, 0x2B1C},
+ {0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x2E80, 0x2E99},
+ {0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x2FFB},
+ {0x3000, 0x303E}, {0x3041, 0x3096}, {0x3099, 0x30FF},
+ {0x3105, 0x312F}, {0x3131, 0x318E}, {0x3190, 0x31E3},
+ {0x31F0, 0x321E}, {0x3220, 0x3247}, {0x3250, 0x4DBF},
+ {0x4E00, 0xA48C}, {0xA490, 0xA4C6}, {0xA960, 0xA97C},
+ {0xAC00, 0xD7A3}, {0xF900, 0xFAFF}, {0xFE10, 0xFE19},
+ {0xFE30, 0xFE52}, {0xFE54, 0xFE66}, {0xFE68, 0xFE6B},
+ {0xFF01, 0xFF60}, {0xFFE0, 0xFFE6}, {0x16FE0, 0x16FE4},
+ {0x16FF0, 0x16FF1}, {0x17000, 0x187F7}, {0x18800, 0x18CD5},
+ {0x18D00, 0x18D08}, {0x1B000, 0x1B11E}, {0x1B150, 0x1B152},
+ {0x1B164, 0x1B167}, {0x1B170, 0x1B2FB}, {0x1F004, 0x1F004},
+ {0x1F0CF, 0x1F0CF}, {0x1F18E, 0x1F18E}, {0x1F191, 0x1F19A},
+ {0x1F200, 0x1F202}, {0x1F210, 0x1F23B}, {0x1F240, 0x1F248},
+ {0x1F250, 0x1F251}, {0x1F260, 0x1F265}, {0x1F300, 0x1F320},
+ {0x1F32D, 0x1F335}, {0x1F337, 0x1F37C}, {0x1F37E, 0x1F393},
+ {0x1F3A0, 0x1F3CA}, {0x1F3CF, 0x1F3D3}, {0x1F3E0, 0x1F3F0},
+ {0x1F3F4, 0x1F3F4}, {0x1F3F8, 0x1F43E}, {0x1F440, 0x1F440},
+ {0x1F442, 0x1F4FC}, {0x1F4FF, 0x1F53D}, {0x1F54B, 0x1F54E},
+ {0x1F550, 0x1F567}, {0x1F57A, 0x1F57A}, {0x1F595, 0x1F596},
+ {0x1F5A4, 0x1F5A4}, {0x1F5FB, 0x1F64F}, {0x1F680, 0x1F6C5},
+ {0x1F6CC, 0x1F6CC}, {0x1F6D0, 0x1F6D2}, {0x1F6D5, 0x1F6D7},
+ {0x1F6EB, 0x1F6EC}, {0x1F6F4, 0x1F6FC}, {0x1F7E0, 0x1F7EB},
+ {0x1F90C, 0x1F93A}, {0x1F93C, 0x1F945}, {0x1F947, 0x1F978},
+ {0x1F97A, 0x1F9CB}, {0x1F9CD, 0x1F9FF}, {0x1FA70, 0x1FA74},
+ {0x1FA78, 0x1FA7A}, {0x1FA80, 0x1FA86}, {0x1FA90, 0x1FAA8},
+ {0x1FAB0, 0x1FAB6}, {0x1FAC0, 0x1FAC2}, {0x1FAD0, 0x1FAD6},
+ {0x20000, 0x2FFFD}, {0x30000, 0x3FFFD},
+}
+
+var ambiguous = table{
+ {0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8},
+ {0x00AA, 0x00AA}, {0x00AD, 0x00AE}, {0x00B0, 0x00B4},
+ {0x00B6, 0x00BA}, {0x00BC, 0x00BF}, {0x00C6, 0x00C6},
+ {0x00D0, 0x00D0}, {0x00D7, 0x00D8}, {0x00DE, 0x00E1},
+ {0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED},
+ {0x00F0, 0x00F0}, {0x00F2, 0x00F3}, {0x00F7, 0x00FA},
+ {0x00FC, 0x00FC}, {0x00FE, 0x00FE}, {0x0101, 0x0101},
+ {0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B},
+ {0x0126, 0x0127}, {0x012B, 0x012B}, {0x0131, 0x0133},
+ {0x0138, 0x0138}, {0x013F, 0x0142}, {0x0144, 0x0144},
+ {0x0148, 0x014B}, {0x014D, 0x014D}, {0x0152, 0x0153},
+ {0x0166, 0x0167}, {0x016B, 0x016B}, {0x01CE, 0x01CE},
+ {0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4},
+ {0x01D6, 0x01D6}, {0x01D8, 0x01D8}, {0x01DA, 0x01DA},
+ {0x01DC, 0x01DC}, {0x0251, 0x0251}, {0x0261, 0x0261},
+ {0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB},
+ {0x02CD, 0x02CD}, {0x02D0, 0x02D0}, {0x02D8, 0x02DB},
+ {0x02DD, 0x02DD}, {0x02DF, 0x02DF}, {0x0300, 0x036F},
+ {0x0391, 0x03A1}, {0x03A3, 0x03A9}, {0x03B1, 0x03C1},
+ {0x03C3, 0x03C9}, {0x0401, 0x0401}, {0x0410, 0x044F},
+ {0x0451, 0x0451}, {0x2010, 0x2010}, {0x2013, 0x2016},
+ {0x2018, 0x2019}, {0x201C, 0x201D}, {0x2020, 0x2022},
+ {0x2024, 0x2027}, {0x2030, 0x2030}, {0x2032, 0x2033},
+ {0x2035, 0x2035}, {0x203B, 0x203B}, {0x203E, 0x203E},
+ {0x2074, 0x2074}, {0x207F, 0x207F}, {0x2081, 0x2084},
+ {0x20AC, 0x20AC}, {0x2103, 0x2103}, {0x2105, 0x2105},
+ {0x2109, 0x2109}, {0x2113, 0x2113}, {0x2116, 0x2116},
+ {0x2121, 0x2122}, {0x2126, 0x2126}, {0x212B, 0x212B},
+ {0x2153, 0x2154}, {0x215B, 0x215E}, {0x2160, 0x216B},
+ {0x2170, 0x2179}, {0x2189, 0x2189}, {0x2190, 0x2199},
+ {0x21B8, 0x21B9}, {0x21D2, 0x21D2}, {0x21D4, 0x21D4},
+ {0x21E7, 0x21E7}, {0x2200, 0x2200}, {0x2202, 0x2203},
+ {0x2207, 0x2208}, {0x220B, 0x220B}, {0x220F, 0x220F},
+ {0x2211, 0x2211}, {0x2215, 0x2215}, {0x221A, 0x221A},
+ {0x221D, 0x2220}, {0x2223, 0x2223}, {0x2225, 0x2225},
+ {0x2227, 0x222C}, {0x222E, 0x222E}, {0x2234, 0x2237},
+ {0x223C, 0x223D}, {0x2248, 0x2248}, {0x224C, 0x224C},
+ {0x2252, 0x2252}, {0x2260, 0x2261}, {0x2264, 0x2267},
+ {0x226A, 0x226B}, {0x226E, 0x226F}, {0x2282, 0x2283},
+ {0x2286, 0x2287}, {0x2295, 0x2295}, {0x2299, 0x2299},
+ {0x22A5, 0x22A5}, {0x22BF, 0x22BF}, {0x2312, 0x2312},
+ {0x2460, 0x24E9}, {0x24EB, 0x254B}, {0x2550, 0x2573},
+ {0x2580, 0x258F}, {0x2592, 0x2595}, {0x25A0, 0x25A1},
+ {0x25A3, 0x25A9}, {0x25B2, 0x25B3}, {0x25B6, 0x25B7},
+ {0x25BC, 0x25BD}, {0x25C0, 0x25C1}, {0x25C6, 0x25C8},
+ {0x25CB, 0x25CB}, {0x25CE, 0x25D1}, {0x25E2, 0x25E5},
+ {0x25EF, 0x25EF}, {0x2605, 0x2606}, {0x2609, 0x2609},
+ {0x260E, 0x260F}, {0x261C, 0x261C}, {0x261E, 0x261E},
+ {0x2640, 0x2640}, {0x2642, 0x2642}, {0x2660, 0x2661},
+ {0x2663, 0x2665}, {0x2667, 0x266A}, {0x266C, 0x266D},
+ {0x266F, 0x266F}, {0x269E, 0x269F}, {0x26BF, 0x26BF},
+ {0x26C6, 0x26CD}, {0x26CF, 0x26D3}, {0x26D5, 0x26E1},
+ {0x26E3, 0x26E3}, {0x26E8, 0x26E9}, {0x26EB, 0x26F1},
+ {0x26F4, 0x26F4}, {0x26F6, 0x26F9}, {0x26FB, 0x26FC},
+ {0x26FE, 0x26FF}, {0x273D, 0x273D}, {0x2776, 0x277F},
+ {0x2B56, 0x2B59}, {0x3248, 0x324F}, {0xE000, 0xF8FF},
+ {0xFE00, 0xFE0F}, {0xFFFD, 0xFFFD}, {0x1F100, 0x1F10A},
+ {0x1F110, 0x1F12D}, {0x1F130, 0x1F169}, {0x1F170, 0x1F18D},
+ {0x1F18F, 0x1F190}, {0x1F19B, 0x1F1AC}, {0xE0100, 0xE01EF},
+ {0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD},
+}
+var narrow = table{
+ {0x0020, 0x007E}, {0x00A2, 0x00A3}, {0x00A5, 0x00A6},
+ {0x00AC, 0x00AC}, {0x00AF, 0x00AF}, {0x27E6, 0x27ED},
+ {0x2985, 0x2986},
+}
+
+var neutral = table{
+ {0x0000, 0x001F}, {0x007F, 0x00A0}, {0x00A9, 0x00A9},
+ {0x00AB, 0x00AB}, {0x00B5, 0x00B5}, {0x00BB, 0x00BB},
+ {0x00C0, 0x00C5}, {0x00C7, 0x00CF}, {0x00D1, 0x00D6},
+ {0x00D9, 0x00DD}, {0x00E2, 0x00E5}, {0x00E7, 0x00E7},
+ {0x00EB, 0x00EB}, {0x00EE, 0x00EF}, {0x00F1, 0x00F1},
+ {0x00F4, 0x00F6}, {0x00FB, 0x00FB}, {0x00FD, 0x00FD},
+ {0x00FF, 0x0100}, {0x0102, 0x0110}, {0x0112, 0x0112},
+ {0x0114, 0x011A}, {0x011C, 0x0125}, {0x0128, 0x012A},
+ {0x012C, 0x0130}, {0x0134, 0x0137}, {0x0139, 0x013E},
+ {0x0143, 0x0143}, {0x0145, 0x0147}, {0x014C, 0x014C},
+ {0x014E, 0x0151}, {0x0154, 0x0165}, {0x0168, 0x016A},
+ {0x016C, 0x01CD}, {0x01CF, 0x01CF}, {0x01D1, 0x01D1},
+ {0x01D3, 0x01D3}, {0x01D5, 0x01D5}, {0x01D7, 0x01D7},
+ {0x01D9, 0x01D9}, {0x01DB, 0x01DB}, {0x01DD, 0x0250},
+ {0x0252, 0x0260}, {0x0262, 0x02C3}, {0x02C5, 0x02C6},
+ {0x02C8, 0x02C8}, {0x02CC, 0x02CC}, {0x02CE, 0x02CF},
+ {0x02D1, 0x02D7}, {0x02DC, 0x02DC}, {0x02DE, 0x02DE},
+ {0x02E0, 0x02FF}, {0x0370, 0x0377}, {0x037A, 0x037F},
+ {0x0384, 0x038A}, {0x038C, 0x038C}, {0x038E, 0x0390},
+ {0x03AA, 0x03B0}, {0x03C2, 0x03C2}, {0x03CA, 0x0400},
+ {0x0402, 0x040F}, {0x0450, 0x0450}, {0x0452, 0x052F},
+ {0x0531, 0x0556}, {0x0559, 0x058A}, {0x058D, 0x058F},
+ {0x0591, 0x05C7}, {0x05D0, 0x05EA}, {0x05EF, 0x05F4},
+ {0x0600, 0x061C}, {0x061E, 0x070D}, {0x070F, 0x074A},
+ {0x074D, 0x07B1}, {0x07C0, 0x07FA}, {0x07FD, 0x082D},
+ {0x0830, 0x083E}, {0x0840, 0x085B}, {0x085E, 0x085E},
+ {0x0860, 0x086A}, {0x08A0, 0x08B4}, {0x08B6, 0x08C7},
+ {0x08D3, 0x0983}, {0x0985, 0x098C}, {0x098F, 0x0990},
+ {0x0993, 0x09A8}, {0x09AA, 0x09B0}, {0x09B2, 0x09B2},
+ {0x09B6, 0x09B9}, {0x09BC, 0x09C4}, {0x09C7, 0x09C8},
+ {0x09CB, 0x09CE}, {0x09D7, 0x09D7}, {0x09DC, 0x09DD},
+ {0x09DF, 0x09E3}, {0x09E6, 0x09FE}, {0x0A01, 0x0A03},
+ {0x0A05, 0x0A0A}, {0x0A0F, 0x0A10}, {0x0A13, 0x0A28},
+ {0x0A2A, 0x0A30}, {0x0A32, 0x0A33}, {0x0A35, 0x0A36},
+ {0x0A38, 0x0A39}, {0x0A3C, 0x0A3C}, {0x0A3E, 0x0A42},
+ {0x0A47, 0x0A48}, {0x0A4B, 0x0A4D}, {0x0A51, 0x0A51},
+ {0x0A59, 0x0A5C}, {0x0A5E, 0x0A5E}, {0x0A66, 0x0A76},
+ {0x0A81, 0x0A83}, {0x0A85, 0x0A8D}, {0x0A8F, 0x0A91},
+ {0x0A93, 0x0AA8}, {0x0AAA, 0x0AB0}, {0x0AB2, 0x0AB3},
+ {0x0AB5, 0x0AB9}, {0x0ABC, 0x0AC5}, {0x0AC7, 0x0AC9},
+ {0x0ACB, 0x0ACD}, {0x0AD0, 0x0AD0}, {0x0AE0, 0x0AE3},
+ {0x0AE6, 0x0AF1}, {0x0AF9, 0x0AFF}, {0x0B01, 0x0B03},
+ {0x0B05, 0x0B0C}, {0x0B0F, 0x0B10}, {0x0B13, 0x0B28},
+ {0x0B2A, 0x0B30}, {0x0B32, 0x0B33}, {0x0B35, 0x0B39},
+ {0x0B3C, 0x0B44}, {0x0B47, 0x0B48}, {0x0B4B, 0x0B4D},
+ {0x0B55, 0x0B57}, {0x0B5C, 0x0B5D}, {0x0B5F, 0x0B63},
+ {0x0B66, 0x0B77}, {0x0B82, 0x0B83}, {0x0B85, 0x0B8A},
+ {0x0B8E, 0x0B90}, {0x0B92, 0x0B95}, {0x0B99, 0x0B9A},
+ {0x0B9C, 0x0B9C}, {0x0B9E, 0x0B9F}, {0x0BA3, 0x0BA4},
+ {0x0BA8, 0x0BAA}, {0x0BAE, 0x0BB9}, {0x0BBE, 0x0BC2},
+ {0x0BC6, 0x0BC8}, {0x0BCA, 0x0BCD}, {0x0BD0, 0x0BD0},
+ {0x0BD7, 0x0BD7}, {0x0BE6, 0x0BFA}, {0x0C00, 0x0C0C},
+ {0x0C0E, 0x0C10}, {0x0C12, 0x0C28}, {0x0C2A, 0x0C39},
+ {0x0C3D, 0x0C44}, {0x0C46, 0x0C48}, {0x0C4A, 0x0C4D},
+ {0x0C55, 0x0C56}, {0x0C58, 0x0C5A}, {0x0C60, 0x0C63},
+ {0x0C66, 0x0C6F}, {0x0C77, 0x0C8C}, {0x0C8E, 0x0C90},
+ {0x0C92, 0x0CA8}, {0x0CAA, 0x0CB3}, {0x0CB5, 0x0CB9},
+ {0x0CBC, 0x0CC4}, {0x0CC6, 0x0CC8}, {0x0CCA, 0x0CCD},
+ {0x0CD5, 0x0CD6}, {0x0CDE, 0x0CDE}, {0x0CE0, 0x0CE3},
+ {0x0CE6, 0x0CEF}, {0x0CF1, 0x0CF2}, {0x0D00, 0x0D0C},
+ {0x0D0E, 0x0D10}, {0x0D12, 0x0D44}, {0x0D46, 0x0D48},
+ {0x0D4A, 0x0D4F}, {0x0D54, 0x0D63}, {0x0D66, 0x0D7F},
+ {0x0D81, 0x0D83}, {0x0D85, 0x0D96}, {0x0D9A, 0x0DB1},
+ {0x0DB3, 0x0DBB}, {0x0DBD, 0x0DBD}, {0x0DC0, 0x0DC6},
+ {0x0DCA, 0x0DCA}, {0x0DCF, 0x0DD4}, {0x0DD6, 0x0DD6},
+ {0x0DD8, 0x0DDF}, {0x0DE6, 0x0DEF}, {0x0DF2, 0x0DF4},
+ {0x0E01, 0x0E3A}, {0x0E3F, 0x0E5B}, {0x0E81, 0x0E82},
+ {0x0E84, 0x0E84}, {0x0E86, 0x0E8A}, {0x0E8C, 0x0EA3},
+ {0x0EA5, 0x0EA5}, {0x0EA7, 0x0EBD}, {0x0EC0, 0x0EC4},
+ {0x0EC6, 0x0EC6}, {0x0EC8, 0x0ECD}, {0x0ED0, 0x0ED9},
+ {0x0EDC, 0x0EDF}, {0x0F00, 0x0F47}, {0x0F49, 0x0F6C},
+ {0x0F71, 0x0F97}, {0x0F99, 0x0FBC}, {0x0FBE, 0x0FCC},
+ {0x0FCE, 0x0FDA}, {0x1000, 0x10C5}, {0x10C7, 0x10C7},
+ {0x10CD, 0x10CD}, {0x10D0, 0x10FF}, {0x1160, 0x1248},
+ {0x124A, 0x124D}, {0x1250, 0x1256}, {0x1258, 0x1258},
+ {0x125A, 0x125D}, {0x1260, 0x1288}, {0x128A, 0x128D},
+ {0x1290, 0x12B0}, {0x12B2, 0x12B5}, {0x12B8, 0x12BE},
+ {0x12C0, 0x12C0}, {0x12C2, 0x12C5}, {0x12C8, 0x12D6},
+ {0x12D8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135A},
+ {0x135D, 0x137C}, {0x1380, 0x1399}, {0x13A0, 0x13F5},
+ {0x13F8, 0x13FD}, {0x1400, 0x169C}, {0x16A0, 0x16F8},
+ {0x1700, 0x170C}, {0x170E, 0x1714}, {0x1720, 0x1736},
+ {0x1740, 0x1753}, {0x1760, 0x176C}, {0x176E, 0x1770},
+ {0x1772, 0x1773}, {0x1780, 0x17DD}, {0x17E0, 0x17E9},
+ {0x17F0, 0x17F9}, {0x1800, 0x180E}, {0x1810, 0x1819},
+ {0x1820, 0x1878}, {0x1880, 0x18AA}, {0x18B0, 0x18F5},
+ {0x1900, 0x191E}, {0x1920, 0x192B}, {0x1930, 0x193B},
+ {0x1940, 0x1940}, {0x1944, 0x196D}, {0x1970, 0x1974},
+ {0x1980, 0x19AB}, {0x19B0, 0x19C9}, {0x19D0, 0x19DA},
+ {0x19DE, 0x1A1B}, {0x1A1E, 0x1A5E}, {0x1A60, 0x1A7C},
+ {0x1A7F, 0x1A89}, {0x1A90, 0x1A99}, {0x1AA0, 0x1AAD},
+ {0x1AB0, 0x1AC0}, {0x1B00, 0x1B4B}, {0x1B50, 0x1B7C},
+ {0x1B80, 0x1BF3}, {0x1BFC, 0x1C37}, {0x1C3B, 0x1C49},
+ {0x1C4D, 0x1C88}, {0x1C90, 0x1CBA}, {0x1CBD, 0x1CC7},
+ {0x1CD0, 0x1CFA}, {0x1D00, 0x1DF9}, {0x1DFB, 0x1F15},
+ {0x1F18, 0x1F1D}, {0x1F20, 0x1F45}, {0x1F48, 0x1F4D},
+ {0x1F50, 0x1F57}, {0x1F59, 0x1F59}, {0x1F5B, 0x1F5B},
+ {0x1F5D, 0x1F5D}, {0x1F5F, 0x1F7D}, {0x1F80, 0x1FB4},
+ {0x1FB6, 0x1FC4}, {0x1FC6, 0x1FD3}, {0x1FD6, 0x1FDB},
+ {0x1FDD, 0x1FEF}, {0x1FF2, 0x1FF4}, {0x1FF6, 0x1FFE},
+ {0x2000, 0x200F}, {0x2011, 0x2012}, {0x2017, 0x2017},
+ {0x201A, 0x201B}, {0x201E, 0x201F}, {0x2023, 0x2023},
+ {0x2028, 0x202F}, {0x2031, 0x2031}, {0x2034, 0x2034},
+ {0x2036, 0x203A}, {0x203C, 0x203D}, {0x203F, 0x2064},
+ {0x2066, 0x2071}, {0x2075, 0x207E}, {0x2080, 0x2080},
+ {0x2085, 0x208E}, {0x2090, 0x209C}, {0x20A0, 0x20A8},
+ {0x20AA, 0x20AB}, {0x20AD, 0x20BF}, {0x20D0, 0x20F0},
+ {0x2100, 0x2102}, {0x2104, 0x2104}, {0x2106, 0x2108},
+ {0x210A, 0x2112}, {0x2114, 0x2115}, {0x2117, 0x2120},
+ {0x2123, 0x2125}, {0x2127, 0x212A}, {0x212C, 0x2152},
+ {0x2155, 0x215A}, {0x215F, 0x215F}, {0x216C, 0x216F},
+ {0x217A, 0x2188}, {0x218A, 0x218B}, {0x219A, 0x21B7},
+ {0x21BA, 0x21D1}, {0x21D3, 0x21D3}, {0x21D5, 0x21E6},
+ {0x21E8, 0x21FF}, {0x2201, 0x2201}, {0x2204, 0x2206},
+ {0x2209, 0x220A}, {0x220C, 0x220E}, {0x2210, 0x2210},
+ {0x2212, 0x2214}, {0x2216, 0x2219}, {0x221B, 0x221C},
+ {0x2221, 0x2222}, {0x2224, 0x2224}, {0x2226, 0x2226},
+ {0x222D, 0x222D}, {0x222F, 0x2233}, {0x2238, 0x223B},
+ {0x223E, 0x2247}, {0x2249, 0x224B}, {0x224D, 0x2251},
+ {0x2253, 0x225F}, {0x2262, 0x2263}, {0x2268, 0x2269},
+ {0x226C, 0x226D}, {0x2270, 0x2281}, {0x2284, 0x2285},
+ {0x2288, 0x2294}, {0x2296, 0x2298}, {0x229A, 0x22A4},
+ {0x22A6, 0x22BE}, {0x22C0, 0x2311}, {0x2313, 0x2319},
+ {0x231C, 0x2328}, {0x232B, 0x23E8}, {0x23ED, 0x23EF},
+ {0x23F1, 0x23F2}, {0x23F4, 0x2426}, {0x2440, 0x244A},
+ {0x24EA, 0x24EA}, {0x254C, 0x254F}, {0x2574, 0x257F},
+ {0x2590, 0x2591}, {0x2596, 0x259F}, {0x25A2, 0x25A2},
+ {0x25AA, 0x25B1}, {0x25B4, 0x25B5}, {0x25B8, 0x25BB},
+ {0x25BE, 0x25BF}, {0x25C2, 0x25C5}, {0x25C9, 0x25CA},
+ {0x25CC, 0x25CD}, {0x25D2, 0x25E1}, {0x25E6, 0x25EE},
+ {0x25F0, 0x25FC}, {0x25FF, 0x2604}, {0x2607, 0x2608},
+ {0x260A, 0x260D}, {0x2610, 0x2613}, {0x2616, 0x261B},
+ {0x261D, 0x261D}, {0x261F, 0x263F}, {0x2641, 0x2641},
+ {0x2643, 0x2647}, {0x2654, 0x265F}, {0x2662, 0x2662},
+ {0x2666, 0x2666}, {0x266B, 0x266B}, {0x266E, 0x266E},
+ {0x2670, 0x267E}, {0x2680, 0x2692}, {0x2694, 0x269D},
+ {0x26A0, 0x26A0}, {0x26A2, 0x26A9}, {0x26AC, 0x26BC},
+ {0x26C0, 0x26C3}, {0x26E2, 0x26E2}, {0x26E4, 0x26E7},
+ {0x2700, 0x2704}, {0x2706, 0x2709}, {0x270C, 0x2727},
+ {0x2729, 0x273C}, {0x273E, 0x274B}, {0x274D, 0x274D},
+ {0x274F, 0x2752}, {0x2756, 0x2756}, {0x2758, 0x2775},
+ {0x2780, 0x2794}, {0x2798, 0x27AF}, {0x27B1, 0x27BE},
+ {0x27C0, 0x27E5}, {0x27EE, 0x2984}, {0x2987, 0x2B1A},
+ {0x2B1D, 0x2B4F}, {0x2B51, 0x2B54}, {0x2B5A, 0x2B73},
+ {0x2B76, 0x2B95}, {0x2B97, 0x2C2E}, {0x2C30, 0x2C5E},
+ {0x2C60, 0x2CF3}, {0x2CF9, 0x2D25}, {0x2D27, 0x2D27},
+ {0x2D2D, 0x2D2D}, {0x2D30, 0x2D67}, {0x2D6F, 0x2D70},
+ {0x2D7F, 0x2D96}, {0x2DA0, 0x2DA6}, {0x2DA8, 0x2DAE},
+ {0x2DB0, 0x2DB6}, {0x2DB8, 0x2DBE}, {0x2DC0, 0x2DC6},
+ {0x2DC8, 0x2DCE}, {0x2DD0, 0x2DD6}, {0x2DD8, 0x2DDE},
+ {0x2DE0, 0x2E52}, {0x303F, 0x303F}, {0x4DC0, 0x4DFF},
+ {0xA4D0, 0xA62B}, {0xA640, 0xA6F7}, {0xA700, 0xA7BF},
+ {0xA7C2, 0xA7CA}, {0xA7F5, 0xA82C}, {0xA830, 0xA839},
+ {0xA840, 0xA877}, {0xA880, 0xA8C5}, {0xA8CE, 0xA8D9},
+ {0xA8E0, 0xA953}, {0xA95F, 0xA95F}, {0xA980, 0xA9CD},
+ {0xA9CF, 0xA9D9}, {0xA9DE, 0xA9FE}, {0xAA00, 0xAA36},
+ {0xAA40, 0xAA4D}, {0xAA50, 0xAA59}, {0xAA5C, 0xAAC2},
+ {0xAADB, 0xAAF6}, {0xAB01, 0xAB06}, {0xAB09, 0xAB0E},
+ {0xAB11, 0xAB16}, {0xAB20, 0xAB26}, {0xAB28, 0xAB2E},
+ {0xAB30, 0xAB6B}, {0xAB70, 0xABED}, {0xABF0, 0xABF9},
+ {0xD7B0, 0xD7C6}, {0xD7CB, 0xD7FB}, {0xD800, 0xDFFF},
+ {0xFB00, 0xFB06}, {0xFB13, 0xFB17}, {0xFB1D, 0xFB36},
+ {0xFB38, 0xFB3C}, {0xFB3E, 0xFB3E}, {0xFB40, 0xFB41},
+ {0xFB43, 0xFB44}, {0xFB46, 0xFBC1}, {0xFBD3, 0xFD3F},
+ {0xFD50, 0xFD8F}, {0xFD92, 0xFDC7}, {0xFDF0, 0xFDFD},
+ {0xFE20, 0xFE2F}, {0xFE70, 0xFE74}, {0xFE76, 0xFEFC},
+ {0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFC}, {0x10000, 0x1000B},
+ {0x1000D, 0x10026}, {0x10028, 0x1003A}, {0x1003C, 0x1003D},
+ {0x1003F, 0x1004D}, {0x10050, 0x1005D}, {0x10080, 0x100FA},
+ {0x10100, 0x10102}, {0x10107, 0x10133}, {0x10137, 0x1018E},
+ {0x10190, 0x1019C}, {0x101A0, 0x101A0}, {0x101D0, 0x101FD},
+ {0x10280, 0x1029C}, {0x102A0, 0x102D0}, {0x102E0, 0x102FB},
+ {0x10300, 0x10323}, {0x1032D, 0x1034A}, {0x10350, 0x1037A},
+ {0x10380, 0x1039D}, {0x1039F, 0x103C3}, {0x103C8, 0x103D5},
+ {0x10400, 0x1049D}, {0x104A0, 0x104A9}, {0x104B0, 0x104D3},
+ {0x104D8, 0x104FB}, {0x10500, 0x10527}, {0x10530, 0x10563},
+ {0x1056F, 0x1056F}, {0x10600, 0x10736}, {0x10740, 0x10755},
+ {0x10760, 0x10767}, {0x10800, 0x10805}, {0x10808, 0x10808},
+ {0x1080A, 0x10835}, {0x10837, 0x10838}, {0x1083C, 0x1083C},
+ {0x1083F, 0x10855}, {0x10857, 0x1089E}, {0x108A7, 0x108AF},
+ {0x108E0, 0x108F2}, {0x108F4, 0x108F5}, {0x108FB, 0x1091B},
+ {0x1091F, 0x10939}, {0x1093F, 0x1093F}, {0x10980, 0x109B7},
+ {0x109BC, 0x109CF}, {0x109D2, 0x10A03}, {0x10A05, 0x10A06},
+ {0x10A0C, 0x10A13}, {0x10A15, 0x10A17}, {0x10A19, 0x10A35},
+ {0x10A38, 0x10A3A}, {0x10A3F, 0x10A48}, {0x10A50, 0x10A58},
+ {0x10A60, 0x10A9F}, {0x10AC0, 0x10AE6}, {0x10AEB, 0x10AF6},
+ {0x10B00, 0x10B35}, {0x10B39, 0x10B55}, {0x10B58, 0x10B72},
+ {0x10B78, 0x10B91}, {0x10B99, 0x10B9C}, {0x10BA9, 0x10BAF},
+ {0x10C00, 0x10C48}, {0x10C80, 0x10CB2}, {0x10CC0, 0x10CF2},
+ {0x10CFA, 0x10D27}, {0x10D30, 0x10D39}, {0x10E60, 0x10E7E},
+ {0x10E80, 0x10EA9}, {0x10EAB, 0x10EAD}, {0x10EB0, 0x10EB1},
+ {0x10F00, 0x10F27}, {0x10F30, 0x10F59}, {0x10FB0, 0x10FCB},
+ {0x10FE0, 0x10FF6}, {0x11000, 0x1104D}, {0x11052, 0x1106F},
+ {0x1107F, 0x110C1}, {0x110CD, 0x110CD}, {0x110D0, 0x110E8},
+ {0x110F0, 0x110F9}, {0x11100, 0x11134}, {0x11136, 0x11147},
+ {0x11150, 0x11176}, {0x11180, 0x111DF}, {0x111E1, 0x111F4},
+ {0x11200, 0x11211}, {0x11213, 0x1123E}, {0x11280, 0x11286},
+ {0x11288, 0x11288}, {0x1128A, 0x1128D}, {0x1128F, 0x1129D},
+ {0x1129F, 0x112A9}, {0x112B0, 0x112EA}, {0x112F0, 0x112F9},
+ {0x11300, 0x11303}, {0x11305, 0x1130C}, {0x1130F, 0x11310},
+ {0x11313, 0x11328}, {0x1132A, 0x11330}, {0x11332, 0x11333},
+ {0x11335, 0x11339}, {0x1133B, 0x11344}, {0x11347, 0x11348},
+ {0x1134B, 0x1134D}, {0x11350, 0x11350}, {0x11357, 0x11357},
+ {0x1135D, 0x11363}, {0x11366, 0x1136C}, {0x11370, 0x11374},
+ {0x11400, 0x1145B}, {0x1145D, 0x11461}, {0x11480, 0x114C7},
+ {0x114D0, 0x114D9}, {0x11580, 0x115B5}, {0x115B8, 0x115DD},
+ {0x11600, 0x11644}, {0x11650, 0x11659}, {0x11660, 0x1166C},
+ {0x11680, 0x116B8}, {0x116C0, 0x116C9}, {0x11700, 0x1171A},
+ {0x1171D, 0x1172B}, {0x11730, 0x1173F}, {0x11800, 0x1183B},
+ {0x118A0, 0x118F2}, {0x118FF, 0x11906}, {0x11909, 0x11909},
+ {0x1190C, 0x11913}, {0x11915, 0x11916}, {0x11918, 0x11935},
+ {0x11937, 0x11938}, {0x1193B, 0x11946}, {0x11950, 0x11959},
+ {0x119A0, 0x119A7}, {0x119AA, 0x119D7}, {0x119DA, 0x119E4},
+ {0x11A00, 0x11A47}, {0x11A50, 0x11AA2}, {0x11AC0, 0x11AF8},
+ {0x11C00, 0x11C08}, {0x11C0A, 0x11C36}, {0x11C38, 0x11C45},
+ {0x11C50, 0x11C6C}, {0x11C70, 0x11C8F}, {0x11C92, 0x11CA7},
+ {0x11CA9, 0x11CB6}, {0x11D00, 0x11D06}, {0x11D08, 0x11D09},
+ {0x11D0B, 0x11D36}, {0x11D3A, 0x11D3A}, {0x11D3C, 0x11D3D},
+ {0x11D3F, 0x11D47}, {0x11D50, 0x11D59}, {0x11D60, 0x11D65},
+ {0x11D67, 0x11D68}, {0x11D6A, 0x11D8E}, {0x11D90, 0x11D91},
+ {0x11D93, 0x11D98}, {0x11DA0, 0x11DA9}, {0x11EE0, 0x11EF8},
+ {0x11FB0, 0x11FB0}, {0x11FC0, 0x11FF1}, {0x11FFF, 0x12399},
+ {0x12400, 0x1246E}, {0x12470, 0x12474}, {0x12480, 0x12543},
+ {0x13000, 0x1342E}, {0x13430, 0x13438}, {0x14400, 0x14646},
+ {0x16800, 0x16A38}, {0x16A40, 0x16A5E}, {0x16A60, 0x16A69},
+ {0x16A6E, 0x16A6F}, {0x16AD0, 0x16AED}, {0x16AF0, 0x16AF5},
+ {0x16B00, 0x16B45}, {0x16B50, 0x16B59}, {0x16B5B, 0x16B61},
+ {0x16B63, 0x16B77}, {0x16B7D, 0x16B8F}, {0x16E40, 0x16E9A},
+ {0x16F00, 0x16F4A}, {0x16F4F, 0x16F87}, {0x16F8F, 0x16F9F},
+ {0x1BC00, 0x1BC6A}, {0x1BC70, 0x1BC7C}, {0x1BC80, 0x1BC88},
+ {0x1BC90, 0x1BC99}, {0x1BC9C, 0x1BCA3}, {0x1D000, 0x1D0F5},
+ {0x1D100, 0x1D126}, {0x1D129, 0x1D1E8}, {0x1D200, 0x1D245},
+ {0x1D2E0, 0x1D2F3}, {0x1D300, 0x1D356}, {0x1D360, 0x1D378},
+ {0x1D400, 0x1D454}, {0x1D456, 0x1D49C}, {0x1D49E, 0x1D49F},
+ {0x1D4A2, 0x1D4A2}, {0x1D4A5, 0x1D4A6}, {0x1D4A9, 0x1D4AC},
+ {0x1D4AE, 0x1D4B9}, {0x1D4BB, 0x1D4BB}, {0x1D4BD, 0x1D4C3},
+ {0x1D4C5, 0x1D505}, {0x1D507, 0x1D50A}, {0x1D50D, 0x1D514},
+ {0x1D516, 0x1D51C}, {0x1D51E, 0x1D539}, {0x1D53B, 0x1D53E},
+ {0x1D540, 0x1D544}, {0x1D546, 0x1D546}, {0x1D54A, 0x1D550},
+ {0x1D552, 0x1D6A5}, {0x1D6A8, 0x1D7CB}, {0x1D7CE, 0x1DA8B},
+ {0x1DA9B, 0x1DA9F}, {0x1DAA1, 0x1DAAF}, {0x1E000, 0x1E006},
+ {0x1E008, 0x1E018}, {0x1E01B, 0x1E021}, {0x1E023, 0x1E024},
+ {0x1E026, 0x1E02A}, {0x1E100, 0x1E12C}, {0x1E130, 0x1E13D},
+ {0x1E140, 0x1E149}, {0x1E14E, 0x1E14F}, {0x1E2C0, 0x1E2F9},
+ {0x1E2FF, 0x1E2FF}, {0x1E800, 0x1E8C4}, {0x1E8C7, 0x1E8D6},
+ {0x1E900, 0x1E94B}, {0x1E950, 0x1E959}, {0x1E95E, 0x1E95F},
+ {0x1EC71, 0x1ECB4}, {0x1ED01, 0x1ED3D}, {0x1EE00, 0x1EE03},
+ {0x1EE05, 0x1EE1F}, {0x1EE21, 0x1EE22}, {0x1EE24, 0x1EE24},
+ {0x1EE27, 0x1EE27}, {0x1EE29, 0x1EE32}, {0x1EE34, 0x1EE37},
+ {0x1EE39, 0x1EE39}, {0x1EE3B, 0x1EE3B}, {0x1EE42, 0x1EE42},
+ {0x1EE47, 0x1EE47}, {0x1EE49, 0x1EE49}, {0x1EE4B, 0x1EE4B},
+ {0x1EE4D, 0x1EE4F}, {0x1EE51, 0x1EE52}, {0x1EE54, 0x1EE54},
+ {0x1EE57, 0x1EE57}, {0x1EE59, 0x1EE59}, {0x1EE5B, 0x1EE5B},
+ {0x1EE5D, 0x1EE5D}, {0x1EE5F, 0x1EE5F}, {0x1EE61, 0x1EE62},
+ {0x1EE64, 0x1EE64}, {0x1EE67, 0x1EE6A}, {0x1EE6C, 0x1EE72},
+ {0x1EE74, 0x1EE77}, {0x1EE79, 0x1EE7C}, {0x1EE7E, 0x1EE7E},
+ {0x1EE80, 0x1EE89}, {0x1EE8B, 0x1EE9B}, {0x1EEA1, 0x1EEA3},
+ {0x1EEA5, 0x1EEA9}, {0x1EEAB, 0x1EEBB}, {0x1EEF0, 0x1EEF1},
+ {0x1F000, 0x1F003}, {0x1F005, 0x1F02B}, {0x1F030, 0x1F093},
+ {0x1F0A0, 0x1F0AE}, {0x1F0B1, 0x1F0BF}, {0x1F0C1, 0x1F0CE},
+ {0x1F0D1, 0x1F0F5}, {0x1F10B, 0x1F10F}, {0x1F12E, 0x1F12F},
+ {0x1F16A, 0x1F16F}, {0x1F1AD, 0x1F1AD}, {0x1F1E6, 0x1F1FF},
+ {0x1F321, 0x1F32C}, {0x1F336, 0x1F336}, {0x1F37D, 0x1F37D},
+ {0x1F394, 0x1F39F}, {0x1F3CB, 0x1F3CE}, {0x1F3D4, 0x1F3DF},
+ {0x1F3F1, 0x1F3F3}, {0x1F3F5, 0x1F3F7}, {0x1F43F, 0x1F43F},
+ {0x1F441, 0x1F441}, {0x1F4FD, 0x1F4FE}, {0x1F53E, 0x1F54A},
+ {0x1F54F, 0x1F54F}, {0x1F568, 0x1F579}, {0x1F57B, 0x1F594},
+ {0x1F597, 0x1F5A3}, {0x1F5A5, 0x1F5FA}, {0x1F650, 0x1F67F},
+ {0x1F6C6, 0x1F6CB}, {0x1F6CD, 0x1F6CF}, {0x1F6D3, 0x1F6D4},
+ {0x1F6E0, 0x1F6EA}, {0x1F6F0, 0x1F6F3}, {0x1F700, 0x1F773},
+ {0x1F780, 0x1F7D8}, {0x1F800, 0x1F80B}, {0x1F810, 0x1F847},
+ {0x1F850, 0x1F859}, {0x1F860, 0x1F887}, {0x1F890, 0x1F8AD},
+ {0x1F8B0, 0x1F8B1}, {0x1F900, 0x1F90B}, {0x1F93B, 0x1F93B},
+ {0x1F946, 0x1F946}, {0x1FA00, 0x1FA53}, {0x1FA60, 0x1FA6D},
+ {0x1FB00, 0x1FB92}, {0x1FB94, 0x1FBCA}, {0x1FBF0, 0x1FBF9},
+ {0xE0001, 0xE0001}, {0xE0020, 0xE007F},
+}
+
+var emoji = table{
+ {0x203C, 0x203C}, {0x2049, 0x2049}, {0x2122, 0x2122},
+ {0x2139, 0x2139}, {0x2194, 0x2199}, {0x21A9, 0x21AA},
+ {0x231A, 0x231B}, {0x2328, 0x2328}, {0x2388, 0x2388},
+ {0x23CF, 0x23CF}, {0x23E9, 0x23F3}, {0x23F8, 0x23FA},
+ {0x24C2, 0x24C2}, {0x25AA, 0x25AB}, {0x25B6, 0x25B6},
+ {0x25C0, 0x25C0}, {0x25FB, 0x25FE}, {0x2600, 0x2605},
+ {0x2607, 0x2612}, {0x2614, 0x2685}, {0x2690, 0x2705},
+ {0x2708, 0x2712}, {0x2714, 0x2714}, {0x2716, 0x2716},
+ {0x271D, 0x271D}, {0x2721, 0x2721}, {0x2728, 0x2728},
+ {0x2733, 0x2734}, {0x2744, 0x2744}, {0x2747, 0x2747},
+ {0x274C, 0x274C}, {0x274E, 0x274E}, {0x2753, 0x2755},
+ {0x2757, 0x2757}, {0x2763, 0x2767}, {0x2795, 0x2797},
+ {0x27A1, 0x27A1}, {0x27B0, 0x27B0}, {0x27BF, 0x27BF},
+ {0x2934, 0x2935}, {0x2B05, 0x2B07}, {0x2B1B, 0x2B1C},
+ {0x2B50, 0x2B50}, {0x2B55, 0x2B55}, {0x3030, 0x3030},
+ {0x303D, 0x303D}, {0x3297, 0x3297}, {0x3299, 0x3299},
+ {0x1F000, 0x1F0FF}, {0x1F10D, 0x1F10F}, {0x1F12F, 0x1F12F},
+ {0x1F16C, 0x1F171}, {0x1F17E, 0x1F17F}, {0x1F18E, 0x1F18E},
+ {0x1F191, 0x1F19A}, {0x1F1AD, 0x1F1E5}, {0x1F201, 0x1F20F},
+ {0x1F21A, 0x1F21A}, {0x1F22F, 0x1F22F}, {0x1F232, 0x1F23A},
+ {0x1F23C, 0x1F23F}, {0x1F249, 0x1F3FA}, {0x1F400, 0x1F53D},
+ {0x1F546, 0x1F64F}, {0x1F680, 0x1F6FF}, {0x1F774, 0x1F77F},
+ {0x1F7D5, 0x1F7FF}, {0x1F80C, 0x1F80F}, {0x1F848, 0x1F84F},
+ {0x1F85A, 0x1F85F}, {0x1F888, 0x1F88F}, {0x1F8AE, 0x1F8FF},
+ {0x1F90C, 0x1F93A}, {0x1F93C, 0x1F945}, {0x1F947, 0x1FAFF},
+ {0x1FC00, 0x1FFFD},
+}
diff --git a/vendor/github.com/mattn/go-runewidth/runewidth_windows.go b/vendor/github.com/mattn/go-runewidth/runewidth_windows.go
new file mode 100644
index 000000000..5f987a310
--- /dev/null
+++ b/vendor/github.com/mattn/go-runewidth/runewidth_windows.go
@@ -0,0 +1,28 @@
+//go:build windows && !appengine
+// +build windows,!appengine
+
+package runewidth
+
+import (
+ "syscall"
+)
+
+var (
+ kernel32 = syscall.NewLazyDLL("kernel32")
+ procGetConsoleOutputCP = kernel32.NewProc("GetConsoleOutputCP")
+)
+
+// IsEastAsian return true if the current locale is CJK
+func IsEastAsian() bool {
+ r1, _, _ := procGetConsoleOutputCP.Call()
+ if r1 == 0 {
+ return false
+ }
+
+ switch int(r1) {
+ case 932, 51932, 936, 949, 950:
+ return true
+ }
+
+ return false
+}
diff --git a/vendor/github.com/muesli/reflow/LICENSE b/vendor/github.com/muesli/reflow/LICENSE
new file mode 100644
index 000000000..8532c45c9
--- /dev/null
+++ b/vendor/github.com/muesli/reflow/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/reflow/ansi/ansi.go b/vendor/github.com/muesli/reflow/ansi/ansi.go
new file mode 100644
index 000000000..f3d0700af
--- /dev/null
+++ b/vendor/github.com/muesli/reflow/ansi/ansi.go
@@ -0,0 +1,7 @@
+package ansi
+
+const Marker = '\x1B'
+
+func IsTerminator(c rune) bool {
+ return (c >= 0x40 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a)
+}
diff --git a/vendor/github.com/muesli/reflow/ansi/buffer.go b/vendor/github.com/muesli/reflow/ansi/buffer.go
new file mode 100644
index 000000000..471bcaf78
--- /dev/null
+++ b/vendor/github.com/muesli/reflow/ansi/buffer.go
@@ -0,0 +1,40 @@
+package ansi
+
+import (
+ "bytes"
+
+ "github.com/mattn/go-runewidth"
+)
+
+// Buffer is a buffer aware of ANSI escape sequences.
+type Buffer struct {
+ bytes.Buffer
+}
+
+// PrintableRuneWidth returns the cell width of all printable runes in the
+// buffer.
+func (w Buffer) PrintableRuneWidth() int {
+ return PrintableRuneWidth(w.String())
+}
+
+// PrintableRuneWidth returns the cell width of the given string.
+func PrintableRuneWidth(s string) int {
+ var n int
+ var ansi bool
+
+ for _, c := range s {
+ if c == Marker {
+ // ANSI escape sequence
+ ansi = true
+ } else if ansi {
+ if IsTerminator(c) {
+ // ANSI sequence terminated
+ ansi = false
+ }
+ } else {
+ n += runewidth.RuneWidth(c)
+ }
+ }
+
+ return n
+}
diff --git a/vendor/github.com/muesli/reflow/ansi/writer.go b/vendor/github.com/muesli/reflow/ansi/writer.go
new file mode 100644
index 000000000..a6aaa1ec6
--- /dev/null
+++ b/vendor/github.com/muesli/reflow/ansi/writer.go
@@ -0,0 +1,76 @@
+package ansi
+
+import (
+ "bytes"
+ "io"
+ "unicode/utf8"
+)
+
+type Writer struct {
+ Forward io.Writer
+
+ ansi bool
+ ansiseq bytes.Buffer
+ lastseq bytes.Buffer
+ seqchanged bool
+ runeBuf []byte
+}
+
+// Write is used to write content to the ANSI buffer.
+func (w *Writer) Write(b []byte) (int, error) {
+ for _, c := range string(b) {
+ if c == Marker {
+ // ANSI escape sequence
+ w.ansi = true
+ w.seqchanged = true
+ _, _ = w.ansiseq.WriteRune(c)
+ } else if w.ansi {
+ _, _ = w.ansiseq.WriteRune(c)
+ if IsTerminator(c) {
+ // ANSI sequence terminated
+ w.ansi = false
+
+ if bytes.HasSuffix(w.ansiseq.Bytes(), []byte("[0m")) {
+ // reset sequence
+ w.lastseq.Reset()
+ w.seqchanged = false
+ } else if c == 'm' {
+ // color code
+ _, _ = w.lastseq.Write(w.ansiseq.Bytes())
+ }
+
+ _, _ = w.ansiseq.WriteTo(w.Forward)
+ }
+ } else {
+ _, err := w.writeRune(c)
+ if err != nil {
+ return 0, err
+ }
+ }
+ }
+
+ return len(b), nil
+}
+
+func (w *Writer) writeRune(r rune) (int, error) {
+ if w.runeBuf == nil {
+ w.runeBuf = make([]byte, utf8.UTFMax)
+ }
+ n := utf8.EncodeRune(w.runeBuf, r)
+ return w.Forward.Write(w.runeBuf[:n])
+}
+
+func (w *Writer) LastSequence() string {
+ return w.lastseq.String()
+}
+
+func (w *Writer) ResetAnsi() {
+ if !w.seqchanged {
+ return
+ }
+ _, _ = w.Forward.Write([]byte("\x1b[0m"))
+}
+
+func (w *Writer) RestoreAnsi() {
+ _, _ = w.Forward.Write(w.lastseq.Bytes())
+}
diff --git a/vendor/github.com/muesli/reflow/truncate/truncate.go b/vendor/github.com/muesli/reflow/truncate/truncate.go
new file mode 100644
index 000000000..5aab5f896
--- /dev/null
+++ b/vendor/github.com/muesli/reflow/truncate/truncate.go
@@ -0,0 +1,120 @@
+package truncate
+
+import (
+ "bytes"
+ "io"
+
+ "github.com/mattn/go-runewidth"
+
+ "github.com/muesli/reflow/ansi"
+)
+
+type Writer struct {
+ width uint
+ tail string
+
+ ansiWriter *ansi.Writer
+ buf bytes.Buffer
+ ansi bool
+}
+
+func NewWriter(width uint, tail string) *Writer {
+ w := &Writer{
+ width: width,
+ tail: tail,
+ }
+ w.ansiWriter = &ansi.Writer{
+ Forward: &w.buf,
+ }
+ return w
+}
+
+func NewWriterPipe(forward io.Writer, width uint, tail string) *Writer {
+ return &Writer{
+ width: width,
+ tail: tail,
+ ansiWriter: &ansi.Writer{
+ Forward: forward,
+ },
+ }
+}
+
+// Bytes is shorthand for declaring a new default truncate-writer instance,
+// used to immediately truncate a byte slice.
+func Bytes(b []byte, width uint) []byte {
+ return BytesWithTail(b, width, []byte(""))
+}
+
+// Bytes is shorthand for declaring a new default truncate-writer instance,
+// used to immediately truncate a byte slice. A tail is then added to the
+// end of the byte slice.
+func BytesWithTail(b []byte, width uint, tail []byte) []byte {
+ f := NewWriter(width, string(tail))
+ _, _ = f.Write(b)
+
+ return f.Bytes()
+}
+
+// String is shorthand for declaring a new default truncate-writer instance,
+// used to immediately truncate a string.
+func String(s string, width uint) string {
+ return StringWithTail(s, width, "")
+}
+
+// StringWithTail is shorthand for declaring a new default truncate-writer instance,
+// used to immediately truncate a string. A tail is then added to the end of the
+// string.
+func StringWithTail(s string, width uint, tail string) string {
+ return string(BytesWithTail([]byte(s), width, []byte(tail)))
+}
+
+// Write truncates content at the given printable cell width, leaving any
+// ansi sequences intact.
+func (w *Writer) Write(b []byte) (int, error) {
+ tw := ansi.PrintableRuneWidth(w.tail)
+ if w.width < uint(tw) {
+ return w.buf.WriteString(w.tail)
+ }
+
+ w.width -= uint(tw)
+ var curWidth uint
+
+ for _, c := range string(b) {
+ if c == ansi.Marker {
+ // ANSI escape sequence
+ w.ansi = true
+ } else if w.ansi {
+ if ansi.IsTerminator(c) {
+ // ANSI sequence terminated
+ w.ansi = false
+ }
+ } else {
+ curWidth += uint(runewidth.RuneWidth(c))
+ }
+
+ if curWidth > w.width {
+ n, err := w.buf.WriteString(w.tail)
+ if w.ansiWriter.LastSequence() != "" {
+ w.ansiWriter.ResetAnsi()
+ }
+ return n, err
+ }
+
+ _, err := w.ansiWriter.Write([]byte(string(c)))
+ if err != nil {
+ return 0, err
+ }
+ }
+
+ return len(b), nil
+}
+
+// Bytes returns the truncated result as a byte slice.
+func (w *Writer) Bytes() []byte {
+ return w.buf.Bytes()
+}
+
+// String returns the truncated result as a string.
+func (w *Writer) String() string {
+ return w.buf.String()
+}
diff --git a/vendor/github.com/muesli/termenv/.gitignore b/vendor/github.com/muesli/termenv/.gitignore
new file mode 100644
index 000000000..66fd13c90
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/.gitignore
@@ -0,0 +1,15 @@
+# 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/
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 000000000..ef456e060
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/.golangci-soft.yml
@@ -0,0 +1,47 @@
+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
+ - gomnd
+ - gomoddirectives
+ - goprintffuncname
+ - ifshort
+ # - lll
+ - misspell
+ - nakedret
+ - nestif
+ - noctx
+ - nolintlint
+ - prealloc
+ - wrapcheck
+
+ # disable default linters, they are already enabled in .golangci.yml
+ disable:
+ - deadcode
+ - errcheck
+ - gosimple
+ - govet
+ - ineffassign
+ - staticcheck
+ - structcheck
+ - typecheck
+ - unused
+ - varcheck
diff --git a/vendor/github.com/muesli/termenv/.golangci.yml b/vendor/github.com/muesli/termenv/.golangci.yml
new file mode 100644
index 000000000..a5a91d0d9
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/.golangci.yml
@@ -0,0 +1,29 @@
+run:
+ tests: false
+
+issues:
+ include:
+ - EXC0001
+ - EXC0005
+ - EXC0011
+ - EXC0012
+ - EXC0013
+
+ max-issues-per-linter: 0
+ max-same-issues: 0
+
+linters:
+ enable:
+ - bodyclose
+ - exportloopref
+ - 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 000000000..8532c45c9
--- /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 000000000..29dcf0176
--- /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, 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 not supported, for more info see [issue#922](https://github.com/alacritty/alacritty/issues/922).
+
+
+
+## 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
+
+![ANSI color chart](https://github.com/muesli/termenv/raw/master/examples/color-chart/color-chart.png)
+
+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 000000000..6b68a3a9a
--- /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 000000000..ee303e22a
--- /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 000000000..1a216e93a
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/color.go
@@ -0,0 +1,204 @@
+package termenv
+
+import (
+ "errors"
+ "fmt"
+ "math"
+ "strings"
+
+ "github.com/lucasb-eyer/go-colorful"
+)
+
+var (
+ // ErrInvalidColor gets returned when a color is invalid.
+ 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.
+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)
+ }
+ return fmt.Sprintf("%d", bgMod(col-8)+90)
+}
+
+// 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))
+}
+
+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)
+}
+
+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 000000000..4262f03b9
--- /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 000000000..4262f03b9
--- /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 000000000..5d664245e
--- /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/copy.go b/vendor/github.com/muesli/termenv/copy.go
new file mode 100644
index 000000000..4bf5c9fea
--- /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 000000000..97e760a3b
--- /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 000000000..2a8cf06a9
--- /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 000000000..e22d369c9
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/output.go
@@ -0,0 +1,197 @@
+package termenv
+
+import (
+ "io"
+ "os"
+ "sync"
+)
+
+var (
+ // output is the default global output.
+ output = NewOutput(os.Stdout)
+)
+
+// File represents a file descriptor.
+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
+ tty 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 file descriptor.
+func NewOutput(tty io.Writer, opts ...OutputOption) *Output {
+ o := &Output{
+ tty: tty,
+ environ: &osEnviron{},
+ Profile: -1,
+ fgSync: &sync.Once{},
+ fgColor: NoColor{},
+ bgSync: &sync.Once{},
+ bgColor: NoColor{},
+ }
+
+ if o.tty == nil {
+ o.tty = 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
+}
+
+// TTY returns the terminal's file descriptor. This may be nil if the output is
+// not a terminal.
+func (o Output) TTY() File {
+ if f, ok := o.tty.(File); ok {
+ return f
+ }
+ return nil
+}
+
+func (o Output) Write(p []byte) (int, error) {
+ return o.tty.Write(p)
+}
+
+// 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 000000000..fa128e209
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/profile.go
@@ -0,0 +1,97 @@
+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
+)
+
+// 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 {
+ 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 000000000..a71181b61
--- /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.tty, CSI+ResetSeq+"m")
+}
+
+// SetForegroundColor sets the default foreground color.
+func (o Output) SetForegroundColor(color Color) {
+ fmt.Fprintf(o.tty, OSC+SetForegroundColorSeq, color)
+}
+
+// SetBackgroundColor sets the default background color.
+func (o Output) SetBackgroundColor(color Color) {
+ fmt.Fprintf(o.tty, OSC+SetBackgroundColorSeq, color)
+}
+
+// SetCursorColor sets the cursor color.
+func (o Output) SetCursorColor(color Color) {
+ fmt.Fprintf(o.tty, OSC+SetCursorColorSeq, color)
+}
+
+// RestoreScreen restores a previously saved screen state.
+func (o Output) RestoreScreen() {
+ fmt.Fprint(o.tty, CSI+RestoreScreenSeq)
+}
+
+// SaveScreen saves the screen state.
+func (o Output) SaveScreen() {
+ fmt.Fprint(o.tty, CSI+SaveScreenSeq)
+}
+
+// AltScreen switches to the alternate screen buffer. The former view can be
+// restored with ExitAltScreen().
+func (o Output) AltScreen() {
+ fmt.Fprint(o.tty, CSI+AltScreenSeq)
+}
+
+// ExitAltScreen exits the alternate screen buffer and returns to the former
+// terminal view.
+func (o Output) ExitAltScreen() {
+ fmt.Fprint(o.tty, CSI+ExitAltScreenSeq)
+}
+
+// ClearScreen clears the visible portion of the terminal.
+func (o Output) ClearScreen() {
+ fmt.Fprintf(o.tty, CSI+EraseDisplaySeq, 2)
+ o.MoveCursor(1, 1)
+}
+
+// MoveCursor moves the cursor to a given position.
+func (o Output) MoveCursor(row int, column int) {
+ fmt.Fprintf(o.tty, CSI+CursorPositionSeq, row, column)
+}
+
+// HideCursor hides the cursor.
+func (o Output) HideCursor() {
+ fmt.Fprint(o.tty, CSI+HideCursorSeq)
+}
+
+// ShowCursor shows the cursor.
+func (o Output) ShowCursor() {
+ fmt.Fprint(o.tty, CSI+ShowCursorSeq)
+}
+
+// SaveCursorPosition saves the cursor position.
+func (o Output) SaveCursorPosition() {
+ fmt.Fprint(o.tty, CSI+SaveCursorPositionSeq)
+}
+
+// RestoreCursorPosition restores a saved cursor position.
+func (o Output) RestoreCursorPosition() {
+ fmt.Fprint(o.tty, CSI+RestoreCursorPositionSeq)
+}
+
+// CursorUp moves the cursor up a given number of lines.
+func (o Output) CursorUp(n int) {
+ fmt.Fprintf(o.tty, CSI+CursorUpSeq, n)
+}
+
+// CursorDown moves the cursor down a given number of lines.
+func (o Output) CursorDown(n int) {
+ fmt.Fprintf(o.tty, CSI+CursorDownSeq, n)
+}
+
+// CursorForward moves the cursor up a given number of lines.
+func (o Output) CursorForward(n int) {
+ fmt.Fprintf(o.tty, CSI+CursorForwardSeq, n)
+}
+
+// CursorBack moves the cursor backwards a given number of cells.
+func (o Output) CursorBack(n int) {
+ fmt.Fprintf(o.tty, CSI+CursorBackSeq, n)
+}
+
+// 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.tty, CSI+CursorNextLineSeq, n)
+}
+
+// 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.tty, CSI+CursorPreviousLineSeq, n)
+}
+
+// ClearLine clears the current line.
+func (o Output) ClearLine() {
+ fmt.Fprint(o.tty, CSI+EraseEntireLineSeq)
+}
+
+// ClearLineLeft clears the line to the left of the cursor.
+func (o Output) ClearLineLeft() {
+ fmt.Fprint(o.tty, CSI+EraseLineLeftSeq)
+}
+
+// ClearLineRight clears the line to the right of the cursor.
+func (o Output) ClearLineRight() {
+ fmt.Fprint(o.tty, CSI+EraseLineRightSeq)
+}
+
+// ClearLines clears a given number of lines.
+func (o Output) ClearLines(n int) {
+ clearLine := fmt.Sprintf(CSI+EraseLineSeq, 2)
+ cursorUp := fmt.Sprintf(CSI+CursorUpSeq, 1)
+ fmt.Fprint(o.tty, clearLine+strings.Repeat(cursorUp+clearLine, n))
+}
+
+// ChangeScrollingRegion sets the scrolling region of the terminal.
+func (o Output) ChangeScrollingRegion(top, bottom int) {
+ fmt.Fprintf(o.tty, CSI+ChangeScrollingRegionSeq, top, bottom)
+}
+
+// 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.tty, CSI+InsertLineSeq, n)
+}
+
+// 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.tty, CSI+DeleteLineSeq, n)
+}
+
+// EnableMousePress enables X10 mouse mode. Button press events are sent only.
+func (o Output) EnableMousePress() {
+ fmt.Fprint(o.tty, CSI+EnableMousePressSeq)
+}
+
+// DisableMousePress disables X10 mouse mode.
+func (o Output) DisableMousePress() {
+ fmt.Fprint(o.tty, CSI+DisableMousePressSeq)
+}
+
+// EnableMouse enables Mouse Tracking mode.
+func (o Output) EnableMouse() {
+ fmt.Fprint(o.tty, CSI+EnableMouseSeq)
+}
+
+// DisableMouse disables Mouse Tracking mode.
+func (o Output) DisableMouse() {
+ fmt.Fprint(o.tty, CSI+DisableMouseSeq)
+}
+
+// EnableMouseHilite enables Hilite Mouse Tracking mode.
+func (o Output) EnableMouseHilite() {
+ fmt.Fprint(o.tty, CSI+EnableMouseHiliteSeq)
+}
+
+// DisableMouseHilite disables Hilite Mouse Tracking mode.
+func (o Output) DisableMouseHilite() {
+ fmt.Fprint(o.tty, CSI+DisableMouseHiliteSeq)
+}
+
+// EnableMouseCellMotion enables Cell Motion Mouse Tracking mode.
+func (o Output) EnableMouseCellMotion() {
+ fmt.Fprint(o.tty, CSI+EnableMouseCellMotionSeq)
+}
+
+// DisableMouseCellMotion disables Cell Motion Mouse Tracking mode.
+func (o Output) DisableMouseCellMotion() {
+ fmt.Fprint(o.tty, CSI+DisableMouseCellMotionSeq)
+}
+
+// EnableMouseAllMotion enables All Motion Mouse mode.
+func (o Output) EnableMouseAllMotion() {
+ fmt.Fprint(o.tty, CSI+EnableMouseAllMotionSeq)
+}
+
+// DisableMouseAllMotion disables All Motion Mouse mode.
+func (o Output) DisableMouseAllMotion() {
+ fmt.Fprint(o.tty, CSI+DisableMouseAllMotionSeq)
+}
+
+// EnableMouseExtendedMotion enables Extended Mouse mode (SGR). This should be
+// enabled in conjunction with EnableMouseCellMotion, and EnableMouseAllMotion.
+func (o Output) EnableMouseExtendedMode() {
+ fmt.Fprint(o.tty, CSI+EnableMouseExtendedModeSeq)
+}
+
+// DisableMouseExtendedMotion disables Extended Mouse mode (SGR).
+func (o Output) DisableMouseExtendedMode() {
+ fmt.Fprint(o.tty, CSI+DisableMouseExtendedModeSeq)
+}
+
+// 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.tty, CSI+EnableMousePixelsModeSeq)
+}
+
+// DisableMousePixelsMotion disables Pixel Motion Mouse mode (SGR-Pixels).
+func (o Output) DisableMousePixelsMode() {
+ fmt.Fprint(o.tty, CSI+DisableMousePixelsModeSeq)
+}
+
+// SetWindowTitle sets the terminal window title.
+func (o Output) SetWindowTitle(title string) {
+ fmt.Fprintf(o.tty, OSC+SetWindowTitleSeq, title)
+}
+
+// EnableBracketedPaste enables bracketed paste.
+func (o Output) EnableBracketedPaste() {
+ fmt.Fprintf(o.tty, CSI+EnableBracketedPasteSeq)
+}
+
+// DisableBracketedPaste disables bracketed paste.
+func (o Output) DisableBracketedPaste() {
+ fmt.Fprintf(o.tty, CSI+DisableBracketedPasteSeq)
+}
+
+// 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 000000000..83b0b4d7a
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/style.go
@@ -0,0 +1,126 @@
+package termenv
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/mattn/go-runewidth"
+)
+
+// 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 runewidth.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 000000000..d75b0796c
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/templatehelper.go
@@ -0,0 +1,86 @@
+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.
+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 000000000..4ceb27177
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/termenv.go
@@ -0,0 +1,114 @@
+package termenv
+
+import (
+ "errors"
+
+ "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 o.TTY() == nil {
+ return false
+ }
+
+ return isatty.IsTerminal(o.TTY().Fd())
+}
+
+// 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 000000000..93a43b6ac
--- /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 000000000..b2109b749
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/termenv_posix.go
@@ -0,0 +1,17 @@
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd
+
+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 000000000..27a95a93e
--- /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 000000000..24d519a5d
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/termenv_unix.go
@@ -0,0 +1,293 @@
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+
+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 "xterm-kitty", "wezterm":
+ return TrueColor
+ case "linux":
+ 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
+}
+
+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)
+}
+
+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))
+
+ for {
+ n, err := unix.Select(int(fd)+1, &readfds, nil, nil, &tv)
+ if err == unix.EINTR {
+ continue
+ }
+ if err != nil {
+ return err
+ }
+ 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
+ }
+
+ 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 {
+ 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") {
+ return "", ErrStatusReport
+ }
+
+ tty := o.TTY()
+ if tty == nil {
+ return "", ErrStatusReport
+ }
+
+ if !o.unsafe {
+ fd := int(tty.Fd())
+ // 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)
+
+ // then, query cursor position, should be supported by all terminals
+ fmt.Fprintf(tty, CSI+"6n")
+
+ // 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 000000000..1d9c61871
--- /dev/null
+++ b/vendor/github.com/muesli/termenv/termenv_windows.go
@@ -0,0 +1,139 @@
+//go:build windows
+// +build windows
+
+package termenv
+
+import (
+ "fmt"
+ "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 := o.TTY()
+ if tty == nil {
+ 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/rivo/uniseg/LICENSE.txt b/vendor/github.com/rivo/uniseg/LICENSE.txt
new file mode 100644
index 000000000..5040f1ef8
--- /dev/null
+++ b/vendor/github.com/rivo/uniseg/LICENSE.txt
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 Oliver Kuederle
+
+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/rivo/uniseg/README.md b/vendor/github.com/rivo/uniseg/README.md
new file mode 100644
index 000000000..a8191b815
--- /dev/null
+++ b/vendor/github.com/rivo/uniseg/README.md
@@ -0,0 +1,137 @@
+# Unicode Text Segmentation for Go
+
+[![Go Reference](https://pkg.go.dev/badge/github.com/rivo/uniseg.svg)](https://pkg.go.dev/github.com/rivo/uniseg)
+[![Go Report](https://img.shields.io/badge/go%20report-A%2B-brightgreen.svg)](https://goreportcard.com/report/github.com/rivo/uniseg)
+
+This Go package implements Unicode Text Segmentation according to [Unicode Standard Annex #29](https://unicode.org/reports/tr29/), Unicode Line Breaking according to [Unicode Standard Annex #14](https://unicode.org/reports/tr14/) (Unicode version 15.0.0), and monospace font string width calculation similar to [wcwidth](https://man7.org/linux/man-pages/man3/wcwidth.3.html).
+
+## Background
+
+### Grapheme Clusters
+
+In Go, [strings are read-only slices of bytes](https://go.dev/blog/strings). They can be turned into Unicode code points using the `for` loop or by casting: `[]rune(str)`. However, multiple code points may be combined into one user-perceived character or what the Unicode specification calls "grapheme cluster". Here are some examples:
+
+|String|Bytes (UTF-8)|Code points (runes)|Grapheme clusters|
+|-|-|-|-|
+|Käse|6 bytes: `4b 61 cc 88 73 65`|5 code points: `4b 61 308 73 65`|4 clusters: `[4b],[61 308],[73],[65]`|
+|🏳️🌈|14 bytes: `f0 9f 8f b3 ef b8 8f e2 80 8d f0 9f 8c 88`|4 code points: `1f3f3 fe0f 200d 1f308`|1 cluster: `[1f3f3 fe0f 200d 1f308]`|
+|🇩🇪|8 bytes: `f0 9f 87 a9 f0 9f 87 aa`|2 code points: `1f1e9 1f1ea`|1 cluster: `[1f1e9 1f1ea]`|
+
+This package provides tools to iterate over these grapheme clusters. This may be used to determine the number of user-perceived characters, to split strings in their intended places, or to extract individual characters which form a unit.
+
+### Word Boundaries
+
+Word boundaries are used in a number of different contexts. The most familiar ones are selection (double-click mouse selection), cursor movement ("move to next word" control-arrow keys), and the dialog option "Whole Word Search" for search and replace. They are also used in database queries, to determine whether elements are within a certain number of words of one another. Searching may also use word boundaries in determining matching items. This package provides tools to determine word boundaries within strings.
+
+### Sentence Boundaries
+
+Sentence boundaries are often used for triple-click or some other method of selecting or iterating through blocks of text that are larger than single words. They are also used to determine whether words occur within the same sentence in database queries. This package provides tools to determine sentence boundaries within strings.
+
+### Line Breaking
+
+Line breaking, also known as word wrapping, is the process of breaking a section of text into lines such that it will fit in the available width of a page, window or other display area. This package provides tools to determine where a string may or may not be broken and where it must be broken (for example after newline characters).
+
+### Monospace Width
+
+Most terminals or text displays / text editors using a monospace font (for example source code editors) use a fixed width for each character. Some characters such as emojis or characters found in Asian and other languages may take up more than one character cell. This package provides tools to determine the number of cells a string will take up when displayed in a monospace font. See [here](https://pkg.go.dev/github.com/rivo/uniseg#hdr-Monospace_Width) for more information.
+
+## Installation
+
+```bash
+go get github.com/rivo/uniseg
+```
+
+## Examples
+
+### Counting Characters in a String
+
+```go
+n := uniseg.GraphemeClusterCount("🇩🇪🏳️🌈")
+fmt.Println(n)
+// 2
+```
+
+### Calculating the Monospace String Width
+
+```go
+width := uniseg.StringWidth("🇩🇪🏳️🌈!")
+fmt.Println(width)
+// 5
+```
+
+### Using the [`Graphemes`](https://pkg.go.dev/github.com/rivo/uniseg#Graphemes) Class
+
+This is the most convenient method of iterating over grapheme clusters:
+
+```go
+gr := uniseg.NewGraphemes("👍🏼!")
+for gr.Next() {
+ fmt.Printf("%x ", gr.Runes())
+}
+// [1f44d 1f3fc] [21]
+```
+
+### Using the [`Step`](https://pkg.go.dev/github.com/rivo/uniseg#Step) or [`StepString`](https://pkg.go.dev/github.com/rivo/uniseg#StepString) Function
+
+This avoids allocating a new `Graphemes` object but it requires the handling of states and boundaries:
+
+```go
+str := "🇩🇪🏳️🌈"
+state := -1
+var c string
+for len(str) > 0 {
+ c, str, _, state = uniseg.StepString(str, state)
+ fmt.Printf("%x ", []rune(c))
+}
+// [1f1e9 1f1ea] [1f3f3 fe0f 200d 1f308]
+```
+
+### Advanced Examples
+
+The [`Graphemes`](https://pkg.go.dev/github.com/rivo/uniseg#Graphemes) class offers the most convenient way to access all functionality of this package. But in some cases, it may be better to use the specialized functions directly. For example, if you're only interested in word segmentation, use [`FirstWord`](https://pkg.go.dev/github.com/rivo/uniseg#FirstWord) or [`FirstWordInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstWordInString):
+
+```go
+str := "Hello, world!"
+state := -1
+var c string
+for len(str) > 0 {
+ c, str, state = uniseg.FirstWordInString(str, state)
+ fmt.Printf("(%s)\n", c)
+}
+// (Hello)
+// (,)
+// ( )
+// (world)
+// (!)
+```
+
+Similarly, use
+
+- [`FirstGraphemeCluster`](https://pkg.go.dev/github.com/rivo/uniseg#FirstGraphemeCluster) or [`FirstGraphemeClusterInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstGraphemeClusterInString) for grapheme cluster determination only,
+- [`FirstSentence`](https://pkg.go.dev/github.com/rivo/uniseg#FirstSentence) or [`FirstSentenceInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstSentenceInString) for sentence segmentation only, and
+- [`FirstLineSegment`](https://pkg.go.dev/github.com/rivo/uniseg#FirstLineSegment) or [`FirstLineSegmentInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstLineSegmentInString) for line breaking / word wrapping (although using [`Step`](https://pkg.go.dev/github.com/rivo/uniseg#Step) or [`StepString`](https://pkg.go.dev/github.com/rivo/uniseg#StepString) is preferred as it will observe grapheme cluster boundaries).
+
+If you're only interested in the width of characters, use [`FirstGraphemeCluster`](https://pkg.go.dev/github.com/rivo/uniseg#FirstGraphemeCluster) or [`FirstGraphemeClusterInString`](https://pkg.go.dev/github.com/rivo/uniseg#FirstGraphemeClusterInString). It is much faster than using [`Step`](https://pkg.go.dev/github.com/rivo/uniseg#Step), [`StepString`](https://pkg.go.dev/github.com/rivo/uniseg#StepString), or the [`Graphemes`](https://pkg.go.dev/github.com/rivo/uniseg#Graphemes) class because it does not include the logic for word / sentence / line boundaries.
+
+Finally, if you need to reverse a string while preserving grapheme clusters, use [`ReverseString`](https://pkg.go.dev/github.com/rivo/uniseg#ReverseString):
+
+```go
+fmt.Println(uniseg.ReverseString("🇩🇪🏳️🌈"))
+// 🏳️🌈🇩🇪
+```
+
+## Documentation
+
+Refer to https://pkg.go.dev/github.com/rivo/uniseg for the package's documentation.
+
+## Dependencies
+
+This package does not depend on any packages outside the standard library.
+
+## Sponsor this Project
+
+[Become a Sponsor on GitHub](https://github.com/sponsors/rivo?metadata_source=uniseg_readme) to support this project!
+
+## Your Feedback
+
+Add your issue here on GitHub, preferably before submitting any PR's. Feel free to get in touch if you have any questions.
\ No newline at end of file
diff --git a/vendor/github.com/rivo/uniseg/doc.go b/vendor/github.com/rivo/uniseg/doc.go
new file mode 100644
index 000000000..11224ae22
--- /dev/null
+++ b/vendor/github.com/rivo/uniseg/doc.go
@@ -0,0 +1,108 @@
+/*
+Package uniseg implements Unicode Text Segmentation, Unicode Line Breaking, and
+string width calculation for monospace fonts. Unicode Text Segmentation conforms
+to Unicode Standard Annex #29 (https://unicode.org/reports/tr29/) and Unicode
+Line Breaking conforms to Unicode Standard Annex #14
+(https://unicode.org/reports/tr14/).
+
+In short, using this package, you can split a string into grapheme clusters
+(what people would usually refer to as a "character"), into words, and into
+sentences. Or, in its simplest case, this package allows you to count the number
+of characters in a string, especially when it contains complex characters such
+as emojis, combining characters, or characters from Asian, Arabic, Hebrew, or
+other languages. Additionally, you can use it to implement line breaking (or
+"word wrapping"), that is, to determine where text can be broken over to the
+next line when the width of the line is not big enough to fit the entire text.
+Finally, you can use it to calculate the display width of a string for monospace
+fonts.
+
+# Getting Started
+
+If you just want to count the number of characters in a string, you can use
+[GraphemeClusterCount]. If you want to determine the display width of a string,
+you can use [StringWidth]. If you want to iterate over a string, you can use
+[Step], [StepString], or the [Graphemes] class (more convenient but less
+performant). This will provide you with all information: grapheme clusters,
+word boundaries, sentence boundaries, line breaks, and monospace character
+widths. The specialized functions [FirstGraphemeCluster],
+[FirstGraphemeClusterInString], [FirstWord], [FirstWordInString],
+[FirstSentence], and [FirstSentenceInString] can be used if only one type of
+information is needed.
+
+# Grapheme Clusters
+
+Consider the rainbow flag emoji: 🏳️🌈. On most modern systems, it appears as one
+character. But its string representation actually has 14 bytes, so counting
+bytes (or using len("🏳️🌈")) will not work as expected. Counting runes won't,
+either: The flag has 4 Unicode code points, thus 4 runes. The stdlib function
+utf8.RuneCountInString("🏳️🌈") and len([]rune("🏳️🌈")) will both return 4.
+
+The [GraphemeClusterCount] function will return 1 for the rainbow flag emoji.
+The Graphemes class and a variety of functions in this package will allow you to
+split strings into its grapheme clusters.
+
+# Word Boundaries
+
+Word boundaries are used in a number of different contexts. The most familiar
+ones are selection (double-click mouse selection), cursor movement ("move to
+next word" control-arrow keys), and the dialog option "Whole Word Search" for
+search and replace. This package provides methods for determining word
+boundaries.
+
+# Sentence Boundaries
+
+Sentence boundaries are often used for triple-click or some other method of
+selecting or iterating through blocks of text that are larger than single words.
+They are also used to determine whether words occur within the same sentence in
+database queries. This package provides methods for determining sentence
+boundaries.
+
+# Line Breaking
+
+Line breaking, also known as word wrapping, is the process of breaking a section
+of text into lines such that it will fit in the available width of a page,
+window or other display area. This package provides methods to determine the
+positions in a string where a line must be broken, may be broken, or must not be
+broken.
+
+# Monospace Width
+
+Monospace width, as referred to in this package, is the width of a string in a
+monospace font. This is commonly used in terminal user interfaces or text
+displays or editors that don't support proportional fonts. A width of 1
+corresponds to a single character cell. The C function [wcswidth()] and its
+implementation in other programming languages is in widespread use for the same
+purpose. However, there is no standard for the calculation of such widths, and
+this package differs from wcswidth() in a number of ways, presumably to generate
+more visually pleasing results.
+
+To start, we assume that every code point has a width of 1, with the following
+exceptions:
+
+ - Code points with grapheme cluster break properties Control, CR, LF, Extend,
+ and ZWJ have a width of 0.
+ - U+2E3A, Two-Em Dash, has a width of 3.
+ - U+2E3B, Three-Em Dash, has a width of 4.
+ - Characters with the East-Asian Width properties "Fullwidth" (F) and "Wide"
+ (W) have a width of 2. (Properties "Ambiguous" (A) and "Neutral" (N) both
+ have a width of 1.)
+ - Code points with grapheme cluster break property Regional Indicator have a
+ width of 2.
+ - Code points with grapheme cluster break property Extended Pictographic have
+ a width of 2, unless their Emoji Presentation flag is "No", in which case
+ the width is 1.
+
+For Hangul grapheme clusters composed of conjoining Jamo and for Regional
+Indicators (flags), all code points except the first one have a width of 0. For
+grapheme clusters starting with an Extended Pictographic, any additional code
+point will force a total width of 2, except if the Variation Selector-15
+(U+FE0E) is included, in which case the total width is always 1. Grapheme
+clusters ending with Variation Selector-16 (U+FE0F) have a width of 2.
+
+Note that whether these widths appear correct depends on your application's
+render engine, to which extent it conforms to the Unicode Standard, and its
+choice of font.
+
+[wcswidth()]: https://man7.org/linux/man-pages/man3/wcswidth.3.html
+*/
+package uniseg
diff --git a/vendor/github.com/rivo/uniseg/eastasianwidth.go b/vendor/github.com/rivo/uniseg/eastasianwidth.go
new file mode 100644
index 000000000..5fc54d991
--- /dev/null
+++ b/vendor/github.com/rivo/uniseg/eastasianwidth.go
@@ -0,0 +1,2588 @@
+// Code generated via go generate from gen_properties.go. DO NOT EDIT.
+
+package uniseg
+
+// eastAsianWidth are taken from
+// https://www.unicode.org/Public/15.0.0/ucd/EastAsianWidth.txt
+// and
+// https://unicode.org/Public/15.0.0/ucd/emoji/emoji-data.txt
+// ("Extended_Pictographic" only)
+// on September 5, 2023. See https://www.unicode.org/license.html for the Unicode
+// license agreement.
+var eastAsianWidth = [][3]int{
+ {0x0000, 0x001F, prN}, // Cc [32] ..
+ {0x0020, 0x0020, prNa}, // Zs SPACE
+ {0x0021, 0x0023, prNa}, // Po [3] EXCLAMATION MARK..NUMBER SIGN
+ {0x0024, 0x0024, prNa}, // Sc DOLLAR SIGN
+ {0x0025, 0x0027, prNa}, // Po [3] PERCENT SIGN..APOSTROPHE
+ {0x0028, 0x0028, prNa}, // Ps LEFT PARENTHESIS
+ {0x0029, 0x0029, prNa}, // Pe RIGHT PARENTHESIS
+ {0x002A, 0x002A, prNa}, // Po ASTERISK
+ {0x002B, 0x002B, prNa}, // Sm PLUS SIGN
+ {0x002C, 0x002C, prNa}, // Po COMMA
+ {0x002D, 0x002D, prNa}, // Pd HYPHEN-MINUS
+ {0x002E, 0x002F, prNa}, // Po [2] FULL STOP..SOLIDUS
+ {0x0030, 0x0039, prNa}, // Nd [10] DIGIT ZERO..DIGIT NINE
+ {0x003A, 0x003B, prNa}, // Po [2] COLON..SEMICOLON
+ {0x003C, 0x003E, prNa}, // Sm [3] LESS-THAN SIGN..GREATER-THAN SIGN
+ {0x003F, 0x0040, prNa}, // Po [2] QUESTION MARK..COMMERCIAL AT
+ {0x0041, 0x005A, prNa}, // Lu [26] LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER Z
+ {0x005B, 0x005B, prNa}, // Ps LEFT SQUARE BRACKET
+ {0x005C, 0x005C, prNa}, // Po REVERSE SOLIDUS
+ {0x005D, 0x005D, prNa}, // Pe RIGHT SQUARE BRACKET
+ {0x005E, 0x005E, prNa}, // Sk CIRCUMFLEX ACCENT
+ {0x005F, 0x005F, prNa}, // Pc LOW LINE
+ {0x0060, 0x0060, prNa}, // Sk GRAVE ACCENT
+ {0x0061, 0x007A, prNa}, // Ll [26] LATIN SMALL LETTER A..LATIN SMALL LETTER Z
+ {0x007B, 0x007B, prNa}, // Ps LEFT CURLY BRACKET
+ {0x007C, 0x007C, prNa}, // Sm VERTICAL LINE
+ {0x007D, 0x007D, prNa}, // Pe RIGHT CURLY BRACKET
+ {0x007E, 0x007E, prNa}, // Sm TILDE
+ {0x007F, 0x007F, prN}, // Cc
+ {0x0080, 0x009F, prN}, // Cc [32] ..
+ {0x00A0, 0x00A0, prN}, // Zs NO-BREAK SPACE
+ {0x00A1, 0x00A1, prA}, // Po INVERTED EXCLAMATION MARK
+ {0x00A2, 0x00A3, prNa}, // Sc [2] CENT SIGN..POUND SIGN
+ {0x00A4, 0x00A4, prA}, // Sc CURRENCY SIGN
+ {0x00A5, 0x00A5, prNa}, // Sc YEN SIGN
+ {0x00A6, 0x00A6, prNa}, // So BROKEN BAR
+ {0x00A7, 0x00A7, prA}, // Po SECTION SIGN
+ {0x00A8, 0x00A8, prA}, // Sk DIAERESIS
+ {0x00A9, 0x00A9, prN}, // So COPYRIGHT SIGN
+ {0x00AA, 0x00AA, prA}, // Lo FEMININE ORDINAL INDICATOR
+ {0x00AB, 0x00AB, prN}, // Pi LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+ {0x00AC, 0x00AC, prNa}, // Sm NOT SIGN
+ {0x00AD, 0x00AD, prA}, // Cf SOFT HYPHEN
+ {0x00AE, 0x00AE, prA}, // So REGISTERED SIGN
+ {0x00AF, 0x00AF, prNa}, // Sk MACRON
+ {0x00B0, 0x00B0, prA}, // So DEGREE SIGN
+ {0x00B1, 0x00B1, prA}, // Sm PLUS-MINUS SIGN
+ {0x00B2, 0x00B3, prA}, // No [2] SUPERSCRIPT TWO..SUPERSCRIPT THREE
+ {0x00B4, 0x00B4, prA}, // Sk ACUTE ACCENT
+ {0x00B5, 0x00B5, prN}, // Ll MICRO SIGN
+ {0x00B6, 0x00B7, prA}, // Po [2] PILCROW SIGN..MIDDLE DOT
+ {0x00B8, 0x00B8, prA}, // Sk CEDILLA
+ {0x00B9, 0x00B9, prA}, // No SUPERSCRIPT ONE
+ {0x00BA, 0x00BA, prA}, // Lo MASCULINE ORDINAL INDICATOR
+ {0x00BB, 0x00BB, prN}, // Pf RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+ {0x00BC, 0x00BE, prA}, // No [3] VULGAR FRACTION ONE QUARTER..VULGAR FRACTION THREE QUARTERS
+ {0x00BF, 0x00BF, prA}, // Po INVERTED QUESTION MARK
+ {0x00C0, 0x00C5, prN}, // Lu [6] LATIN CAPITAL LETTER A WITH GRAVE..LATIN CAPITAL LETTER A WITH RING ABOVE
+ {0x00C6, 0x00C6, prA}, // Lu LATIN CAPITAL LETTER AE
+ {0x00C7, 0x00CF, prN}, // Lu [9] LATIN CAPITAL LETTER C WITH CEDILLA..LATIN CAPITAL LETTER I WITH DIAERESIS
+ {0x00D0, 0x00D0, prA}, // Lu LATIN CAPITAL LETTER ETH
+ {0x00D1, 0x00D6, prN}, // Lu [6] LATIN CAPITAL LETTER N WITH TILDE..LATIN CAPITAL LETTER O WITH DIAERESIS
+ {0x00D7, 0x00D7, prA}, // Sm MULTIPLICATION SIGN
+ {0x00D8, 0x00D8, prA}, // Lu LATIN CAPITAL LETTER O WITH STROKE
+ {0x00D9, 0x00DD, prN}, // Lu [5] LATIN CAPITAL LETTER U WITH GRAVE..LATIN CAPITAL LETTER Y WITH ACUTE
+ {0x00DE, 0x00E1, prA}, // L& [4] LATIN CAPITAL LETTER THORN..LATIN SMALL LETTER A WITH ACUTE
+ {0x00E2, 0x00E5, prN}, // Ll [4] LATIN SMALL LETTER A WITH CIRCUMFLEX..LATIN SMALL LETTER A WITH RING ABOVE
+ {0x00E6, 0x00E6, prA}, // Ll LATIN SMALL LETTER AE
+ {0x00E7, 0x00E7, prN}, // Ll LATIN SMALL LETTER C WITH CEDILLA
+ {0x00E8, 0x00EA, prA}, // Ll [3] LATIN SMALL LETTER E WITH GRAVE..LATIN SMALL LETTER E WITH CIRCUMFLEX
+ {0x00EB, 0x00EB, prN}, // Ll LATIN SMALL LETTER E WITH DIAERESIS
+ {0x00EC, 0x00ED, prA}, // Ll [2] LATIN SMALL LETTER I WITH GRAVE..LATIN SMALL LETTER I WITH ACUTE
+ {0x00EE, 0x00EF, prN}, // Ll [2] LATIN SMALL LETTER I WITH CIRCUMFLEX..LATIN SMALL LETTER I WITH DIAERESIS
+ {0x00F0, 0x00F0, prA}, // Ll LATIN SMALL LETTER ETH
+ {0x00F1, 0x00F1, prN}, // Ll LATIN SMALL LETTER N WITH TILDE
+ {0x00F2, 0x00F3, prA}, // Ll [2] LATIN SMALL LETTER O WITH GRAVE..LATIN SMALL LETTER O WITH ACUTE
+ {0x00F4, 0x00F6, prN}, // Ll [3] LATIN SMALL LETTER O WITH CIRCUMFLEX..LATIN SMALL LETTER O WITH DIAERESIS
+ {0x00F7, 0x00F7, prA}, // Sm DIVISION SIGN
+ {0x00F8, 0x00FA, prA}, // Ll [3] LATIN SMALL LETTER O WITH STROKE..LATIN SMALL LETTER U WITH ACUTE
+ {0x00FB, 0x00FB, prN}, // Ll LATIN SMALL LETTER U WITH CIRCUMFLEX
+ {0x00FC, 0x00FC, prA}, // Ll LATIN SMALL LETTER U WITH DIAERESIS
+ {0x00FD, 0x00FD, prN}, // Ll LATIN SMALL LETTER Y WITH ACUTE
+ {0x00FE, 0x00FE, prA}, // Ll LATIN SMALL LETTER THORN
+ {0x00FF, 0x00FF, prN}, // Ll LATIN SMALL LETTER Y WITH DIAERESIS
+ {0x0100, 0x0100, prN}, // Lu LATIN CAPITAL LETTER A WITH MACRON
+ {0x0101, 0x0101, prA}, // Ll LATIN SMALL LETTER A WITH MACRON
+ {0x0102, 0x0110, prN}, // L& [15] LATIN CAPITAL LETTER A WITH BREVE..LATIN CAPITAL LETTER D WITH STROKE
+ {0x0111, 0x0111, prA}, // Ll LATIN SMALL LETTER D WITH STROKE
+ {0x0112, 0x0112, prN}, // Lu LATIN CAPITAL LETTER E WITH MACRON
+ {0x0113, 0x0113, prA}, // Ll LATIN SMALL LETTER E WITH MACRON
+ {0x0114, 0x011A, prN}, // L& [7] LATIN CAPITAL LETTER E WITH BREVE..LATIN CAPITAL LETTER E WITH CARON
+ {0x011B, 0x011B, prA}, // Ll LATIN SMALL LETTER E WITH CARON
+ {0x011C, 0x0125, prN}, // L& [10] LATIN CAPITAL LETTER G WITH CIRCUMFLEX..LATIN SMALL LETTER H WITH CIRCUMFLEX
+ {0x0126, 0x0127, prA}, // L& [2] LATIN CAPITAL LETTER H WITH STROKE..LATIN SMALL LETTER H WITH STROKE
+ {0x0128, 0x012A, prN}, // L& [3] LATIN CAPITAL LETTER I WITH TILDE..LATIN CAPITAL LETTER I WITH MACRON
+ {0x012B, 0x012B, prA}, // Ll LATIN SMALL LETTER I WITH MACRON
+ {0x012C, 0x0130, prN}, // L& [5] LATIN CAPITAL LETTER I WITH BREVE..LATIN CAPITAL LETTER I WITH DOT ABOVE
+ {0x0131, 0x0133, prA}, // L& [3] LATIN SMALL LETTER DOTLESS I..LATIN SMALL LIGATURE IJ
+ {0x0134, 0x0137, prN}, // L& [4] LATIN CAPITAL LETTER J WITH CIRCUMFLEX..LATIN SMALL LETTER K WITH CEDILLA
+ {0x0138, 0x0138, prA}, // Ll LATIN SMALL LETTER KRA
+ {0x0139, 0x013E, prN}, // L& [6] LATIN CAPITAL LETTER L WITH ACUTE..LATIN SMALL LETTER L WITH CARON
+ {0x013F, 0x0142, prA}, // L& [4] LATIN CAPITAL LETTER L WITH MIDDLE DOT..LATIN SMALL LETTER L WITH STROKE
+ {0x0143, 0x0143, prN}, // Lu LATIN CAPITAL LETTER N WITH ACUTE
+ {0x0144, 0x0144, prA}, // Ll LATIN SMALL LETTER N WITH ACUTE
+ {0x0145, 0x0147, prN}, // L& [3] LATIN CAPITAL LETTER N WITH CEDILLA..LATIN CAPITAL LETTER N WITH CARON
+ {0x0148, 0x014B, prA}, // L& [4] LATIN SMALL LETTER N WITH CARON..LATIN SMALL LETTER ENG
+ {0x014C, 0x014C, prN}, // Lu LATIN CAPITAL LETTER O WITH MACRON
+ {0x014D, 0x014D, prA}, // Ll LATIN SMALL LETTER O WITH MACRON
+ {0x014E, 0x0151, prN}, // L& [4] LATIN CAPITAL LETTER O WITH BREVE..LATIN SMALL LETTER O WITH DOUBLE ACUTE
+ {0x0152, 0x0153, prA}, // L& [2] LATIN CAPITAL LIGATURE OE..LATIN SMALL LIGATURE OE
+ {0x0154, 0x0165, prN}, // L& [18] LATIN CAPITAL LETTER R WITH ACUTE..LATIN SMALL LETTER T WITH CARON
+ {0x0166, 0x0167, prA}, // L& [2] LATIN CAPITAL LETTER T WITH STROKE..LATIN SMALL LETTER T WITH STROKE
+ {0x0168, 0x016A, prN}, // L& [3] LATIN CAPITAL LETTER U WITH TILDE..LATIN CAPITAL LETTER U WITH MACRON
+ {0x016B, 0x016B, prA}, // Ll LATIN SMALL LETTER U WITH MACRON
+ {0x016C, 0x017F, prN}, // L& [20] LATIN CAPITAL LETTER U WITH BREVE..LATIN SMALL LETTER LONG S
+ {0x0180, 0x01BA, prN}, // L& [59] LATIN SMALL LETTER B WITH STROKE..LATIN SMALL LETTER EZH WITH TAIL
+ {0x01BB, 0x01BB, prN}, // Lo LATIN LETTER TWO WITH STROKE
+ {0x01BC, 0x01BF, prN}, // L& [4] LATIN CAPITAL LETTER TONE FIVE..LATIN LETTER WYNN
+ {0x01C0, 0x01C3, prN}, // Lo [4] LATIN LETTER DENTAL CLICK..LATIN LETTER RETROFLEX CLICK
+ {0x01C4, 0x01CD, prN}, // L& [10] LATIN CAPITAL LETTER DZ WITH CARON..LATIN CAPITAL LETTER A WITH CARON
+ {0x01CE, 0x01CE, prA}, // Ll LATIN SMALL LETTER A WITH CARON
+ {0x01CF, 0x01CF, prN}, // Lu LATIN CAPITAL LETTER I WITH CARON
+ {0x01D0, 0x01D0, prA}, // Ll LATIN SMALL LETTER I WITH CARON
+ {0x01D1, 0x01D1, prN}, // Lu LATIN CAPITAL LETTER O WITH CARON
+ {0x01D2, 0x01D2, prA}, // Ll LATIN SMALL LETTER O WITH CARON
+ {0x01D3, 0x01D3, prN}, // Lu LATIN CAPITAL LETTER U WITH CARON
+ {0x01D4, 0x01D4, prA}, // Ll LATIN SMALL LETTER U WITH CARON
+ {0x01D5, 0x01D5, prN}, // Lu LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON
+ {0x01D6, 0x01D6, prA}, // Ll LATIN SMALL LETTER U WITH DIAERESIS AND MACRON
+ {0x01D7, 0x01D7, prN}, // Lu LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE
+ {0x01D8, 0x01D8, prA}, // Ll LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE
+ {0x01D9, 0x01D9, prN}, // Lu LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON
+ {0x01DA, 0x01DA, prA}, // Ll LATIN SMALL LETTER U WITH DIAERESIS AND CARON
+ {0x01DB, 0x01DB, prN}, // Lu LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE
+ {0x01DC, 0x01DC, prA}, // Ll LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE
+ {0x01DD, 0x024F, prN}, // L& [115] LATIN SMALL LETTER TURNED E..LATIN SMALL LETTER Y WITH STROKE
+ {0x0250, 0x0250, prN}, // Ll LATIN SMALL LETTER TURNED A
+ {0x0251, 0x0251, prA}, // Ll LATIN SMALL LETTER ALPHA
+ {0x0252, 0x0260, prN}, // Ll [15] LATIN SMALL LETTER TURNED ALPHA..LATIN SMALL LETTER G WITH HOOK
+ {0x0261, 0x0261, prA}, // Ll LATIN SMALL LETTER SCRIPT G
+ {0x0262, 0x0293, prN}, // Ll [50] LATIN LETTER SMALL CAPITAL G..LATIN SMALL LETTER EZH WITH CURL
+ {0x0294, 0x0294, prN}, // Lo LATIN LETTER GLOTTAL STOP
+ {0x0295, 0x02AF, prN}, // Ll [27] LATIN LETTER PHARYNGEAL VOICED FRICATIVE..LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL
+ {0x02B0, 0x02C1, prN}, // Lm [18] MODIFIER LETTER SMALL H..MODIFIER LETTER REVERSED GLOTTAL STOP
+ {0x02C2, 0x02C3, prN}, // Sk [2] MODIFIER LETTER LEFT ARROWHEAD..MODIFIER LETTER RIGHT ARROWHEAD
+ {0x02C4, 0x02C4, prA}, // Sk MODIFIER LETTER UP ARROWHEAD
+ {0x02C5, 0x02C5, prN}, // Sk MODIFIER LETTER DOWN ARROWHEAD
+ {0x02C6, 0x02C6, prN}, // Lm MODIFIER LETTER CIRCUMFLEX ACCENT
+ {0x02C7, 0x02C7, prA}, // Lm CARON
+ {0x02C8, 0x02C8, prN}, // Lm MODIFIER LETTER VERTICAL LINE
+ {0x02C9, 0x02CB, prA}, // Lm [3] MODIFIER LETTER MACRON..MODIFIER LETTER GRAVE ACCENT
+ {0x02CC, 0x02CC, prN}, // Lm MODIFIER LETTER LOW VERTICAL LINE
+ {0x02CD, 0x02CD, prA}, // Lm MODIFIER LETTER LOW MACRON
+ {0x02CE, 0x02CF, prN}, // Lm [2] MODIFIER LETTER LOW GRAVE ACCENT..MODIFIER LETTER LOW ACUTE ACCENT
+ {0x02D0, 0x02D0, prA}, // Lm MODIFIER LETTER TRIANGULAR COLON
+ {0x02D1, 0x02D1, prN}, // Lm MODIFIER LETTER HALF TRIANGULAR COLON
+ {0x02D2, 0x02D7, prN}, // Sk [6] MODIFIER LETTER CENTRED RIGHT HALF RING..MODIFIER LETTER MINUS SIGN
+ {0x02D8, 0x02DB, prA}, // Sk [4] BREVE..OGONEK
+ {0x02DC, 0x02DC, prN}, // Sk SMALL TILDE
+ {0x02DD, 0x02DD, prA}, // Sk DOUBLE ACUTE ACCENT
+ {0x02DE, 0x02DE, prN}, // Sk MODIFIER LETTER RHOTIC HOOK
+ {0x02DF, 0x02DF, prA}, // Sk MODIFIER LETTER CROSS ACCENT
+ {0x02E0, 0x02E4, prN}, // Lm [5] MODIFIER LETTER SMALL GAMMA..MODIFIER LETTER SMALL REVERSED GLOTTAL STOP
+ {0x02E5, 0x02EB, prN}, // Sk [7] MODIFIER LETTER EXTRA-HIGH TONE BAR..MODIFIER LETTER YANG DEPARTING TONE MARK
+ {0x02EC, 0x02EC, prN}, // Lm MODIFIER LETTER VOICING
+ {0x02ED, 0x02ED, prN}, // Sk MODIFIER LETTER UNASPIRATED
+ {0x02EE, 0x02EE, prN}, // Lm MODIFIER LETTER DOUBLE APOSTROPHE
+ {0x02EF, 0x02FF, prN}, // Sk [17] MODIFIER LETTER LOW DOWN ARROWHEAD..MODIFIER LETTER LOW LEFT ARROW
+ {0x0300, 0x036F, prA}, // Mn [112] COMBINING GRAVE ACCENT..COMBINING LATIN SMALL LETTER X
+ {0x0370, 0x0373, prN}, // L& [4] GREEK CAPITAL LETTER HETA..GREEK SMALL LETTER ARCHAIC SAMPI
+ {0x0374, 0x0374, prN}, // Lm GREEK NUMERAL SIGN
+ {0x0375, 0x0375, prN}, // Sk GREEK LOWER NUMERAL SIGN
+ {0x0376, 0x0377, prN}, // L& [2] GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA..GREEK SMALL LETTER PAMPHYLIAN DIGAMMA
+ {0x037A, 0x037A, prN}, // Lm GREEK YPOGEGRAMMENI
+ {0x037B, 0x037D, prN}, // Ll [3] GREEK SMALL REVERSED LUNATE SIGMA SYMBOL..GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL
+ {0x037E, 0x037E, prN}, // Po GREEK QUESTION MARK
+ {0x037F, 0x037F, prN}, // Lu GREEK CAPITAL LETTER YOT
+ {0x0384, 0x0385, prN}, // Sk [2] GREEK TONOS..GREEK DIALYTIKA TONOS
+ {0x0386, 0x0386, prN}, // Lu GREEK CAPITAL LETTER ALPHA WITH TONOS
+ {0x0387, 0x0387, prN}, // Po GREEK ANO TELEIA
+ {0x0388, 0x038A, prN}, // Lu [3] GREEK CAPITAL LETTER EPSILON WITH TONOS..GREEK CAPITAL LETTER IOTA WITH TONOS
+ {0x038C, 0x038C, prN}, // Lu GREEK CAPITAL LETTER OMICRON WITH TONOS
+ {0x038E, 0x0390, prN}, // L& [3] GREEK CAPITAL LETTER UPSILON WITH TONOS..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
+ {0x0391, 0x03A1, prA}, // Lu [17] GREEK CAPITAL LETTER ALPHA..GREEK CAPITAL LETTER RHO
+ {0x03A3, 0x03A9, prA}, // Lu [7] GREEK CAPITAL LETTER SIGMA..GREEK CAPITAL LETTER OMEGA
+ {0x03AA, 0x03B0, prN}, // L& [7] GREEK CAPITAL LETTER IOTA WITH DIALYTIKA..GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
+ {0x03B1, 0x03C1, prA}, // Ll [17] GREEK SMALL LETTER ALPHA..GREEK SMALL LETTER RHO
+ {0x03C2, 0x03C2, prN}, // Ll GREEK SMALL LETTER FINAL SIGMA
+ {0x03C3, 0x03C9, prA}, // Ll [7] GREEK SMALL LETTER SIGMA..GREEK SMALL LETTER OMEGA
+ {0x03CA, 0x03F5, prN}, // L& [44] GREEK SMALL LETTER IOTA WITH DIALYTIKA..GREEK LUNATE EPSILON SYMBOL
+ {0x03F6, 0x03F6, prN}, // Sm GREEK REVERSED LUNATE EPSILON SYMBOL
+ {0x03F7, 0x03FF, prN}, // L& [9] GREEK CAPITAL LETTER SHO..GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL
+ {0x0400, 0x0400, prN}, // Lu CYRILLIC CAPITAL LETTER IE WITH GRAVE
+ {0x0401, 0x0401, prA}, // Lu CYRILLIC CAPITAL LETTER IO
+ {0x0402, 0x040F, prN}, // Lu [14] CYRILLIC CAPITAL LETTER DJE..CYRILLIC CAPITAL LETTER DZHE
+ {0x0410, 0x044F, prA}, // L& [64] CYRILLIC CAPITAL LETTER A..CYRILLIC SMALL LETTER YA
+ {0x0450, 0x0450, prN}, // Ll CYRILLIC SMALL LETTER IE WITH GRAVE
+ {0x0451, 0x0451, prA}, // Ll CYRILLIC SMALL LETTER IO
+ {0x0452, 0x0481, prN}, // L& [48] CYRILLIC SMALL LETTER DJE..CYRILLIC SMALL LETTER KOPPA
+ {0x0482, 0x0482, prN}, // So CYRILLIC THOUSANDS SIGN
+ {0x0483, 0x0487, prN}, // Mn [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE
+ {0x0488, 0x0489, prN}, // Me [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN
+ {0x048A, 0x04FF, prN}, // L& [118] CYRILLIC CAPITAL LETTER SHORT I WITH TAIL..CYRILLIC SMALL LETTER HA WITH STROKE
+ {0x0500, 0x052F, prN}, // L& [48] CYRILLIC CAPITAL LETTER KOMI DE..CYRILLIC SMALL LETTER EL WITH DESCENDER
+ {0x0531, 0x0556, prN}, // Lu [38] ARMENIAN CAPITAL LETTER AYB..ARMENIAN CAPITAL LETTER FEH
+ {0x0559, 0x0559, prN}, // Lm ARMENIAN MODIFIER LETTER LEFT HALF RING
+ {0x055A, 0x055F, prN}, // Po [6] ARMENIAN APOSTROPHE..ARMENIAN ABBREVIATION MARK
+ {0x0560, 0x0588, prN}, // Ll [41] ARMENIAN SMALL LETTER TURNED AYB..ARMENIAN SMALL LETTER YI WITH STROKE
+ {0x0589, 0x0589, prN}, // Po ARMENIAN FULL STOP
+ {0x058A, 0x058A, prN}, // Pd ARMENIAN HYPHEN
+ {0x058D, 0x058E, prN}, // So [2] RIGHT-FACING ARMENIAN ETERNITY SIGN..LEFT-FACING ARMENIAN ETERNITY SIGN
+ {0x058F, 0x058F, prN}, // Sc ARMENIAN DRAM SIGN
+ {0x0591, 0x05BD, prN}, // Mn [45] HEBREW ACCENT ETNAHTA..HEBREW POINT METEG
+ {0x05BE, 0x05BE, prN}, // Pd HEBREW PUNCTUATION MAQAF
+ {0x05BF, 0x05BF, prN}, // Mn HEBREW POINT RAFE
+ {0x05C0, 0x05C0, prN}, // Po HEBREW PUNCTUATION PASEQ
+ {0x05C1, 0x05C2, prN}, // Mn [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT
+ {0x05C3, 0x05C3, prN}, // Po HEBREW PUNCTUATION SOF PASUQ
+ {0x05C4, 0x05C5, prN}, // Mn [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT
+ {0x05C6, 0x05C6, prN}, // Po HEBREW PUNCTUATION NUN HAFUKHA
+ {0x05C7, 0x05C7, prN}, // Mn HEBREW POINT QAMATS QATAN
+ {0x05D0, 0x05EA, prN}, // Lo [27] HEBREW LETTER ALEF..HEBREW LETTER TAV
+ {0x05EF, 0x05F2, prN}, // Lo [4] HEBREW YOD TRIANGLE..HEBREW LIGATURE YIDDISH DOUBLE YOD
+ {0x05F3, 0x05F4, prN}, // Po [2] HEBREW PUNCTUATION GERESH..HEBREW PUNCTUATION GERSHAYIM
+ {0x0600, 0x0605, prN}, // Cf [6] ARABIC NUMBER SIGN..ARABIC NUMBER MARK ABOVE
+ {0x0606, 0x0608, prN}, // Sm [3] ARABIC-INDIC CUBE ROOT..ARABIC RAY
+ {0x0609, 0x060A, prN}, // Po [2] ARABIC-INDIC PER MILLE SIGN..ARABIC-INDIC PER TEN THOUSAND SIGN
+ {0x060B, 0x060B, prN}, // Sc AFGHANI SIGN
+ {0x060C, 0x060D, prN}, // Po [2] ARABIC COMMA..ARABIC DATE SEPARATOR
+ {0x060E, 0x060F, prN}, // So [2] ARABIC POETIC VERSE SIGN..ARABIC SIGN MISRA
+ {0x0610, 0x061A, prN}, // Mn [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA
+ {0x061B, 0x061B, prN}, // Po ARABIC SEMICOLON
+ {0x061C, 0x061C, prN}, // Cf ARABIC LETTER MARK
+ {0x061D, 0x061F, prN}, // Po [3] ARABIC END OF TEXT MARK..ARABIC QUESTION MARK
+ {0x0620, 0x063F, prN}, // Lo [32] ARABIC LETTER KASHMIRI YEH..ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE
+ {0x0640, 0x0640, prN}, // Lm ARABIC TATWEEL
+ {0x0641, 0x064A, prN}, // Lo [10] ARABIC LETTER FEH..ARABIC LETTER YEH
+ {0x064B, 0x065F, prN}, // Mn [21] ARABIC FATHATAN..ARABIC WAVY HAMZA BELOW
+ {0x0660, 0x0669, prN}, // Nd [10] ARABIC-INDIC DIGIT ZERO..ARABIC-INDIC DIGIT NINE
+ {0x066A, 0x066D, prN}, // Po [4] ARABIC PERCENT SIGN..ARABIC FIVE POINTED STAR
+ {0x066E, 0x066F, prN}, // Lo [2] ARABIC LETTER DOTLESS BEH..ARABIC LETTER DOTLESS QAF
+ {0x0670, 0x0670, prN}, // Mn ARABIC LETTER SUPERSCRIPT ALEF
+ {0x0671, 0x06D3, prN}, // Lo [99] ARABIC LETTER ALEF WASLA..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE
+ {0x06D4, 0x06D4, prN}, // Po ARABIC FULL STOP
+ {0x06D5, 0x06D5, prN}, // Lo ARABIC LETTER AE
+ {0x06D6, 0x06DC, prN}, // Mn [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN
+ {0x06DD, 0x06DD, prN}, // Cf ARABIC END OF AYAH
+ {0x06DE, 0x06DE, prN}, // So ARABIC START OF RUB EL HIZB
+ {0x06DF, 0x06E4, prN}, // Mn [6] ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MADDA
+ {0x06E5, 0x06E6, prN}, // Lm [2] ARABIC SMALL WAW..ARABIC SMALL YEH
+ {0x06E7, 0x06E8, prN}, // Mn [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON
+ {0x06E9, 0x06E9, prN}, // So ARABIC PLACE OF SAJDAH
+ {0x06EA, 0x06ED, prN}, // Mn [4] ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM
+ {0x06EE, 0x06EF, prN}, // Lo [2] ARABIC LETTER DAL WITH INVERTED V..ARABIC LETTER REH WITH INVERTED V
+ {0x06F0, 0x06F9, prN}, // Nd [10] EXTENDED ARABIC-INDIC DIGIT ZERO..EXTENDED ARABIC-INDIC DIGIT NINE
+ {0x06FA, 0x06FC, prN}, // Lo [3] ARABIC LETTER SHEEN WITH DOT BELOW..ARABIC LETTER GHAIN WITH DOT BELOW
+ {0x06FD, 0x06FE, prN}, // So [2] ARABIC SIGN SINDHI AMPERSAND..ARABIC SIGN SINDHI POSTPOSITION MEN
+ {0x06FF, 0x06FF, prN}, // Lo ARABIC LETTER HEH WITH INVERTED V
+ {0x0700, 0x070D, prN}, // Po [14] SYRIAC END OF PARAGRAPH..SYRIAC HARKLEAN ASTERISCUS
+ {0x070F, 0x070F, prN}, // Cf SYRIAC ABBREVIATION MARK
+ {0x0710, 0x0710, prN}, // Lo SYRIAC LETTER ALAPH
+ {0x0711, 0x0711, prN}, // Mn SYRIAC LETTER SUPERSCRIPT ALAPH
+ {0x0712, 0x072F, prN}, // Lo [30] SYRIAC LETTER BETH..SYRIAC LETTER PERSIAN DHALATH
+ {0x0730, 0x074A, prN}, // Mn [27] SYRIAC PTHAHA ABOVE..SYRIAC BARREKH
+ {0x074D, 0x074F, prN}, // Lo [3] SYRIAC LETTER SOGDIAN ZHAIN..SYRIAC LETTER SOGDIAN FE
+ {0x0750, 0x077F, prN}, // Lo [48] ARABIC LETTER BEH WITH THREE DOTS HORIZONTALLY BELOW..ARABIC LETTER KAF WITH TWO DOTS ABOVE
+ {0x0780, 0x07A5, prN}, // Lo [38] THAANA LETTER HAA..THAANA LETTER WAAVU
+ {0x07A6, 0x07B0, prN}, // Mn [11] THAANA ABAFILI..THAANA SUKUN
+ {0x07B1, 0x07B1, prN}, // Lo THAANA LETTER NAA
+ {0x07C0, 0x07C9, prN}, // Nd [10] NKO DIGIT ZERO..NKO DIGIT NINE
+ {0x07CA, 0x07EA, prN}, // Lo [33] NKO LETTER A..NKO LETTER JONA RA
+ {0x07EB, 0x07F3, prN}, // Mn [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE
+ {0x07F4, 0x07F5, prN}, // Lm [2] NKO HIGH TONE APOSTROPHE..NKO LOW TONE APOSTROPHE
+ {0x07F6, 0x07F6, prN}, // So NKO SYMBOL OO DENNEN
+ {0x07F7, 0x07F9, prN}, // Po [3] NKO SYMBOL GBAKURUNEN..NKO EXCLAMATION MARK
+ {0x07FA, 0x07FA, prN}, // Lm NKO LAJANYALAN
+ {0x07FD, 0x07FD, prN}, // Mn NKO DANTAYALAN
+ {0x07FE, 0x07FF, prN}, // Sc [2] NKO DOROME SIGN..NKO TAMAN SIGN
+ {0x0800, 0x0815, prN}, // Lo [22] SAMARITAN LETTER ALAF..SAMARITAN LETTER TAAF
+ {0x0816, 0x0819, prN}, // Mn [4] SAMARITAN MARK IN..SAMARITAN MARK DAGESH
+ {0x081A, 0x081A, prN}, // Lm SAMARITAN MODIFIER LETTER EPENTHETIC YUT
+ {0x081B, 0x0823, prN}, // Mn [9] SAMARITAN MARK EPENTHETIC YUT..SAMARITAN VOWEL SIGN A
+ {0x0824, 0x0824, prN}, // Lm SAMARITAN MODIFIER LETTER SHORT A
+ {0x0825, 0x0827, prN}, // Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U
+ {0x0828, 0x0828, prN}, // Lm SAMARITAN MODIFIER LETTER I
+ {0x0829, 0x082D, prN}, // Mn [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA
+ {0x0830, 0x083E, prN}, // Po [15] SAMARITAN PUNCTUATION NEQUDAA..SAMARITAN PUNCTUATION ANNAAU
+ {0x0840, 0x0858, prN}, // Lo [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN
+ {0x0859, 0x085B, prN}, // Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK
+ {0x085E, 0x085E, prN}, // Po MANDAIC PUNCTUATION
+ {0x0860, 0x086A, prN}, // Lo [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA
+ {0x0870, 0x0887, prN}, // Lo [24] ARABIC LETTER ALEF WITH ATTACHED FATHA..ARABIC BASELINE ROUND DOT
+ {0x0888, 0x0888, prN}, // Sk ARABIC RAISED ROUND DOT
+ {0x0889, 0x088E, prN}, // Lo [6] ARABIC LETTER NOON WITH INVERTED SMALL V..ARABIC VERTICAL TAIL
+ {0x0890, 0x0891, prN}, // Cf [2] ARABIC POUND MARK ABOVE..ARABIC PIASTRE MARK ABOVE
+ {0x0898, 0x089F, prN}, // Mn [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA
+ {0x08A0, 0x08C8, prN}, // Lo [41] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER GRAF
+ {0x08C9, 0x08C9, prN}, // Lm ARABIC SMALL FARSI YEH
+ {0x08CA, 0x08E1, prN}, // Mn [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA
+ {0x08E2, 0x08E2, prN}, // Cf ARABIC DISPUTED END OF AYAH
+ {0x08E3, 0x08FF, prN}, // Mn [29] ARABIC TURNED DAMMA BELOW..ARABIC MARK SIDEWAYS NOON GHUNNA
+ {0x0900, 0x0902, prN}, // Mn [3] DEVANAGARI SIGN INVERTED CANDRABINDU..DEVANAGARI SIGN ANUSVARA
+ {0x0903, 0x0903, prN}, // Mc DEVANAGARI SIGN VISARGA
+ {0x0904, 0x0939, prN}, // Lo [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA
+ {0x093A, 0x093A, prN}, // Mn DEVANAGARI VOWEL SIGN OE
+ {0x093B, 0x093B, prN}, // Mc DEVANAGARI VOWEL SIGN OOE
+ {0x093C, 0x093C, prN}, // Mn DEVANAGARI SIGN NUKTA
+ {0x093D, 0x093D, prN}, // Lo DEVANAGARI SIGN AVAGRAHA
+ {0x093E, 0x0940, prN}, // Mc [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II
+ {0x0941, 0x0948, prN}, // Mn [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI
+ {0x0949, 0x094C, prN}, // Mc [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU
+ {0x094D, 0x094D, prN}, // Mn DEVANAGARI SIGN VIRAMA
+ {0x094E, 0x094F, prN}, // Mc [2] DEVANAGARI VOWEL SIGN PRISHTHAMATRA E..DEVANAGARI VOWEL SIGN AW
+ {0x0950, 0x0950, prN}, // Lo DEVANAGARI OM
+ {0x0951, 0x0957, prN}, // Mn [7] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI VOWEL SIGN UUE
+ {0x0958, 0x0961, prN}, // Lo [10] DEVANAGARI LETTER QA..DEVANAGARI LETTER VOCALIC LL
+ {0x0962, 0x0963, prN}, // Mn [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL
+ {0x0964, 0x0965, prN}, // Po [2] DEVANAGARI DANDA..DEVANAGARI DOUBLE DANDA
+ {0x0966, 0x096F, prN}, // Nd [10] DEVANAGARI DIGIT ZERO..DEVANAGARI DIGIT NINE
+ {0x0970, 0x0970, prN}, // Po DEVANAGARI ABBREVIATION SIGN
+ {0x0971, 0x0971, prN}, // Lm DEVANAGARI SIGN HIGH SPACING DOT
+ {0x0972, 0x097F, prN}, // Lo [14] DEVANAGARI LETTER CANDRA A..DEVANAGARI LETTER BBA
+ {0x0980, 0x0980, prN}, // Lo BENGALI ANJI
+ {0x0981, 0x0981, prN}, // Mn BENGALI SIGN CANDRABINDU
+ {0x0982, 0x0983, prN}, // Mc [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA
+ {0x0985, 0x098C, prN}, // Lo [8] BENGALI LETTER A..BENGALI LETTER VOCALIC L
+ {0x098F, 0x0990, prN}, // Lo [2] BENGALI LETTER E..BENGALI LETTER AI
+ {0x0993, 0x09A8, prN}, // Lo [22] BENGALI LETTER O..BENGALI LETTER NA
+ {0x09AA, 0x09B0, prN}, // Lo [7] BENGALI LETTER PA..BENGALI LETTER RA
+ {0x09B2, 0x09B2, prN}, // Lo BENGALI LETTER LA
+ {0x09B6, 0x09B9, prN}, // Lo [4] BENGALI LETTER SHA..BENGALI LETTER HA
+ {0x09BC, 0x09BC, prN}, // Mn BENGALI SIGN NUKTA
+ {0x09BD, 0x09BD, prN}, // Lo BENGALI SIGN AVAGRAHA
+ {0x09BE, 0x09C0, prN}, // Mc [3] BENGALI VOWEL SIGN AA..BENGALI VOWEL SIGN II
+ {0x09C1, 0x09C4, prN}, // Mn [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR
+ {0x09C7, 0x09C8, prN}, // Mc [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI
+ {0x09CB, 0x09CC, prN}, // Mc [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU
+ {0x09CD, 0x09CD, prN}, // Mn BENGALI SIGN VIRAMA
+ {0x09CE, 0x09CE, prN}, // Lo BENGALI LETTER KHANDA TA
+ {0x09D7, 0x09D7, prN}, // Mc BENGALI AU LENGTH MARK
+ {0x09DC, 0x09DD, prN}, // Lo [2] BENGALI LETTER RRA..BENGALI LETTER RHA
+ {0x09DF, 0x09E1, prN}, // Lo [3] BENGALI LETTER YYA..BENGALI LETTER VOCALIC LL
+ {0x09E2, 0x09E3, prN}, // Mn [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL
+ {0x09E6, 0x09EF, prN}, // Nd [10] BENGALI DIGIT ZERO..BENGALI DIGIT NINE
+ {0x09F0, 0x09F1, prN}, // Lo [2] BENGALI LETTER RA WITH MIDDLE DIAGONAL..BENGALI LETTER RA WITH LOWER DIAGONAL
+ {0x09F2, 0x09F3, prN}, // Sc [2] BENGALI RUPEE MARK..BENGALI RUPEE SIGN
+ {0x09F4, 0x09F9, prN}, // No [6] BENGALI CURRENCY NUMERATOR ONE..BENGALI CURRENCY DENOMINATOR SIXTEEN
+ {0x09FA, 0x09FA, prN}, // So BENGALI ISSHAR
+ {0x09FB, 0x09FB, prN}, // Sc BENGALI GANDA MARK
+ {0x09FC, 0x09FC, prN}, // Lo BENGALI LETTER VEDIC ANUSVARA
+ {0x09FD, 0x09FD, prN}, // Po BENGALI ABBREVIATION SIGN
+ {0x09FE, 0x09FE, prN}, // Mn BENGALI SANDHI MARK
+ {0x0A01, 0x0A02, prN}, // Mn [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI
+ {0x0A03, 0x0A03, prN}, // Mc GURMUKHI SIGN VISARGA
+ {0x0A05, 0x0A0A, prN}, // Lo [6] GURMUKHI LETTER A..GURMUKHI LETTER UU
+ {0x0A0F, 0x0A10, prN}, // Lo [2] GURMUKHI LETTER EE..GURMUKHI LETTER AI
+ {0x0A13, 0x0A28, prN}, // Lo [22] GURMUKHI LETTER OO..GURMUKHI LETTER NA
+ {0x0A2A, 0x0A30, prN}, // Lo [7] GURMUKHI LETTER PA..GURMUKHI LETTER RA
+ {0x0A32, 0x0A33, prN}, // Lo [2] GURMUKHI LETTER LA..GURMUKHI LETTER LLA
+ {0x0A35, 0x0A36, prN}, // Lo [2] GURMUKHI LETTER VA..GURMUKHI LETTER SHA
+ {0x0A38, 0x0A39, prN}, // Lo [2] GURMUKHI LETTER SA..GURMUKHI LETTER HA
+ {0x0A3C, 0x0A3C, prN}, // Mn GURMUKHI SIGN NUKTA
+ {0x0A3E, 0x0A40, prN}, // Mc [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II
+ {0x0A41, 0x0A42, prN}, // Mn [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU
+ {0x0A47, 0x0A48, prN}, // Mn [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI
+ {0x0A4B, 0x0A4D, prN}, // Mn [3] GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA
+ {0x0A51, 0x0A51, prN}, // Mn GURMUKHI SIGN UDAAT
+ {0x0A59, 0x0A5C, prN}, // Lo [4] GURMUKHI LETTER KHHA..GURMUKHI LETTER RRA
+ {0x0A5E, 0x0A5E, prN}, // Lo GURMUKHI LETTER FA
+ {0x0A66, 0x0A6F, prN}, // Nd [10] GURMUKHI DIGIT ZERO..GURMUKHI DIGIT NINE
+ {0x0A70, 0x0A71, prN}, // Mn [2] GURMUKHI TIPPI..GURMUKHI ADDAK
+ {0x0A72, 0x0A74, prN}, // Lo [3] GURMUKHI IRI..GURMUKHI EK ONKAR
+ {0x0A75, 0x0A75, prN}, // Mn GURMUKHI SIGN YAKASH
+ {0x0A76, 0x0A76, prN}, // Po GURMUKHI ABBREVIATION SIGN
+ {0x0A81, 0x0A82, prN}, // Mn [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA
+ {0x0A83, 0x0A83, prN}, // Mc GUJARATI SIGN VISARGA
+ {0x0A85, 0x0A8D, prN}, // Lo [9] GUJARATI LETTER A..GUJARATI VOWEL CANDRA E
+ {0x0A8F, 0x0A91, prN}, // Lo [3] GUJARATI LETTER E..GUJARATI VOWEL CANDRA O
+ {0x0A93, 0x0AA8, prN}, // Lo [22] GUJARATI LETTER O..GUJARATI LETTER NA
+ {0x0AAA, 0x0AB0, prN}, // Lo [7] GUJARATI LETTER PA..GUJARATI LETTER RA
+ {0x0AB2, 0x0AB3, prN}, // Lo [2] GUJARATI LETTER LA..GUJARATI LETTER LLA
+ {0x0AB5, 0x0AB9, prN}, // Lo [5] GUJARATI LETTER VA..GUJARATI LETTER HA
+ {0x0ABC, 0x0ABC, prN}, // Mn GUJARATI SIGN NUKTA
+ {0x0ABD, 0x0ABD, prN}, // Lo GUJARATI SIGN AVAGRAHA
+ {0x0ABE, 0x0AC0, prN}, // Mc [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II
+ {0x0AC1, 0x0AC5, prN}, // Mn [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E
+ {0x0AC7, 0x0AC8, prN}, // Mn [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI
+ {0x0AC9, 0x0AC9, prN}, // Mc GUJARATI VOWEL SIGN CANDRA O
+ {0x0ACB, 0x0ACC, prN}, // Mc [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU
+ {0x0ACD, 0x0ACD, prN}, // Mn GUJARATI SIGN VIRAMA
+ {0x0AD0, 0x0AD0, prN}, // Lo GUJARATI OM
+ {0x0AE0, 0x0AE1, prN}, // Lo [2] GUJARATI LETTER VOCALIC RR..GUJARATI LETTER VOCALIC LL
+ {0x0AE2, 0x0AE3, prN}, // Mn [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL
+ {0x0AE6, 0x0AEF, prN}, // Nd [10] GUJARATI DIGIT ZERO..GUJARATI DIGIT NINE
+ {0x0AF0, 0x0AF0, prN}, // Po GUJARATI ABBREVIATION SIGN
+ {0x0AF1, 0x0AF1, prN}, // Sc GUJARATI RUPEE SIGN
+ {0x0AF9, 0x0AF9, prN}, // Lo GUJARATI LETTER ZHA
+ {0x0AFA, 0x0AFF, prN}, // Mn [6] GUJARATI SIGN SUKUN..GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE
+ {0x0B01, 0x0B01, prN}, // Mn ORIYA SIGN CANDRABINDU
+ {0x0B02, 0x0B03, prN}, // Mc [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA
+ {0x0B05, 0x0B0C, prN}, // Lo [8] ORIYA LETTER A..ORIYA LETTER VOCALIC L
+ {0x0B0F, 0x0B10, prN}, // Lo [2] ORIYA LETTER E..ORIYA LETTER AI
+ {0x0B13, 0x0B28, prN}, // Lo [22] ORIYA LETTER O..ORIYA LETTER NA
+ {0x0B2A, 0x0B30, prN}, // Lo [7] ORIYA LETTER PA..ORIYA LETTER RA
+ {0x0B32, 0x0B33, prN}, // Lo [2] ORIYA LETTER LA..ORIYA LETTER LLA
+ {0x0B35, 0x0B39, prN}, // Lo [5] ORIYA LETTER VA..ORIYA LETTER HA
+ {0x0B3C, 0x0B3C, prN}, // Mn ORIYA SIGN NUKTA
+ {0x0B3D, 0x0B3D, prN}, // Lo ORIYA SIGN AVAGRAHA
+ {0x0B3E, 0x0B3E, prN}, // Mc ORIYA VOWEL SIGN AA
+ {0x0B3F, 0x0B3F, prN}, // Mn ORIYA VOWEL SIGN I
+ {0x0B40, 0x0B40, prN}, // Mc ORIYA VOWEL SIGN II
+ {0x0B41, 0x0B44, prN}, // Mn [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR
+ {0x0B47, 0x0B48, prN}, // Mc [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI
+ {0x0B4B, 0x0B4C, prN}, // Mc [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU
+ {0x0B4D, 0x0B4D, prN}, // Mn ORIYA SIGN VIRAMA
+ {0x0B55, 0x0B56, prN}, // Mn [2] ORIYA SIGN OVERLINE..ORIYA AI LENGTH MARK
+ {0x0B57, 0x0B57, prN}, // Mc ORIYA AU LENGTH MARK
+ {0x0B5C, 0x0B5D, prN}, // Lo [2] ORIYA LETTER RRA..ORIYA LETTER RHA
+ {0x0B5F, 0x0B61, prN}, // Lo [3] ORIYA LETTER YYA..ORIYA LETTER VOCALIC LL
+ {0x0B62, 0x0B63, prN}, // Mn [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL
+ {0x0B66, 0x0B6F, prN}, // Nd [10] ORIYA DIGIT ZERO..ORIYA DIGIT NINE
+ {0x0B70, 0x0B70, prN}, // So ORIYA ISSHAR
+ {0x0B71, 0x0B71, prN}, // Lo ORIYA LETTER WA
+ {0x0B72, 0x0B77, prN}, // No [6] ORIYA FRACTION ONE QUARTER..ORIYA FRACTION THREE SIXTEENTHS
+ {0x0B82, 0x0B82, prN}, // Mn TAMIL SIGN ANUSVARA
+ {0x0B83, 0x0B83, prN}, // Lo TAMIL SIGN VISARGA
+ {0x0B85, 0x0B8A, prN}, // Lo [6] TAMIL LETTER A..TAMIL LETTER UU
+ {0x0B8E, 0x0B90, prN}, // Lo [3] TAMIL LETTER E..TAMIL LETTER AI
+ {0x0B92, 0x0B95, prN}, // Lo [4] TAMIL LETTER O..TAMIL LETTER KA
+ {0x0B99, 0x0B9A, prN}, // Lo [2] TAMIL LETTER NGA..TAMIL LETTER CA
+ {0x0B9C, 0x0B9C, prN}, // Lo TAMIL LETTER JA
+ {0x0B9E, 0x0B9F, prN}, // Lo [2] TAMIL LETTER NYA..TAMIL LETTER TTA
+ {0x0BA3, 0x0BA4, prN}, // Lo [2] TAMIL LETTER NNA..TAMIL LETTER TA
+ {0x0BA8, 0x0BAA, prN}, // Lo [3] TAMIL LETTER NA..TAMIL LETTER PA
+ {0x0BAE, 0x0BB9, prN}, // Lo [12] TAMIL LETTER MA..TAMIL LETTER HA
+ {0x0BBE, 0x0BBF, prN}, // Mc [2] TAMIL VOWEL SIGN AA..TAMIL VOWEL SIGN I
+ {0x0BC0, 0x0BC0, prN}, // Mn TAMIL VOWEL SIGN II
+ {0x0BC1, 0x0BC2, prN}, // Mc [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU
+ {0x0BC6, 0x0BC8, prN}, // Mc [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI
+ {0x0BCA, 0x0BCC, prN}, // Mc [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU
+ {0x0BCD, 0x0BCD, prN}, // Mn TAMIL SIGN VIRAMA
+ {0x0BD0, 0x0BD0, prN}, // Lo TAMIL OM
+ {0x0BD7, 0x0BD7, prN}, // Mc TAMIL AU LENGTH MARK
+ {0x0BE6, 0x0BEF, prN}, // Nd [10] TAMIL DIGIT ZERO..TAMIL DIGIT NINE
+ {0x0BF0, 0x0BF2, prN}, // No [3] TAMIL NUMBER TEN..TAMIL NUMBER ONE THOUSAND
+ {0x0BF3, 0x0BF8, prN}, // So [6] TAMIL DAY SIGN..TAMIL AS ABOVE SIGN
+ {0x0BF9, 0x0BF9, prN}, // Sc TAMIL RUPEE SIGN
+ {0x0BFA, 0x0BFA, prN}, // So TAMIL NUMBER SIGN
+ {0x0C00, 0x0C00, prN}, // Mn TELUGU SIGN COMBINING CANDRABINDU ABOVE
+ {0x0C01, 0x0C03, prN}, // Mc [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA
+ {0x0C04, 0x0C04, prN}, // Mn TELUGU SIGN COMBINING ANUSVARA ABOVE
+ {0x0C05, 0x0C0C, prN}, // Lo [8] TELUGU LETTER A..TELUGU LETTER VOCALIC L
+ {0x0C0E, 0x0C10, prN}, // Lo [3] TELUGU LETTER E..TELUGU LETTER AI
+ {0x0C12, 0x0C28, prN}, // Lo [23] TELUGU LETTER O..TELUGU LETTER NA
+ {0x0C2A, 0x0C39, prN}, // Lo [16] TELUGU LETTER PA..TELUGU LETTER HA
+ {0x0C3C, 0x0C3C, prN}, // Mn TELUGU SIGN NUKTA
+ {0x0C3D, 0x0C3D, prN}, // Lo TELUGU SIGN AVAGRAHA
+ {0x0C3E, 0x0C40, prN}, // Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II
+ {0x0C41, 0x0C44, prN}, // Mc [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR
+ {0x0C46, 0x0C48, prN}, // Mn [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI
+ {0x0C4A, 0x0C4D, prN}, // Mn [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA
+ {0x0C55, 0x0C56, prN}, // Mn [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK
+ {0x0C58, 0x0C5A, prN}, // Lo [3] TELUGU LETTER TSA..TELUGU LETTER RRRA
+ {0x0C5D, 0x0C5D, prN}, // Lo TELUGU LETTER NAKAARA POLLU
+ {0x0C60, 0x0C61, prN}, // Lo [2] TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL
+ {0x0C62, 0x0C63, prN}, // Mn [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL
+ {0x0C66, 0x0C6F, prN}, // Nd [10] TELUGU DIGIT ZERO..TELUGU DIGIT NINE
+ {0x0C77, 0x0C77, prN}, // Po TELUGU SIGN SIDDHAM
+ {0x0C78, 0x0C7E, prN}, // No [7] TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR..TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR
+ {0x0C7F, 0x0C7F, prN}, // So TELUGU SIGN TUUMU
+ {0x0C80, 0x0C80, prN}, // Lo KANNADA SIGN SPACING CANDRABINDU
+ {0x0C81, 0x0C81, prN}, // Mn KANNADA SIGN CANDRABINDU
+ {0x0C82, 0x0C83, prN}, // Mc [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA
+ {0x0C84, 0x0C84, prN}, // Po KANNADA SIGN SIDDHAM
+ {0x0C85, 0x0C8C, prN}, // Lo [8] KANNADA LETTER A..KANNADA LETTER VOCALIC L
+ {0x0C8E, 0x0C90, prN}, // Lo [3] KANNADA LETTER E..KANNADA LETTER AI
+ {0x0C92, 0x0CA8, prN}, // Lo [23] KANNADA LETTER O..KANNADA LETTER NA
+ {0x0CAA, 0x0CB3, prN}, // Lo [10] KANNADA LETTER PA..KANNADA LETTER LLA
+ {0x0CB5, 0x0CB9, prN}, // Lo [5] KANNADA LETTER VA..KANNADA LETTER HA
+ {0x0CBC, 0x0CBC, prN}, // Mn KANNADA SIGN NUKTA
+ {0x0CBD, 0x0CBD, prN}, // Lo KANNADA SIGN AVAGRAHA
+ {0x0CBE, 0x0CBE, prN}, // Mc KANNADA VOWEL SIGN AA
+ {0x0CBF, 0x0CBF, prN}, // Mn KANNADA VOWEL SIGN I
+ {0x0CC0, 0x0CC4, prN}, // Mc [5] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN VOCALIC RR
+ {0x0CC6, 0x0CC6, prN}, // Mn KANNADA VOWEL SIGN E
+ {0x0CC7, 0x0CC8, prN}, // Mc [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI
+ {0x0CCA, 0x0CCB, prN}, // Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO
+ {0x0CCC, 0x0CCD, prN}, // Mn [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA
+ {0x0CD5, 0x0CD6, prN}, // Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK
+ {0x0CDD, 0x0CDE, prN}, // Lo [2] KANNADA LETTER NAKAARA POLLU..KANNADA LETTER FA
+ {0x0CE0, 0x0CE1, prN}, // Lo [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL
+ {0x0CE2, 0x0CE3, prN}, // Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL
+ {0x0CE6, 0x0CEF, prN}, // Nd [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE
+ {0x0CF1, 0x0CF2, prN}, // Lo [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA
+ {0x0CF3, 0x0CF3, prN}, // Mc KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT
+ {0x0D00, 0x0D01, prN}, // Mn [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU
+ {0x0D02, 0x0D03, prN}, // Mc [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA
+ {0x0D04, 0x0D0C, prN}, // Lo [9] MALAYALAM LETTER VEDIC ANUSVARA..MALAYALAM LETTER VOCALIC L
+ {0x0D0E, 0x0D10, prN}, // Lo [3] MALAYALAM LETTER E..MALAYALAM LETTER AI
+ {0x0D12, 0x0D3A, prN}, // Lo [41] MALAYALAM LETTER O..MALAYALAM LETTER TTTA
+ {0x0D3B, 0x0D3C, prN}, // Mn [2] MALAYALAM SIGN VERTICAL BAR VIRAMA..MALAYALAM SIGN CIRCULAR VIRAMA
+ {0x0D3D, 0x0D3D, prN}, // Lo MALAYALAM SIGN AVAGRAHA
+ {0x0D3E, 0x0D40, prN}, // Mc [3] MALAYALAM VOWEL SIGN AA..MALAYALAM VOWEL SIGN II
+ {0x0D41, 0x0D44, prN}, // Mn [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR
+ {0x0D46, 0x0D48, prN}, // Mc [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI
+ {0x0D4A, 0x0D4C, prN}, // Mc [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU
+ {0x0D4D, 0x0D4D, prN}, // Mn MALAYALAM SIGN VIRAMA
+ {0x0D4E, 0x0D4E, prN}, // Lo MALAYALAM LETTER DOT REPH
+ {0x0D4F, 0x0D4F, prN}, // So MALAYALAM SIGN PARA
+ {0x0D54, 0x0D56, prN}, // Lo [3] MALAYALAM LETTER CHILLU M..MALAYALAM LETTER CHILLU LLL
+ {0x0D57, 0x0D57, prN}, // Mc MALAYALAM AU LENGTH MARK
+ {0x0D58, 0x0D5E, prN}, // No [7] MALAYALAM FRACTION ONE ONE-HUNDRED-AND-SIXTIETH..MALAYALAM FRACTION ONE FIFTH
+ {0x0D5F, 0x0D61, prN}, // Lo [3] MALAYALAM LETTER ARCHAIC II..MALAYALAM LETTER VOCALIC LL
+ {0x0D62, 0x0D63, prN}, // Mn [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL
+ {0x0D66, 0x0D6F, prN}, // Nd [10] MALAYALAM DIGIT ZERO..MALAYALAM DIGIT NINE
+ {0x0D70, 0x0D78, prN}, // No [9] MALAYALAM NUMBER TEN..MALAYALAM FRACTION THREE SIXTEENTHS
+ {0x0D79, 0x0D79, prN}, // So MALAYALAM DATE MARK
+ {0x0D7A, 0x0D7F, prN}, // Lo [6] MALAYALAM LETTER CHILLU NN..MALAYALAM LETTER CHILLU K
+ {0x0D81, 0x0D81, prN}, // Mn SINHALA SIGN CANDRABINDU
+ {0x0D82, 0x0D83, prN}, // Mc [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA
+ {0x0D85, 0x0D96, prN}, // Lo [18] SINHALA LETTER AYANNA..SINHALA LETTER AUYANNA
+ {0x0D9A, 0x0DB1, prN}, // Lo [24] SINHALA LETTER ALPAPRAANA KAYANNA..SINHALA LETTER DANTAJA NAYANNA
+ {0x0DB3, 0x0DBB, prN}, // Lo [9] SINHALA LETTER SANYAKA DAYANNA..SINHALA LETTER RAYANNA
+ {0x0DBD, 0x0DBD, prN}, // Lo SINHALA LETTER DANTAJA LAYANNA
+ {0x0DC0, 0x0DC6, prN}, // Lo [7] SINHALA LETTER VAYANNA..SINHALA LETTER FAYANNA
+ {0x0DCA, 0x0DCA, prN}, // Mn SINHALA SIGN AL-LAKUNA
+ {0x0DCF, 0x0DD1, prN}, // Mc [3] SINHALA VOWEL SIGN AELA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA
+ {0x0DD2, 0x0DD4, prN}, // Mn [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA
+ {0x0DD6, 0x0DD6, prN}, // Mn SINHALA VOWEL SIGN DIGA PAA-PILLA
+ {0x0DD8, 0x0DDF, prN}, // Mc [8] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN GAYANUKITTA
+ {0x0DE6, 0x0DEF, prN}, // Nd [10] SINHALA LITH DIGIT ZERO..SINHALA LITH DIGIT NINE
+ {0x0DF2, 0x0DF3, prN}, // Mc [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA
+ {0x0DF4, 0x0DF4, prN}, // Po SINHALA PUNCTUATION KUNDDALIYA
+ {0x0E01, 0x0E30, prN}, // Lo [48] THAI CHARACTER KO KAI..THAI CHARACTER SARA A
+ {0x0E31, 0x0E31, prN}, // Mn THAI CHARACTER MAI HAN-AKAT
+ {0x0E32, 0x0E33, prN}, // Lo [2] THAI CHARACTER SARA AA..THAI CHARACTER SARA AM
+ {0x0E34, 0x0E3A, prN}, // Mn [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU
+ {0x0E3F, 0x0E3F, prN}, // Sc THAI CURRENCY SYMBOL BAHT
+ {0x0E40, 0x0E45, prN}, // Lo [6] THAI CHARACTER SARA E..THAI CHARACTER LAKKHANGYAO
+ {0x0E46, 0x0E46, prN}, // Lm THAI CHARACTER MAIYAMOK
+ {0x0E47, 0x0E4E, prN}, // Mn [8] THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN
+ {0x0E4F, 0x0E4F, prN}, // Po THAI CHARACTER FONGMAN
+ {0x0E50, 0x0E59, prN}, // Nd [10] THAI DIGIT ZERO..THAI DIGIT NINE
+ {0x0E5A, 0x0E5B, prN}, // Po [2] THAI CHARACTER ANGKHANKHU..THAI CHARACTER KHOMUT
+ {0x0E81, 0x0E82, prN}, // Lo [2] LAO LETTER KO..LAO LETTER KHO SUNG
+ {0x0E84, 0x0E84, prN}, // Lo LAO LETTER KHO TAM
+ {0x0E86, 0x0E8A, prN}, // Lo [5] LAO LETTER PALI GHA..LAO LETTER SO TAM
+ {0x0E8C, 0x0EA3, prN}, // Lo [24] LAO LETTER PALI JHA..LAO LETTER LO LING
+ {0x0EA5, 0x0EA5, prN}, // Lo LAO LETTER LO LOOT
+ {0x0EA7, 0x0EB0, prN}, // Lo [10] LAO LETTER WO..LAO VOWEL SIGN A
+ {0x0EB1, 0x0EB1, prN}, // Mn LAO VOWEL SIGN MAI KAN
+ {0x0EB2, 0x0EB3, prN}, // Lo [2] LAO VOWEL SIGN AA..LAO VOWEL SIGN AM
+ {0x0EB4, 0x0EBC, prN}, // Mn [9] LAO VOWEL SIGN I..LAO SEMIVOWEL SIGN LO
+ {0x0EBD, 0x0EBD, prN}, // Lo LAO SEMIVOWEL SIGN NYO
+ {0x0EC0, 0x0EC4, prN}, // Lo [5] LAO VOWEL SIGN E..LAO VOWEL SIGN AI
+ {0x0EC6, 0x0EC6, prN}, // Lm LAO KO LA
+ {0x0EC8, 0x0ECE, prN}, // Mn [7] LAO TONE MAI EK..LAO YAMAKKAN
+ {0x0ED0, 0x0ED9, prN}, // Nd [10] LAO DIGIT ZERO..LAO DIGIT NINE
+ {0x0EDC, 0x0EDF, prN}, // Lo [4] LAO HO NO..LAO LETTER KHMU NYO
+ {0x0F00, 0x0F00, prN}, // Lo TIBETAN SYLLABLE OM
+ {0x0F01, 0x0F03, prN}, // So [3] TIBETAN MARK GTER YIG MGO TRUNCATED A..TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA
+ {0x0F04, 0x0F12, prN}, // Po [15] TIBETAN MARK INITIAL YIG MGO MDUN MA..TIBETAN MARK RGYA GRAM SHAD
+ {0x0F13, 0x0F13, prN}, // So TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN
+ {0x0F14, 0x0F14, prN}, // Po TIBETAN MARK GTER TSHEG
+ {0x0F15, 0x0F17, prN}, // So [3] TIBETAN LOGOTYPE SIGN CHAD RTAGS..TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS
+ {0x0F18, 0x0F19, prN}, // Mn [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS
+ {0x0F1A, 0x0F1F, prN}, // So [6] TIBETAN SIGN RDEL DKAR GCIG..TIBETAN SIGN RDEL DKAR RDEL NAG
+ {0x0F20, 0x0F29, prN}, // Nd [10] TIBETAN DIGIT ZERO..TIBETAN DIGIT NINE
+ {0x0F2A, 0x0F33, prN}, // No [10] TIBETAN DIGIT HALF ONE..TIBETAN DIGIT HALF ZERO
+ {0x0F34, 0x0F34, prN}, // So TIBETAN MARK BSDUS RTAGS
+ {0x0F35, 0x0F35, prN}, // Mn TIBETAN MARK NGAS BZUNG NYI ZLA
+ {0x0F36, 0x0F36, prN}, // So TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN
+ {0x0F37, 0x0F37, prN}, // Mn TIBETAN MARK NGAS BZUNG SGOR RTAGS
+ {0x0F38, 0x0F38, prN}, // So TIBETAN MARK CHE MGO
+ {0x0F39, 0x0F39, prN}, // Mn TIBETAN MARK TSA -PHRU
+ {0x0F3A, 0x0F3A, prN}, // Ps TIBETAN MARK GUG RTAGS GYON
+ {0x0F3B, 0x0F3B, prN}, // Pe TIBETAN MARK GUG RTAGS GYAS
+ {0x0F3C, 0x0F3C, prN}, // Ps TIBETAN MARK ANG KHANG GYON
+ {0x0F3D, 0x0F3D, prN}, // Pe TIBETAN MARK ANG KHANG GYAS
+ {0x0F3E, 0x0F3F, prN}, // Mc [2] TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES
+ {0x0F40, 0x0F47, prN}, // Lo [8] TIBETAN LETTER KA..TIBETAN LETTER JA
+ {0x0F49, 0x0F6C, prN}, // Lo [36] TIBETAN LETTER NYA..TIBETAN LETTER RRA
+ {0x0F71, 0x0F7E, prN}, // Mn [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO
+ {0x0F7F, 0x0F7F, prN}, // Mc TIBETAN SIGN RNAM BCAD
+ {0x0F80, 0x0F84, prN}, // Mn [5] TIBETAN VOWEL SIGN REVERSED I..TIBETAN MARK HALANTA
+ {0x0F85, 0x0F85, prN}, // Po TIBETAN MARK PALUTA
+ {0x0F86, 0x0F87, prN}, // Mn [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS
+ {0x0F88, 0x0F8C, prN}, // Lo [5] TIBETAN SIGN LCE TSA CAN..TIBETAN SIGN INVERTED MCHU CAN
+ {0x0F8D, 0x0F97, prN}, // Mn [11] TIBETAN SUBJOINED SIGN LCE TSA CAN..TIBETAN SUBJOINED LETTER JA
+ {0x0F99, 0x0FBC, prN}, // Mn [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA
+ {0x0FBE, 0x0FC5, prN}, // So [8] TIBETAN KU RU KHA..TIBETAN SYMBOL RDO RJE
+ {0x0FC6, 0x0FC6, prN}, // Mn TIBETAN SYMBOL PADMA GDAN
+ {0x0FC7, 0x0FCC, prN}, // So [6] TIBETAN SYMBOL RDO RJE RGYA GRAM..TIBETAN SYMBOL NOR BU BZHI -KHYIL
+ {0x0FCE, 0x0FCF, prN}, // So [2] TIBETAN SIGN RDEL NAG RDEL DKAR..TIBETAN SIGN RDEL NAG GSUM
+ {0x0FD0, 0x0FD4, prN}, // Po [5] TIBETAN MARK BSKA- SHOG GI MGO RGYAN..TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA
+ {0x0FD5, 0x0FD8, prN}, // So [4] RIGHT-FACING SVASTI SIGN..LEFT-FACING SVASTI SIGN WITH DOTS
+ {0x0FD9, 0x0FDA, prN}, // Po [2] TIBETAN MARK LEADING MCHAN RTAGS..TIBETAN MARK TRAILING MCHAN RTAGS
+ {0x1000, 0x102A, prN}, // Lo [43] MYANMAR LETTER KA..MYANMAR LETTER AU
+ {0x102B, 0x102C, prN}, // Mc [2] MYANMAR VOWEL SIGN TALL AA..MYANMAR VOWEL SIGN AA
+ {0x102D, 0x1030, prN}, // Mn [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU
+ {0x1031, 0x1031, prN}, // Mc MYANMAR VOWEL SIGN E
+ {0x1032, 0x1037, prN}, // Mn [6] MYANMAR VOWEL SIGN AI..MYANMAR SIGN DOT BELOW
+ {0x1038, 0x1038, prN}, // Mc MYANMAR SIGN VISARGA
+ {0x1039, 0x103A, prN}, // Mn [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT
+ {0x103B, 0x103C, prN}, // Mc [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA
+ {0x103D, 0x103E, prN}, // Mn [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA
+ {0x103F, 0x103F, prN}, // Lo MYANMAR LETTER GREAT SA
+ {0x1040, 0x1049, prN}, // Nd [10] MYANMAR DIGIT ZERO..MYANMAR DIGIT NINE
+ {0x104A, 0x104F, prN}, // Po [6] MYANMAR SIGN LITTLE SECTION..MYANMAR SYMBOL GENITIVE
+ {0x1050, 0x1055, prN}, // Lo [6] MYANMAR LETTER SHA..MYANMAR LETTER VOCALIC LL
+ {0x1056, 0x1057, prN}, // Mc [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR
+ {0x1058, 0x1059, prN}, // Mn [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL
+ {0x105A, 0x105D, prN}, // Lo [4] MYANMAR LETTER MON NGA..MYANMAR LETTER MON BBE
+ {0x105E, 0x1060, prN}, // Mn [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA
+ {0x1061, 0x1061, prN}, // Lo MYANMAR LETTER SGAW KAREN SHA
+ {0x1062, 0x1064, prN}, // Mc [3] MYANMAR VOWEL SIGN SGAW KAREN EU..MYANMAR TONE MARK SGAW KAREN KE PHO
+ {0x1065, 0x1066, prN}, // Lo [2] MYANMAR LETTER WESTERN PWO KAREN THA..MYANMAR LETTER WESTERN PWO KAREN PWA
+ {0x1067, 0x106D, prN}, // Mc [7] MYANMAR VOWEL SIGN WESTERN PWO KAREN EU..MYANMAR SIGN WESTERN PWO KAREN TONE-5
+ {0x106E, 0x1070, prN}, // Lo [3] MYANMAR LETTER EASTERN PWO KAREN NNA..MYANMAR LETTER EASTERN PWO KAREN GHWA
+ {0x1071, 0x1074, prN}, // Mn [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE
+ {0x1075, 0x1081, prN}, // Lo [13] MYANMAR LETTER SHAN KA..MYANMAR LETTER SHAN HA
+ {0x1082, 0x1082, prN}, // Mn MYANMAR CONSONANT SIGN SHAN MEDIAL WA
+ {0x1083, 0x1084, prN}, // Mc [2] MYANMAR VOWEL SIGN SHAN AA..MYANMAR VOWEL SIGN SHAN E
+ {0x1085, 0x1086, prN}, // Mn [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y
+ {0x1087, 0x108C, prN}, // Mc [6] MYANMAR SIGN SHAN TONE-2..MYANMAR SIGN SHAN COUNCIL TONE-3
+ {0x108D, 0x108D, prN}, // Mn MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE
+ {0x108E, 0x108E, prN}, // Lo MYANMAR LETTER RUMAI PALAUNG FA
+ {0x108F, 0x108F, prN}, // Mc MYANMAR SIGN RUMAI PALAUNG TONE-5
+ {0x1090, 0x1099, prN}, // Nd [10] MYANMAR SHAN DIGIT ZERO..MYANMAR SHAN DIGIT NINE
+ {0x109A, 0x109C, prN}, // Mc [3] MYANMAR SIGN KHAMTI TONE-1..MYANMAR VOWEL SIGN AITON A
+ {0x109D, 0x109D, prN}, // Mn MYANMAR VOWEL SIGN AITON AI
+ {0x109E, 0x109F, prN}, // So [2] MYANMAR SYMBOL SHAN ONE..MYANMAR SYMBOL SHAN EXCLAMATION
+ {0x10A0, 0x10C5, prN}, // Lu [38] GEORGIAN CAPITAL LETTER AN..GEORGIAN CAPITAL LETTER HOE
+ {0x10C7, 0x10C7, prN}, // Lu GEORGIAN CAPITAL LETTER YN
+ {0x10CD, 0x10CD, prN}, // Lu GEORGIAN CAPITAL LETTER AEN
+ {0x10D0, 0x10FA, prN}, // Ll [43] GEORGIAN LETTER AN..GEORGIAN LETTER AIN
+ {0x10FB, 0x10FB, prN}, // Po GEORGIAN PARAGRAPH SEPARATOR
+ {0x10FC, 0x10FC, prN}, // Lm MODIFIER LETTER GEORGIAN NAR
+ {0x10FD, 0x10FF, prN}, // Ll [3] GEORGIAN LETTER AEN..GEORGIAN LETTER LABIAL SIGN
+ {0x1100, 0x115F, prW}, // Lo [96] HANGUL CHOSEONG KIYEOK..HANGUL CHOSEONG FILLER
+ {0x1160, 0x11FF, prN}, // Lo [160] HANGUL JUNGSEONG FILLER..HANGUL JONGSEONG SSANGNIEUN
+ {0x1200, 0x1248, prN}, // Lo [73] ETHIOPIC SYLLABLE HA..ETHIOPIC SYLLABLE QWA
+ {0x124A, 0x124D, prN}, // Lo [4] ETHIOPIC SYLLABLE QWI..ETHIOPIC SYLLABLE QWE
+ {0x1250, 0x1256, prN}, // Lo [7] ETHIOPIC SYLLABLE QHA..ETHIOPIC SYLLABLE QHO
+ {0x1258, 0x1258, prN}, // Lo ETHIOPIC SYLLABLE QHWA
+ {0x125A, 0x125D, prN}, // Lo [4] ETHIOPIC SYLLABLE QHWI..ETHIOPIC SYLLABLE QHWE
+ {0x1260, 0x1288, prN}, // Lo [41] ETHIOPIC SYLLABLE BA..ETHIOPIC SYLLABLE XWA
+ {0x128A, 0x128D, prN}, // Lo [4] ETHIOPIC SYLLABLE XWI..ETHIOPIC SYLLABLE XWE
+ {0x1290, 0x12B0, prN}, // Lo [33] ETHIOPIC SYLLABLE NA..ETHIOPIC SYLLABLE KWA
+ {0x12B2, 0x12B5, prN}, // Lo [4] ETHIOPIC SYLLABLE KWI..ETHIOPIC SYLLABLE KWE
+ {0x12B8, 0x12BE, prN}, // Lo [7] ETHIOPIC SYLLABLE KXA..ETHIOPIC SYLLABLE KXO
+ {0x12C0, 0x12C0, prN}, // Lo ETHIOPIC SYLLABLE KXWA
+ {0x12C2, 0x12C5, prN}, // Lo [4] ETHIOPIC SYLLABLE KXWI..ETHIOPIC SYLLABLE KXWE
+ {0x12C8, 0x12D6, prN}, // Lo [15] ETHIOPIC SYLLABLE WA..ETHIOPIC SYLLABLE PHARYNGEAL O
+ {0x12D8, 0x1310, prN}, // Lo [57] ETHIOPIC SYLLABLE ZA..ETHIOPIC SYLLABLE GWA
+ {0x1312, 0x1315, prN}, // Lo [4] ETHIOPIC SYLLABLE GWI..ETHIOPIC SYLLABLE GWE
+ {0x1318, 0x135A, prN}, // Lo [67] ETHIOPIC SYLLABLE GGA..ETHIOPIC SYLLABLE FYA
+ {0x135D, 0x135F, prN}, // Mn [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK
+ {0x1360, 0x1368, prN}, // Po [9] ETHIOPIC SECTION MARK..ETHIOPIC PARAGRAPH SEPARATOR
+ {0x1369, 0x137C, prN}, // No [20] ETHIOPIC DIGIT ONE..ETHIOPIC NUMBER TEN THOUSAND
+ {0x1380, 0x138F, prN}, // Lo [16] ETHIOPIC SYLLABLE SEBATBEIT MWA..ETHIOPIC SYLLABLE PWE
+ {0x1390, 0x1399, prN}, // So [10] ETHIOPIC TONAL MARK YIZET..ETHIOPIC TONAL MARK KURT
+ {0x13A0, 0x13F5, prN}, // Lu [86] CHEROKEE LETTER A..CHEROKEE LETTER MV
+ {0x13F8, 0x13FD, prN}, // Ll [6] CHEROKEE SMALL LETTER YE..CHEROKEE SMALL LETTER MV
+ {0x1400, 0x1400, prN}, // Pd CANADIAN SYLLABICS HYPHEN
+ {0x1401, 0x166C, prN}, // Lo [620] CANADIAN SYLLABICS E..CANADIAN SYLLABICS CARRIER TTSA
+ {0x166D, 0x166D, prN}, // So CANADIAN SYLLABICS CHI SIGN
+ {0x166E, 0x166E, prN}, // Po CANADIAN SYLLABICS FULL STOP
+ {0x166F, 0x167F, prN}, // Lo [17] CANADIAN SYLLABICS QAI..CANADIAN SYLLABICS BLACKFOOT W
+ {0x1680, 0x1680, prN}, // Zs OGHAM SPACE MARK
+ {0x1681, 0x169A, prN}, // Lo [26] OGHAM LETTER BEITH..OGHAM LETTER PEITH
+ {0x169B, 0x169B, prN}, // Ps OGHAM FEATHER MARK
+ {0x169C, 0x169C, prN}, // Pe OGHAM REVERSED FEATHER MARK
+ {0x16A0, 0x16EA, prN}, // Lo [75] RUNIC LETTER FEHU FEOH FE F..RUNIC LETTER X
+ {0x16EB, 0x16ED, prN}, // Po [3] RUNIC SINGLE PUNCTUATION..RUNIC CROSS PUNCTUATION
+ {0x16EE, 0x16F0, prN}, // Nl [3] RUNIC ARLAUG SYMBOL..RUNIC BELGTHOR SYMBOL
+ {0x16F1, 0x16F8, prN}, // Lo [8] RUNIC LETTER K..RUNIC LETTER FRANKS CASKET AESC
+ {0x1700, 0x1711, prN}, // Lo [18] TAGALOG LETTER A..TAGALOG LETTER HA
+ {0x1712, 0x1714, prN}, // Mn [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA
+ {0x1715, 0x1715, prN}, // Mc TAGALOG SIGN PAMUDPOD
+ {0x171F, 0x171F, prN}, // Lo TAGALOG LETTER ARCHAIC RA
+ {0x1720, 0x1731, prN}, // Lo [18] HANUNOO LETTER A..HANUNOO LETTER HA
+ {0x1732, 0x1733, prN}, // Mn [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U
+ {0x1734, 0x1734, prN}, // Mc HANUNOO SIGN PAMUDPOD
+ {0x1735, 0x1736, prN}, // Po [2] PHILIPPINE SINGLE PUNCTUATION..PHILIPPINE DOUBLE PUNCTUATION
+ {0x1740, 0x1751, prN}, // Lo [18] BUHID LETTER A..BUHID LETTER HA
+ {0x1752, 0x1753, prN}, // Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U
+ {0x1760, 0x176C, prN}, // Lo [13] TAGBANWA LETTER A..TAGBANWA LETTER YA
+ {0x176E, 0x1770, prN}, // Lo [3] TAGBANWA LETTER LA..TAGBANWA LETTER SA
+ {0x1772, 0x1773, prN}, // Mn [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U
+ {0x1780, 0x17B3, prN}, // Lo [52] KHMER LETTER KA..KHMER INDEPENDENT VOWEL QAU
+ {0x17B4, 0x17B5, prN}, // Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA
+ {0x17B6, 0x17B6, prN}, // Mc KHMER VOWEL SIGN AA
+ {0x17B7, 0x17BD, prN}, // Mn [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA
+ {0x17BE, 0x17C5, prN}, // Mc [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU
+ {0x17C6, 0x17C6, prN}, // Mn KHMER SIGN NIKAHIT
+ {0x17C7, 0x17C8, prN}, // Mc [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU
+ {0x17C9, 0x17D3, prN}, // Mn [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT
+ {0x17D4, 0x17D6, prN}, // Po [3] KHMER SIGN KHAN..KHMER SIGN CAMNUC PII KUUH
+ {0x17D7, 0x17D7, prN}, // Lm KHMER SIGN LEK TOO
+ {0x17D8, 0x17DA, prN}, // Po [3] KHMER SIGN BEYYAL..KHMER SIGN KOOMUUT
+ {0x17DB, 0x17DB, prN}, // Sc KHMER CURRENCY SYMBOL RIEL
+ {0x17DC, 0x17DC, prN}, // Lo KHMER SIGN AVAKRAHASANYA
+ {0x17DD, 0x17DD, prN}, // Mn KHMER SIGN ATTHACAN
+ {0x17E0, 0x17E9, prN}, // Nd [10] KHMER DIGIT ZERO..KHMER DIGIT NINE
+ {0x17F0, 0x17F9, prN}, // No [10] KHMER SYMBOL LEK ATTAK SON..KHMER SYMBOL LEK ATTAK PRAM-BUON
+ {0x1800, 0x1805, prN}, // Po [6] MONGOLIAN BIRGA..MONGOLIAN FOUR DOTS
+ {0x1806, 0x1806, prN}, // Pd MONGOLIAN TODO SOFT HYPHEN
+ {0x1807, 0x180A, prN}, // Po [4] MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER..MONGOLIAN NIRUGU
+ {0x180B, 0x180D, prN}, // Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE
+ {0x180E, 0x180E, prN}, // Cf MONGOLIAN VOWEL SEPARATOR
+ {0x180F, 0x180F, prN}, // Mn MONGOLIAN FREE VARIATION SELECTOR FOUR
+ {0x1810, 0x1819, prN}, // Nd [10] MONGOLIAN DIGIT ZERO..MONGOLIAN DIGIT NINE
+ {0x1820, 0x1842, prN}, // Lo [35] MONGOLIAN LETTER A..MONGOLIAN LETTER CHI
+ {0x1843, 0x1843, prN}, // Lm MONGOLIAN LETTER TODO LONG VOWEL SIGN
+ {0x1844, 0x1878, prN}, // Lo [53] MONGOLIAN LETTER TODO E..MONGOLIAN LETTER CHA WITH TWO DOTS
+ {0x1880, 0x1884, prN}, // Lo [5] MONGOLIAN LETTER ALI GALI ANUSVARA ONE..MONGOLIAN LETTER ALI GALI INVERTED UBADAMA
+ {0x1885, 0x1886, prN}, // Mn [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA
+ {0x1887, 0x18A8, prN}, // Lo [34] MONGOLIAN LETTER ALI GALI A..MONGOLIAN LETTER MANCHU ALI GALI BHA
+ {0x18A9, 0x18A9, prN}, // Mn MONGOLIAN LETTER ALI GALI DAGALGA
+ {0x18AA, 0x18AA, prN}, // Lo MONGOLIAN LETTER MANCHU ALI GALI LHA
+ {0x18B0, 0x18F5, prN}, // Lo [70] CANADIAN SYLLABICS OY..CANADIAN SYLLABICS CARRIER DENTAL S
+ {0x1900, 0x191E, prN}, // Lo [31] LIMBU VOWEL-CARRIER LETTER..LIMBU LETTER TRA
+ {0x1920, 0x1922, prN}, // Mn [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U
+ {0x1923, 0x1926, prN}, // Mc [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU
+ {0x1927, 0x1928, prN}, // Mn [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O
+ {0x1929, 0x192B, prN}, // Mc [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA
+ {0x1930, 0x1931, prN}, // Mc [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA
+ {0x1932, 0x1932, prN}, // Mn LIMBU SMALL LETTER ANUSVARA
+ {0x1933, 0x1938, prN}, // Mc [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA
+ {0x1939, 0x193B, prN}, // Mn [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I
+ {0x1940, 0x1940, prN}, // So LIMBU SIGN LOO
+ {0x1944, 0x1945, prN}, // Po [2] LIMBU EXCLAMATION MARK..LIMBU QUESTION MARK
+ {0x1946, 0x194F, prN}, // Nd [10] LIMBU DIGIT ZERO..LIMBU DIGIT NINE
+ {0x1950, 0x196D, prN}, // Lo [30] TAI LE LETTER KA..TAI LE LETTER AI
+ {0x1970, 0x1974, prN}, // Lo [5] TAI LE LETTER TONE-2..TAI LE LETTER TONE-6
+ {0x1980, 0x19AB, prN}, // Lo [44] NEW TAI LUE LETTER HIGH QA..NEW TAI LUE LETTER LOW SUA
+ {0x19B0, 0x19C9, prN}, // Lo [26] NEW TAI LUE VOWEL SIGN VOWEL SHORTENER..NEW TAI LUE TONE MARK-2
+ {0x19D0, 0x19D9, prN}, // Nd [10] NEW TAI LUE DIGIT ZERO..NEW TAI LUE DIGIT NINE
+ {0x19DA, 0x19DA, prN}, // No NEW TAI LUE THAM DIGIT ONE
+ {0x19DE, 0x19DF, prN}, // So [2] NEW TAI LUE SIGN LAE..NEW TAI LUE SIGN LAEV
+ {0x19E0, 0x19FF, prN}, // So [32] KHMER SYMBOL PATHAMASAT..KHMER SYMBOL DAP-PRAM ROC
+ {0x1A00, 0x1A16, prN}, // Lo [23] BUGINESE LETTER KA..BUGINESE LETTER HA
+ {0x1A17, 0x1A18, prN}, // Mn [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U
+ {0x1A19, 0x1A1A, prN}, // Mc [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O
+ {0x1A1B, 0x1A1B, prN}, // Mn BUGINESE VOWEL SIGN AE
+ {0x1A1E, 0x1A1F, prN}, // Po [2] BUGINESE PALLAWA..BUGINESE END OF SECTION
+ {0x1A20, 0x1A54, prN}, // Lo [53] TAI THAM LETTER HIGH KA..TAI THAM LETTER GREAT SA
+ {0x1A55, 0x1A55, prN}, // Mc TAI THAM CONSONANT SIGN MEDIAL RA
+ {0x1A56, 0x1A56, prN}, // Mn TAI THAM CONSONANT SIGN MEDIAL LA
+ {0x1A57, 0x1A57, prN}, // Mc TAI THAM CONSONANT SIGN LA TANG LAI
+ {0x1A58, 0x1A5E, prN}, // Mn [7] TAI THAM SIGN MAI KANG LAI..TAI THAM CONSONANT SIGN SA
+ {0x1A60, 0x1A60, prN}, // Mn TAI THAM SIGN SAKOT
+ {0x1A61, 0x1A61, prN}, // Mc TAI THAM VOWEL SIGN A
+ {0x1A62, 0x1A62, prN}, // Mn TAI THAM VOWEL SIGN MAI SAT
+ {0x1A63, 0x1A64, prN}, // Mc [2] TAI THAM VOWEL SIGN AA..TAI THAM VOWEL SIGN TALL AA
+ {0x1A65, 0x1A6C, prN}, // Mn [8] TAI THAM VOWEL SIGN I..TAI THAM VOWEL SIGN OA BELOW
+ {0x1A6D, 0x1A72, prN}, // Mc [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI
+ {0x1A73, 0x1A7C, prN}, // Mn [10] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN KHUEN-LUE KARAN
+ {0x1A7F, 0x1A7F, prN}, // Mn TAI THAM COMBINING CRYPTOGRAMMIC DOT
+ {0x1A80, 0x1A89, prN}, // Nd [10] TAI THAM HORA DIGIT ZERO..TAI THAM HORA DIGIT NINE
+ {0x1A90, 0x1A99, prN}, // Nd [10] TAI THAM THAM DIGIT ZERO..TAI THAM THAM DIGIT NINE
+ {0x1AA0, 0x1AA6, prN}, // Po [7] TAI THAM SIGN WIANG..TAI THAM SIGN REVERSED ROTATED RANA
+ {0x1AA7, 0x1AA7, prN}, // Lm TAI THAM SIGN MAI YAMOK
+ {0x1AA8, 0x1AAD, prN}, // Po [6] TAI THAM SIGN KAAN..TAI THAM SIGN CAANG
+ {0x1AB0, 0x1ABD, prN}, // Mn [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW
+ {0x1ABE, 0x1ABE, prN}, // Me COMBINING PARENTHESES OVERLAY
+ {0x1ABF, 0x1ACE, prN}, // Mn [16] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER INSULAR T
+ {0x1B00, 0x1B03, prN}, // Mn [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG
+ {0x1B04, 0x1B04, prN}, // Mc BALINESE SIGN BISAH
+ {0x1B05, 0x1B33, prN}, // Lo [47] BALINESE LETTER AKARA..BALINESE LETTER HA
+ {0x1B34, 0x1B34, prN}, // Mn BALINESE SIGN REREKAN
+ {0x1B35, 0x1B35, prN}, // Mc BALINESE VOWEL SIGN TEDUNG
+ {0x1B36, 0x1B3A, prN}, // Mn [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA
+ {0x1B3B, 0x1B3B, prN}, // Mc BALINESE VOWEL SIGN RA REPA TEDUNG
+ {0x1B3C, 0x1B3C, prN}, // Mn BALINESE VOWEL SIGN LA LENGA
+ {0x1B3D, 0x1B41, prN}, // Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG
+ {0x1B42, 0x1B42, prN}, // Mn BALINESE VOWEL SIGN PEPET
+ {0x1B43, 0x1B44, prN}, // Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG
+ {0x1B45, 0x1B4C, prN}, // Lo [8] BALINESE LETTER KAF SASAK..BALINESE LETTER ARCHAIC JNYA
+ {0x1B50, 0x1B59, prN}, // Nd [10] BALINESE DIGIT ZERO..BALINESE DIGIT NINE
+ {0x1B5A, 0x1B60, prN}, // Po [7] BALINESE PANTI..BALINESE PAMENENG
+ {0x1B61, 0x1B6A, prN}, // So [10] BALINESE MUSICAL SYMBOL DONG..BALINESE MUSICAL SYMBOL DANG GEDE
+ {0x1B6B, 0x1B73, prN}, // Mn [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG
+ {0x1B74, 0x1B7C, prN}, // So [9] BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG..BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING
+ {0x1B7D, 0x1B7E, prN}, // Po [2] BALINESE PANTI LANTANG..BALINESE PAMADA LANTANG
+ {0x1B80, 0x1B81, prN}, // Mn [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR
+ {0x1B82, 0x1B82, prN}, // Mc SUNDANESE SIGN PANGWISAD
+ {0x1B83, 0x1BA0, prN}, // Lo [30] SUNDANESE LETTER A..SUNDANESE LETTER HA
+ {0x1BA1, 0x1BA1, prN}, // Mc SUNDANESE CONSONANT SIGN PAMINGKAL
+ {0x1BA2, 0x1BA5, prN}, // Mn [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU
+ {0x1BA6, 0x1BA7, prN}, // Mc [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG
+ {0x1BA8, 0x1BA9, prN}, // Mn [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG
+ {0x1BAA, 0x1BAA, prN}, // Mc SUNDANESE SIGN PAMAAEH
+ {0x1BAB, 0x1BAD, prN}, // Mn [3] SUNDANESE SIGN VIRAMA..SUNDANESE CONSONANT SIGN PASANGAN WA
+ {0x1BAE, 0x1BAF, prN}, // Lo [2] SUNDANESE LETTER KHA..SUNDANESE LETTER SYA
+ {0x1BB0, 0x1BB9, prN}, // Nd [10] SUNDANESE DIGIT ZERO..SUNDANESE DIGIT NINE
+ {0x1BBA, 0x1BBF, prN}, // Lo [6] SUNDANESE AVAGRAHA..SUNDANESE LETTER FINAL M
+ {0x1BC0, 0x1BE5, prN}, // Lo [38] BATAK LETTER A..BATAK LETTER U
+ {0x1BE6, 0x1BE6, prN}, // Mn BATAK SIGN TOMPI
+ {0x1BE7, 0x1BE7, prN}, // Mc BATAK VOWEL SIGN E
+ {0x1BE8, 0x1BE9, prN}, // Mn [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE
+ {0x1BEA, 0x1BEC, prN}, // Mc [3] BATAK VOWEL SIGN I..BATAK VOWEL SIGN O
+ {0x1BED, 0x1BED, prN}, // Mn BATAK VOWEL SIGN KARO O
+ {0x1BEE, 0x1BEE, prN}, // Mc BATAK VOWEL SIGN U
+ {0x1BEF, 0x1BF1, prN}, // Mn [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H
+ {0x1BF2, 0x1BF3, prN}, // Mc [2] BATAK PANGOLAT..BATAK PANONGONAN
+ {0x1BFC, 0x1BFF, prN}, // Po [4] BATAK SYMBOL BINDU NA METEK..BATAK SYMBOL BINDU PANGOLAT
+ {0x1C00, 0x1C23, prN}, // Lo [36] LEPCHA LETTER KA..LEPCHA LETTER A
+ {0x1C24, 0x1C2B, prN}, // Mc [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU
+ {0x1C2C, 0x1C33, prN}, // Mn [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T
+ {0x1C34, 0x1C35, prN}, // Mc [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG
+ {0x1C36, 0x1C37, prN}, // Mn [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA
+ {0x1C3B, 0x1C3F, prN}, // Po [5] LEPCHA PUNCTUATION TA-ROL..LEPCHA PUNCTUATION TSHOOK
+ {0x1C40, 0x1C49, prN}, // Nd [10] LEPCHA DIGIT ZERO..LEPCHA DIGIT NINE
+ {0x1C4D, 0x1C4F, prN}, // Lo [3] LEPCHA LETTER TTA..LEPCHA LETTER DDA
+ {0x1C50, 0x1C59, prN}, // Nd [10] OL CHIKI DIGIT ZERO..OL CHIKI DIGIT NINE
+ {0x1C5A, 0x1C77, prN}, // Lo [30] OL CHIKI LETTER LA..OL CHIKI LETTER OH
+ {0x1C78, 0x1C7D, prN}, // Lm [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD
+ {0x1C7E, 0x1C7F, prN}, // Po [2] OL CHIKI PUNCTUATION MUCAAD..OL CHIKI PUNCTUATION DOUBLE MUCAAD
+ {0x1C80, 0x1C88, prN}, // Ll [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK
+ {0x1C90, 0x1CBA, prN}, // Lu [43] GEORGIAN MTAVRULI CAPITAL LETTER AN..GEORGIAN MTAVRULI CAPITAL LETTER AIN
+ {0x1CBD, 0x1CBF, prN}, // Lu [3] GEORGIAN MTAVRULI CAPITAL LETTER AEN..GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN
+ {0x1CC0, 0x1CC7, prN}, // Po [8] SUNDANESE PUNCTUATION BINDU SURYA..SUNDANESE PUNCTUATION BINDU BA SATANGA
+ {0x1CD0, 0x1CD2, prN}, // Mn [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA
+ {0x1CD3, 0x1CD3, prN}, // Po VEDIC SIGN NIHSHVASA
+ {0x1CD4, 0x1CE0, prN}, // Mn [13] VEDIC SIGN YAJURVEDIC MIDLINE SVARITA..VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA
+ {0x1CE1, 0x1CE1, prN}, // Mc VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA
+ {0x1CE2, 0x1CE8, prN}, // Mn [7] VEDIC SIGN VISARGA SVARITA..VEDIC SIGN VISARGA ANUDATTA WITH TAIL
+ {0x1CE9, 0x1CEC, prN}, // Lo [4] VEDIC SIGN ANUSVARA ANTARGOMUKHA..VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL
+ {0x1CED, 0x1CED, prN}, // Mn VEDIC SIGN TIRYAK
+ {0x1CEE, 0x1CF3, prN}, // Lo [6] VEDIC SIGN HEXIFORM LONG ANUSVARA..VEDIC SIGN ROTATED ARDHAVISARGA
+ {0x1CF4, 0x1CF4, prN}, // Mn VEDIC TONE CANDRA ABOVE
+ {0x1CF5, 0x1CF6, prN}, // Lo [2] VEDIC SIGN JIHVAMULIYA..VEDIC SIGN UPADHMANIYA
+ {0x1CF7, 0x1CF7, prN}, // Mc VEDIC SIGN ATIKRAMA
+ {0x1CF8, 0x1CF9, prN}, // Mn [2] VEDIC TONE RING ABOVE..VEDIC TONE DOUBLE RING ABOVE
+ {0x1CFA, 0x1CFA, prN}, // Lo VEDIC SIGN DOUBLE ANUSVARA ANTARGOMUKHA
+ {0x1D00, 0x1D2B, prN}, // Ll [44] LATIN LETTER SMALL CAPITAL A..CYRILLIC LETTER SMALL CAPITAL EL
+ {0x1D2C, 0x1D6A, prN}, // Lm [63] MODIFIER LETTER CAPITAL A..GREEK SUBSCRIPT SMALL LETTER CHI
+ {0x1D6B, 0x1D77, prN}, // Ll [13] LATIN SMALL LETTER UE..LATIN SMALL LETTER TURNED G
+ {0x1D78, 0x1D78, prN}, // Lm MODIFIER LETTER CYRILLIC EN
+ {0x1D79, 0x1D7F, prN}, // Ll [7] LATIN SMALL LETTER INSULAR G..LATIN SMALL LETTER UPSILON WITH STROKE
+ {0x1D80, 0x1D9A, prN}, // Ll [27] LATIN SMALL LETTER B WITH PALATAL HOOK..LATIN SMALL LETTER EZH WITH RETROFLEX HOOK
+ {0x1D9B, 0x1DBF, prN}, // Lm [37] MODIFIER LETTER SMALL TURNED ALPHA..MODIFIER LETTER SMALL THETA
+ {0x1DC0, 0x1DFF, prN}, // Mn [64] COMBINING DOTTED GRAVE ACCENT..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW
+ {0x1E00, 0x1EFF, prN}, // L& [256] LATIN CAPITAL LETTER A WITH RING BELOW..LATIN SMALL LETTER Y WITH LOOP
+ {0x1F00, 0x1F15, prN}, // L& [22] GREEK SMALL LETTER ALPHA WITH PSILI..GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA
+ {0x1F18, 0x1F1D, prN}, // Lu [6] GREEK CAPITAL LETTER EPSILON WITH PSILI..GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA
+ {0x1F20, 0x1F45, prN}, // L& [38] GREEK SMALL LETTER ETA WITH PSILI..GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA
+ {0x1F48, 0x1F4D, prN}, // Lu [6] GREEK CAPITAL LETTER OMICRON WITH PSILI..GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA
+ {0x1F50, 0x1F57, prN}, // Ll [8] GREEK SMALL LETTER UPSILON WITH PSILI..GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI
+ {0x1F59, 0x1F59, prN}, // Lu GREEK CAPITAL LETTER UPSILON WITH DASIA
+ {0x1F5B, 0x1F5B, prN}, // Lu GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA
+ {0x1F5D, 0x1F5D, prN}, // Lu GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA
+ {0x1F5F, 0x1F7D, prN}, // L& [31] GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI..GREEK SMALL LETTER OMEGA WITH OXIA
+ {0x1F80, 0x1FB4, prN}, // L& [53] GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI
+ {0x1FB6, 0x1FBC, prN}, // L& [7] GREEK SMALL LETTER ALPHA WITH PERISPOMENI..GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
+ {0x1FBD, 0x1FBD, prN}, // Sk GREEK KORONIS
+ {0x1FBE, 0x1FBE, prN}, // Ll GREEK PROSGEGRAMMENI
+ {0x1FBF, 0x1FC1, prN}, // Sk [3] GREEK PSILI..GREEK DIALYTIKA AND PERISPOMENI
+ {0x1FC2, 0x1FC4, prN}, // Ll [3] GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI
+ {0x1FC6, 0x1FCC, prN}, // L& [7] GREEK SMALL LETTER ETA WITH PERISPOMENI..GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
+ {0x1FCD, 0x1FCF, prN}, // Sk [3] GREEK PSILI AND VARIA..GREEK PSILI AND PERISPOMENI
+ {0x1FD0, 0x1FD3, prN}, // Ll [4] GREEK SMALL LETTER IOTA WITH VRACHY..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
+ {0x1FD6, 0x1FDB, prN}, // L& [6] GREEK SMALL LETTER IOTA WITH PERISPOMENI..GREEK CAPITAL LETTER IOTA WITH OXIA
+ {0x1FDD, 0x1FDF, prN}, // Sk [3] GREEK DASIA AND VARIA..GREEK DASIA AND PERISPOMENI
+ {0x1FE0, 0x1FEC, prN}, // L& [13] GREEK SMALL LETTER UPSILON WITH VRACHY..GREEK CAPITAL LETTER RHO WITH DASIA
+ {0x1FED, 0x1FEF, prN}, // Sk [3] GREEK DIALYTIKA AND VARIA..GREEK VARIA
+ {0x1FF2, 0x1FF4, prN}, // Ll [3] GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI
+ {0x1FF6, 0x1FFC, prN}, // L& [7] GREEK SMALL LETTER OMEGA WITH PERISPOMENI..GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
+ {0x1FFD, 0x1FFE, prN}, // Sk [2] GREEK OXIA..GREEK DASIA
+ {0x2000, 0x200A, prN}, // Zs [11] EN QUAD..HAIR SPACE
+ {0x200B, 0x200F, prN}, // Cf [5] ZERO WIDTH SPACE..RIGHT-TO-LEFT MARK
+ {0x2010, 0x2010, prA}, // Pd HYPHEN
+ {0x2011, 0x2012, prN}, // Pd [2] NON-BREAKING HYPHEN..FIGURE DASH
+ {0x2013, 0x2015, prA}, // Pd [3] EN DASH..HORIZONTAL BAR
+ {0x2016, 0x2016, prA}, // Po DOUBLE VERTICAL LINE
+ {0x2017, 0x2017, prN}, // Po DOUBLE LOW LINE
+ {0x2018, 0x2018, prA}, // Pi LEFT SINGLE QUOTATION MARK
+ {0x2019, 0x2019, prA}, // Pf RIGHT SINGLE QUOTATION MARK
+ {0x201A, 0x201A, prN}, // Ps SINGLE LOW-9 QUOTATION MARK
+ {0x201B, 0x201B, prN}, // Pi SINGLE HIGH-REVERSED-9 QUOTATION MARK
+ {0x201C, 0x201C, prA}, // Pi LEFT DOUBLE QUOTATION MARK
+ {0x201D, 0x201D, prA}, // Pf RIGHT DOUBLE QUOTATION MARK
+ {0x201E, 0x201E, prN}, // Ps DOUBLE LOW-9 QUOTATION MARK
+ {0x201F, 0x201F, prN}, // Pi DOUBLE HIGH-REVERSED-9 QUOTATION MARK
+ {0x2020, 0x2022, prA}, // Po [3] DAGGER..BULLET
+ {0x2023, 0x2023, prN}, // Po TRIANGULAR BULLET
+ {0x2024, 0x2027, prA}, // Po [4] ONE DOT LEADER..HYPHENATION POINT
+ {0x2028, 0x2028, prN}, // Zl LINE SEPARATOR
+ {0x2029, 0x2029, prN}, // Zp PARAGRAPH SEPARATOR
+ {0x202A, 0x202E, prN}, // Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE
+ {0x202F, 0x202F, prN}, // Zs NARROW NO-BREAK SPACE
+ {0x2030, 0x2030, prA}, // Po PER MILLE SIGN
+ {0x2031, 0x2031, prN}, // Po PER TEN THOUSAND SIGN
+ {0x2032, 0x2033, prA}, // Po [2] PRIME..DOUBLE PRIME
+ {0x2034, 0x2034, prN}, // Po TRIPLE PRIME
+ {0x2035, 0x2035, prA}, // Po REVERSED PRIME
+ {0x2036, 0x2038, prN}, // Po [3] REVERSED DOUBLE PRIME..CARET
+ {0x2039, 0x2039, prN}, // Pi SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+ {0x203A, 0x203A, prN}, // Pf SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+ {0x203B, 0x203B, prA}, // Po REFERENCE MARK
+ {0x203C, 0x203D, prN}, // Po [2] DOUBLE EXCLAMATION MARK..INTERROBANG
+ {0x203E, 0x203E, prA}, // Po OVERLINE
+ {0x203F, 0x2040, prN}, // Pc [2] UNDERTIE..CHARACTER TIE
+ {0x2041, 0x2043, prN}, // Po [3] CARET INSERTION POINT..HYPHEN BULLET
+ {0x2044, 0x2044, prN}, // Sm FRACTION SLASH
+ {0x2045, 0x2045, prN}, // Ps LEFT SQUARE BRACKET WITH QUILL
+ {0x2046, 0x2046, prN}, // Pe RIGHT SQUARE BRACKET WITH QUILL
+ {0x2047, 0x2051, prN}, // Po [11] DOUBLE QUESTION MARK..TWO ASTERISKS ALIGNED VERTICALLY
+ {0x2052, 0x2052, prN}, // Sm COMMERCIAL MINUS SIGN
+ {0x2053, 0x2053, prN}, // Po SWUNG DASH
+ {0x2054, 0x2054, prN}, // Pc INVERTED UNDERTIE
+ {0x2055, 0x205E, prN}, // Po [10] FLOWER PUNCTUATION MARK..VERTICAL FOUR DOTS
+ {0x205F, 0x205F, prN}, // Zs MEDIUM MATHEMATICAL SPACE
+ {0x2060, 0x2064, prN}, // Cf [5] WORD JOINER..INVISIBLE PLUS
+ {0x2066, 0x206F, prN}, // Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES
+ {0x2070, 0x2070, prN}, // No SUPERSCRIPT ZERO
+ {0x2071, 0x2071, prN}, // Lm SUPERSCRIPT LATIN SMALL LETTER I
+ {0x2074, 0x2074, prA}, // No SUPERSCRIPT FOUR
+ {0x2075, 0x2079, prN}, // No [5] SUPERSCRIPT FIVE..SUPERSCRIPT NINE
+ {0x207A, 0x207C, prN}, // Sm [3] SUPERSCRIPT PLUS SIGN..SUPERSCRIPT EQUALS SIGN
+ {0x207D, 0x207D, prN}, // Ps SUPERSCRIPT LEFT PARENTHESIS
+ {0x207E, 0x207E, prN}, // Pe SUPERSCRIPT RIGHT PARENTHESIS
+ {0x207F, 0x207F, prA}, // Lm SUPERSCRIPT LATIN SMALL LETTER N
+ {0x2080, 0x2080, prN}, // No SUBSCRIPT ZERO
+ {0x2081, 0x2084, prA}, // No [4] SUBSCRIPT ONE..SUBSCRIPT FOUR
+ {0x2085, 0x2089, prN}, // No [5] SUBSCRIPT FIVE..SUBSCRIPT NINE
+ {0x208A, 0x208C, prN}, // Sm [3] SUBSCRIPT PLUS SIGN..SUBSCRIPT EQUALS SIGN
+ {0x208D, 0x208D, prN}, // Ps SUBSCRIPT LEFT PARENTHESIS
+ {0x208E, 0x208E, prN}, // Pe SUBSCRIPT RIGHT PARENTHESIS
+ {0x2090, 0x209C, prN}, // Lm [13] LATIN SUBSCRIPT SMALL LETTER A..LATIN SUBSCRIPT SMALL LETTER T
+ {0x20A0, 0x20A8, prN}, // Sc [9] EURO-CURRENCY SIGN..RUPEE SIGN
+ {0x20A9, 0x20A9, prH}, // Sc WON SIGN
+ {0x20AA, 0x20AB, prN}, // Sc [2] NEW SHEQEL SIGN..DONG SIGN
+ {0x20AC, 0x20AC, prA}, // Sc EURO SIGN
+ {0x20AD, 0x20C0, prN}, // Sc [20] KIP SIGN..SOM SIGN
+ {0x20D0, 0x20DC, prN}, // Mn [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE
+ {0x20DD, 0x20E0, prN}, // Me [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH
+ {0x20E1, 0x20E1, prN}, // Mn COMBINING LEFT RIGHT ARROW ABOVE
+ {0x20E2, 0x20E4, prN}, // Me [3] COMBINING ENCLOSING SCREEN..COMBINING ENCLOSING UPWARD POINTING TRIANGLE
+ {0x20E5, 0x20F0, prN}, // Mn [12] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING ASTERISK ABOVE
+ {0x2100, 0x2101, prN}, // So [2] ACCOUNT OF..ADDRESSED TO THE SUBJECT
+ {0x2102, 0x2102, prN}, // Lu DOUBLE-STRUCK CAPITAL C
+ {0x2103, 0x2103, prA}, // So DEGREE CELSIUS
+ {0x2104, 0x2104, prN}, // So CENTRE LINE SYMBOL
+ {0x2105, 0x2105, prA}, // So CARE OF
+ {0x2106, 0x2106, prN}, // So CADA UNA
+ {0x2107, 0x2107, prN}, // Lu EULER CONSTANT
+ {0x2108, 0x2108, prN}, // So SCRUPLE
+ {0x2109, 0x2109, prA}, // So DEGREE FAHRENHEIT
+ {0x210A, 0x2112, prN}, // L& [9] SCRIPT SMALL G..SCRIPT CAPITAL L
+ {0x2113, 0x2113, prA}, // Ll SCRIPT SMALL L
+ {0x2114, 0x2114, prN}, // So L B BAR SYMBOL
+ {0x2115, 0x2115, prN}, // Lu DOUBLE-STRUCK CAPITAL N
+ {0x2116, 0x2116, prA}, // So NUMERO SIGN
+ {0x2117, 0x2117, prN}, // So SOUND RECORDING COPYRIGHT
+ {0x2118, 0x2118, prN}, // Sm SCRIPT CAPITAL P
+ {0x2119, 0x211D, prN}, // Lu [5] DOUBLE-STRUCK CAPITAL P..DOUBLE-STRUCK CAPITAL R
+ {0x211E, 0x2120, prN}, // So [3] PRESCRIPTION TAKE..SERVICE MARK
+ {0x2121, 0x2122, prA}, // So [2] TELEPHONE SIGN..TRADE MARK SIGN
+ {0x2123, 0x2123, prN}, // So VERSICLE
+ {0x2124, 0x2124, prN}, // Lu DOUBLE-STRUCK CAPITAL Z
+ {0x2125, 0x2125, prN}, // So OUNCE SIGN
+ {0x2126, 0x2126, prA}, // Lu OHM SIGN
+ {0x2127, 0x2127, prN}, // So INVERTED OHM SIGN
+ {0x2128, 0x2128, prN}, // Lu BLACK-LETTER CAPITAL Z
+ {0x2129, 0x2129, prN}, // So TURNED GREEK SMALL LETTER IOTA
+ {0x212A, 0x212A, prN}, // Lu KELVIN SIGN
+ {0x212B, 0x212B, prA}, // Lu ANGSTROM SIGN
+ {0x212C, 0x212D, prN}, // Lu [2] SCRIPT CAPITAL B..BLACK-LETTER CAPITAL C
+ {0x212E, 0x212E, prN}, // So ESTIMATED SYMBOL
+ {0x212F, 0x2134, prN}, // L& [6] SCRIPT SMALL E..SCRIPT SMALL O
+ {0x2135, 0x2138, prN}, // Lo [4] ALEF SYMBOL..DALET SYMBOL
+ {0x2139, 0x2139, prN}, // Ll INFORMATION SOURCE
+ {0x213A, 0x213B, prN}, // So [2] ROTATED CAPITAL Q..FACSIMILE SIGN
+ {0x213C, 0x213F, prN}, // L& [4] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK CAPITAL PI
+ {0x2140, 0x2144, prN}, // Sm [5] DOUBLE-STRUCK N-ARY SUMMATION..TURNED SANS-SERIF CAPITAL Y
+ {0x2145, 0x2149, prN}, // L& [5] DOUBLE-STRUCK ITALIC CAPITAL D..DOUBLE-STRUCK ITALIC SMALL J
+ {0x214A, 0x214A, prN}, // So PROPERTY LINE
+ {0x214B, 0x214B, prN}, // Sm TURNED AMPERSAND
+ {0x214C, 0x214D, prN}, // So [2] PER SIGN..AKTIESELSKAB
+ {0x214E, 0x214E, prN}, // Ll TURNED SMALL F
+ {0x214F, 0x214F, prN}, // So SYMBOL FOR SAMARITAN SOURCE
+ {0x2150, 0x2152, prN}, // No [3] VULGAR FRACTION ONE SEVENTH..VULGAR FRACTION ONE TENTH
+ {0x2153, 0x2154, prA}, // No [2] VULGAR FRACTION ONE THIRD..VULGAR FRACTION TWO THIRDS
+ {0x2155, 0x215A, prN}, // No [6] VULGAR FRACTION ONE FIFTH..VULGAR FRACTION FIVE SIXTHS
+ {0x215B, 0x215E, prA}, // No [4] VULGAR FRACTION ONE EIGHTH..VULGAR FRACTION SEVEN EIGHTHS
+ {0x215F, 0x215F, prN}, // No FRACTION NUMERATOR ONE
+ {0x2160, 0x216B, prA}, // Nl [12] ROMAN NUMERAL ONE..ROMAN NUMERAL TWELVE
+ {0x216C, 0x216F, prN}, // Nl [4] ROMAN NUMERAL FIFTY..ROMAN NUMERAL ONE THOUSAND
+ {0x2170, 0x2179, prA}, // Nl [10] SMALL ROMAN NUMERAL ONE..SMALL ROMAN NUMERAL TEN
+ {0x217A, 0x2182, prN}, // Nl [9] SMALL ROMAN NUMERAL ELEVEN..ROMAN NUMERAL TEN THOUSAND
+ {0x2183, 0x2184, prN}, // L& [2] ROMAN NUMERAL REVERSED ONE HUNDRED..LATIN SMALL LETTER REVERSED C
+ {0x2185, 0x2188, prN}, // Nl [4] ROMAN NUMERAL SIX LATE FORM..ROMAN NUMERAL ONE HUNDRED THOUSAND
+ {0x2189, 0x2189, prA}, // No VULGAR FRACTION ZERO THIRDS
+ {0x218A, 0x218B, prN}, // So [2] TURNED DIGIT TWO..TURNED DIGIT THREE
+ {0x2190, 0x2194, prA}, // Sm [5] LEFTWARDS ARROW..LEFT RIGHT ARROW
+ {0x2195, 0x2199, prA}, // So [5] UP DOWN ARROW..SOUTH WEST ARROW
+ {0x219A, 0x219B, prN}, // Sm [2] LEFTWARDS ARROW WITH STROKE..RIGHTWARDS ARROW WITH STROKE
+ {0x219C, 0x219F, prN}, // So [4] LEFTWARDS WAVE ARROW..UPWARDS TWO HEADED ARROW
+ {0x21A0, 0x21A0, prN}, // Sm RIGHTWARDS TWO HEADED ARROW
+ {0x21A1, 0x21A2, prN}, // So [2] DOWNWARDS TWO HEADED ARROW..LEFTWARDS ARROW WITH TAIL
+ {0x21A3, 0x21A3, prN}, // Sm RIGHTWARDS ARROW WITH TAIL
+ {0x21A4, 0x21A5, prN}, // So [2] LEFTWARDS ARROW FROM BAR..UPWARDS ARROW FROM BAR
+ {0x21A6, 0x21A6, prN}, // Sm RIGHTWARDS ARROW FROM BAR
+ {0x21A7, 0x21AD, prN}, // So [7] DOWNWARDS ARROW FROM BAR..LEFT RIGHT WAVE ARROW
+ {0x21AE, 0x21AE, prN}, // Sm LEFT RIGHT ARROW WITH STROKE
+ {0x21AF, 0x21B7, prN}, // So [9] DOWNWARDS ZIGZAG ARROW..CLOCKWISE TOP SEMICIRCLE ARROW
+ {0x21B8, 0x21B9, prA}, // So [2] NORTH WEST ARROW TO LONG BAR..LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR
+ {0x21BA, 0x21CD, prN}, // So [20] ANTICLOCKWISE OPEN CIRCLE ARROW..LEFTWARDS DOUBLE ARROW WITH STROKE
+ {0x21CE, 0x21CF, prN}, // Sm [2] LEFT RIGHT DOUBLE ARROW WITH STROKE..RIGHTWARDS DOUBLE ARROW WITH STROKE
+ {0x21D0, 0x21D1, prN}, // So [2] LEFTWARDS DOUBLE ARROW..UPWARDS DOUBLE ARROW
+ {0x21D2, 0x21D2, prA}, // Sm RIGHTWARDS DOUBLE ARROW
+ {0x21D3, 0x21D3, prN}, // So DOWNWARDS DOUBLE ARROW
+ {0x21D4, 0x21D4, prA}, // Sm LEFT RIGHT DOUBLE ARROW
+ {0x21D5, 0x21E6, prN}, // So [18] UP DOWN DOUBLE ARROW..LEFTWARDS WHITE ARROW
+ {0x21E7, 0x21E7, prA}, // So UPWARDS WHITE ARROW
+ {0x21E8, 0x21F3, prN}, // So [12] RIGHTWARDS WHITE ARROW..UP DOWN WHITE ARROW
+ {0x21F4, 0x21FF, prN}, // Sm [12] RIGHT ARROW WITH SMALL CIRCLE..LEFT RIGHT OPEN-HEADED ARROW
+ {0x2200, 0x2200, prA}, // Sm FOR ALL
+ {0x2201, 0x2201, prN}, // Sm COMPLEMENT
+ {0x2202, 0x2203, prA}, // Sm [2] PARTIAL DIFFERENTIAL..THERE EXISTS
+ {0x2204, 0x2206, prN}, // Sm [3] THERE DOES NOT EXIST..INCREMENT
+ {0x2207, 0x2208, prA}, // Sm [2] NABLA..ELEMENT OF
+ {0x2209, 0x220A, prN}, // Sm [2] NOT AN ELEMENT OF..SMALL ELEMENT OF
+ {0x220B, 0x220B, prA}, // Sm CONTAINS AS MEMBER
+ {0x220C, 0x220E, prN}, // Sm [3] DOES NOT CONTAIN AS MEMBER..END OF PROOF
+ {0x220F, 0x220F, prA}, // Sm N-ARY PRODUCT
+ {0x2210, 0x2210, prN}, // Sm N-ARY COPRODUCT
+ {0x2211, 0x2211, prA}, // Sm N-ARY SUMMATION
+ {0x2212, 0x2214, prN}, // Sm [3] MINUS SIGN..DOT PLUS
+ {0x2215, 0x2215, prA}, // Sm DIVISION SLASH
+ {0x2216, 0x2219, prN}, // Sm [4] SET MINUS..BULLET OPERATOR
+ {0x221A, 0x221A, prA}, // Sm SQUARE ROOT
+ {0x221B, 0x221C, prN}, // Sm [2] CUBE ROOT..FOURTH ROOT
+ {0x221D, 0x2220, prA}, // Sm [4] PROPORTIONAL TO..ANGLE
+ {0x2221, 0x2222, prN}, // Sm [2] MEASURED ANGLE..SPHERICAL ANGLE
+ {0x2223, 0x2223, prA}, // Sm DIVIDES
+ {0x2224, 0x2224, prN}, // Sm DOES NOT DIVIDE
+ {0x2225, 0x2225, prA}, // Sm PARALLEL TO
+ {0x2226, 0x2226, prN}, // Sm NOT PARALLEL TO
+ {0x2227, 0x222C, prA}, // Sm [6] LOGICAL AND..DOUBLE INTEGRAL
+ {0x222D, 0x222D, prN}, // Sm TRIPLE INTEGRAL
+ {0x222E, 0x222E, prA}, // Sm CONTOUR INTEGRAL
+ {0x222F, 0x2233, prN}, // Sm [5] SURFACE INTEGRAL..ANTICLOCKWISE CONTOUR INTEGRAL
+ {0x2234, 0x2237, prA}, // Sm [4] THEREFORE..PROPORTION
+ {0x2238, 0x223B, prN}, // Sm [4] DOT MINUS..HOMOTHETIC
+ {0x223C, 0x223D, prA}, // Sm [2] TILDE OPERATOR..REVERSED TILDE
+ {0x223E, 0x2247, prN}, // Sm [10] INVERTED LAZY S..NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO
+ {0x2248, 0x2248, prA}, // Sm ALMOST EQUAL TO
+ {0x2249, 0x224B, prN}, // Sm [3] NOT ALMOST EQUAL TO..TRIPLE TILDE
+ {0x224C, 0x224C, prA}, // Sm ALL EQUAL TO
+ {0x224D, 0x2251, prN}, // Sm [5] EQUIVALENT TO..GEOMETRICALLY EQUAL TO
+ {0x2252, 0x2252, prA}, // Sm APPROXIMATELY EQUAL TO OR THE IMAGE OF
+ {0x2253, 0x225F, prN}, // Sm [13] IMAGE OF OR APPROXIMATELY EQUAL TO..QUESTIONED EQUAL TO
+ {0x2260, 0x2261, prA}, // Sm [2] NOT EQUAL TO..IDENTICAL TO
+ {0x2262, 0x2263, prN}, // Sm [2] NOT IDENTICAL TO..STRICTLY EQUIVALENT TO
+ {0x2264, 0x2267, prA}, // Sm [4] LESS-THAN OR EQUAL TO..GREATER-THAN OVER EQUAL TO
+ {0x2268, 0x2269, prN}, // Sm [2] LESS-THAN BUT NOT EQUAL TO..GREATER-THAN BUT NOT EQUAL TO
+ {0x226A, 0x226B, prA}, // Sm [2] MUCH LESS-THAN..MUCH GREATER-THAN
+ {0x226C, 0x226D, prN}, // Sm [2] BETWEEN..NOT EQUIVALENT TO
+ {0x226E, 0x226F, prA}, // Sm [2] NOT LESS-THAN..NOT GREATER-THAN
+ {0x2270, 0x2281, prN}, // Sm [18] NEITHER LESS-THAN NOR EQUAL TO..DOES NOT SUCCEED
+ {0x2282, 0x2283, prA}, // Sm [2] SUBSET OF..SUPERSET OF
+ {0x2284, 0x2285, prN}, // Sm [2] NOT A SUBSET OF..NOT A SUPERSET OF
+ {0x2286, 0x2287, prA}, // Sm [2] SUBSET OF OR EQUAL TO..SUPERSET OF OR EQUAL TO
+ {0x2288, 0x2294, prN}, // Sm [13] NEITHER A SUBSET OF NOR EQUAL TO..SQUARE CUP
+ {0x2295, 0x2295, prA}, // Sm CIRCLED PLUS
+ {0x2296, 0x2298, prN}, // Sm [3] CIRCLED MINUS..CIRCLED DIVISION SLASH
+ {0x2299, 0x2299, prA}, // Sm CIRCLED DOT OPERATOR
+ {0x229A, 0x22A4, prN}, // Sm [11] CIRCLED RING OPERATOR..DOWN TACK
+ {0x22A5, 0x22A5, prA}, // Sm UP TACK
+ {0x22A6, 0x22BE, prN}, // Sm [25] ASSERTION..RIGHT ANGLE WITH ARC
+ {0x22BF, 0x22BF, prA}, // Sm RIGHT TRIANGLE
+ {0x22C0, 0x22FF, prN}, // Sm [64] N-ARY LOGICAL AND..Z NOTATION BAG MEMBERSHIP
+ {0x2300, 0x2307, prN}, // So [8] DIAMETER SIGN..WAVY LINE
+ {0x2308, 0x2308, prN}, // Ps LEFT CEILING
+ {0x2309, 0x2309, prN}, // Pe RIGHT CEILING
+ {0x230A, 0x230A, prN}, // Ps LEFT FLOOR
+ {0x230B, 0x230B, prN}, // Pe RIGHT FLOOR
+ {0x230C, 0x2311, prN}, // So [6] BOTTOM RIGHT CROP..SQUARE LOZENGE
+ {0x2312, 0x2312, prA}, // So ARC
+ {0x2313, 0x2319, prN}, // So [7] SEGMENT..TURNED NOT SIGN
+ {0x231A, 0x231B, prW}, // So [2] WATCH..HOURGLASS
+ {0x231C, 0x231F, prN}, // So [4] TOP LEFT CORNER..BOTTOM RIGHT CORNER
+ {0x2320, 0x2321, prN}, // Sm [2] TOP HALF INTEGRAL..BOTTOM HALF INTEGRAL
+ {0x2322, 0x2328, prN}, // So [7] FROWN..KEYBOARD
+ {0x2329, 0x2329, prW}, // Ps LEFT-POINTING ANGLE BRACKET
+ {0x232A, 0x232A, prW}, // Pe RIGHT-POINTING ANGLE BRACKET
+ {0x232B, 0x237B, prN}, // So [81] ERASE TO THE LEFT..NOT CHECK MARK
+ {0x237C, 0x237C, prN}, // Sm RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW
+ {0x237D, 0x239A, prN}, // So [30] SHOULDERED OPEN BOX..CLEAR SCREEN SYMBOL
+ {0x239B, 0x23B3, prN}, // Sm [25] LEFT PARENTHESIS UPPER HOOK..SUMMATION BOTTOM
+ {0x23B4, 0x23DB, prN}, // So [40] TOP SQUARE BRACKET..FUSE
+ {0x23DC, 0x23E1, prN}, // Sm [6] TOP PARENTHESIS..BOTTOM TORTOISE SHELL BRACKET
+ {0x23E2, 0x23E8, prN}, // So [7] WHITE TRAPEZIUM..DECIMAL EXPONENT SYMBOL
+ {0x23E9, 0x23EC, prW}, // So [4] BLACK RIGHT-POINTING DOUBLE TRIANGLE..BLACK DOWN-POINTING DOUBLE TRIANGLE
+ {0x23ED, 0x23EF, prN}, // So [3] BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR..BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR
+ {0x23F0, 0x23F0, prW}, // So ALARM CLOCK
+ {0x23F1, 0x23F2, prN}, // So [2] STOPWATCH..TIMER CLOCK
+ {0x23F3, 0x23F3, prW}, // So HOURGLASS WITH FLOWING SAND
+ {0x23F4, 0x23FF, prN}, // So [12] BLACK MEDIUM LEFT-POINTING TRIANGLE..OBSERVER EYE SYMBOL
+ {0x2400, 0x2426, prN}, // So [39] SYMBOL FOR NULL..SYMBOL FOR SUBSTITUTE FORM TWO
+ {0x2440, 0x244A, prN}, // So [11] OCR HOOK..OCR DOUBLE BACKSLASH
+ {0x2460, 0x249B, prA}, // No [60] CIRCLED DIGIT ONE..NUMBER TWENTY FULL STOP
+ {0x249C, 0x24E9, prA}, // So [78] PARENTHESIZED LATIN SMALL LETTER A..CIRCLED LATIN SMALL LETTER Z
+ {0x24EA, 0x24EA, prN}, // No CIRCLED DIGIT ZERO
+ {0x24EB, 0x24FF, prA}, // No [21] NEGATIVE CIRCLED NUMBER ELEVEN..NEGATIVE CIRCLED DIGIT ZERO
+ {0x2500, 0x254B, prA}, // So [76] BOX DRAWINGS LIGHT HORIZONTAL..BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL
+ {0x254C, 0x254F, prN}, // So [4] BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL..BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL
+ {0x2550, 0x2573, prA}, // So [36] BOX DRAWINGS DOUBLE HORIZONTAL..BOX DRAWINGS LIGHT DIAGONAL CROSS
+ {0x2574, 0x257F, prN}, // So [12] BOX DRAWINGS LIGHT LEFT..BOX DRAWINGS HEAVY UP AND LIGHT DOWN
+ {0x2580, 0x258F, prA}, // So [16] UPPER HALF BLOCK..LEFT ONE EIGHTH BLOCK
+ {0x2590, 0x2591, prN}, // So [2] RIGHT HALF BLOCK..LIGHT SHADE
+ {0x2592, 0x2595, prA}, // So [4] MEDIUM SHADE..RIGHT ONE EIGHTH BLOCK
+ {0x2596, 0x259F, prN}, // So [10] QUADRANT LOWER LEFT..QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
+ {0x25A0, 0x25A1, prA}, // So [2] BLACK SQUARE..WHITE SQUARE
+ {0x25A2, 0x25A2, prN}, // So WHITE SQUARE WITH ROUNDED CORNERS
+ {0x25A3, 0x25A9, prA}, // So [7] WHITE SQUARE CONTAINING BLACK SMALL SQUARE..SQUARE WITH DIAGONAL CROSSHATCH FILL
+ {0x25AA, 0x25B1, prN}, // So [8] BLACK SMALL SQUARE..WHITE PARALLELOGRAM
+ {0x25B2, 0x25B3, prA}, // So [2] BLACK UP-POINTING TRIANGLE..WHITE UP-POINTING TRIANGLE
+ {0x25B4, 0x25B5, prN}, // So [2] BLACK UP-POINTING SMALL TRIANGLE..WHITE UP-POINTING SMALL TRIANGLE
+ {0x25B6, 0x25B6, prA}, // So BLACK RIGHT-POINTING TRIANGLE
+ {0x25B7, 0x25B7, prA}, // Sm WHITE RIGHT-POINTING TRIANGLE
+ {0x25B8, 0x25BB, prN}, // So [4] BLACK RIGHT-POINTING SMALL TRIANGLE..WHITE RIGHT-POINTING POINTER
+ {0x25BC, 0x25BD, prA}, // So [2] BLACK DOWN-POINTING TRIANGLE..WHITE DOWN-POINTING TRIANGLE
+ {0x25BE, 0x25BF, prN}, // So [2] BLACK DOWN-POINTING SMALL TRIANGLE..WHITE DOWN-POINTING SMALL TRIANGLE
+ {0x25C0, 0x25C0, prA}, // So BLACK LEFT-POINTING TRIANGLE
+ {0x25C1, 0x25C1, prA}, // Sm WHITE LEFT-POINTING TRIANGLE
+ {0x25C2, 0x25C5, prN}, // So [4] BLACK LEFT-POINTING SMALL TRIANGLE..WHITE LEFT-POINTING POINTER
+ {0x25C6, 0x25C8, prA}, // So [3] BLACK DIAMOND..WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND
+ {0x25C9, 0x25CA, prN}, // So [2] FISHEYE..LOZENGE
+ {0x25CB, 0x25CB, prA}, // So WHITE CIRCLE
+ {0x25CC, 0x25CD, prN}, // So [2] DOTTED CIRCLE..CIRCLE WITH VERTICAL FILL
+ {0x25CE, 0x25D1, prA}, // So [4] BULLSEYE..CIRCLE WITH RIGHT HALF BLACK
+ {0x25D2, 0x25E1, prN}, // So [16] CIRCLE WITH LOWER HALF BLACK..LOWER HALF CIRCLE
+ {0x25E2, 0x25E5, prA}, // So [4] BLACK LOWER RIGHT TRIANGLE..BLACK UPPER RIGHT TRIANGLE
+ {0x25E6, 0x25EE, prN}, // So [9] WHITE BULLET..UP-POINTING TRIANGLE WITH RIGHT HALF BLACK
+ {0x25EF, 0x25EF, prA}, // So LARGE CIRCLE
+ {0x25F0, 0x25F7, prN}, // So [8] WHITE SQUARE WITH UPPER LEFT QUADRANT..WHITE CIRCLE WITH UPPER RIGHT QUADRANT
+ {0x25F8, 0x25FC, prN}, // Sm [5] UPPER LEFT TRIANGLE..BLACK MEDIUM SQUARE
+ {0x25FD, 0x25FE, prW}, // Sm [2] WHITE MEDIUM SMALL SQUARE..BLACK MEDIUM SMALL SQUARE
+ {0x25FF, 0x25FF, prN}, // Sm LOWER RIGHT TRIANGLE
+ {0x2600, 0x2604, prN}, // So [5] BLACK SUN WITH RAYS..COMET
+ {0x2605, 0x2606, prA}, // So [2] BLACK STAR..WHITE STAR
+ {0x2607, 0x2608, prN}, // So [2] LIGHTNING..THUNDERSTORM
+ {0x2609, 0x2609, prA}, // So SUN
+ {0x260A, 0x260D, prN}, // So [4] ASCENDING NODE..OPPOSITION
+ {0x260E, 0x260F, prA}, // So [2] BLACK TELEPHONE..WHITE TELEPHONE
+ {0x2610, 0x2613, prN}, // So [4] BALLOT BOX..SALTIRE
+ {0x2614, 0x2615, prW}, // So [2] UMBRELLA WITH RAIN DROPS..HOT BEVERAGE
+ {0x2616, 0x261B, prN}, // So [6] WHITE SHOGI PIECE..BLACK RIGHT POINTING INDEX
+ {0x261C, 0x261C, prA}, // So WHITE LEFT POINTING INDEX
+ {0x261D, 0x261D, prN}, // So WHITE UP POINTING INDEX
+ {0x261E, 0x261E, prA}, // So WHITE RIGHT POINTING INDEX
+ {0x261F, 0x263F, prN}, // So [33] WHITE DOWN POINTING INDEX..MERCURY
+ {0x2640, 0x2640, prA}, // So FEMALE SIGN
+ {0x2641, 0x2641, prN}, // So EARTH
+ {0x2642, 0x2642, prA}, // So MALE SIGN
+ {0x2643, 0x2647, prN}, // So [5] JUPITER..PLUTO
+ {0x2648, 0x2653, prW}, // So [12] ARIES..PISCES
+ {0x2654, 0x265F, prN}, // So [12] WHITE CHESS KING..BLACK CHESS PAWN
+ {0x2660, 0x2661, prA}, // So [2] BLACK SPADE SUIT..WHITE HEART SUIT
+ {0x2662, 0x2662, prN}, // So WHITE DIAMOND SUIT
+ {0x2663, 0x2665, prA}, // So [3] BLACK CLUB SUIT..BLACK HEART SUIT
+ {0x2666, 0x2666, prN}, // So BLACK DIAMOND SUIT
+ {0x2667, 0x266A, prA}, // So [4] WHITE CLUB SUIT..EIGHTH NOTE
+ {0x266B, 0x266B, prN}, // So BEAMED EIGHTH NOTES
+ {0x266C, 0x266D, prA}, // So [2] BEAMED SIXTEENTH NOTES..MUSIC FLAT SIGN
+ {0x266E, 0x266E, prN}, // So MUSIC NATURAL SIGN
+ {0x266F, 0x266F, prA}, // Sm MUSIC SHARP SIGN
+ {0x2670, 0x267E, prN}, // So [15] WEST SYRIAC CROSS..PERMANENT PAPER SIGN
+ {0x267F, 0x267F, prW}, // So WHEELCHAIR SYMBOL
+ {0x2680, 0x2692, prN}, // So [19] DIE FACE-1..HAMMER AND PICK
+ {0x2693, 0x2693, prW}, // So ANCHOR
+ {0x2694, 0x269D, prN}, // So [10] CROSSED SWORDS..OUTLINED WHITE STAR
+ {0x269E, 0x269F, prA}, // So [2] THREE LINES CONVERGING RIGHT..THREE LINES CONVERGING LEFT
+ {0x26A0, 0x26A0, prN}, // So WARNING SIGN
+ {0x26A1, 0x26A1, prW}, // So HIGH VOLTAGE SIGN
+ {0x26A2, 0x26A9, prN}, // So [8] DOUBLED FEMALE SIGN..HORIZONTAL MALE WITH STROKE SIGN
+ {0x26AA, 0x26AB, prW}, // So [2] MEDIUM WHITE CIRCLE..MEDIUM BLACK CIRCLE
+ {0x26AC, 0x26BC, prN}, // So [17] MEDIUM SMALL WHITE CIRCLE..SESQUIQUADRATE
+ {0x26BD, 0x26BE, prW}, // So [2] SOCCER BALL..BASEBALL
+ {0x26BF, 0x26BF, prA}, // So SQUARED KEY
+ {0x26C0, 0x26C3, prN}, // So [4] WHITE DRAUGHTS MAN..BLACK DRAUGHTS KING
+ {0x26C4, 0x26C5, prW}, // So [2] SNOWMAN WITHOUT SNOW..SUN BEHIND CLOUD
+ {0x26C6, 0x26CD, prA}, // So [8] RAIN..DISABLED CAR
+ {0x26CE, 0x26CE, prW}, // So OPHIUCHUS
+ {0x26CF, 0x26D3, prA}, // So [5] PICK..CHAINS
+ {0x26D4, 0x26D4, prW}, // So NO ENTRY
+ {0x26D5, 0x26E1, prA}, // So [13] ALTERNATE ONE-WAY LEFT WAY TRAFFIC..RESTRICTED LEFT ENTRY-2
+ {0x26E2, 0x26E2, prN}, // So ASTRONOMICAL SYMBOL FOR URANUS
+ {0x26E3, 0x26E3, prA}, // So HEAVY CIRCLE WITH STROKE AND TWO DOTS ABOVE
+ {0x26E4, 0x26E7, prN}, // So [4] PENTAGRAM..INVERTED PENTAGRAM
+ {0x26E8, 0x26E9, prA}, // So [2] BLACK CROSS ON SHIELD..SHINTO SHRINE
+ {0x26EA, 0x26EA, prW}, // So CHURCH
+ {0x26EB, 0x26F1, prA}, // So [7] CASTLE..UMBRELLA ON GROUND
+ {0x26F2, 0x26F3, prW}, // So [2] FOUNTAIN..FLAG IN HOLE
+ {0x26F4, 0x26F4, prA}, // So FERRY
+ {0x26F5, 0x26F5, prW}, // So SAILBOAT
+ {0x26F6, 0x26F9, prA}, // So [4] SQUARE FOUR CORNERS..PERSON WITH BALL
+ {0x26FA, 0x26FA, prW}, // So TENT
+ {0x26FB, 0x26FC, prA}, // So [2] JAPANESE BANK SYMBOL..HEADSTONE GRAVEYARD SYMBOL
+ {0x26FD, 0x26FD, prW}, // So FUEL PUMP
+ {0x26FE, 0x26FF, prA}, // So [2] CUP ON BLACK SQUARE..WHITE FLAG WITH HORIZONTAL MIDDLE BLACK STRIPE
+ {0x2700, 0x2704, prN}, // So [5] BLACK SAFETY SCISSORS..WHITE SCISSORS
+ {0x2705, 0x2705, prW}, // So WHITE HEAVY CHECK MARK
+ {0x2706, 0x2709, prN}, // So [4] TELEPHONE LOCATION SIGN..ENVELOPE
+ {0x270A, 0x270B, prW}, // So [2] RAISED FIST..RAISED HAND
+ {0x270C, 0x2727, prN}, // So [28] VICTORY HAND..WHITE FOUR POINTED STAR
+ {0x2728, 0x2728, prW}, // So SPARKLES
+ {0x2729, 0x273C, prN}, // So [20] STRESS OUTLINED WHITE STAR..OPEN CENTRE TEARDROP-SPOKED ASTERISK
+ {0x273D, 0x273D, prA}, // So HEAVY TEARDROP-SPOKED ASTERISK
+ {0x273E, 0x274B, prN}, // So [14] SIX PETALLED BLACK AND WHITE FLORETTE..HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK
+ {0x274C, 0x274C, prW}, // So CROSS MARK
+ {0x274D, 0x274D, prN}, // So SHADOWED WHITE CIRCLE
+ {0x274E, 0x274E, prW}, // So NEGATIVE SQUARED CROSS MARK
+ {0x274F, 0x2752, prN}, // So [4] LOWER RIGHT DROP-SHADOWED WHITE SQUARE..UPPER RIGHT SHADOWED WHITE SQUARE
+ {0x2753, 0x2755, prW}, // So [3] BLACK QUESTION MARK ORNAMENT..WHITE EXCLAMATION MARK ORNAMENT
+ {0x2756, 0x2756, prN}, // So BLACK DIAMOND MINUS WHITE X
+ {0x2757, 0x2757, prW}, // So HEAVY EXCLAMATION MARK SYMBOL
+ {0x2758, 0x2767, prN}, // So [16] LIGHT VERTICAL BAR..ROTATED FLORAL HEART BULLET
+ {0x2768, 0x2768, prN}, // Ps MEDIUM LEFT PARENTHESIS ORNAMENT
+ {0x2769, 0x2769, prN}, // Pe MEDIUM RIGHT PARENTHESIS ORNAMENT
+ {0x276A, 0x276A, prN}, // Ps MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT
+ {0x276B, 0x276B, prN}, // Pe MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT
+ {0x276C, 0x276C, prN}, // Ps MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT
+ {0x276D, 0x276D, prN}, // Pe MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT
+ {0x276E, 0x276E, prN}, // Ps HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT
+ {0x276F, 0x276F, prN}, // Pe HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT
+ {0x2770, 0x2770, prN}, // Ps HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT
+ {0x2771, 0x2771, prN}, // Pe HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT
+ {0x2772, 0x2772, prN}, // Ps LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT
+ {0x2773, 0x2773, prN}, // Pe LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT
+ {0x2774, 0x2774, prN}, // Ps MEDIUM LEFT CURLY BRACKET ORNAMENT
+ {0x2775, 0x2775, prN}, // Pe MEDIUM RIGHT CURLY BRACKET ORNAMENT
+ {0x2776, 0x277F, prA}, // No [10] DINGBAT NEGATIVE CIRCLED DIGIT ONE..DINGBAT NEGATIVE CIRCLED NUMBER TEN
+ {0x2780, 0x2793, prN}, // No [20] DINGBAT CIRCLED SANS-SERIF DIGIT ONE..DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN
+ {0x2794, 0x2794, prN}, // So HEAVY WIDE-HEADED RIGHTWARDS ARROW
+ {0x2795, 0x2797, prW}, // So [3] HEAVY PLUS SIGN..HEAVY DIVISION SIGN
+ {0x2798, 0x27AF, prN}, // So [24] HEAVY SOUTH EAST ARROW..NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW
+ {0x27B0, 0x27B0, prW}, // So CURLY LOOP
+ {0x27B1, 0x27BE, prN}, // So [14] NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW..OPEN-OUTLINED RIGHTWARDS ARROW
+ {0x27BF, 0x27BF, prW}, // So DOUBLE CURLY LOOP
+ {0x27C0, 0x27C4, prN}, // Sm [5] THREE DIMENSIONAL ANGLE..OPEN SUPERSET
+ {0x27C5, 0x27C5, prN}, // Ps LEFT S-SHAPED BAG DELIMITER
+ {0x27C6, 0x27C6, prN}, // Pe RIGHT S-SHAPED BAG DELIMITER
+ {0x27C7, 0x27E5, prN}, // Sm [31] OR WITH DOT INSIDE..WHITE SQUARE WITH RIGHTWARDS TICK
+ {0x27E6, 0x27E6, prNa}, // Ps MATHEMATICAL LEFT WHITE SQUARE BRACKET
+ {0x27E7, 0x27E7, prNa}, // Pe MATHEMATICAL RIGHT WHITE SQUARE BRACKET
+ {0x27E8, 0x27E8, prNa}, // Ps MATHEMATICAL LEFT ANGLE BRACKET
+ {0x27E9, 0x27E9, prNa}, // Pe MATHEMATICAL RIGHT ANGLE BRACKET
+ {0x27EA, 0x27EA, prNa}, // Ps MATHEMATICAL LEFT DOUBLE ANGLE BRACKET
+ {0x27EB, 0x27EB, prNa}, // Pe MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET
+ {0x27EC, 0x27EC, prNa}, // Ps MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET
+ {0x27ED, 0x27ED, prNa}, // Pe MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET
+ {0x27EE, 0x27EE, prN}, // Ps MATHEMATICAL LEFT FLATTENED PARENTHESIS
+ {0x27EF, 0x27EF, prN}, // Pe MATHEMATICAL RIGHT FLATTENED PARENTHESIS
+ {0x27F0, 0x27FF, prN}, // Sm [16] UPWARDS QUADRUPLE ARROW..LONG RIGHTWARDS SQUIGGLE ARROW
+ {0x2800, 0x28FF, prN}, // So [256] BRAILLE PATTERN BLANK..BRAILLE PATTERN DOTS-12345678
+ {0x2900, 0x297F, prN}, // Sm [128] RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE..DOWN FISH TAIL
+ {0x2980, 0x2982, prN}, // Sm [3] TRIPLE VERTICAL BAR DELIMITER..Z NOTATION TYPE COLON
+ {0x2983, 0x2983, prN}, // Ps LEFT WHITE CURLY BRACKET
+ {0x2984, 0x2984, prN}, // Pe RIGHT WHITE CURLY BRACKET
+ {0x2985, 0x2985, prNa}, // Ps LEFT WHITE PARENTHESIS
+ {0x2986, 0x2986, prNa}, // Pe RIGHT WHITE PARENTHESIS
+ {0x2987, 0x2987, prN}, // Ps Z NOTATION LEFT IMAGE BRACKET
+ {0x2988, 0x2988, prN}, // Pe Z NOTATION RIGHT IMAGE BRACKET
+ {0x2989, 0x2989, prN}, // Ps Z NOTATION LEFT BINDING BRACKET
+ {0x298A, 0x298A, prN}, // Pe Z NOTATION RIGHT BINDING BRACKET
+ {0x298B, 0x298B, prN}, // Ps LEFT SQUARE BRACKET WITH UNDERBAR
+ {0x298C, 0x298C, prN}, // Pe RIGHT SQUARE BRACKET WITH UNDERBAR
+ {0x298D, 0x298D, prN}, // Ps LEFT SQUARE BRACKET WITH TICK IN TOP CORNER
+ {0x298E, 0x298E, prN}, // Pe RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
+ {0x298F, 0x298F, prN}, // Ps LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
+ {0x2990, 0x2990, prN}, // Pe RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER
+ {0x2991, 0x2991, prN}, // Ps LEFT ANGLE BRACKET WITH DOT
+ {0x2992, 0x2992, prN}, // Pe RIGHT ANGLE BRACKET WITH DOT
+ {0x2993, 0x2993, prN}, // Ps LEFT ARC LESS-THAN BRACKET
+ {0x2994, 0x2994, prN}, // Pe RIGHT ARC GREATER-THAN BRACKET
+ {0x2995, 0x2995, prN}, // Ps DOUBLE LEFT ARC GREATER-THAN BRACKET
+ {0x2996, 0x2996, prN}, // Pe DOUBLE RIGHT ARC LESS-THAN BRACKET
+ {0x2997, 0x2997, prN}, // Ps LEFT BLACK TORTOISE SHELL BRACKET
+ {0x2998, 0x2998, prN}, // Pe RIGHT BLACK TORTOISE SHELL BRACKET
+ {0x2999, 0x29D7, prN}, // Sm [63] DOTTED FENCE..BLACK HOURGLASS
+ {0x29D8, 0x29D8, prN}, // Ps LEFT WIGGLY FENCE
+ {0x29D9, 0x29D9, prN}, // Pe RIGHT WIGGLY FENCE
+ {0x29DA, 0x29DA, prN}, // Ps LEFT DOUBLE WIGGLY FENCE
+ {0x29DB, 0x29DB, prN}, // Pe RIGHT DOUBLE WIGGLY FENCE
+ {0x29DC, 0x29FB, prN}, // Sm [32] INCOMPLETE INFINITY..TRIPLE PLUS
+ {0x29FC, 0x29FC, prN}, // Ps LEFT-POINTING CURVED ANGLE BRACKET
+ {0x29FD, 0x29FD, prN}, // Pe RIGHT-POINTING CURVED ANGLE BRACKET
+ {0x29FE, 0x29FF, prN}, // Sm [2] TINY..MINY
+ {0x2A00, 0x2AFF, prN}, // Sm [256] N-ARY CIRCLED DOT OPERATOR..N-ARY WHITE VERTICAL BAR
+ {0x2B00, 0x2B1A, prN}, // So [27] NORTH EAST WHITE ARROW..DOTTED SQUARE
+ {0x2B1B, 0x2B1C, prW}, // So [2] BLACK LARGE SQUARE..WHITE LARGE SQUARE
+ {0x2B1D, 0x2B2F, prN}, // So [19] BLACK VERY SMALL SQUARE..WHITE VERTICAL ELLIPSE
+ {0x2B30, 0x2B44, prN}, // Sm [21] LEFT ARROW WITH SMALL CIRCLE..RIGHTWARDS ARROW THROUGH SUPERSET
+ {0x2B45, 0x2B46, prN}, // So [2] LEFTWARDS QUADRUPLE ARROW..RIGHTWARDS QUADRUPLE ARROW
+ {0x2B47, 0x2B4C, prN}, // Sm [6] REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW..RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR
+ {0x2B4D, 0x2B4F, prN}, // So [3] DOWNWARDS TRIANGLE-HEADED ZIGZAG ARROW..SHORT BACKSLANTED SOUTH ARROW
+ {0x2B50, 0x2B50, prW}, // So WHITE MEDIUM STAR
+ {0x2B51, 0x2B54, prN}, // So [4] BLACK SMALL STAR..WHITE RIGHT-POINTING PENTAGON
+ {0x2B55, 0x2B55, prW}, // So HEAVY LARGE CIRCLE
+ {0x2B56, 0x2B59, prA}, // So [4] HEAVY OVAL WITH OVAL INSIDE..HEAVY CIRCLED SALTIRE
+ {0x2B5A, 0x2B73, prN}, // So [26] SLANTED NORTH ARROW WITH HOOKED HEAD..DOWNWARDS TRIANGLE-HEADED ARROW TO BAR
+ {0x2B76, 0x2B95, prN}, // So [32] NORTH WEST TRIANGLE-HEADED ARROW TO BAR..RIGHTWARDS BLACK ARROW
+ {0x2B97, 0x2BFF, prN}, // So [105] SYMBOL FOR TYPE A ELECTRONICS..HELLSCHREIBER PAUSE SYMBOL
+ {0x2C00, 0x2C5F, prN}, // L& [96] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC SMALL LETTER CAUDATE CHRIVI
+ {0x2C60, 0x2C7B, prN}, // L& [28] LATIN CAPITAL LETTER L WITH DOUBLE BAR..LATIN LETTER SMALL CAPITAL TURNED E
+ {0x2C7C, 0x2C7D, prN}, // Lm [2] LATIN SUBSCRIPT SMALL LETTER J..MODIFIER LETTER CAPITAL V
+ {0x2C7E, 0x2C7F, prN}, // Lu [2] LATIN CAPITAL LETTER S WITH SWASH TAIL..LATIN CAPITAL LETTER Z WITH SWASH TAIL
+ {0x2C80, 0x2CE4, prN}, // L& [101] COPTIC CAPITAL LETTER ALFA..COPTIC SYMBOL KAI
+ {0x2CE5, 0x2CEA, prN}, // So [6] COPTIC SYMBOL MI RO..COPTIC SYMBOL SHIMA SIMA
+ {0x2CEB, 0x2CEE, prN}, // L& [4] COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI..COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA
+ {0x2CEF, 0x2CF1, prN}, // Mn [3] COPTIC COMBINING NI ABOVE..COPTIC COMBINING SPIRITUS LENIS
+ {0x2CF2, 0x2CF3, prN}, // L& [2] COPTIC CAPITAL LETTER BOHAIRIC KHEI..COPTIC SMALL LETTER BOHAIRIC KHEI
+ {0x2CF9, 0x2CFC, prN}, // Po [4] COPTIC OLD NUBIAN FULL STOP..COPTIC OLD NUBIAN VERSE DIVIDER
+ {0x2CFD, 0x2CFD, prN}, // No COPTIC FRACTION ONE HALF
+ {0x2CFE, 0x2CFF, prN}, // Po [2] COPTIC FULL STOP..COPTIC MORPHOLOGICAL DIVIDER
+ {0x2D00, 0x2D25, prN}, // Ll [38] GEORGIAN SMALL LETTER AN..GEORGIAN SMALL LETTER HOE
+ {0x2D27, 0x2D27, prN}, // Ll GEORGIAN SMALL LETTER YN
+ {0x2D2D, 0x2D2D, prN}, // Ll GEORGIAN SMALL LETTER AEN
+ {0x2D30, 0x2D67, prN}, // Lo [56] TIFINAGH LETTER YA..TIFINAGH LETTER YO
+ {0x2D6F, 0x2D6F, prN}, // Lm TIFINAGH MODIFIER LETTER LABIALIZATION MARK
+ {0x2D70, 0x2D70, prN}, // Po TIFINAGH SEPARATOR MARK
+ {0x2D7F, 0x2D7F, prN}, // Mn TIFINAGH CONSONANT JOINER
+ {0x2D80, 0x2D96, prN}, // Lo [23] ETHIOPIC SYLLABLE LOA..ETHIOPIC SYLLABLE GGWE
+ {0x2DA0, 0x2DA6, prN}, // Lo [7] ETHIOPIC SYLLABLE SSA..ETHIOPIC SYLLABLE SSO
+ {0x2DA8, 0x2DAE, prN}, // Lo [7] ETHIOPIC SYLLABLE CCA..ETHIOPIC SYLLABLE CCO
+ {0x2DB0, 0x2DB6, prN}, // Lo [7] ETHIOPIC SYLLABLE ZZA..ETHIOPIC SYLLABLE ZZO
+ {0x2DB8, 0x2DBE, prN}, // Lo [7] ETHIOPIC SYLLABLE CCHA..ETHIOPIC SYLLABLE CCHO
+ {0x2DC0, 0x2DC6, prN}, // Lo [7] ETHIOPIC SYLLABLE QYA..ETHIOPIC SYLLABLE QYO
+ {0x2DC8, 0x2DCE, prN}, // Lo [7] ETHIOPIC SYLLABLE KYA..ETHIOPIC SYLLABLE KYO
+ {0x2DD0, 0x2DD6, prN}, // Lo [7] ETHIOPIC SYLLABLE XYA..ETHIOPIC SYLLABLE XYO
+ {0x2DD8, 0x2DDE, prN}, // Lo [7] ETHIOPIC SYLLABLE GYA..ETHIOPIC SYLLABLE GYO
+ {0x2DE0, 0x2DFF, prN}, // Mn [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS
+ {0x2E00, 0x2E01, prN}, // Po [2] RIGHT ANGLE SUBSTITUTION MARKER..RIGHT ANGLE DOTTED SUBSTITUTION MARKER
+ {0x2E02, 0x2E02, prN}, // Pi LEFT SUBSTITUTION BRACKET
+ {0x2E03, 0x2E03, prN}, // Pf RIGHT SUBSTITUTION BRACKET
+ {0x2E04, 0x2E04, prN}, // Pi LEFT DOTTED SUBSTITUTION BRACKET
+ {0x2E05, 0x2E05, prN}, // Pf RIGHT DOTTED SUBSTITUTION BRACKET
+ {0x2E06, 0x2E08, prN}, // Po [3] RAISED INTERPOLATION MARKER..DOTTED TRANSPOSITION MARKER
+ {0x2E09, 0x2E09, prN}, // Pi LEFT TRANSPOSITION BRACKET
+ {0x2E0A, 0x2E0A, prN}, // Pf RIGHT TRANSPOSITION BRACKET
+ {0x2E0B, 0x2E0B, prN}, // Po RAISED SQUARE
+ {0x2E0C, 0x2E0C, prN}, // Pi LEFT RAISED OMISSION BRACKET
+ {0x2E0D, 0x2E0D, prN}, // Pf RIGHT RAISED OMISSION BRACKET
+ {0x2E0E, 0x2E16, prN}, // Po [9] EDITORIAL CORONIS..DOTTED RIGHT-POINTING ANGLE
+ {0x2E17, 0x2E17, prN}, // Pd DOUBLE OBLIQUE HYPHEN
+ {0x2E18, 0x2E19, prN}, // Po [2] INVERTED INTERROBANG..PALM BRANCH
+ {0x2E1A, 0x2E1A, prN}, // Pd HYPHEN WITH DIAERESIS
+ {0x2E1B, 0x2E1B, prN}, // Po TILDE WITH RING ABOVE
+ {0x2E1C, 0x2E1C, prN}, // Pi LEFT LOW PARAPHRASE BRACKET
+ {0x2E1D, 0x2E1D, prN}, // Pf RIGHT LOW PARAPHRASE BRACKET
+ {0x2E1E, 0x2E1F, prN}, // Po [2] TILDE WITH DOT ABOVE..TILDE WITH DOT BELOW
+ {0x2E20, 0x2E20, prN}, // Pi LEFT VERTICAL BAR WITH QUILL
+ {0x2E21, 0x2E21, prN}, // Pf RIGHT VERTICAL BAR WITH QUILL
+ {0x2E22, 0x2E22, prN}, // Ps TOP LEFT HALF BRACKET
+ {0x2E23, 0x2E23, prN}, // Pe TOP RIGHT HALF BRACKET
+ {0x2E24, 0x2E24, prN}, // Ps BOTTOM LEFT HALF BRACKET
+ {0x2E25, 0x2E25, prN}, // Pe BOTTOM RIGHT HALF BRACKET
+ {0x2E26, 0x2E26, prN}, // Ps LEFT SIDEWAYS U BRACKET
+ {0x2E27, 0x2E27, prN}, // Pe RIGHT SIDEWAYS U BRACKET
+ {0x2E28, 0x2E28, prN}, // Ps LEFT DOUBLE PARENTHESIS
+ {0x2E29, 0x2E29, prN}, // Pe RIGHT DOUBLE PARENTHESIS
+ {0x2E2A, 0x2E2E, prN}, // Po [5] TWO DOTS OVER ONE DOT PUNCTUATION..REVERSED QUESTION MARK
+ {0x2E2F, 0x2E2F, prN}, // Lm VERTICAL TILDE
+ {0x2E30, 0x2E39, prN}, // Po [10] RING POINT..TOP HALF SECTION SIGN
+ {0x2E3A, 0x2E3B, prN}, // Pd [2] TWO-EM DASH..THREE-EM DASH
+ {0x2E3C, 0x2E3F, prN}, // Po [4] STENOGRAPHIC FULL STOP..CAPITULUM
+ {0x2E40, 0x2E40, prN}, // Pd DOUBLE HYPHEN
+ {0x2E41, 0x2E41, prN}, // Po REVERSED COMMA
+ {0x2E42, 0x2E42, prN}, // Ps DOUBLE LOW-REVERSED-9 QUOTATION MARK
+ {0x2E43, 0x2E4F, prN}, // Po [13] DASH WITH LEFT UPTURN..CORNISH VERSE DIVIDER
+ {0x2E50, 0x2E51, prN}, // So [2] CROSS PATTY WITH RIGHT CROSSBAR..CROSS PATTY WITH LEFT CROSSBAR
+ {0x2E52, 0x2E54, prN}, // Po [3] TIRONIAN SIGN CAPITAL ET..MEDIEVAL QUESTION MARK
+ {0x2E55, 0x2E55, prN}, // Ps LEFT SQUARE BRACKET WITH STROKE
+ {0x2E56, 0x2E56, prN}, // Pe RIGHT SQUARE BRACKET WITH STROKE
+ {0x2E57, 0x2E57, prN}, // Ps LEFT SQUARE BRACKET WITH DOUBLE STROKE
+ {0x2E58, 0x2E58, prN}, // Pe RIGHT SQUARE BRACKET WITH DOUBLE STROKE
+ {0x2E59, 0x2E59, prN}, // Ps TOP HALF LEFT PARENTHESIS
+ {0x2E5A, 0x2E5A, prN}, // Pe TOP HALF RIGHT PARENTHESIS
+ {0x2E5B, 0x2E5B, prN}, // Ps BOTTOM HALF LEFT PARENTHESIS
+ {0x2E5C, 0x2E5C, prN}, // Pe BOTTOM HALF RIGHT PARENTHESIS
+ {0x2E5D, 0x2E5D, prN}, // Pd OBLIQUE HYPHEN
+ {0x2E80, 0x2E99, prW}, // So [26] CJK RADICAL REPEAT..CJK RADICAL RAP
+ {0x2E9B, 0x2EF3, prW}, // So [89] CJK RADICAL CHOKE..CJK RADICAL C-SIMPLIFIED TURTLE
+ {0x2F00, 0x2FD5, prW}, // So [214] KANGXI RADICAL ONE..KANGXI RADICAL FLUTE
+ {0x2FF0, 0x2FFB, prW}, // So [12] IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT..IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID
+ {0x3000, 0x3000, prF}, // Zs IDEOGRAPHIC SPACE
+ {0x3001, 0x3003, prW}, // Po [3] IDEOGRAPHIC COMMA..DITTO MARK
+ {0x3004, 0x3004, prW}, // So JAPANESE INDUSTRIAL STANDARD SYMBOL
+ {0x3005, 0x3005, prW}, // Lm IDEOGRAPHIC ITERATION MARK
+ {0x3006, 0x3006, prW}, // Lo IDEOGRAPHIC CLOSING MARK
+ {0x3007, 0x3007, prW}, // Nl IDEOGRAPHIC NUMBER ZERO
+ {0x3008, 0x3008, prW}, // Ps LEFT ANGLE BRACKET
+ {0x3009, 0x3009, prW}, // Pe RIGHT ANGLE BRACKET
+ {0x300A, 0x300A, prW}, // Ps LEFT DOUBLE ANGLE BRACKET
+ {0x300B, 0x300B, prW}, // Pe RIGHT DOUBLE ANGLE BRACKET
+ {0x300C, 0x300C, prW}, // Ps LEFT CORNER BRACKET
+ {0x300D, 0x300D, prW}, // Pe RIGHT CORNER BRACKET
+ {0x300E, 0x300E, prW}, // Ps LEFT WHITE CORNER BRACKET
+ {0x300F, 0x300F, prW}, // Pe RIGHT WHITE CORNER BRACKET
+ {0x3010, 0x3010, prW}, // Ps LEFT BLACK LENTICULAR BRACKET
+ {0x3011, 0x3011, prW}, // Pe RIGHT BLACK LENTICULAR BRACKET
+ {0x3012, 0x3013, prW}, // So [2] POSTAL MARK..GETA MARK
+ {0x3014, 0x3014, prW}, // Ps LEFT TORTOISE SHELL BRACKET
+ {0x3015, 0x3015, prW}, // Pe RIGHT TORTOISE SHELL BRACKET
+ {0x3016, 0x3016, prW}, // Ps LEFT WHITE LENTICULAR BRACKET
+ {0x3017, 0x3017, prW}, // Pe RIGHT WHITE LENTICULAR BRACKET
+ {0x3018, 0x3018, prW}, // Ps LEFT WHITE TORTOISE SHELL BRACKET
+ {0x3019, 0x3019, prW}, // Pe RIGHT WHITE TORTOISE SHELL BRACKET
+ {0x301A, 0x301A, prW}, // Ps LEFT WHITE SQUARE BRACKET
+ {0x301B, 0x301B, prW}, // Pe RIGHT WHITE SQUARE BRACKET
+ {0x301C, 0x301C, prW}, // Pd WAVE DASH
+ {0x301D, 0x301D, prW}, // Ps REVERSED DOUBLE PRIME QUOTATION MARK
+ {0x301E, 0x301F, prW}, // Pe [2] DOUBLE PRIME QUOTATION MARK..LOW DOUBLE PRIME QUOTATION MARK
+ {0x3020, 0x3020, prW}, // So POSTAL MARK FACE
+ {0x3021, 0x3029, prW}, // Nl [9] HANGZHOU NUMERAL ONE..HANGZHOU NUMERAL NINE
+ {0x302A, 0x302D, prW}, // Mn [4] IDEOGRAPHIC LEVEL TONE MARK..IDEOGRAPHIC ENTERING TONE MARK
+ {0x302E, 0x302F, prW}, // Mc [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK
+ {0x3030, 0x3030, prW}, // Pd WAVY DASH
+ {0x3031, 0x3035, prW}, // Lm [5] VERTICAL KANA REPEAT MARK..VERTICAL KANA REPEAT MARK LOWER HALF
+ {0x3036, 0x3037, prW}, // So [2] CIRCLED POSTAL MARK..IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL
+ {0x3038, 0x303A, prW}, // Nl [3] HANGZHOU NUMERAL TEN..HANGZHOU NUMERAL THIRTY
+ {0x303B, 0x303B, prW}, // Lm VERTICAL IDEOGRAPHIC ITERATION MARK
+ {0x303C, 0x303C, prW}, // Lo MASU MARK
+ {0x303D, 0x303D, prW}, // Po PART ALTERNATION MARK
+ {0x303E, 0x303E, prW}, // So IDEOGRAPHIC VARIATION INDICATOR
+ {0x303F, 0x303F, prN}, // So IDEOGRAPHIC HALF FILL SPACE
+ {0x3041, 0x3096, prW}, // Lo [86] HIRAGANA LETTER SMALL A..HIRAGANA LETTER SMALL KE
+ {0x3099, 0x309A, prW}, // Mn [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+ {0x309B, 0x309C, prW}, // Sk [2] KATAKANA-HIRAGANA VOICED SOUND MARK..KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+ {0x309D, 0x309E, prW}, // Lm [2] HIRAGANA ITERATION MARK..HIRAGANA VOICED ITERATION MARK
+ {0x309F, 0x309F, prW}, // Lo HIRAGANA DIGRAPH YORI
+ {0x30A0, 0x30A0, prW}, // Pd KATAKANA-HIRAGANA DOUBLE HYPHEN
+ {0x30A1, 0x30FA, prW}, // Lo [90] KATAKANA LETTER SMALL A..KATAKANA LETTER VO
+ {0x30FB, 0x30FB, prW}, // Po KATAKANA MIDDLE DOT
+ {0x30FC, 0x30FE, prW}, // Lm [3] KATAKANA-HIRAGANA PROLONGED SOUND MARK..KATAKANA VOICED ITERATION MARK
+ {0x30FF, 0x30FF, prW}, // Lo KATAKANA DIGRAPH KOTO
+ {0x3105, 0x312F, prW}, // Lo [43] BOPOMOFO LETTER B..BOPOMOFO LETTER NN
+ {0x3131, 0x318E, prW}, // Lo [94] HANGUL LETTER KIYEOK..HANGUL LETTER ARAEAE
+ {0x3190, 0x3191, prW}, // So [2] IDEOGRAPHIC ANNOTATION LINKING MARK..IDEOGRAPHIC ANNOTATION REVERSE MARK
+ {0x3192, 0x3195, prW}, // No [4] IDEOGRAPHIC ANNOTATION ONE MARK..IDEOGRAPHIC ANNOTATION FOUR MARK
+ {0x3196, 0x319F, prW}, // So [10] IDEOGRAPHIC ANNOTATION TOP MARK..IDEOGRAPHIC ANNOTATION MAN MARK
+ {0x31A0, 0x31BF, prW}, // Lo [32] BOPOMOFO LETTER BU..BOPOMOFO LETTER AH
+ {0x31C0, 0x31E3, prW}, // So [36] CJK STROKE T..CJK STROKE Q
+ {0x31F0, 0x31FF, prW}, // Lo [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO
+ {0x3200, 0x321E, prW}, // So [31] PARENTHESIZED HANGUL KIYEOK..PARENTHESIZED KOREAN CHARACTER O HU
+ {0x3220, 0x3229, prW}, // No [10] PARENTHESIZED IDEOGRAPH ONE..PARENTHESIZED IDEOGRAPH TEN
+ {0x322A, 0x3247, prW}, // So [30] PARENTHESIZED IDEOGRAPH MOON..CIRCLED IDEOGRAPH KOTO
+ {0x3248, 0x324F, prA}, // No [8] CIRCLED NUMBER TEN ON BLACK SQUARE..CIRCLED NUMBER EIGHTY ON BLACK SQUARE
+ {0x3250, 0x3250, prW}, // So PARTNERSHIP SIGN
+ {0x3251, 0x325F, prW}, // No [15] CIRCLED NUMBER TWENTY ONE..CIRCLED NUMBER THIRTY FIVE
+ {0x3260, 0x327F, prW}, // So [32] CIRCLED HANGUL KIYEOK..KOREAN STANDARD SYMBOL
+ {0x3280, 0x3289, prW}, // No [10] CIRCLED IDEOGRAPH ONE..CIRCLED IDEOGRAPH TEN
+ {0x328A, 0x32B0, prW}, // So [39] CIRCLED IDEOGRAPH MOON..CIRCLED IDEOGRAPH NIGHT
+ {0x32B1, 0x32BF, prW}, // No [15] CIRCLED NUMBER THIRTY SIX..CIRCLED NUMBER FIFTY
+ {0x32C0, 0x32FF, prW}, // So [64] IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY..SQUARE ERA NAME REIWA
+ {0x3300, 0x33FF, prW}, // So [256] SQUARE APAATO..SQUARE GAL
+ {0x3400, 0x4DBF, prW}, // Lo [6592] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DBF
+ {0x4DC0, 0x4DFF, prN}, // So [64] HEXAGRAM FOR THE CREATIVE HEAVEN..HEXAGRAM FOR BEFORE COMPLETION
+ {0x4E00, 0x9FFF, prW}, // Lo [20992] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FFF
+ {0xA000, 0xA014, prW}, // Lo [21] YI SYLLABLE IT..YI SYLLABLE E
+ {0xA015, 0xA015, prW}, // Lm YI SYLLABLE WU
+ {0xA016, 0xA48C, prW}, // Lo [1143] YI SYLLABLE BIT..YI SYLLABLE YYR
+ {0xA490, 0xA4C6, prW}, // So [55] YI RADICAL QOT..YI RADICAL KE
+ {0xA4D0, 0xA4F7, prN}, // Lo [40] LISU LETTER BA..LISU LETTER OE
+ {0xA4F8, 0xA4FD, prN}, // Lm [6] LISU LETTER TONE MYA TI..LISU LETTER TONE MYA JEU
+ {0xA4FE, 0xA4FF, prN}, // Po [2] LISU PUNCTUATION COMMA..LISU PUNCTUATION FULL STOP
+ {0xA500, 0xA60B, prN}, // Lo [268] VAI SYLLABLE EE..VAI SYLLABLE NG
+ {0xA60C, 0xA60C, prN}, // Lm VAI SYLLABLE LENGTHENER
+ {0xA60D, 0xA60F, prN}, // Po [3] VAI COMMA..VAI QUESTION MARK
+ {0xA610, 0xA61F, prN}, // Lo [16] VAI SYLLABLE NDOLE FA..VAI SYMBOL JONG
+ {0xA620, 0xA629, prN}, // Nd [10] VAI DIGIT ZERO..VAI DIGIT NINE
+ {0xA62A, 0xA62B, prN}, // Lo [2] VAI SYLLABLE NDOLE MA..VAI SYLLABLE NDOLE DO
+ {0xA640, 0xA66D, prN}, // L& [46] CYRILLIC CAPITAL LETTER ZEMLYA..CYRILLIC SMALL LETTER DOUBLE MONOCULAR O
+ {0xA66E, 0xA66E, prN}, // Lo CYRILLIC LETTER MULTIOCULAR O
+ {0xA66F, 0xA66F, prN}, // Mn COMBINING CYRILLIC VZMET
+ {0xA670, 0xA672, prN}, // Me [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN
+ {0xA673, 0xA673, prN}, // Po SLAVONIC ASTERISK
+ {0xA674, 0xA67D, prN}, // Mn [10] COMBINING CYRILLIC LETTER UKRAINIAN IE..COMBINING CYRILLIC PAYEROK
+ {0xA67E, 0xA67E, prN}, // Po CYRILLIC KAVYKA
+ {0xA67F, 0xA67F, prN}, // Lm CYRILLIC PAYEROK
+ {0xA680, 0xA69B, prN}, // L& [28] CYRILLIC CAPITAL LETTER DWE..CYRILLIC SMALL LETTER CROSSED O
+ {0xA69C, 0xA69D, prN}, // Lm [2] MODIFIER LETTER CYRILLIC HARD SIGN..MODIFIER LETTER CYRILLIC SOFT SIGN
+ {0xA69E, 0xA69F, prN}, // Mn [2] COMBINING CYRILLIC LETTER EF..COMBINING CYRILLIC LETTER IOTIFIED E
+ {0xA6A0, 0xA6E5, prN}, // Lo [70] BAMUM LETTER A..BAMUM LETTER KI
+ {0xA6E6, 0xA6EF, prN}, // Nl [10] BAMUM LETTER MO..BAMUM LETTER KOGHOM
+ {0xA6F0, 0xA6F1, prN}, // Mn [2] BAMUM COMBINING MARK KOQNDON..BAMUM COMBINING MARK TUKWENTIS
+ {0xA6F2, 0xA6F7, prN}, // Po [6] BAMUM NJAEMLI..BAMUM QUESTION MARK
+ {0xA700, 0xA716, prN}, // Sk [23] MODIFIER LETTER CHINESE TONE YIN PING..MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR
+ {0xA717, 0xA71F, prN}, // Lm [9] MODIFIER LETTER DOT VERTICAL BAR..MODIFIER LETTER LOW INVERTED EXCLAMATION MARK
+ {0xA720, 0xA721, prN}, // Sk [2] MODIFIER LETTER STRESS AND HIGH TONE..MODIFIER LETTER STRESS AND LOW TONE
+ {0xA722, 0xA76F, prN}, // L& [78] LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF..LATIN SMALL LETTER CON
+ {0xA770, 0xA770, prN}, // Lm MODIFIER LETTER US
+ {0xA771, 0xA787, prN}, // L& [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER INSULAR T
+ {0xA788, 0xA788, prN}, // Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT
+ {0xA789, 0xA78A, prN}, // Sk [2] MODIFIER LETTER COLON..MODIFIER LETTER SHORT EQUALS SIGN
+ {0xA78B, 0xA78E, prN}, // L& [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT
+ {0xA78F, 0xA78F, prN}, // Lo LATIN LETTER SINOLOGICAL DOT
+ {0xA790, 0xA7CA, prN}, // L& [59] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY
+ {0xA7D0, 0xA7D1, prN}, // L& [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G
+ {0xA7D3, 0xA7D3, prN}, // Ll LATIN SMALL LETTER DOUBLE THORN
+ {0xA7D5, 0xA7D9, prN}, // L& [5] LATIN SMALL LETTER DOUBLE WYNN..LATIN SMALL LETTER SIGMOID S
+ {0xA7F2, 0xA7F4, prN}, // Lm [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q
+ {0xA7F5, 0xA7F6, prN}, // L& [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H
+ {0xA7F7, 0xA7F7, prN}, // Lo LATIN EPIGRAPHIC LETTER SIDEWAYS I
+ {0xA7F8, 0xA7F9, prN}, // Lm [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE
+ {0xA7FA, 0xA7FA, prN}, // Ll LATIN LETTER SMALL CAPITAL TURNED M
+ {0xA7FB, 0xA7FF, prN}, // Lo [5] LATIN EPIGRAPHIC LETTER REVERSED F..LATIN EPIGRAPHIC LETTER ARCHAIC M
+ {0xA800, 0xA801, prN}, // Lo [2] SYLOTI NAGRI LETTER A..SYLOTI NAGRI LETTER I
+ {0xA802, 0xA802, prN}, // Mn SYLOTI NAGRI SIGN DVISVARA
+ {0xA803, 0xA805, prN}, // Lo [3] SYLOTI NAGRI LETTER U..SYLOTI NAGRI LETTER O
+ {0xA806, 0xA806, prN}, // Mn SYLOTI NAGRI SIGN HASANTA
+ {0xA807, 0xA80A, prN}, // Lo [4] SYLOTI NAGRI LETTER KO..SYLOTI NAGRI LETTER GHO
+ {0xA80B, 0xA80B, prN}, // Mn SYLOTI NAGRI SIGN ANUSVARA
+ {0xA80C, 0xA822, prN}, // Lo [23] SYLOTI NAGRI LETTER CO..SYLOTI NAGRI LETTER HO
+ {0xA823, 0xA824, prN}, // Mc [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I
+ {0xA825, 0xA826, prN}, // Mn [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E
+ {0xA827, 0xA827, prN}, // Mc SYLOTI NAGRI VOWEL SIGN OO
+ {0xA828, 0xA82B, prN}, // So [4] SYLOTI NAGRI POETRY MARK-1..SYLOTI NAGRI POETRY MARK-4
+ {0xA82C, 0xA82C, prN}, // Mn SYLOTI NAGRI SIGN ALTERNATE HASANTA
+ {0xA830, 0xA835, prN}, // No [6] NORTH INDIC FRACTION ONE QUARTER..NORTH INDIC FRACTION THREE SIXTEENTHS
+ {0xA836, 0xA837, prN}, // So [2] NORTH INDIC QUARTER MARK..NORTH INDIC PLACEHOLDER MARK
+ {0xA838, 0xA838, prN}, // Sc NORTH INDIC RUPEE MARK
+ {0xA839, 0xA839, prN}, // So NORTH INDIC QUANTITY MARK
+ {0xA840, 0xA873, prN}, // Lo [52] PHAGS-PA LETTER KA..PHAGS-PA LETTER CANDRABINDU
+ {0xA874, 0xA877, prN}, // Po [4] PHAGS-PA SINGLE HEAD MARK..PHAGS-PA MARK DOUBLE SHAD
+ {0xA880, 0xA881, prN}, // Mc [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA
+ {0xA882, 0xA8B3, prN}, // Lo [50] SAURASHTRA LETTER A..SAURASHTRA LETTER LLA
+ {0xA8B4, 0xA8C3, prN}, // Mc [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU
+ {0xA8C4, 0xA8C5, prN}, // Mn [2] SAURASHTRA SIGN VIRAMA..SAURASHTRA SIGN CANDRABINDU
+ {0xA8CE, 0xA8CF, prN}, // Po [2] SAURASHTRA DANDA..SAURASHTRA DOUBLE DANDA
+ {0xA8D0, 0xA8D9, prN}, // Nd [10] SAURASHTRA DIGIT ZERO..SAURASHTRA DIGIT NINE
+ {0xA8E0, 0xA8F1, prN}, // Mn [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA
+ {0xA8F2, 0xA8F7, prN}, // Lo [6] DEVANAGARI SIGN SPACING CANDRABINDU..DEVANAGARI SIGN CANDRABINDU AVAGRAHA
+ {0xA8F8, 0xA8FA, prN}, // Po [3] DEVANAGARI SIGN PUSHPIKA..DEVANAGARI CARET
+ {0xA8FB, 0xA8FB, prN}, // Lo DEVANAGARI HEADSTROKE
+ {0xA8FC, 0xA8FC, prN}, // Po DEVANAGARI SIGN SIDDHAM
+ {0xA8FD, 0xA8FE, prN}, // Lo [2] DEVANAGARI JAIN OM..DEVANAGARI LETTER AY
+ {0xA8FF, 0xA8FF, prN}, // Mn DEVANAGARI VOWEL SIGN AY
+ {0xA900, 0xA909, prN}, // Nd [10] KAYAH LI DIGIT ZERO..KAYAH LI DIGIT NINE
+ {0xA90A, 0xA925, prN}, // Lo [28] KAYAH LI LETTER KA..KAYAH LI LETTER OO
+ {0xA926, 0xA92D, prN}, // Mn [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU
+ {0xA92E, 0xA92F, prN}, // Po [2] KAYAH LI SIGN CWI..KAYAH LI SIGN SHYA
+ {0xA930, 0xA946, prN}, // Lo [23] REJANG LETTER KA..REJANG LETTER A
+ {0xA947, 0xA951, prN}, // Mn [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R
+ {0xA952, 0xA953, prN}, // Mc [2] REJANG CONSONANT SIGN H..REJANG VIRAMA
+ {0xA95F, 0xA95F, prN}, // Po REJANG SECTION MARK
+ {0xA960, 0xA97C, prW}, // Lo [29] HANGUL CHOSEONG TIKEUT-MIEUM..HANGUL CHOSEONG SSANGYEORINHIEUH
+ {0xA980, 0xA982, prN}, // Mn [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR
+ {0xA983, 0xA983, prN}, // Mc JAVANESE SIGN WIGNYAN
+ {0xA984, 0xA9B2, prN}, // Lo [47] JAVANESE LETTER A..JAVANESE LETTER HA
+ {0xA9B3, 0xA9B3, prN}, // Mn JAVANESE SIGN CECAK TELU
+ {0xA9B4, 0xA9B5, prN}, // Mc [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG
+ {0xA9B6, 0xA9B9, prN}, // Mn [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT
+ {0xA9BA, 0xA9BB, prN}, // Mc [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE
+ {0xA9BC, 0xA9BD, prN}, // Mn [2] JAVANESE VOWEL SIGN PEPET..JAVANESE CONSONANT SIGN KERET
+ {0xA9BE, 0xA9C0, prN}, // Mc [3] JAVANESE CONSONANT SIGN PENGKAL..JAVANESE PANGKON
+ {0xA9C1, 0xA9CD, prN}, // Po [13] JAVANESE LEFT RERENGGAN..JAVANESE TURNED PADA PISELEH
+ {0xA9CF, 0xA9CF, prN}, // Lm JAVANESE PANGRANGKEP
+ {0xA9D0, 0xA9D9, prN}, // Nd [10] JAVANESE DIGIT ZERO..JAVANESE DIGIT NINE
+ {0xA9DE, 0xA9DF, prN}, // Po [2] JAVANESE PADA TIRTA TUMETES..JAVANESE PADA ISEN-ISEN
+ {0xA9E0, 0xA9E4, prN}, // Lo [5] MYANMAR LETTER SHAN GHA..MYANMAR LETTER SHAN BHA
+ {0xA9E5, 0xA9E5, prN}, // Mn MYANMAR SIGN SHAN SAW
+ {0xA9E6, 0xA9E6, prN}, // Lm MYANMAR MODIFIER LETTER SHAN REDUPLICATION
+ {0xA9E7, 0xA9EF, prN}, // Lo [9] MYANMAR LETTER TAI LAING NYA..MYANMAR LETTER TAI LAING NNA
+ {0xA9F0, 0xA9F9, prN}, // Nd [10] MYANMAR TAI LAING DIGIT ZERO..MYANMAR TAI LAING DIGIT NINE
+ {0xA9FA, 0xA9FE, prN}, // Lo [5] MYANMAR LETTER TAI LAING LLA..MYANMAR LETTER TAI LAING BHA
+ {0xAA00, 0xAA28, prN}, // Lo [41] CHAM LETTER A..CHAM LETTER HA
+ {0xAA29, 0xAA2E, prN}, // Mn [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE
+ {0xAA2F, 0xAA30, prN}, // Mc [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI
+ {0xAA31, 0xAA32, prN}, // Mn [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE
+ {0xAA33, 0xAA34, prN}, // Mc [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA
+ {0xAA35, 0xAA36, prN}, // Mn [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA
+ {0xAA40, 0xAA42, prN}, // Lo [3] CHAM LETTER FINAL K..CHAM LETTER FINAL NG
+ {0xAA43, 0xAA43, prN}, // Mn CHAM CONSONANT SIGN FINAL NG
+ {0xAA44, 0xAA4B, prN}, // Lo [8] CHAM LETTER FINAL CH..CHAM LETTER FINAL SS
+ {0xAA4C, 0xAA4C, prN}, // Mn CHAM CONSONANT SIGN FINAL M
+ {0xAA4D, 0xAA4D, prN}, // Mc CHAM CONSONANT SIGN FINAL H
+ {0xAA50, 0xAA59, prN}, // Nd [10] CHAM DIGIT ZERO..CHAM DIGIT NINE
+ {0xAA5C, 0xAA5F, prN}, // Po [4] CHAM PUNCTUATION SPIRAL..CHAM PUNCTUATION TRIPLE DANDA
+ {0xAA60, 0xAA6F, prN}, // Lo [16] MYANMAR LETTER KHAMTI GA..MYANMAR LETTER KHAMTI FA
+ {0xAA70, 0xAA70, prN}, // Lm MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION
+ {0xAA71, 0xAA76, prN}, // Lo [6] MYANMAR LETTER KHAMTI XA..MYANMAR LOGOGRAM KHAMTI HM
+ {0xAA77, 0xAA79, prN}, // So [3] MYANMAR SYMBOL AITON EXCLAMATION..MYANMAR SYMBOL AITON TWO
+ {0xAA7A, 0xAA7A, prN}, // Lo MYANMAR LETTER AITON RA
+ {0xAA7B, 0xAA7B, prN}, // Mc MYANMAR SIGN PAO KAREN TONE
+ {0xAA7C, 0xAA7C, prN}, // Mn MYANMAR SIGN TAI LAING TONE-2
+ {0xAA7D, 0xAA7D, prN}, // Mc MYANMAR SIGN TAI LAING TONE-5
+ {0xAA7E, 0xAA7F, prN}, // Lo [2] MYANMAR LETTER SHWE PALAUNG CHA..MYANMAR LETTER SHWE PALAUNG SHA
+ {0xAA80, 0xAAAF, prN}, // Lo [48] TAI VIET LETTER LOW KO..TAI VIET LETTER HIGH O
+ {0xAAB0, 0xAAB0, prN}, // Mn TAI VIET MAI KANG
+ {0xAAB1, 0xAAB1, prN}, // Lo TAI VIET VOWEL AA
+ {0xAAB2, 0xAAB4, prN}, // Mn [3] TAI VIET VOWEL I..TAI VIET VOWEL U
+ {0xAAB5, 0xAAB6, prN}, // Lo [2] TAI VIET VOWEL E..TAI VIET VOWEL O
+ {0xAAB7, 0xAAB8, prN}, // Mn [2] TAI VIET MAI KHIT..TAI VIET VOWEL IA
+ {0xAAB9, 0xAABD, prN}, // Lo [5] TAI VIET VOWEL UEA..TAI VIET VOWEL AN
+ {0xAABE, 0xAABF, prN}, // Mn [2] TAI VIET VOWEL AM..TAI VIET TONE MAI EK
+ {0xAAC0, 0xAAC0, prN}, // Lo TAI VIET TONE MAI NUENG
+ {0xAAC1, 0xAAC1, prN}, // Mn TAI VIET TONE MAI THO
+ {0xAAC2, 0xAAC2, prN}, // Lo TAI VIET TONE MAI SONG
+ {0xAADB, 0xAADC, prN}, // Lo [2] TAI VIET SYMBOL KON..TAI VIET SYMBOL NUENG
+ {0xAADD, 0xAADD, prN}, // Lm TAI VIET SYMBOL SAM
+ {0xAADE, 0xAADF, prN}, // Po [2] TAI VIET SYMBOL HO HOI..TAI VIET SYMBOL KOI KOI
+ {0xAAE0, 0xAAEA, prN}, // Lo [11] MEETEI MAYEK LETTER E..MEETEI MAYEK LETTER SSA
+ {0xAAEB, 0xAAEB, prN}, // Mc MEETEI MAYEK VOWEL SIGN II
+ {0xAAEC, 0xAAED, prN}, // Mn [2] MEETEI MAYEK VOWEL SIGN UU..MEETEI MAYEK VOWEL SIGN AAI
+ {0xAAEE, 0xAAEF, prN}, // Mc [2] MEETEI MAYEK VOWEL SIGN AU..MEETEI MAYEK VOWEL SIGN AAU
+ {0xAAF0, 0xAAF1, prN}, // Po [2] MEETEI MAYEK CHEIKHAN..MEETEI MAYEK AHANG KHUDAM
+ {0xAAF2, 0xAAF2, prN}, // Lo MEETEI MAYEK ANJI
+ {0xAAF3, 0xAAF4, prN}, // Lm [2] MEETEI MAYEK SYLLABLE REPETITION MARK..MEETEI MAYEK WORD REPETITION MARK
+ {0xAAF5, 0xAAF5, prN}, // Mc MEETEI MAYEK VOWEL SIGN VISARGA
+ {0xAAF6, 0xAAF6, prN}, // Mn MEETEI MAYEK VIRAMA
+ {0xAB01, 0xAB06, prN}, // Lo [6] ETHIOPIC SYLLABLE TTHU..ETHIOPIC SYLLABLE TTHO
+ {0xAB09, 0xAB0E, prN}, // Lo [6] ETHIOPIC SYLLABLE DDHU..ETHIOPIC SYLLABLE DDHO
+ {0xAB11, 0xAB16, prN}, // Lo [6] ETHIOPIC SYLLABLE DZU..ETHIOPIC SYLLABLE DZO
+ {0xAB20, 0xAB26, prN}, // Lo [7] ETHIOPIC SYLLABLE CCHHA..ETHIOPIC SYLLABLE CCHHO
+ {0xAB28, 0xAB2E, prN}, // Lo [7] ETHIOPIC SYLLABLE BBA..ETHIOPIC SYLLABLE BBO
+ {0xAB30, 0xAB5A, prN}, // Ll [43] LATIN SMALL LETTER BARRED ALPHA..LATIN SMALL LETTER Y WITH SHORT RIGHT LEG
+ {0xAB5B, 0xAB5B, prN}, // Sk MODIFIER BREVE WITH INVERTED BREVE
+ {0xAB5C, 0xAB5F, prN}, // Lm [4] MODIFIER LETTER SMALL HENG..MODIFIER LETTER SMALL U WITH LEFT HOOK
+ {0xAB60, 0xAB68, prN}, // Ll [9] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TURNED R WITH MIDDLE TILDE
+ {0xAB69, 0xAB69, prN}, // Lm MODIFIER LETTER SMALL TURNED W
+ {0xAB6A, 0xAB6B, prN}, // Sk [2] MODIFIER LETTER LEFT TACK..MODIFIER LETTER RIGHT TACK
+ {0xAB70, 0xABBF, prN}, // Ll [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA
+ {0xABC0, 0xABE2, prN}, // Lo [35] MEETEI MAYEK LETTER KOK..MEETEI MAYEK LETTER I LONSUM
+ {0xABE3, 0xABE4, prN}, // Mc [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP
+ {0xABE5, 0xABE5, prN}, // Mn MEETEI MAYEK VOWEL SIGN ANAP
+ {0xABE6, 0xABE7, prN}, // Mc [2] MEETEI MAYEK VOWEL SIGN YENAP..MEETEI MAYEK VOWEL SIGN SOUNAP
+ {0xABE8, 0xABE8, prN}, // Mn MEETEI MAYEK VOWEL SIGN UNAP
+ {0xABE9, 0xABEA, prN}, // Mc [2] MEETEI MAYEK VOWEL SIGN CHEINAP..MEETEI MAYEK VOWEL SIGN NUNG
+ {0xABEB, 0xABEB, prN}, // Po MEETEI MAYEK CHEIKHEI
+ {0xABEC, 0xABEC, prN}, // Mc MEETEI MAYEK LUM IYEK
+ {0xABED, 0xABED, prN}, // Mn MEETEI MAYEK APUN IYEK
+ {0xABF0, 0xABF9, prN}, // Nd [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DIGIT NINE
+ {0xAC00, 0xD7A3, prW}, // Lo [11172] HANGUL SYLLABLE GA..HANGUL SYLLABLE HIH
+ {0xD7B0, 0xD7C6, prN}, // Lo [23] HANGUL JUNGSEONG O-YEO..HANGUL JUNGSEONG ARAEA-E
+ {0xD7CB, 0xD7FB, prN}, // Lo [49] HANGUL JONGSEONG NIEUN-RIEUL..HANGUL JONGSEONG PHIEUPH-THIEUTH
+ {0xD800, 0xDB7F, prN}, // Cs [896] ..
+ {0xDB80, 0xDBFF, prN}, // Cs [128] ..
+ {0xDC00, 0xDFFF, prN}, // Cs [1024] ..
+ {0xE000, 0xF8FF, prA}, // Co [6400] ..
+ {0xF900, 0xFA6D, prW}, // Lo [366] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA6D
+ {0xFA6E, 0xFA6F, prW}, // Cn [2] ..
+ {0xFA70, 0xFAD9, prW}, // Lo [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9
+ {0xFADA, 0xFAFF, prW}, // Cn [38] ..
+ {0xFB00, 0xFB06, prN}, // Ll [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST
+ {0xFB13, 0xFB17, prN}, // Ll [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN SMALL LIGATURE MEN XEH
+ {0xFB1D, 0xFB1D, prN}, // Lo HEBREW LETTER YOD WITH HIRIQ
+ {0xFB1E, 0xFB1E, prN}, // Mn HEBREW POINT JUDEO-SPANISH VARIKA
+ {0xFB1F, 0xFB28, prN}, // Lo [10] HEBREW LIGATURE YIDDISH YOD YOD PATAH..HEBREW LETTER WIDE TAV
+ {0xFB29, 0xFB29, prN}, // Sm HEBREW LETTER ALTERNATIVE PLUS SIGN
+ {0xFB2A, 0xFB36, prN}, // Lo [13] HEBREW LETTER SHIN WITH SHIN DOT..HEBREW LETTER ZAYIN WITH DAGESH
+ {0xFB38, 0xFB3C, prN}, // Lo [5] HEBREW LETTER TET WITH DAGESH..HEBREW LETTER LAMED WITH DAGESH
+ {0xFB3E, 0xFB3E, prN}, // Lo HEBREW LETTER MEM WITH DAGESH
+ {0xFB40, 0xFB41, prN}, // Lo [2] HEBREW LETTER NUN WITH DAGESH..HEBREW LETTER SAMEKH WITH DAGESH
+ {0xFB43, 0xFB44, prN}, // Lo [2] HEBREW LETTER FINAL PE WITH DAGESH..HEBREW LETTER PE WITH DAGESH
+ {0xFB46, 0xFB4F, prN}, // Lo [10] HEBREW LETTER TSADI WITH DAGESH..HEBREW LIGATURE ALEF LAMED
+ {0xFB50, 0xFBB1, prN}, // Lo [98] ARABIC LETTER ALEF WASLA ISOLATED FORM..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM
+ {0xFBB2, 0xFBC2, prN}, // Sk [17] ARABIC SYMBOL DOT ABOVE..ARABIC SYMBOL WASLA ABOVE
+ {0xFBD3, 0xFD3D, prN}, // Lo [363] ARABIC LETTER NG ISOLATED FORM..ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM
+ {0xFD3E, 0xFD3E, prN}, // Pe ORNATE LEFT PARENTHESIS
+ {0xFD3F, 0xFD3F, prN}, // Ps ORNATE RIGHT PARENTHESIS
+ {0xFD40, 0xFD4F, prN}, // So [16] ARABIC LIGATURE RAHIMAHU ALLAAH..ARABIC LIGATURE RAHIMAHUM ALLAAH
+ {0xFD50, 0xFD8F, prN}, // Lo [64] ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM..ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM
+ {0xFD92, 0xFDC7, prN}, // Lo [54] ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM..ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM
+ {0xFDCF, 0xFDCF, prN}, // So ARABIC LIGATURE SALAAMUHU ALAYNAA
+ {0xFDF0, 0xFDFB, prN}, // Lo [12] ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM..ARABIC LIGATURE JALLAJALALOUHOU
+ {0xFDFC, 0xFDFC, prN}, // Sc RIAL SIGN
+ {0xFDFD, 0xFDFF, prN}, // So [3] ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM..ARABIC LIGATURE AZZA WA JALL
+ {0xFE00, 0xFE0F, prA}, // Mn [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16
+ {0xFE10, 0xFE16, prW}, // Po [7] PRESENTATION FORM FOR VERTICAL COMMA..PRESENTATION FORM FOR VERTICAL QUESTION MARK
+ {0xFE17, 0xFE17, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET
+ {0xFE18, 0xFE18, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET
+ {0xFE19, 0xFE19, prW}, // Po PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS
+ {0xFE20, 0xFE2F, prN}, // Mn [16] COMBINING LIGATURE LEFT HALF..COMBINING CYRILLIC TITLO RIGHT HALF
+ {0xFE30, 0xFE30, prW}, // Po PRESENTATION FORM FOR VERTICAL TWO DOT LEADER
+ {0xFE31, 0xFE32, prW}, // Pd [2] PRESENTATION FORM FOR VERTICAL EM DASH..PRESENTATION FORM FOR VERTICAL EN DASH
+ {0xFE33, 0xFE34, prW}, // Pc [2] PRESENTATION FORM FOR VERTICAL LOW LINE..PRESENTATION FORM FOR VERTICAL WAVY LOW LINE
+ {0xFE35, 0xFE35, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS
+ {0xFE36, 0xFE36, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS
+ {0xFE37, 0xFE37, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET
+ {0xFE38, 0xFE38, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET
+ {0xFE39, 0xFE39, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET
+ {0xFE3A, 0xFE3A, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET
+ {0xFE3B, 0xFE3B, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET
+ {0xFE3C, 0xFE3C, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET
+ {0xFE3D, 0xFE3D, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET
+ {0xFE3E, 0xFE3E, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET
+ {0xFE3F, 0xFE3F, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET
+ {0xFE40, 0xFE40, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET
+ {0xFE41, 0xFE41, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET
+ {0xFE42, 0xFE42, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET
+ {0xFE43, 0xFE43, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET
+ {0xFE44, 0xFE44, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET
+ {0xFE45, 0xFE46, prW}, // Po [2] SESAME DOT..WHITE SESAME DOT
+ {0xFE47, 0xFE47, prW}, // Ps PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET
+ {0xFE48, 0xFE48, prW}, // Pe PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET
+ {0xFE49, 0xFE4C, prW}, // Po [4] DASHED OVERLINE..DOUBLE WAVY OVERLINE
+ {0xFE4D, 0xFE4F, prW}, // Pc [3] DASHED LOW LINE..WAVY LOW LINE
+ {0xFE50, 0xFE52, prW}, // Po [3] SMALL COMMA..SMALL FULL STOP
+ {0xFE54, 0xFE57, prW}, // Po [4] SMALL SEMICOLON..SMALL EXCLAMATION MARK
+ {0xFE58, 0xFE58, prW}, // Pd SMALL EM DASH
+ {0xFE59, 0xFE59, prW}, // Ps SMALL LEFT PARENTHESIS
+ {0xFE5A, 0xFE5A, prW}, // Pe SMALL RIGHT PARENTHESIS
+ {0xFE5B, 0xFE5B, prW}, // Ps SMALL LEFT CURLY BRACKET
+ {0xFE5C, 0xFE5C, prW}, // Pe SMALL RIGHT CURLY BRACKET
+ {0xFE5D, 0xFE5D, prW}, // Ps SMALL LEFT TORTOISE SHELL BRACKET
+ {0xFE5E, 0xFE5E, prW}, // Pe SMALL RIGHT TORTOISE SHELL BRACKET
+ {0xFE5F, 0xFE61, prW}, // Po [3] SMALL NUMBER SIGN..SMALL ASTERISK
+ {0xFE62, 0xFE62, prW}, // Sm SMALL PLUS SIGN
+ {0xFE63, 0xFE63, prW}, // Pd SMALL HYPHEN-MINUS
+ {0xFE64, 0xFE66, prW}, // Sm [3] SMALL LESS-THAN SIGN..SMALL EQUALS SIGN
+ {0xFE68, 0xFE68, prW}, // Po SMALL REVERSE SOLIDUS
+ {0xFE69, 0xFE69, prW}, // Sc SMALL DOLLAR SIGN
+ {0xFE6A, 0xFE6B, prW}, // Po [2] SMALL PERCENT SIGN..SMALL COMMERCIAL AT
+ {0xFE70, 0xFE74, prN}, // Lo [5] ARABIC FATHATAN ISOLATED FORM..ARABIC KASRATAN ISOLATED FORM
+ {0xFE76, 0xFEFC, prN}, // Lo [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LAM WITH ALEF FINAL FORM
+ {0xFEFF, 0xFEFF, prN}, // Cf ZERO WIDTH NO-BREAK SPACE
+ {0xFF01, 0xFF03, prF}, // Po [3] FULLWIDTH EXCLAMATION MARK..FULLWIDTH NUMBER SIGN
+ {0xFF04, 0xFF04, prF}, // Sc FULLWIDTH DOLLAR SIGN
+ {0xFF05, 0xFF07, prF}, // Po [3] FULLWIDTH PERCENT SIGN..FULLWIDTH APOSTROPHE
+ {0xFF08, 0xFF08, prF}, // Ps FULLWIDTH LEFT PARENTHESIS
+ {0xFF09, 0xFF09, prF}, // Pe FULLWIDTH RIGHT PARENTHESIS
+ {0xFF0A, 0xFF0A, prF}, // Po FULLWIDTH ASTERISK
+ {0xFF0B, 0xFF0B, prF}, // Sm FULLWIDTH PLUS SIGN
+ {0xFF0C, 0xFF0C, prF}, // Po FULLWIDTH COMMA
+ {0xFF0D, 0xFF0D, prF}, // Pd FULLWIDTH HYPHEN-MINUS
+ {0xFF0E, 0xFF0F, prF}, // Po [2] FULLWIDTH FULL STOP..FULLWIDTH SOLIDUS
+ {0xFF10, 0xFF19, prF}, // Nd [10] FULLWIDTH DIGIT ZERO..FULLWIDTH DIGIT NINE
+ {0xFF1A, 0xFF1B, prF}, // Po [2] FULLWIDTH COLON..FULLWIDTH SEMICOLON
+ {0xFF1C, 0xFF1E, prF}, // Sm [3] FULLWIDTH LESS-THAN SIGN..FULLWIDTH GREATER-THAN SIGN
+ {0xFF1F, 0xFF20, prF}, // Po [2] FULLWIDTH QUESTION MARK..FULLWIDTH COMMERCIAL AT
+ {0xFF21, 0xFF3A, prF}, // Lu [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z
+ {0xFF3B, 0xFF3B, prF}, // Ps FULLWIDTH LEFT SQUARE BRACKET
+ {0xFF3C, 0xFF3C, prF}, // Po FULLWIDTH REVERSE SOLIDUS
+ {0xFF3D, 0xFF3D, prF}, // Pe FULLWIDTH RIGHT SQUARE BRACKET
+ {0xFF3E, 0xFF3E, prF}, // Sk FULLWIDTH CIRCUMFLEX ACCENT
+ {0xFF3F, 0xFF3F, prF}, // Pc FULLWIDTH LOW LINE
+ {0xFF40, 0xFF40, prF}, // Sk FULLWIDTH GRAVE ACCENT
+ {0xFF41, 0xFF5A, prF}, // Ll [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER Z
+ {0xFF5B, 0xFF5B, prF}, // Ps FULLWIDTH LEFT CURLY BRACKET
+ {0xFF5C, 0xFF5C, prF}, // Sm FULLWIDTH VERTICAL LINE
+ {0xFF5D, 0xFF5D, prF}, // Pe FULLWIDTH RIGHT CURLY BRACKET
+ {0xFF5E, 0xFF5E, prF}, // Sm FULLWIDTH TILDE
+ {0xFF5F, 0xFF5F, prF}, // Ps FULLWIDTH LEFT WHITE PARENTHESIS
+ {0xFF60, 0xFF60, prF}, // Pe FULLWIDTH RIGHT WHITE PARENTHESIS
+ {0xFF61, 0xFF61, prH}, // Po HALFWIDTH IDEOGRAPHIC FULL STOP
+ {0xFF62, 0xFF62, prH}, // Ps HALFWIDTH LEFT CORNER BRACKET
+ {0xFF63, 0xFF63, prH}, // Pe HALFWIDTH RIGHT CORNER BRACKET
+ {0xFF64, 0xFF65, prH}, // Po [2] HALFWIDTH IDEOGRAPHIC COMMA..HALFWIDTH KATAKANA MIDDLE DOT
+ {0xFF66, 0xFF6F, prH}, // Lo [10] HALFWIDTH KATAKANA LETTER WO..HALFWIDTH KATAKANA LETTER SMALL TU
+ {0xFF70, 0xFF70, prH}, // Lm HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
+ {0xFF71, 0xFF9D, prH}, // Lo [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAKANA LETTER N
+ {0xFF9E, 0xFF9F, prH}, // Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
+ {0xFFA0, 0xFFBE, prH}, // Lo [31] HALFWIDTH HANGUL FILLER..HALFWIDTH HANGUL LETTER HIEUH
+ {0xFFC2, 0xFFC7, prH}, // Lo [6] HALFWIDTH HANGUL LETTER A..HALFWIDTH HANGUL LETTER E
+ {0xFFCA, 0xFFCF, prH}, // Lo [6] HALFWIDTH HANGUL LETTER YEO..HALFWIDTH HANGUL LETTER OE
+ {0xFFD2, 0xFFD7, prH}, // Lo [6] HALFWIDTH HANGUL LETTER YO..HALFWIDTH HANGUL LETTER YU
+ {0xFFDA, 0xFFDC, prH}, // Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL LETTER I
+ {0xFFE0, 0xFFE1, prF}, // Sc [2] FULLWIDTH CENT SIGN..FULLWIDTH POUND SIGN
+ {0xFFE2, 0xFFE2, prF}, // Sm FULLWIDTH NOT SIGN
+ {0xFFE3, 0xFFE3, prF}, // Sk FULLWIDTH MACRON
+ {0xFFE4, 0xFFE4, prF}, // So FULLWIDTH BROKEN BAR
+ {0xFFE5, 0xFFE6, prF}, // Sc [2] FULLWIDTH YEN SIGN..FULLWIDTH WON SIGN
+ {0xFFE8, 0xFFE8, prH}, // So HALFWIDTH FORMS LIGHT VERTICAL
+ {0xFFE9, 0xFFEC, prH}, // Sm [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS ARROW
+ {0xFFED, 0xFFEE, prH}, // So [2] HALFWIDTH BLACK SQUARE..HALFWIDTH WHITE CIRCLE
+ {0xFFF9, 0xFFFB, prN}, // Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR
+ {0xFFFC, 0xFFFC, prN}, // So OBJECT REPLACEMENT CHARACTER
+ {0xFFFD, 0xFFFD, prA}, // So REPLACEMENT CHARACTER
+ {0x10000, 0x1000B, prN}, // Lo [12] LINEAR B SYLLABLE B008 A..LINEAR B SYLLABLE B046 JE
+ {0x1000D, 0x10026, prN}, // Lo [26] LINEAR B SYLLABLE B036 JO..LINEAR B SYLLABLE B032 QO
+ {0x10028, 0x1003A, prN}, // Lo [19] LINEAR B SYLLABLE B060 RA..LINEAR B SYLLABLE B042 WO
+ {0x1003C, 0x1003D, prN}, // Lo [2] LINEAR B SYLLABLE B017 ZA..LINEAR B SYLLABLE B074 ZE
+ {0x1003F, 0x1004D, prN}, // Lo [15] LINEAR B SYLLABLE B020 ZO..LINEAR B SYLLABLE B091 TWO
+ {0x10050, 0x1005D, prN}, // Lo [14] LINEAR B SYMBOL B018..LINEAR B SYMBOL B089
+ {0x10080, 0x100FA, prN}, // Lo [123] LINEAR B IDEOGRAM B100 MAN..LINEAR B IDEOGRAM VESSEL B305
+ {0x10100, 0x10102, prN}, // Po [3] AEGEAN WORD SEPARATOR LINE..AEGEAN CHECK MARK
+ {0x10107, 0x10133, prN}, // No [45] AEGEAN NUMBER ONE..AEGEAN NUMBER NINETY THOUSAND
+ {0x10137, 0x1013F, prN}, // So [9] AEGEAN WEIGHT BASE UNIT..AEGEAN MEASURE THIRD SUBUNIT
+ {0x10140, 0x10174, prN}, // Nl [53] GREEK ACROPHONIC ATTIC ONE QUARTER..GREEK ACROPHONIC STRATIAN FIFTY MNAS
+ {0x10175, 0x10178, prN}, // No [4] GREEK ONE HALF SIGN..GREEK THREE QUARTERS SIGN
+ {0x10179, 0x10189, prN}, // So [17] GREEK YEAR SIGN..GREEK TRYBLION BASE SIGN
+ {0x1018A, 0x1018B, prN}, // No [2] GREEK ZERO SIGN..GREEK ONE QUARTER SIGN
+ {0x1018C, 0x1018E, prN}, // So [3] GREEK SINUSOID SIGN..NOMISMA SIGN
+ {0x10190, 0x1019C, prN}, // So [13] ROMAN SEXTANS SIGN..ASCIA SYMBOL
+ {0x101A0, 0x101A0, prN}, // So GREEK SYMBOL TAU RHO
+ {0x101D0, 0x101FC, prN}, // So [45] PHAISTOS DISC SIGN PEDESTRIAN..PHAISTOS DISC SIGN WAVY BAND
+ {0x101FD, 0x101FD, prN}, // Mn PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE
+ {0x10280, 0x1029C, prN}, // Lo [29] LYCIAN LETTER A..LYCIAN LETTER X
+ {0x102A0, 0x102D0, prN}, // Lo [49] CARIAN LETTER A..CARIAN LETTER UUU3
+ {0x102E0, 0x102E0, prN}, // Mn COPTIC EPACT THOUSANDS MARK
+ {0x102E1, 0x102FB, prN}, // No [27] COPTIC EPACT DIGIT ONE..COPTIC EPACT NUMBER NINE HUNDRED
+ {0x10300, 0x1031F, prN}, // Lo [32] OLD ITALIC LETTER A..OLD ITALIC LETTER ESS
+ {0x10320, 0x10323, prN}, // No [4] OLD ITALIC NUMERAL ONE..OLD ITALIC NUMERAL FIFTY
+ {0x1032D, 0x1032F, prN}, // Lo [3] OLD ITALIC LETTER YE..OLD ITALIC LETTER SOUTHERN TSE
+ {0x10330, 0x10340, prN}, // Lo [17] GOTHIC LETTER AHSA..GOTHIC LETTER PAIRTHRA
+ {0x10341, 0x10341, prN}, // Nl GOTHIC LETTER NINETY
+ {0x10342, 0x10349, prN}, // Lo [8] GOTHIC LETTER RAIDA..GOTHIC LETTER OTHAL
+ {0x1034A, 0x1034A, prN}, // Nl GOTHIC LETTER NINE HUNDRED
+ {0x10350, 0x10375, prN}, // Lo [38] OLD PERMIC LETTER AN..OLD PERMIC LETTER IA
+ {0x10376, 0x1037A, prN}, // Mn [5] COMBINING OLD PERMIC LETTER AN..COMBINING OLD PERMIC LETTER SII
+ {0x10380, 0x1039D, prN}, // Lo [30] UGARITIC LETTER ALPA..UGARITIC LETTER SSU
+ {0x1039F, 0x1039F, prN}, // Po UGARITIC WORD DIVIDER
+ {0x103A0, 0x103C3, prN}, // Lo [36] OLD PERSIAN SIGN A..OLD PERSIAN SIGN HA
+ {0x103C8, 0x103CF, prN}, // Lo [8] OLD PERSIAN SIGN AURAMAZDAA..OLD PERSIAN SIGN BUUMISH
+ {0x103D0, 0x103D0, prN}, // Po OLD PERSIAN WORD DIVIDER
+ {0x103D1, 0x103D5, prN}, // Nl [5] OLD PERSIAN NUMBER ONE..OLD PERSIAN NUMBER HUNDRED
+ {0x10400, 0x1044F, prN}, // L& [80] DESERET CAPITAL LETTER LONG I..DESERET SMALL LETTER EW
+ {0x10450, 0x1047F, prN}, // Lo [48] SHAVIAN LETTER PEEP..SHAVIAN LETTER YEW
+ {0x10480, 0x1049D, prN}, // Lo [30] OSMANYA LETTER ALEF..OSMANYA LETTER OO
+ {0x104A0, 0x104A9, prN}, // Nd [10] OSMANYA DIGIT ZERO..OSMANYA DIGIT NINE
+ {0x104B0, 0x104D3, prN}, // Lu [36] OSAGE CAPITAL LETTER A..OSAGE CAPITAL LETTER ZHA
+ {0x104D8, 0x104FB, prN}, // Ll [36] OSAGE SMALL LETTER A..OSAGE SMALL LETTER ZHA
+ {0x10500, 0x10527, prN}, // Lo [40] ELBASAN LETTER A..ELBASAN LETTER KHE
+ {0x10530, 0x10563, prN}, // Lo [52] CAUCASIAN ALBANIAN LETTER ALT..CAUCASIAN ALBANIAN LETTER KIW
+ {0x1056F, 0x1056F, prN}, // Po CAUCASIAN ALBANIAN CITATION MARK
+ {0x10570, 0x1057A, prN}, // Lu [11] VITHKUQI CAPITAL LETTER A..VITHKUQI CAPITAL LETTER GA
+ {0x1057C, 0x1058A, prN}, // Lu [15] VITHKUQI CAPITAL LETTER HA..VITHKUQI CAPITAL LETTER RE
+ {0x1058C, 0x10592, prN}, // Lu [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE
+ {0x10594, 0x10595, prN}, // Lu [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE
+ {0x10597, 0x105A1, prN}, // Ll [11] VITHKUQI SMALL LETTER A..VITHKUQI SMALL LETTER GA
+ {0x105A3, 0x105B1, prN}, // Ll [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE
+ {0x105B3, 0x105B9, prN}, // Ll [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE
+ {0x105BB, 0x105BC, prN}, // Ll [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE
+ {0x10600, 0x10736, prN}, // Lo [311] LINEAR A SIGN AB001..LINEAR A SIGN A664
+ {0x10740, 0x10755, prN}, // Lo [22] LINEAR A SIGN A701 A..LINEAR A SIGN A732 JE
+ {0x10760, 0x10767, prN}, // Lo [8] LINEAR A SIGN A800..LINEAR A SIGN A807
+ {0x10780, 0x10785, prN}, // Lm [6] MODIFIER LETTER SMALL CAPITAL AA..MODIFIER LETTER SMALL B WITH HOOK
+ {0x10787, 0x107B0, prN}, // Lm [42] MODIFIER LETTER SMALL DZ DIGRAPH..MODIFIER LETTER SMALL V WITH RIGHT HOOK
+ {0x107B2, 0x107BA, prN}, // Lm [9] MODIFIER LETTER SMALL CAPITAL Y..MODIFIER LETTER SMALL S WITH CURL
+ {0x10800, 0x10805, prN}, // Lo [6] CYPRIOT SYLLABLE A..CYPRIOT SYLLABLE JA
+ {0x10808, 0x10808, prN}, // Lo CYPRIOT SYLLABLE JO
+ {0x1080A, 0x10835, prN}, // Lo [44] CYPRIOT SYLLABLE KA..CYPRIOT SYLLABLE WO
+ {0x10837, 0x10838, prN}, // Lo [2] CYPRIOT SYLLABLE XA..CYPRIOT SYLLABLE XE
+ {0x1083C, 0x1083C, prN}, // Lo CYPRIOT SYLLABLE ZA
+ {0x1083F, 0x1083F, prN}, // Lo CYPRIOT SYLLABLE ZO
+ {0x10840, 0x10855, prN}, // Lo [22] IMPERIAL ARAMAIC LETTER ALEPH..IMPERIAL ARAMAIC LETTER TAW
+ {0x10857, 0x10857, prN}, // Po IMPERIAL ARAMAIC SECTION SIGN
+ {0x10858, 0x1085F, prN}, // No [8] IMPERIAL ARAMAIC NUMBER ONE..IMPERIAL ARAMAIC NUMBER TEN THOUSAND
+ {0x10860, 0x10876, prN}, // Lo [23] PALMYRENE LETTER ALEPH..PALMYRENE LETTER TAW
+ {0x10877, 0x10878, prN}, // So [2] PALMYRENE LEFT-POINTING FLEURON..PALMYRENE RIGHT-POINTING FLEURON
+ {0x10879, 0x1087F, prN}, // No [7] PALMYRENE NUMBER ONE..PALMYRENE NUMBER TWENTY
+ {0x10880, 0x1089E, prN}, // Lo [31] NABATAEAN LETTER FINAL ALEPH..NABATAEAN LETTER TAW
+ {0x108A7, 0x108AF, prN}, // No [9] NABATAEAN NUMBER ONE..NABATAEAN NUMBER ONE HUNDRED
+ {0x108E0, 0x108F2, prN}, // Lo [19] HATRAN LETTER ALEPH..HATRAN LETTER QOPH
+ {0x108F4, 0x108F5, prN}, // Lo [2] HATRAN LETTER SHIN..HATRAN LETTER TAW
+ {0x108FB, 0x108FF, prN}, // No [5] HATRAN NUMBER ONE..HATRAN NUMBER ONE HUNDRED
+ {0x10900, 0x10915, prN}, // Lo [22] PHOENICIAN LETTER ALF..PHOENICIAN LETTER TAU
+ {0x10916, 0x1091B, prN}, // No [6] PHOENICIAN NUMBER ONE..PHOENICIAN NUMBER THREE
+ {0x1091F, 0x1091F, prN}, // Po PHOENICIAN WORD SEPARATOR
+ {0x10920, 0x10939, prN}, // Lo [26] LYDIAN LETTER A..LYDIAN LETTER C
+ {0x1093F, 0x1093F, prN}, // Po LYDIAN TRIANGULAR MARK
+ {0x10980, 0x1099F, prN}, // Lo [32] MEROITIC HIEROGLYPHIC LETTER A..MEROITIC HIEROGLYPHIC SYMBOL VIDJ-2
+ {0x109A0, 0x109B7, prN}, // Lo [24] MEROITIC CURSIVE LETTER A..MEROITIC CURSIVE LETTER DA
+ {0x109BC, 0x109BD, prN}, // No [2] MEROITIC CURSIVE FRACTION ELEVEN TWELFTHS..MEROITIC CURSIVE FRACTION ONE HALF
+ {0x109BE, 0x109BF, prN}, // Lo [2] MEROITIC CURSIVE LOGOGRAM RMT..MEROITIC CURSIVE LOGOGRAM IMN
+ {0x109C0, 0x109CF, prN}, // No [16] MEROITIC CURSIVE NUMBER ONE..MEROITIC CURSIVE NUMBER SEVENTY
+ {0x109D2, 0x109FF, prN}, // No [46] MEROITIC CURSIVE NUMBER ONE HUNDRED..MEROITIC CURSIVE FRACTION TEN TWELFTHS
+ {0x10A00, 0x10A00, prN}, // Lo KHAROSHTHI LETTER A
+ {0x10A01, 0x10A03, prN}, // Mn [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R
+ {0x10A05, 0x10A06, prN}, // Mn [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O
+ {0x10A0C, 0x10A0F, prN}, // Mn [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA
+ {0x10A10, 0x10A13, prN}, // Lo [4] KHAROSHTHI LETTER KA..KHAROSHTHI LETTER GHA
+ {0x10A15, 0x10A17, prN}, // Lo [3] KHAROSHTHI LETTER CA..KHAROSHTHI LETTER JA
+ {0x10A19, 0x10A35, prN}, // Lo [29] KHAROSHTHI LETTER NYA..KHAROSHTHI LETTER VHA
+ {0x10A38, 0x10A3A, prN}, // Mn [3] KHAROSHTHI SIGN BAR ABOVE..KHAROSHTHI SIGN DOT BELOW
+ {0x10A3F, 0x10A3F, prN}, // Mn KHAROSHTHI VIRAMA
+ {0x10A40, 0x10A48, prN}, // No [9] KHAROSHTHI DIGIT ONE..KHAROSHTHI FRACTION ONE HALF
+ {0x10A50, 0x10A58, prN}, // Po [9] KHAROSHTHI PUNCTUATION DOT..KHAROSHTHI PUNCTUATION LINES
+ {0x10A60, 0x10A7C, prN}, // Lo [29] OLD SOUTH ARABIAN LETTER HE..OLD SOUTH ARABIAN LETTER THETH
+ {0x10A7D, 0x10A7E, prN}, // No [2] OLD SOUTH ARABIAN NUMBER ONE..OLD SOUTH ARABIAN NUMBER FIFTY
+ {0x10A7F, 0x10A7F, prN}, // Po OLD SOUTH ARABIAN NUMERIC INDICATOR
+ {0x10A80, 0x10A9C, prN}, // Lo [29] OLD NORTH ARABIAN LETTER HEH..OLD NORTH ARABIAN LETTER ZAH
+ {0x10A9D, 0x10A9F, prN}, // No [3] OLD NORTH ARABIAN NUMBER ONE..OLD NORTH ARABIAN NUMBER TWENTY
+ {0x10AC0, 0x10AC7, prN}, // Lo [8] MANICHAEAN LETTER ALEPH..MANICHAEAN LETTER WAW
+ {0x10AC8, 0x10AC8, prN}, // So MANICHAEAN SIGN UD
+ {0x10AC9, 0x10AE4, prN}, // Lo [28] MANICHAEAN LETTER ZAYIN..MANICHAEAN LETTER TAW
+ {0x10AE5, 0x10AE6, prN}, // Mn [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW
+ {0x10AEB, 0x10AEF, prN}, // No [5] MANICHAEAN NUMBER ONE..MANICHAEAN NUMBER ONE HUNDRED
+ {0x10AF0, 0x10AF6, prN}, // Po [7] MANICHAEAN PUNCTUATION STAR..MANICHAEAN PUNCTUATION LINE FILLER
+ {0x10B00, 0x10B35, prN}, // Lo [54] AVESTAN LETTER A..AVESTAN LETTER HE
+ {0x10B39, 0x10B3F, prN}, // Po [7] AVESTAN ABBREVIATION MARK..LARGE ONE RING OVER TWO RINGS PUNCTUATION
+ {0x10B40, 0x10B55, prN}, // Lo [22] INSCRIPTIONAL PARTHIAN LETTER ALEPH..INSCRIPTIONAL PARTHIAN LETTER TAW
+ {0x10B58, 0x10B5F, prN}, // No [8] INSCRIPTIONAL PARTHIAN NUMBER ONE..INSCRIPTIONAL PARTHIAN NUMBER ONE THOUSAND
+ {0x10B60, 0x10B72, prN}, // Lo [19] INSCRIPTIONAL PAHLAVI LETTER ALEPH..INSCRIPTIONAL PAHLAVI LETTER TAW
+ {0x10B78, 0x10B7F, prN}, // No [8] INSCRIPTIONAL PAHLAVI NUMBER ONE..INSCRIPTIONAL PAHLAVI NUMBER ONE THOUSAND
+ {0x10B80, 0x10B91, prN}, // Lo [18] PSALTER PAHLAVI LETTER ALEPH..PSALTER PAHLAVI LETTER TAW
+ {0x10B99, 0x10B9C, prN}, // Po [4] PSALTER PAHLAVI SECTION MARK..PSALTER PAHLAVI FOUR DOTS WITH DOT
+ {0x10BA9, 0x10BAF, prN}, // No [7] PSALTER PAHLAVI NUMBER ONE..PSALTER PAHLAVI NUMBER ONE HUNDRED
+ {0x10C00, 0x10C48, prN}, // Lo [73] OLD TURKIC LETTER ORKHON A..OLD TURKIC LETTER ORKHON BASH
+ {0x10C80, 0x10CB2, prN}, // Lu [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US
+ {0x10CC0, 0x10CF2, prN}, // Ll [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US
+ {0x10CFA, 0x10CFF, prN}, // No [6] OLD HUNGARIAN NUMBER ONE..OLD HUNGARIAN NUMBER ONE THOUSAND
+ {0x10D00, 0x10D23, prN}, // Lo [36] HANIFI ROHINGYA LETTER A..HANIFI ROHINGYA MARK NA KHONNA
+ {0x10D24, 0x10D27, prN}, // Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI
+ {0x10D30, 0x10D39, prN}, // Nd [10] HANIFI ROHINGYA DIGIT ZERO..HANIFI ROHINGYA DIGIT NINE
+ {0x10E60, 0x10E7E, prN}, // No [31] RUMI DIGIT ONE..RUMI FRACTION TWO THIRDS
+ {0x10E80, 0x10EA9, prN}, // Lo [42] YEZIDI LETTER ELIF..YEZIDI LETTER ET
+ {0x10EAB, 0x10EAC, prN}, // Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK
+ {0x10EAD, 0x10EAD, prN}, // Pd YEZIDI HYPHENATION MARK
+ {0x10EB0, 0x10EB1, prN}, // Lo [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE
+ {0x10EFD, 0x10EFF, prN}, // Mn [3] ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA
+ {0x10F00, 0x10F1C, prN}, // Lo [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL
+ {0x10F1D, 0x10F26, prN}, // No [10] OLD SOGDIAN NUMBER ONE..OLD SOGDIAN FRACTION ONE HALF
+ {0x10F27, 0x10F27, prN}, // Lo OLD SOGDIAN LIGATURE AYIN-DALETH
+ {0x10F30, 0x10F45, prN}, // Lo [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN
+ {0x10F46, 0x10F50, prN}, // Mn [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW
+ {0x10F51, 0x10F54, prN}, // No [4] SOGDIAN NUMBER ONE..SOGDIAN NUMBER ONE HUNDRED
+ {0x10F55, 0x10F59, prN}, // Po [5] SOGDIAN PUNCTUATION TWO VERTICAL BARS..SOGDIAN PUNCTUATION HALF CIRCLE WITH DOT
+ {0x10F70, 0x10F81, prN}, // Lo [18] OLD UYGHUR LETTER ALEPH..OLD UYGHUR LETTER LESH
+ {0x10F82, 0x10F85, prN}, // Mn [4] OLD UYGHUR COMBINING DOT ABOVE..OLD UYGHUR COMBINING TWO DOTS BELOW
+ {0x10F86, 0x10F89, prN}, // Po [4] OLD UYGHUR PUNCTUATION BAR..OLD UYGHUR PUNCTUATION FOUR DOTS
+ {0x10FB0, 0x10FC4, prN}, // Lo [21] CHORASMIAN LETTER ALEPH..CHORASMIAN LETTER TAW
+ {0x10FC5, 0x10FCB, prN}, // No [7] CHORASMIAN NUMBER ONE..CHORASMIAN NUMBER ONE HUNDRED
+ {0x10FE0, 0x10FF6, prN}, // Lo [23] ELYMAIC LETTER ALEPH..ELYMAIC LIGATURE ZAYIN-YODH
+ {0x11000, 0x11000, prN}, // Mc BRAHMI SIGN CANDRABINDU
+ {0x11001, 0x11001, prN}, // Mn BRAHMI SIGN ANUSVARA
+ {0x11002, 0x11002, prN}, // Mc BRAHMI SIGN VISARGA
+ {0x11003, 0x11037, prN}, // Lo [53] BRAHMI SIGN JIHVAMULIYA..BRAHMI LETTER OLD TAMIL NNNA
+ {0x11038, 0x11046, prN}, // Mn [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA
+ {0x11047, 0x1104D, prN}, // Po [7] BRAHMI DANDA..BRAHMI PUNCTUATION LOTUS
+ {0x11052, 0x11065, prN}, // No [20] BRAHMI NUMBER ONE..BRAHMI NUMBER ONE THOUSAND
+ {0x11066, 0x1106F, prN}, // Nd [10] BRAHMI DIGIT ZERO..BRAHMI DIGIT NINE
+ {0x11070, 0x11070, prN}, // Mn BRAHMI SIGN OLD TAMIL VIRAMA
+ {0x11071, 0x11072, prN}, // Lo [2] BRAHMI LETTER OLD TAMIL SHORT E..BRAHMI LETTER OLD TAMIL SHORT O
+ {0x11073, 0x11074, prN}, // Mn [2] BRAHMI VOWEL SIGN OLD TAMIL SHORT E..BRAHMI VOWEL SIGN OLD TAMIL SHORT O
+ {0x11075, 0x11075, prN}, // Lo BRAHMI LETTER OLD TAMIL LLA
+ {0x1107F, 0x1107F, prN}, // Mn BRAHMI NUMBER JOINER
+ {0x11080, 0x11081, prN}, // Mn [2] KAITHI SIGN CANDRABINDU..KAITHI SIGN ANUSVARA
+ {0x11082, 0x11082, prN}, // Mc KAITHI SIGN VISARGA
+ {0x11083, 0x110AF, prN}, // Lo [45] KAITHI LETTER A..KAITHI LETTER HA
+ {0x110B0, 0x110B2, prN}, // Mc [3] KAITHI VOWEL SIGN AA..KAITHI VOWEL SIGN II
+ {0x110B3, 0x110B6, prN}, // Mn [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI
+ {0x110B7, 0x110B8, prN}, // Mc [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU
+ {0x110B9, 0x110BA, prN}, // Mn [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA
+ {0x110BB, 0x110BC, prN}, // Po [2] KAITHI ABBREVIATION SIGN..KAITHI ENUMERATION SIGN
+ {0x110BD, 0x110BD, prN}, // Cf KAITHI NUMBER SIGN
+ {0x110BE, 0x110C1, prN}, // Po [4] KAITHI SECTION MARK..KAITHI DOUBLE DANDA
+ {0x110C2, 0x110C2, prN}, // Mn KAITHI VOWEL SIGN VOCALIC R
+ {0x110CD, 0x110CD, prN}, // Cf KAITHI NUMBER SIGN ABOVE
+ {0x110D0, 0x110E8, prN}, // Lo [25] SORA SOMPENG LETTER SAH..SORA SOMPENG LETTER MAE
+ {0x110F0, 0x110F9, prN}, // Nd [10] SORA SOMPENG DIGIT ZERO..SORA SOMPENG DIGIT NINE
+ {0x11100, 0x11102, prN}, // Mn [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA
+ {0x11103, 0x11126, prN}, // Lo [36] CHAKMA LETTER AA..CHAKMA LETTER HAA
+ {0x11127, 0x1112B, prN}, // Mn [5] CHAKMA VOWEL SIGN A..CHAKMA VOWEL SIGN UU
+ {0x1112C, 0x1112C, prN}, // Mc CHAKMA VOWEL SIGN E
+ {0x1112D, 0x11134, prN}, // Mn [8] CHAKMA VOWEL SIGN AI..CHAKMA MAAYYAA
+ {0x11136, 0x1113F, prN}, // Nd [10] CHAKMA DIGIT ZERO..CHAKMA DIGIT NINE
+ {0x11140, 0x11143, prN}, // Po [4] CHAKMA SECTION MARK..CHAKMA QUESTION MARK
+ {0x11144, 0x11144, prN}, // Lo CHAKMA LETTER LHAA
+ {0x11145, 0x11146, prN}, // Mc [2] CHAKMA VOWEL SIGN AA..CHAKMA VOWEL SIGN EI
+ {0x11147, 0x11147, prN}, // Lo CHAKMA LETTER VAA
+ {0x11150, 0x11172, prN}, // Lo [35] MAHAJANI LETTER A..MAHAJANI LETTER RRA
+ {0x11173, 0x11173, prN}, // Mn MAHAJANI SIGN NUKTA
+ {0x11174, 0x11175, prN}, // Po [2] MAHAJANI ABBREVIATION SIGN..MAHAJANI SECTION MARK
+ {0x11176, 0x11176, prN}, // Lo MAHAJANI LIGATURE SHRI
+ {0x11180, 0x11181, prN}, // Mn [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA
+ {0x11182, 0x11182, prN}, // Mc SHARADA SIGN VISARGA
+ {0x11183, 0x111B2, prN}, // Lo [48] SHARADA LETTER A..SHARADA LETTER HA
+ {0x111B3, 0x111B5, prN}, // Mc [3] SHARADA VOWEL SIGN AA..SHARADA VOWEL SIGN II
+ {0x111B6, 0x111BE, prN}, // Mn [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O
+ {0x111BF, 0x111C0, prN}, // Mc [2] SHARADA VOWEL SIGN AU..SHARADA SIGN VIRAMA
+ {0x111C1, 0x111C4, prN}, // Lo [4] SHARADA SIGN AVAGRAHA..SHARADA OM
+ {0x111C5, 0x111C8, prN}, // Po [4] SHARADA DANDA..SHARADA SEPARATOR
+ {0x111C9, 0x111CC, prN}, // Mn [4] SHARADA SANDHI MARK..SHARADA EXTRA SHORT VOWEL MARK
+ {0x111CD, 0x111CD, prN}, // Po SHARADA SUTRA MARK
+ {0x111CE, 0x111CE, prN}, // Mc SHARADA VOWEL SIGN PRISHTHAMATRA E
+ {0x111CF, 0x111CF, prN}, // Mn SHARADA SIGN INVERTED CANDRABINDU
+ {0x111D0, 0x111D9, prN}, // Nd [10] SHARADA DIGIT ZERO..SHARADA DIGIT NINE
+ {0x111DA, 0x111DA, prN}, // Lo SHARADA EKAM
+ {0x111DB, 0x111DB, prN}, // Po SHARADA SIGN SIDDHAM
+ {0x111DC, 0x111DC, prN}, // Lo SHARADA HEADSTROKE
+ {0x111DD, 0x111DF, prN}, // Po [3] SHARADA CONTINUATION SIGN..SHARADA SECTION MARK-2
+ {0x111E1, 0x111F4, prN}, // No [20] SINHALA ARCHAIC DIGIT ONE..SINHALA ARCHAIC NUMBER ONE THOUSAND
+ {0x11200, 0x11211, prN}, // Lo [18] KHOJKI LETTER A..KHOJKI LETTER JJA
+ {0x11213, 0x1122B, prN}, // Lo [25] KHOJKI LETTER NYA..KHOJKI LETTER LLA
+ {0x1122C, 0x1122E, prN}, // Mc [3] KHOJKI VOWEL SIGN AA..KHOJKI VOWEL SIGN II
+ {0x1122F, 0x11231, prN}, // Mn [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI
+ {0x11232, 0x11233, prN}, // Mc [2] KHOJKI VOWEL SIGN O..KHOJKI VOWEL SIGN AU
+ {0x11234, 0x11234, prN}, // Mn KHOJKI SIGN ANUSVARA
+ {0x11235, 0x11235, prN}, // Mc KHOJKI SIGN VIRAMA
+ {0x11236, 0x11237, prN}, // Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA
+ {0x11238, 0x1123D, prN}, // Po [6] KHOJKI DANDA..KHOJKI ABBREVIATION SIGN
+ {0x1123E, 0x1123E, prN}, // Mn KHOJKI SIGN SUKUN
+ {0x1123F, 0x11240, prN}, // Lo [2] KHOJKI LETTER QA..KHOJKI LETTER SHORT I
+ {0x11241, 0x11241, prN}, // Mn KHOJKI VOWEL SIGN VOCALIC R
+ {0x11280, 0x11286, prN}, // Lo [7] MULTANI LETTER A..MULTANI LETTER GA
+ {0x11288, 0x11288, prN}, // Lo MULTANI LETTER GHA
+ {0x1128A, 0x1128D, prN}, // Lo [4] MULTANI LETTER CA..MULTANI LETTER JJA
+ {0x1128F, 0x1129D, prN}, // Lo [15] MULTANI LETTER NYA..MULTANI LETTER BA
+ {0x1129F, 0x112A8, prN}, // Lo [10] MULTANI LETTER BHA..MULTANI LETTER RHA
+ {0x112A9, 0x112A9, prN}, // Po MULTANI SECTION MARK
+ {0x112B0, 0x112DE, prN}, // Lo [47] KHUDAWADI LETTER A..KHUDAWADI LETTER HA
+ {0x112DF, 0x112DF, prN}, // Mn KHUDAWADI SIGN ANUSVARA
+ {0x112E0, 0x112E2, prN}, // Mc [3] KHUDAWADI VOWEL SIGN AA..KHUDAWADI VOWEL SIGN II
+ {0x112E3, 0x112EA, prN}, // Mn [8] KHUDAWADI VOWEL SIGN U..KHUDAWADI SIGN VIRAMA
+ {0x112F0, 0x112F9, prN}, // Nd [10] KHUDAWADI DIGIT ZERO..KHUDAWADI DIGIT NINE
+ {0x11300, 0x11301, prN}, // Mn [2] GRANTHA SIGN COMBINING ANUSVARA ABOVE..GRANTHA SIGN CANDRABINDU
+ {0x11302, 0x11303, prN}, // Mc [2] GRANTHA SIGN ANUSVARA..GRANTHA SIGN VISARGA
+ {0x11305, 0x1130C, prN}, // Lo [8] GRANTHA LETTER A..GRANTHA LETTER VOCALIC L
+ {0x1130F, 0x11310, prN}, // Lo [2] GRANTHA LETTER EE..GRANTHA LETTER AI
+ {0x11313, 0x11328, prN}, // Lo [22] GRANTHA LETTER OO..GRANTHA LETTER NA
+ {0x1132A, 0x11330, prN}, // Lo [7] GRANTHA LETTER PA..GRANTHA LETTER RA
+ {0x11332, 0x11333, prN}, // Lo [2] GRANTHA LETTER LA..GRANTHA LETTER LLA
+ {0x11335, 0x11339, prN}, // Lo [5] GRANTHA LETTER VA..GRANTHA LETTER HA
+ {0x1133B, 0x1133C, prN}, // Mn [2] COMBINING BINDU BELOW..GRANTHA SIGN NUKTA
+ {0x1133D, 0x1133D, prN}, // Lo GRANTHA SIGN AVAGRAHA
+ {0x1133E, 0x1133F, prN}, // Mc [2] GRANTHA VOWEL SIGN AA..GRANTHA VOWEL SIGN I
+ {0x11340, 0x11340, prN}, // Mn GRANTHA VOWEL SIGN II
+ {0x11341, 0x11344, prN}, // Mc [4] GRANTHA VOWEL SIGN U..GRANTHA VOWEL SIGN VOCALIC RR
+ {0x11347, 0x11348, prN}, // Mc [2] GRANTHA VOWEL SIGN EE..GRANTHA VOWEL SIGN AI
+ {0x1134B, 0x1134D, prN}, // Mc [3] GRANTHA VOWEL SIGN OO..GRANTHA SIGN VIRAMA
+ {0x11350, 0x11350, prN}, // Lo GRANTHA OM
+ {0x11357, 0x11357, prN}, // Mc GRANTHA AU LENGTH MARK
+ {0x1135D, 0x11361, prN}, // Lo [5] GRANTHA SIGN PLUTA..GRANTHA LETTER VOCALIC LL
+ {0x11362, 0x11363, prN}, // Mc [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL
+ {0x11366, 0x1136C, prN}, // Mn [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX
+ {0x11370, 0x11374, prN}, // Mn [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA
+ {0x11400, 0x11434, prN}, // Lo [53] NEWA LETTER A..NEWA LETTER HA
+ {0x11435, 0x11437, prN}, // Mc [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II
+ {0x11438, 0x1143F, prN}, // Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI
+ {0x11440, 0x11441, prN}, // Mc [2] NEWA VOWEL SIGN O..NEWA VOWEL SIGN AU
+ {0x11442, 0x11444, prN}, // Mn [3] NEWA SIGN VIRAMA..NEWA SIGN ANUSVARA
+ {0x11445, 0x11445, prN}, // Mc NEWA SIGN VISARGA
+ {0x11446, 0x11446, prN}, // Mn NEWA SIGN NUKTA
+ {0x11447, 0x1144A, prN}, // Lo [4] NEWA SIGN AVAGRAHA..NEWA SIDDHI
+ {0x1144B, 0x1144F, prN}, // Po [5] NEWA DANDA..NEWA ABBREVIATION SIGN
+ {0x11450, 0x11459, prN}, // Nd [10] NEWA DIGIT ZERO..NEWA DIGIT NINE
+ {0x1145A, 0x1145B, prN}, // Po [2] NEWA DOUBLE COMMA..NEWA PLACEHOLDER MARK
+ {0x1145D, 0x1145D, prN}, // Po NEWA INSERTION SIGN
+ {0x1145E, 0x1145E, prN}, // Mn NEWA SANDHI MARK
+ {0x1145F, 0x11461, prN}, // Lo [3] NEWA LETTER VEDIC ANUSVARA..NEWA SIGN UPADHMANIYA
+ {0x11480, 0x114AF, prN}, // Lo [48] TIRHUTA ANJI..TIRHUTA LETTER HA
+ {0x114B0, 0x114B2, prN}, // Mc [3] TIRHUTA VOWEL SIGN AA..TIRHUTA VOWEL SIGN II
+ {0x114B3, 0x114B8, prN}, // Mn [6] TIRHUTA VOWEL SIGN U..TIRHUTA VOWEL SIGN VOCALIC LL
+ {0x114B9, 0x114B9, prN}, // Mc TIRHUTA VOWEL SIGN E
+ {0x114BA, 0x114BA, prN}, // Mn TIRHUTA VOWEL SIGN SHORT E
+ {0x114BB, 0x114BE, prN}, // Mc [4] TIRHUTA VOWEL SIGN AI..TIRHUTA VOWEL SIGN AU
+ {0x114BF, 0x114C0, prN}, // Mn [2] TIRHUTA SIGN CANDRABINDU..TIRHUTA SIGN ANUSVARA
+ {0x114C1, 0x114C1, prN}, // Mc TIRHUTA SIGN VISARGA
+ {0x114C2, 0x114C3, prN}, // Mn [2] TIRHUTA SIGN VIRAMA..TIRHUTA SIGN NUKTA
+ {0x114C4, 0x114C5, prN}, // Lo [2] TIRHUTA SIGN AVAGRAHA..TIRHUTA GVANG
+ {0x114C6, 0x114C6, prN}, // Po TIRHUTA ABBREVIATION SIGN
+ {0x114C7, 0x114C7, prN}, // Lo TIRHUTA OM
+ {0x114D0, 0x114D9, prN}, // Nd [10] TIRHUTA DIGIT ZERO..TIRHUTA DIGIT NINE
+ {0x11580, 0x115AE, prN}, // Lo [47] SIDDHAM LETTER A..SIDDHAM LETTER HA
+ {0x115AF, 0x115B1, prN}, // Mc [3] SIDDHAM VOWEL SIGN AA..SIDDHAM VOWEL SIGN II
+ {0x115B2, 0x115B5, prN}, // Mn [4] SIDDHAM VOWEL SIGN U..SIDDHAM VOWEL SIGN VOCALIC RR
+ {0x115B8, 0x115BB, prN}, // Mc [4] SIDDHAM VOWEL SIGN E..SIDDHAM VOWEL SIGN AU
+ {0x115BC, 0x115BD, prN}, // Mn [2] SIDDHAM SIGN CANDRABINDU..SIDDHAM SIGN ANUSVARA
+ {0x115BE, 0x115BE, prN}, // Mc SIDDHAM SIGN VISARGA
+ {0x115BF, 0x115C0, prN}, // Mn [2] SIDDHAM SIGN VIRAMA..SIDDHAM SIGN NUKTA
+ {0x115C1, 0x115D7, prN}, // Po [23] SIDDHAM SIGN SIDDHAM..SIDDHAM SECTION MARK WITH CIRCLES AND FOUR ENCLOSURES
+ {0x115D8, 0x115DB, prN}, // Lo [4] SIDDHAM LETTER THREE-CIRCLE ALTERNATE I..SIDDHAM LETTER ALTERNATE U
+ {0x115DC, 0x115DD, prN}, // Mn [2] SIDDHAM VOWEL SIGN ALTERNATE U..SIDDHAM VOWEL SIGN ALTERNATE UU
+ {0x11600, 0x1162F, prN}, // Lo [48] MODI LETTER A..MODI LETTER LLA
+ {0x11630, 0x11632, prN}, // Mc [3] MODI VOWEL SIGN AA..MODI VOWEL SIGN II
+ {0x11633, 0x1163A, prN}, // Mn [8] MODI VOWEL SIGN U..MODI VOWEL SIGN AI
+ {0x1163B, 0x1163C, prN}, // Mc [2] MODI VOWEL SIGN O..MODI VOWEL SIGN AU
+ {0x1163D, 0x1163D, prN}, // Mn MODI SIGN ANUSVARA
+ {0x1163E, 0x1163E, prN}, // Mc MODI SIGN VISARGA
+ {0x1163F, 0x11640, prN}, // Mn [2] MODI SIGN VIRAMA..MODI SIGN ARDHACANDRA
+ {0x11641, 0x11643, prN}, // Po [3] MODI DANDA..MODI ABBREVIATION SIGN
+ {0x11644, 0x11644, prN}, // Lo MODI SIGN HUVA
+ {0x11650, 0x11659, prN}, // Nd [10] MODI DIGIT ZERO..MODI DIGIT NINE
+ {0x11660, 0x1166C, prN}, // Po [13] MONGOLIAN BIRGA WITH ORNAMENT..MONGOLIAN TURNED SWIRL BIRGA WITH DOUBLE ORNAMENT
+ {0x11680, 0x116AA, prN}, // Lo [43] TAKRI LETTER A..TAKRI LETTER RRA
+ {0x116AB, 0x116AB, prN}, // Mn TAKRI SIGN ANUSVARA
+ {0x116AC, 0x116AC, prN}, // Mc TAKRI SIGN VISARGA
+ {0x116AD, 0x116AD, prN}, // Mn TAKRI VOWEL SIGN AA
+ {0x116AE, 0x116AF, prN}, // Mc [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II
+ {0x116B0, 0x116B5, prN}, // Mn [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU
+ {0x116B6, 0x116B6, prN}, // Mc TAKRI SIGN VIRAMA
+ {0x116B7, 0x116B7, prN}, // Mn TAKRI SIGN NUKTA
+ {0x116B8, 0x116B8, prN}, // Lo TAKRI LETTER ARCHAIC KHA
+ {0x116B9, 0x116B9, prN}, // Po TAKRI ABBREVIATION SIGN
+ {0x116C0, 0x116C9, prN}, // Nd [10] TAKRI DIGIT ZERO..TAKRI DIGIT NINE
+ {0x11700, 0x1171A, prN}, // Lo [27] AHOM LETTER KA..AHOM LETTER ALTERNATE BA
+ {0x1171D, 0x1171F, prN}, // Mn [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA
+ {0x11720, 0x11721, prN}, // Mc [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA
+ {0x11722, 0x11725, prN}, // Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU
+ {0x11726, 0x11726, prN}, // Mc AHOM VOWEL SIGN E
+ {0x11727, 0x1172B, prN}, // Mn [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER
+ {0x11730, 0x11739, prN}, // Nd [10] AHOM DIGIT ZERO..AHOM DIGIT NINE
+ {0x1173A, 0x1173B, prN}, // No [2] AHOM NUMBER TEN..AHOM NUMBER TWENTY
+ {0x1173C, 0x1173E, prN}, // Po [3] AHOM SIGN SMALL SECTION..AHOM SIGN RULAI
+ {0x1173F, 0x1173F, prN}, // So AHOM SYMBOL VI
+ {0x11740, 0x11746, prN}, // Lo [7] AHOM LETTER CA..AHOM LETTER LLA
+ {0x11800, 0x1182B, prN}, // Lo [44] DOGRA LETTER A..DOGRA LETTER RRA
+ {0x1182C, 0x1182E, prN}, // Mc [3] DOGRA VOWEL SIGN AA..DOGRA VOWEL SIGN II
+ {0x1182F, 0x11837, prN}, // Mn [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA
+ {0x11838, 0x11838, prN}, // Mc DOGRA SIGN VISARGA
+ {0x11839, 0x1183A, prN}, // Mn [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA
+ {0x1183B, 0x1183B, prN}, // Po DOGRA ABBREVIATION SIGN
+ {0x118A0, 0x118DF, prN}, // L& [64] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI SMALL LETTER VIYO
+ {0x118E0, 0x118E9, prN}, // Nd [10] WARANG CITI DIGIT ZERO..WARANG CITI DIGIT NINE
+ {0x118EA, 0x118F2, prN}, // No [9] WARANG CITI NUMBER TEN..WARANG CITI NUMBER NINETY
+ {0x118FF, 0x118FF, prN}, // Lo WARANG CITI OM
+ {0x11900, 0x11906, prN}, // Lo [7] DIVES AKURU LETTER A..DIVES AKURU LETTER E
+ {0x11909, 0x11909, prN}, // Lo DIVES AKURU LETTER O
+ {0x1190C, 0x11913, prN}, // Lo [8] DIVES AKURU LETTER KA..DIVES AKURU LETTER JA
+ {0x11915, 0x11916, prN}, // Lo [2] DIVES AKURU LETTER NYA..DIVES AKURU LETTER TTA
+ {0x11918, 0x1192F, prN}, // Lo [24] DIVES AKURU LETTER DDA..DIVES AKURU LETTER ZA
+ {0x11930, 0x11935, prN}, // Mc [6] DIVES AKURU VOWEL SIGN AA..DIVES AKURU VOWEL SIGN E
+ {0x11937, 0x11938, prN}, // Mc [2] DIVES AKURU VOWEL SIGN AI..DIVES AKURU VOWEL SIGN O
+ {0x1193B, 0x1193C, prN}, // Mn [2] DIVES AKURU SIGN ANUSVARA..DIVES AKURU SIGN CANDRABINDU
+ {0x1193D, 0x1193D, prN}, // Mc DIVES AKURU SIGN HALANTA
+ {0x1193E, 0x1193E, prN}, // Mn DIVES AKURU VIRAMA
+ {0x1193F, 0x1193F, prN}, // Lo DIVES AKURU PREFIXED NASAL SIGN
+ {0x11940, 0x11940, prN}, // Mc DIVES AKURU MEDIAL YA
+ {0x11941, 0x11941, prN}, // Lo DIVES AKURU INITIAL RA
+ {0x11942, 0x11942, prN}, // Mc DIVES AKURU MEDIAL RA
+ {0x11943, 0x11943, prN}, // Mn DIVES AKURU SIGN NUKTA
+ {0x11944, 0x11946, prN}, // Po [3] DIVES AKURU DOUBLE DANDA..DIVES AKURU END OF TEXT MARK
+ {0x11950, 0x11959, prN}, // Nd [10] DIVES AKURU DIGIT ZERO..DIVES AKURU DIGIT NINE
+ {0x119A0, 0x119A7, prN}, // Lo [8] NANDINAGARI LETTER A..NANDINAGARI LETTER VOCALIC RR
+ {0x119AA, 0x119D0, prN}, // Lo [39] NANDINAGARI LETTER E..NANDINAGARI LETTER RRA
+ {0x119D1, 0x119D3, prN}, // Mc [3] NANDINAGARI VOWEL SIGN AA..NANDINAGARI VOWEL SIGN II
+ {0x119D4, 0x119D7, prN}, // Mn [4] NANDINAGARI VOWEL SIGN U..NANDINAGARI VOWEL SIGN VOCALIC RR
+ {0x119DA, 0x119DB, prN}, // Mn [2] NANDINAGARI VOWEL SIGN E..NANDINAGARI VOWEL SIGN AI
+ {0x119DC, 0x119DF, prN}, // Mc [4] NANDINAGARI VOWEL SIGN O..NANDINAGARI SIGN VISARGA
+ {0x119E0, 0x119E0, prN}, // Mn NANDINAGARI SIGN VIRAMA
+ {0x119E1, 0x119E1, prN}, // Lo NANDINAGARI SIGN AVAGRAHA
+ {0x119E2, 0x119E2, prN}, // Po NANDINAGARI SIGN SIDDHAM
+ {0x119E3, 0x119E3, prN}, // Lo NANDINAGARI HEADSTROKE
+ {0x119E4, 0x119E4, prN}, // Mc NANDINAGARI VOWEL SIGN PRISHTHAMATRA E
+ {0x11A00, 0x11A00, prN}, // Lo ZANABAZAR SQUARE LETTER A
+ {0x11A01, 0x11A0A, prN}, // Mn [10] ZANABAZAR SQUARE VOWEL SIGN I..ZANABAZAR SQUARE VOWEL LENGTH MARK
+ {0x11A0B, 0x11A32, prN}, // Lo [40] ZANABAZAR SQUARE LETTER KA..ZANABAZAR SQUARE LETTER KSSA
+ {0x11A33, 0x11A38, prN}, // Mn [6] ZANABAZAR SQUARE FINAL CONSONANT MARK..ZANABAZAR SQUARE SIGN ANUSVARA
+ {0x11A39, 0x11A39, prN}, // Mc ZANABAZAR SQUARE SIGN VISARGA
+ {0x11A3A, 0x11A3A, prN}, // Lo ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA
+ {0x11A3B, 0x11A3E, prN}, // Mn [4] ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA..ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA
+ {0x11A3F, 0x11A46, prN}, // Po [8] ZANABAZAR SQUARE INITIAL HEAD MARK..ZANABAZAR SQUARE CLOSING DOUBLE-LINED HEAD MARK
+ {0x11A47, 0x11A47, prN}, // Mn ZANABAZAR SQUARE SUBJOINER
+ {0x11A50, 0x11A50, prN}, // Lo SOYOMBO LETTER A
+ {0x11A51, 0x11A56, prN}, // Mn [6] SOYOMBO VOWEL SIGN I..SOYOMBO VOWEL SIGN OE
+ {0x11A57, 0x11A58, prN}, // Mc [2] SOYOMBO VOWEL SIGN AI..SOYOMBO VOWEL SIGN AU
+ {0x11A59, 0x11A5B, prN}, // Mn [3] SOYOMBO VOWEL SIGN VOCALIC R..SOYOMBO VOWEL LENGTH MARK
+ {0x11A5C, 0x11A89, prN}, // Lo [46] SOYOMBO LETTER KA..SOYOMBO CLUSTER-INITIAL LETTER SA
+ {0x11A8A, 0x11A96, prN}, // Mn [13] SOYOMBO FINAL CONSONANT SIGN G..SOYOMBO SIGN ANUSVARA
+ {0x11A97, 0x11A97, prN}, // Mc SOYOMBO SIGN VISARGA
+ {0x11A98, 0x11A99, prN}, // Mn [2] SOYOMBO GEMINATION MARK..SOYOMBO SUBJOINER
+ {0x11A9A, 0x11A9C, prN}, // Po [3] SOYOMBO MARK TSHEG..SOYOMBO MARK DOUBLE SHAD
+ {0x11A9D, 0x11A9D, prN}, // Lo SOYOMBO MARK PLUTA
+ {0x11A9E, 0x11AA2, prN}, // Po [5] SOYOMBO HEAD MARK WITH MOON AND SUN AND TRIPLE FLAME..SOYOMBO TERMINAL MARK-2
+ {0x11AB0, 0x11ABF, prN}, // Lo [16] CANADIAN SYLLABICS NATTILIK HI..CANADIAN SYLLABICS SPA
+ {0x11AC0, 0x11AF8, prN}, // Lo [57] PAU CIN HAU LETTER PA..PAU CIN HAU GLOTTAL STOP FINAL
+ {0x11B00, 0x11B09, prN}, // Po [10] DEVANAGARI HEAD MARK..DEVANAGARI SIGN MINDU
+ {0x11C00, 0x11C08, prN}, // Lo [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L
+ {0x11C0A, 0x11C2E, prN}, // Lo [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA
+ {0x11C2F, 0x11C2F, prN}, // Mc BHAIKSUKI VOWEL SIGN AA
+ {0x11C30, 0x11C36, prN}, // Mn [7] BHAIKSUKI VOWEL SIGN I..BHAIKSUKI VOWEL SIGN VOCALIC L
+ {0x11C38, 0x11C3D, prN}, // Mn [6] BHAIKSUKI VOWEL SIGN E..BHAIKSUKI SIGN ANUSVARA
+ {0x11C3E, 0x11C3E, prN}, // Mc BHAIKSUKI SIGN VISARGA
+ {0x11C3F, 0x11C3F, prN}, // Mn BHAIKSUKI SIGN VIRAMA
+ {0x11C40, 0x11C40, prN}, // Lo BHAIKSUKI SIGN AVAGRAHA
+ {0x11C41, 0x11C45, prN}, // Po [5] BHAIKSUKI DANDA..BHAIKSUKI GAP FILLER-2
+ {0x11C50, 0x11C59, prN}, // Nd [10] BHAIKSUKI DIGIT ZERO..BHAIKSUKI DIGIT NINE
+ {0x11C5A, 0x11C6C, prN}, // No [19] BHAIKSUKI NUMBER ONE..BHAIKSUKI HUNDREDS UNIT MARK
+ {0x11C70, 0x11C71, prN}, // Po [2] MARCHEN HEAD MARK..MARCHEN MARK SHAD
+ {0x11C72, 0x11C8F, prN}, // Lo [30] MARCHEN LETTER KA..MARCHEN LETTER A
+ {0x11C92, 0x11CA7, prN}, // Mn [22] MARCHEN SUBJOINED LETTER KA..MARCHEN SUBJOINED LETTER ZA
+ {0x11CA9, 0x11CA9, prN}, // Mc MARCHEN SUBJOINED LETTER YA
+ {0x11CAA, 0x11CB0, prN}, // Mn [7] MARCHEN SUBJOINED LETTER RA..MARCHEN VOWEL SIGN AA
+ {0x11CB1, 0x11CB1, prN}, // Mc MARCHEN VOWEL SIGN I
+ {0x11CB2, 0x11CB3, prN}, // Mn [2] MARCHEN VOWEL SIGN U..MARCHEN VOWEL SIGN E
+ {0x11CB4, 0x11CB4, prN}, // Mc MARCHEN VOWEL SIGN O
+ {0x11CB5, 0x11CB6, prN}, // Mn [2] MARCHEN SIGN ANUSVARA..MARCHEN SIGN CANDRABINDU
+ {0x11D00, 0x11D06, prN}, // Lo [7] MASARAM GONDI LETTER A..MASARAM GONDI LETTER E
+ {0x11D08, 0x11D09, prN}, // Lo [2] MASARAM GONDI LETTER AI..MASARAM GONDI LETTER O
+ {0x11D0B, 0x11D30, prN}, // Lo [38] MASARAM GONDI LETTER AU..MASARAM GONDI LETTER TRA
+ {0x11D31, 0x11D36, prN}, // Mn [6] MASARAM GONDI VOWEL SIGN AA..MASARAM GONDI VOWEL SIGN VOCALIC R
+ {0x11D3A, 0x11D3A, prN}, // Mn MASARAM GONDI VOWEL SIGN E
+ {0x11D3C, 0x11D3D, prN}, // Mn [2] MASARAM GONDI VOWEL SIGN AI..MASARAM GONDI VOWEL SIGN O
+ {0x11D3F, 0x11D45, prN}, // Mn [7] MASARAM GONDI VOWEL SIGN AU..MASARAM GONDI VIRAMA
+ {0x11D46, 0x11D46, prN}, // Lo MASARAM GONDI REPHA
+ {0x11D47, 0x11D47, prN}, // Mn MASARAM GONDI RA-KARA
+ {0x11D50, 0x11D59, prN}, // Nd [10] MASARAM GONDI DIGIT ZERO..MASARAM GONDI DIGIT NINE
+ {0x11D60, 0x11D65, prN}, // Lo [6] GUNJALA GONDI LETTER A..GUNJALA GONDI LETTER UU
+ {0x11D67, 0x11D68, prN}, // Lo [2] GUNJALA GONDI LETTER EE..GUNJALA GONDI LETTER AI
+ {0x11D6A, 0x11D89, prN}, // Lo [32] GUNJALA GONDI LETTER OO..GUNJALA GONDI LETTER SA
+ {0x11D8A, 0x11D8E, prN}, // Mc [5] GUNJALA GONDI VOWEL SIGN AA..GUNJALA GONDI VOWEL SIGN UU
+ {0x11D90, 0x11D91, prN}, // Mn [2] GUNJALA GONDI VOWEL SIGN EE..GUNJALA GONDI VOWEL SIGN AI
+ {0x11D93, 0x11D94, prN}, // Mc [2] GUNJALA GONDI VOWEL SIGN OO..GUNJALA GONDI VOWEL SIGN AU
+ {0x11D95, 0x11D95, prN}, // Mn GUNJALA GONDI SIGN ANUSVARA
+ {0x11D96, 0x11D96, prN}, // Mc GUNJALA GONDI SIGN VISARGA
+ {0x11D97, 0x11D97, prN}, // Mn GUNJALA GONDI VIRAMA
+ {0x11D98, 0x11D98, prN}, // Lo GUNJALA GONDI OM
+ {0x11DA0, 0x11DA9, prN}, // Nd [10] GUNJALA GONDI DIGIT ZERO..GUNJALA GONDI DIGIT NINE
+ {0x11EE0, 0x11EF2, prN}, // Lo [19] MAKASAR LETTER KA..MAKASAR ANGKA
+ {0x11EF3, 0x11EF4, prN}, // Mn [2] MAKASAR VOWEL SIGN I..MAKASAR VOWEL SIGN U
+ {0x11EF5, 0x11EF6, prN}, // Mc [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O
+ {0x11EF7, 0x11EF8, prN}, // Po [2] MAKASAR PASSIMBANG..MAKASAR END OF SECTION
+ {0x11F00, 0x11F01, prN}, // Mn [2] KAWI SIGN CANDRABINDU..KAWI SIGN ANUSVARA
+ {0x11F02, 0x11F02, prN}, // Lo KAWI SIGN REPHA
+ {0x11F03, 0x11F03, prN}, // Mc KAWI SIGN VISARGA
+ {0x11F04, 0x11F10, prN}, // Lo [13] KAWI LETTER A..KAWI LETTER O
+ {0x11F12, 0x11F33, prN}, // Lo [34] KAWI LETTER KA..KAWI LETTER JNYA
+ {0x11F34, 0x11F35, prN}, // Mc [2] KAWI VOWEL SIGN AA..KAWI VOWEL SIGN ALTERNATE AA
+ {0x11F36, 0x11F3A, prN}, // Mn [5] KAWI VOWEL SIGN I..KAWI VOWEL SIGN VOCALIC R
+ {0x11F3E, 0x11F3F, prN}, // Mc [2] KAWI VOWEL SIGN E..KAWI VOWEL SIGN AI
+ {0x11F40, 0x11F40, prN}, // Mn KAWI VOWEL SIGN EU
+ {0x11F41, 0x11F41, prN}, // Mc KAWI SIGN KILLER
+ {0x11F42, 0x11F42, prN}, // Mn KAWI CONJOINER
+ {0x11F43, 0x11F4F, prN}, // Po [13] KAWI DANDA..KAWI PUNCTUATION CLOSING SPIRAL
+ {0x11F50, 0x11F59, prN}, // Nd [10] KAWI DIGIT ZERO..KAWI DIGIT NINE
+ {0x11FB0, 0x11FB0, prN}, // Lo LISU LETTER YHA
+ {0x11FC0, 0x11FD4, prN}, // No [21] TAMIL FRACTION ONE THREE-HUNDRED-AND-TWENTIETH..TAMIL FRACTION DOWNSCALING FACTOR KIIZH
+ {0x11FD5, 0x11FDC, prN}, // So [8] TAMIL SIGN NEL..TAMIL SIGN MUKKURUNI
+ {0x11FDD, 0x11FE0, prN}, // Sc [4] TAMIL SIGN KAACU..TAMIL SIGN VARAAKAN
+ {0x11FE1, 0x11FF1, prN}, // So [17] TAMIL SIGN PAARAM..TAMIL SIGN VAKAIYARAA
+ {0x11FFF, 0x11FFF, prN}, // Po TAMIL PUNCTUATION END OF TEXT
+ {0x12000, 0x12399, prN}, // Lo [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U
+ {0x12400, 0x1246E, prN}, // Nl [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM
+ {0x12470, 0x12474, prN}, // Po [5] CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER..CUNEIFORM PUNCTUATION SIGN DIAGONAL QUADCOLON
+ {0x12480, 0x12543, prN}, // Lo [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU
+ {0x12F90, 0x12FF0, prN}, // Lo [97] CYPRO-MINOAN SIGN CM001..CYPRO-MINOAN SIGN CM114
+ {0x12FF1, 0x12FF2, prN}, // Po [2] CYPRO-MINOAN SIGN CM301..CYPRO-MINOAN SIGN CM302
+ {0x13000, 0x1342F, prN}, // Lo [1072] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH V011D
+ {0x13430, 0x1343F, prN}, // Cf [16] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH END WALLED ENCLOSURE
+ {0x13440, 0x13440, prN}, // Mn EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY
+ {0x13441, 0x13446, prN}, // Lo [6] EGYPTIAN HIEROGLYPH FULL BLANK..EGYPTIAN HIEROGLYPH WIDE LOST SIGN
+ {0x13447, 0x13455, prN}, // Mn [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED
+ {0x14400, 0x14646, prN}, // Lo [583] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A530
+ {0x16800, 0x16A38, prN}, // Lo [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ
+ {0x16A40, 0x16A5E, prN}, // Lo [31] MRO LETTER TA..MRO LETTER TEK
+ {0x16A60, 0x16A69, prN}, // Nd [10] MRO DIGIT ZERO..MRO DIGIT NINE
+ {0x16A6E, 0x16A6F, prN}, // Po [2] MRO DANDA..MRO DOUBLE DANDA
+ {0x16A70, 0x16ABE, prN}, // Lo [79] TANGSA LETTER OZ..TANGSA LETTER ZA
+ {0x16AC0, 0x16AC9, prN}, // Nd [10] TANGSA DIGIT ZERO..TANGSA DIGIT NINE
+ {0x16AD0, 0x16AED, prN}, // Lo [30] BASSA VAH LETTER ENNI..BASSA VAH LETTER I
+ {0x16AF0, 0x16AF4, prN}, // Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE
+ {0x16AF5, 0x16AF5, prN}, // Po BASSA VAH FULL STOP
+ {0x16B00, 0x16B2F, prN}, // Lo [48] PAHAWH HMONG VOWEL KEEB..PAHAWH HMONG CONSONANT CAU
+ {0x16B30, 0x16B36, prN}, // Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM
+ {0x16B37, 0x16B3B, prN}, // Po [5] PAHAWH HMONG SIGN VOS THOM..PAHAWH HMONG SIGN VOS FEEM
+ {0x16B3C, 0x16B3F, prN}, // So [4] PAHAWH HMONG SIGN XYEEM NTXIV..PAHAWH HMONG SIGN XYEEM FAIB
+ {0x16B40, 0x16B43, prN}, // Lm [4] PAHAWH HMONG SIGN VOS SEEV..PAHAWH HMONG SIGN IB YAM
+ {0x16B44, 0x16B44, prN}, // Po PAHAWH HMONG SIGN XAUS
+ {0x16B45, 0x16B45, prN}, // So PAHAWH HMONG SIGN CIM TSOV ROG
+ {0x16B50, 0x16B59, prN}, // Nd [10] PAHAWH HMONG DIGIT ZERO..PAHAWH HMONG DIGIT NINE
+ {0x16B5B, 0x16B61, prN}, // No [7] PAHAWH HMONG NUMBER TENS..PAHAWH HMONG NUMBER TRILLIONS
+ {0x16B63, 0x16B77, prN}, // Lo [21] PAHAWH HMONG SIGN VOS LUB..PAHAWH HMONG SIGN CIM NRES TOS
+ {0x16B7D, 0x16B8F, prN}, // Lo [19] PAHAWH HMONG CLAN SIGN TSHEEJ..PAHAWH HMONG CLAN SIGN VWJ
+ {0x16E40, 0x16E7F, prN}, // L& [64] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN SMALL LETTER Y
+ {0x16E80, 0x16E96, prN}, // No [23] MEDEFAIDRIN DIGIT ZERO..MEDEFAIDRIN DIGIT THREE ALTERNATE FORM
+ {0x16E97, 0x16E9A, prN}, // Po [4] MEDEFAIDRIN COMMA..MEDEFAIDRIN EXCLAMATION OH
+ {0x16F00, 0x16F4A, prN}, // Lo [75] MIAO LETTER PA..MIAO LETTER RTE
+ {0x16F4F, 0x16F4F, prN}, // Mn MIAO SIGN CONSONANT MODIFIER BAR
+ {0x16F50, 0x16F50, prN}, // Lo MIAO LETTER NASALIZATION
+ {0x16F51, 0x16F87, prN}, // Mc [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI
+ {0x16F8F, 0x16F92, prN}, // Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW
+ {0x16F93, 0x16F9F, prN}, // Lm [13] MIAO LETTER TONE-2..MIAO LETTER REFORMED TONE-8
+ {0x16FE0, 0x16FE1, prW}, // Lm [2] TANGUT ITERATION MARK..NUSHU ITERATION MARK
+ {0x16FE2, 0x16FE2, prW}, // Po OLD CHINESE HOOK MARK
+ {0x16FE3, 0x16FE3, prW}, // Lm OLD CHINESE ITERATION MARK
+ {0x16FE4, 0x16FE4, prW}, // Mn KHITAN SMALL SCRIPT FILLER
+ {0x16FF0, 0x16FF1, prW}, // Mc [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY
+ {0x17000, 0x187F7, prW}, // Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7
+ {0x18800, 0x18AFF, prW}, // Lo [768] TANGUT COMPONENT-001..TANGUT COMPONENT-768
+ {0x18B00, 0x18CD5, prW}, // Lo [470] KHITAN SMALL SCRIPT CHARACTER-18B00..KHITAN SMALL SCRIPT CHARACTER-18CD5
+ {0x18D00, 0x18D08, prW}, // Lo [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08
+ {0x1AFF0, 0x1AFF3, prW}, // Lm [4] KATAKANA LETTER MINNAN TONE-2..KATAKANA LETTER MINNAN TONE-5
+ {0x1AFF5, 0x1AFFB, prW}, // Lm [7] KATAKANA LETTER MINNAN TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-5
+ {0x1AFFD, 0x1AFFE, prW}, // Lm [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8
+ {0x1B000, 0x1B0FF, prW}, // Lo [256] KATAKANA LETTER ARCHAIC E..HENTAIGANA LETTER RE-2
+ {0x1B100, 0x1B122, prW}, // Lo [35] HENTAIGANA LETTER RE-3..KATAKANA LETTER ARCHAIC WU
+ {0x1B132, 0x1B132, prW}, // Lo HIRAGANA LETTER SMALL KO
+ {0x1B150, 0x1B152, prW}, // Lo [3] HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO
+ {0x1B155, 0x1B155, prW}, // Lo KATAKANA LETTER SMALL KO
+ {0x1B164, 0x1B167, prW}, // Lo [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N
+ {0x1B170, 0x1B2FB, prW}, // Lo [396] NUSHU CHARACTER-1B170..NUSHU CHARACTER-1B2FB
+ {0x1BC00, 0x1BC6A, prN}, // Lo [107] DUPLOYAN LETTER H..DUPLOYAN LETTER VOCALIC M
+ {0x1BC70, 0x1BC7C, prN}, // Lo [13] DUPLOYAN AFFIX LEFT HORIZONTAL SECANT..DUPLOYAN AFFIX ATTACHED TANGENT HOOK
+ {0x1BC80, 0x1BC88, prN}, // Lo [9] DUPLOYAN AFFIX HIGH ACUTE..DUPLOYAN AFFIX HIGH VERTICAL
+ {0x1BC90, 0x1BC99, prN}, // Lo [10] DUPLOYAN AFFIX LOW ACUTE..DUPLOYAN AFFIX LOW ARROW
+ {0x1BC9C, 0x1BC9C, prN}, // So DUPLOYAN SIGN O WITH CROSS
+ {0x1BC9D, 0x1BC9E, prN}, // Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK
+ {0x1BC9F, 0x1BC9F, prN}, // Po DUPLOYAN PUNCTUATION CHINOOK FULL STOP
+ {0x1BCA0, 0x1BCA3, prN}, // Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP
+ {0x1CF00, 0x1CF2D, prN}, // Mn [46] ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT..ZNAMENNY COMBINING MARK KRYZH ON LEFT
+ {0x1CF30, 0x1CF46, prN}, // Mn [23] ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO..ZNAMENNY PRIZNAK MODIFIER ROG
+ {0x1CF50, 0x1CFC3, prN}, // So [116] ZNAMENNY NEUME KRYUK..ZNAMENNY NEUME PAUK
+ {0x1D000, 0x1D0F5, prN}, // So [246] BYZANTINE MUSICAL SYMBOL PSILI..BYZANTINE MUSICAL SYMBOL GORGON NEO KATO
+ {0x1D100, 0x1D126, prN}, // So [39] MUSICAL SYMBOL SINGLE BARLINE..MUSICAL SYMBOL DRUM CLEF-2
+ {0x1D129, 0x1D164, prN}, // So [60] MUSICAL SYMBOL MULTIPLE MEASURE REST..MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE
+ {0x1D165, 0x1D166, prN}, // Mc [2] MUSICAL SYMBOL COMBINING STEM..MUSICAL SYMBOL COMBINING SPRECHGESANG STEM
+ {0x1D167, 0x1D169, prN}, // Mn [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3
+ {0x1D16A, 0x1D16C, prN}, // So [3] MUSICAL SYMBOL FINGERED TREMOLO-1..MUSICAL SYMBOL FINGERED TREMOLO-3
+ {0x1D16D, 0x1D172, prN}, // Mc [6] MUSICAL SYMBOL COMBINING AUGMENTATION DOT..MUSICAL SYMBOL COMBINING FLAG-5
+ {0x1D173, 0x1D17A, prN}, // Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE
+ {0x1D17B, 0x1D182, prN}, // Mn [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE
+ {0x1D183, 0x1D184, prN}, // So [2] MUSICAL SYMBOL ARPEGGIATO UP..MUSICAL SYMBOL ARPEGGIATO DOWN
+ {0x1D185, 0x1D18B, prN}, // Mn [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE
+ {0x1D18C, 0x1D1A9, prN}, // So [30] MUSICAL SYMBOL RINFORZANDO..MUSICAL SYMBOL DEGREE SLASH
+ {0x1D1AA, 0x1D1AD, prN}, // Mn [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO
+ {0x1D1AE, 0x1D1EA, prN}, // So [61] MUSICAL SYMBOL PEDAL MARK..MUSICAL SYMBOL KORON
+ {0x1D200, 0x1D241, prN}, // So [66] GREEK VOCAL NOTATION SYMBOL-1..GREEK INSTRUMENTAL NOTATION SYMBOL-54
+ {0x1D242, 0x1D244, prN}, // Mn [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME
+ {0x1D245, 0x1D245, prN}, // So GREEK MUSICAL LEIMMA
+ {0x1D2C0, 0x1D2D3, prN}, // No [20] KAKTOVIK NUMERAL ZERO..KAKTOVIK NUMERAL NINETEEN
+ {0x1D2E0, 0x1D2F3, prN}, // No [20] MAYAN NUMERAL ZERO..MAYAN NUMERAL NINETEEN
+ {0x1D300, 0x1D356, prN}, // So [87] MONOGRAM FOR EARTH..TETRAGRAM FOR FOSTERING
+ {0x1D360, 0x1D378, prN}, // No [25] COUNTING ROD UNIT DIGIT ONE..TALLY MARK FIVE
+ {0x1D400, 0x1D454, prN}, // L& [85] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL ITALIC SMALL G
+ {0x1D456, 0x1D49C, prN}, // L& [71] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL SCRIPT CAPITAL A
+ {0x1D49E, 0x1D49F, prN}, // Lu [2] MATHEMATICAL SCRIPT CAPITAL C..MATHEMATICAL SCRIPT CAPITAL D
+ {0x1D4A2, 0x1D4A2, prN}, // Lu MATHEMATICAL SCRIPT CAPITAL G
+ {0x1D4A5, 0x1D4A6, prN}, // Lu [2] MATHEMATICAL SCRIPT CAPITAL J..MATHEMATICAL SCRIPT CAPITAL K
+ {0x1D4A9, 0x1D4AC, prN}, // Lu [4] MATHEMATICAL SCRIPT CAPITAL N..MATHEMATICAL SCRIPT CAPITAL Q
+ {0x1D4AE, 0x1D4B9, prN}, // L& [12] MATHEMATICAL SCRIPT CAPITAL S..MATHEMATICAL SCRIPT SMALL D
+ {0x1D4BB, 0x1D4BB, prN}, // Ll MATHEMATICAL SCRIPT SMALL F
+ {0x1D4BD, 0x1D4C3, prN}, // Ll [7] MATHEMATICAL SCRIPT SMALL H..MATHEMATICAL SCRIPT SMALL N
+ {0x1D4C5, 0x1D505, prN}, // L& [65] MATHEMATICAL SCRIPT SMALL P..MATHEMATICAL FRAKTUR CAPITAL B
+ {0x1D507, 0x1D50A, prN}, // Lu [4] MATHEMATICAL FRAKTUR CAPITAL D..MATHEMATICAL FRAKTUR CAPITAL G
+ {0x1D50D, 0x1D514, prN}, // Lu [8] MATHEMATICAL FRAKTUR CAPITAL J..MATHEMATICAL FRAKTUR CAPITAL Q
+ {0x1D516, 0x1D51C, prN}, // Lu [7] MATHEMATICAL FRAKTUR CAPITAL S..MATHEMATICAL FRAKTUR CAPITAL Y
+ {0x1D51E, 0x1D539, prN}, // L& [28] MATHEMATICAL FRAKTUR SMALL A..MATHEMATICAL DOUBLE-STRUCK CAPITAL B
+ {0x1D53B, 0x1D53E, prN}, // Lu [4] MATHEMATICAL DOUBLE-STRUCK CAPITAL D..MATHEMATICAL DOUBLE-STRUCK CAPITAL G
+ {0x1D540, 0x1D544, prN}, // Lu [5] MATHEMATICAL DOUBLE-STRUCK CAPITAL I..MATHEMATICAL DOUBLE-STRUCK CAPITAL M
+ {0x1D546, 0x1D546, prN}, // Lu MATHEMATICAL DOUBLE-STRUCK CAPITAL O
+ {0x1D54A, 0x1D550, prN}, // Lu [7] MATHEMATICAL DOUBLE-STRUCK CAPITAL S..MATHEMATICAL DOUBLE-STRUCK CAPITAL Y
+ {0x1D552, 0x1D6A5, prN}, // L& [340] MATHEMATICAL DOUBLE-STRUCK SMALL A..MATHEMATICAL ITALIC SMALL DOTLESS J
+ {0x1D6A8, 0x1D6C0, prN}, // Lu [25] MATHEMATICAL BOLD CAPITAL ALPHA..MATHEMATICAL BOLD CAPITAL OMEGA
+ {0x1D6C1, 0x1D6C1, prN}, // Sm MATHEMATICAL BOLD NABLA
+ {0x1D6C2, 0x1D6DA, prN}, // Ll [25] MATHEMATICAL BOLD SMALL ALPHA..MATHEMATICAL BOLD SMALL OMEGA
+ {0x1D6DB, 0x1D6DB, prN}, // Sm MATHEMATICAL BOLD PARTIAL DIFFERENTIAL
+ {0x1D6DC, 0x1D6FA, prN}, // L& [31] MATHEMATICAL BOLD EPSILON SYMBOL..MATHEMATICAL ITALIC CAPITAL OMEGA
+ {0x1D6FB, 0x1D6FB, prN}, // Sm MATHEMATICAL ITALIC NABLA
+ {0x1D6FC, 0x1D714, prN}, // Ll [25] MATHEMATICAL ITALIC SMALL ALPHA..MATHEMATICAL ITALIC SMALL OMEGA
+ {0x1D715, 0x1D715, prN}, // Sm MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL
+ {0x1D716, 0x1D734, prN}, // L& [31] MATHEMATICAL ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD ITALIC CAPITAL OMEGA
+ {0x1D735, 0x1D735, prN}, // Sm MATHEMATICAL BOLD ITALIC NABLA
+ {0x1D736, 0x1D74E, prN}, // Ll [25] MATHEMATICAL BOLD ITALIC SMALL ALPHA..MATHEMATICAL BOLD ITALIC SMALL OMEGA
+ {0x1D74F, 0x1D74F, prN}, // Sm MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL
+ {0x1D750, 0x1D76E, prN}, // L& [31] MATHEMATICAL BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA
+ {0x1D76F, 0x1D76F, prN}, // Sm MATHEMATICAL SANS-SERIF BOLD NABLA
+ {0x1D770, 0x1D788, prN}, // Ll [25] MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA
+ {0x1D789, 0x1D789, prN}, // Sm MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL
+ {0x1D78A, 0x1D7A8, prN}, // L& [31] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA
+ {0x1D7A9, 0x1D7A9, prN}, // Sm MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA
+ {0x1D7AA, 0x1D7C2, prN}, // Ll [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA
+ {0x1D7C3, 0x1D7C3, prN}, // Sm MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL
+ {0x1D7C4, 0x1D7CB, prN}, // L& [8] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD SMALL DIGAMMA
+ {0x1D7CE, 0x1D7FF, prN}, // Nd [50] MATHEMATICAL BOLD DIGIT ZERO..MATHEMATICAL MONOSPACE DIGIT NINE
+ {0x1D800, 0x1D9FF, prN}, // So [512] SIGNWRITING HAND-FIST INDEX..SIGNWRITING HEAD
+ {0x1DA00, 0x1DA36, prN}, // Mn [55] SIGNWRITING HEAD RIM..SIGNWRITING AIR SUCKING IN
+ {0x1DA37, 0x1DA3A, prN}, // So [4] SIGNWRITING AIR BLOW SMALL ROTATIONS..SIGNWRITING BREATH EXHALE
+ {0x1DA3B, 0x1DA6C, prN}, // Mn [50] SIGNWRITING MOUTH CLOSED NEUTRAL..SIGNWRITING EXCITEMENT
+ {0x1DA6D, 0x1DA74, prN}, // So [8] SIGNWRITING SHOULDER HIP SPINE..SIGNWRITING TORSO-FLOORPLANE TWISTING
+ {0x1DA75, 0x1DA75, prN}, // Mn SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS
+ {0x1DA76, 0x1DA83, prN}, // So [14] SIGNWRITING LIMB COMBINATION..SIGNWRITING LOCATION DEPTH
+ {0x1DA84, 0x1DA84, prN}, // Mn SIGNWRITING LOCATION HEAD NECK
+ {0x1DA85, 0x1DA86, prN}, // So [2] SIGNWRITING LOCATION TORSO..SIGNWRITING LOCATION LIMBS DIGITS
+ {0x1DA87, 0x1DA8B, prN}, // Po [5] SIGNWRITING COMMA..SIGNWRITING PARENTHESIS
+ {0x1DA9B, 0x1DA9F, prN}, // Mn [5] SIGNWRITING FILL MODIFIER-2..SIGNWRITING FILL MODIFIER-6
+ {0x1DAA1, 0x1DAAF, prN}, // Mn [15] SIGNWRITING ROTATION MODIFIER-2..SIGNWRITING ROTATION MODIFIER-16
+ {0x1DF00, 0x1DF09, prN}, // Ll [10] LATIN SMALL LETTER FENG DIGRAPH WITH TRILL..LATIN SMALL LETTER T WITH HOOK AND RETROFLEX HOOK
+ {0x1DF0A, 0x1DF0A, prN}, // Lo LATIN LETTER RETROFLEX CLICK WITH RETROFLEX HOOK
+ {0x1DF0B, 0x1DF1E, prN}, // Ll [20] LATIN SMALL LETTER ESH WITH DOUBLE BAR..LATIN SMALL LETTER S WITH CURL
+ {0x1DF25, 0x1DF2A, prN}, // Ll [6] LATIN SMALL LETTER D WITH MID-HEIGHT LEFT HOOK..LATIN SMALL LETTER T WITH MID-HEIGHT LEFT HOOK
+ {0x1E000, 0x1E006, prN}, // Mn [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE
+ {0x1E008, 0x1E018, prN}, // Mn [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU
+ {0x1E01B, 0x1E021, prN}, // Mn [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI
+ {0x1E023, 0x1E024, prN}, // Mn [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS
+ {0x1E026, 0x1E02A, prN}, // Mn [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA
+ {0x1E030, 0x1E06D, prN}, // Lm [62] MODIFIER LETTER CYRILLIC SMALL A..MODIFIER LETTER CYRILLIC SMALL STRAIGHT U WITH STROKE
+ {0x1E08F, 0x1E08F, prN}, // Mn COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+ {0x1E100, 0x1E12C, prN}, // Lo [45] NYIAKENG PUACHUE HMONG LETTER MA..NYIAKENG PUACHUE HMONG LETTER W
+ {0x1E130, 0x1E136, prN}, // Mn [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D
+ {0x1E137, 0x1E13D, prN}, // Lm [7] NYIAKENG PUACHUE HMONG SIGN FOR PERSON..NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER
+ {0x1E140, 0x1E149, prN}, // Nd [10] NYIAKENG PUACHUE HMONG DIGIT ZERO..NYIAKENG PUACHUE HMONG DIGIT NINE
+ {0x1E14E, 0x1E14E, prN}, // Lo NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ
+ {0x1E14F, 0x1E14F, prN}, // So NYIAKENG PUACHUE HMONG CIRCLED CA
+ {0x1E290, 0x1E2AD, prN}, // Lo [30] TOTO LETTER PA..TOTO LETTER A
+ {0x1E2AE, 0x1E2AE, prN}, // Mn TOTO SIGN RISING TONE
+ {0x1E2C0, 0x1E2EB, prN}, // Lo [44] WANCHO LETTER AA..WANCHO LETTER YIH
+ {0x1E2EC, 0x1E2EF, prN}, // Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI
+ {0x1E2F0, 0x1E2F9, prN}, // Nd [10] WANCHO DIGIT ZERO..WANCHO DIGIT NINE
+ {0x1E2FF, 0x1E2FF, prN}, // Sc WANCHO NGUN SIGN
+ {0x1E4D0, 0x1E4EA, prN}, // Lo [27] NAG MUNDARI LETTER O..NAG MUNDARI LETTER ELL
+ {0x1E4EB, 0x1E4EB, prN}, // Lm NAG MUNDARI SIGN OJOD
+ {0x1E4EC, 0x1E4EF, prN}, // Mn [4] NAG MUNDARI SIGN MUHOR..NAG MUNDARI SIGN SUTUH
+ {0x1E4F0, 0x1E4F9, prN}, // Nd [10] NAG MUNDARI DIGIT ZERO..NAG MUNDARI DIGIT NINE
+ {0x1E7E0, 0x1E7E6, prN}, // Lo [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO
+ {0x1E7E8, 0x1E7EB, prN}, // Lo [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE
+ {0x1E7ED, 0x1E7EE, prN}, // Lo [2] ETHIOPIC SYLLABLE GURAGE MWI..ETHIOPIC SYLLABLE GURAGE MWEE
+ {0x1E7F0, 0x1E7FE, prN}, // Lo [15] ETHIOPIC SYLLABLE GURAGE QWI..ETHIOPIC SYLLABLE GURAGE PWEE
+ {0x1E800, 0x1E8C4, prN}, // Lo [197] MENDE KIKAKUI SYLLABLE M001 KI..MENDE KIKAKUI SYLLABLE M060 NYON
+ {0x1E8C7, 0x1E8CF, prN}, // No [9] MENDE KIKAKUI DIGIT ONE..MENDE KIKAKUI DIGIT NINE
+ {0x1E8D0, 0x1E8D6, prN}, // Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS
+ {0x1E900, 0x1E943, prN}, // L& [68] ADLAM CAPITAL LETTER ALIF..ADLAM SMALL LETTER SHA
+ {0x1E944, 0x1E94A, prN}, // Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA
+ {0x1E94B, 0x1E94B, prN}, // Lm ADLAM NASALIZATION MARK
+ {0x1E950, 0x1E959, prN}, // Nd [10] ADLAM DIGIT ZERO..ADLAM DIGIT NINE
+ {0x1E95E, 0x1E95F, prN}, // Po [2] ADLAM INITIAL EXCLAMATION MARK..ADLAM INITIAL QUESTION MARK
+ {0x1EC71, 0x1ECAB, prN}, // No [59] INDIC SIYAQ NUMBER ONE..INDIC SIYAQ NUMBER PREFIXED NINE
+ {0x1ECAC, 0x1ECAC, prN}, // So INDIC SIYAQ PLACEHOLDER
+ {0x1ECAD, 0x1ECAF, prN}, // No [3] INDIC SIYAQ FRACTION ONE QUARTER..INDIC SIYAQ FRACTION THREE QUARTERS
+ {0x1ECB0, 0x1ECB0, prN}, // Sc INDIC SIYAQ RUPEE MARK
+ {0x1ECB1, 0x1ECB4, prN}, // No [4] INDIC SIYAQ NUMBER ALTERNATE ONE..INDIC SIYAQ ALTERNATE LAKH MARK
+ {0x1ED01, 0x1ED2D, prN}, // No [45] OTTOMAN SIYAQ NUMBER ONE..OTTOMAN SIYAQ NUMBER NINETY THOUSAND
+ {0x1ED2E, 0x1ED2E, prN}, // So OTTOMAN SIYAQ MARRATAN
+ {0x1ED2F, 0x1ED3D, prN}, // No [15] OTTOMAN SIYAQ ALTERNATE NUMBER TWO..OTTOMAN SIYAQ FRACTION ONE SIXTH
+ {0x1EE00, 0x1EE03, prN}, // Lo [4] ARABIC MATHEMATICAL ALEF..ARABIC MATHEMATICAL DAL
+ {0x1EE05, 0x1EE1F, prN}, // Lo [27] ARABIC MATHEMATICAL WAW..ARABIC MATHEMATICAL DOTLESS QAF
+ {0x1EE21, 0x1EE22, prN}, // Lo [2] ARABIC MATHEMATICAL INITIAL BEH..ARABIC MATHEMATICAL INITIAL JEEM
+ {0x1EE24, 0x1EE24, prN}, // Lo ARABIC MATHEMATICAL INITIAL HEH
+ {0x1EE27, 0x1EE27, prN}, // Lo ARABIC MATHEMATICAL INITIAL HAH
+ {0x1EE29, 0x1EE32, prN}, // Lo [10] ARABIC MATHEMATICAL INITIAL YEH..ARABIC MATHEMATICAL INITIAL QAF
+ {0x1EE34, 0x1EE37, prN}, // Lo [4] ARABIC MATHEMATICAL INITIAL SHEEN..ARABIC MATHEMATICAL INITIAL KHAH
+ {0x1EE39, 0x1EE39, prN}, // Lo ARABIC MATHEMATICAL INITIAL DAD
+ {0x1EE3B, 0x1EE3B, prN}, // Lo ARABIC MATHEMATICAL INITIAL GHAIN
+ {0x1EE42, 0x1EE42, prN}, // Lo ARABIC MATHEMATICAL TAILED JEEM
+ {0x1EE47, 0x1EE47, prN}, // Lo ARABIC MATHEMATICAL TAILED HAH
+ {0x1EE49, 0x1EE49, prN}, // Lo ARABIC MATHEMATICAL TAILED YEH
+ {0x1EE4B, 0x1EE4B, prN}, // Lo ARABIC MATHEMATICAL TAILED LAM
+ {0x1EE4D, 0x1EE4F, prN}, // Lo [3] ARABIC MATHEMATICAL TAILED NOON..ARABIC MATHEMATICAL TAILED AIN
+ {0x1EE51, 0x1EE52, prN}, // Lo [2] ARABIC MATHEMATICAL TAILED SAD..ARABIC MATHEMATICAL TAILED QAF
+ {0x1EE54, 0x1EE54, prN}, // Lo ARABIC MATHEMATICAL TAILED SHEEN
+ {0x1EE57, 0x1EE57, prN}, // Lo ARABIC MATHEMATICAL TAILED KHAH
+ {0x1EE59, 0x1EE59, prN}, // Lo ARABIC MATHEMATICAL TAILED DAD
+ {0x1EE5B, 0x1EE5B, prN}, // Lo ARABIC MATHEMATICAL TAILED GHAIN
+ {0x1EE5D, 0x1EE5D, prN}, // Lo ARABIC MATHEMATICAL TAILED DOTLESS NOON
+ {0x1EE5F, 0x1EE5F, prN}, // Lo ARABIC MATHEMATICAL TAILED DOTLESS QAF
+ {0x1EE61, 0x1EE62, prN}, // Lo [2] ARABIC MATHEMATICAL STRETCHED BEH..ARABIC MATHEMATICAL STRETCHED JEEM
+ {0x1EE64, 0x1EE64, prN}, // Lo ARABIC MATHEMATICAL STRETCHED HEH
+ {0x1EE67, 0x1EE6A, prN}, // Lo [4] ARABIC MATHEMATICAL STRETCHED HAH..ARABIC MATHEMATICAL STRETCHED KAF
+ {0x1EE6C, 0x1EE72, prN}, // Lo [7] ARABIC MATHEMATICAL STRETCHED MEEM..ARABIC MATHEMATICAL STRETCHED QAF
+ {0x1EE74, 0x1EE77, prN}, // Lo [4] ARABIC MATHEMATICAL STRETCHED SHEEN..ARABIC MATHEMATICAL STRETCHED KHAH
+ {0x1EE79, 0x1EE7C, prN}, // Lo [4] ARABIC MATHEMATICAL STRETCHED DAD..ARABIC MATHEMATICAL STRETCHED DOTLESS BEH
+ {0x1EE7E, 0x1EE7E, prN}, // Lo ARABIC MATHEMATICAL STRETCHED DOTLESS FEH
+ {0x1EE80, 0x1EE89, prN}, // Lo [10] ARABIC MATHEMATICAL LOOPED ALEF..ARABIC MATHEMATICAL LOOPED YEH
+ {0x1EE8B, 0x1EE9B, prN}, // Lo [17] ARABIC MATHEMATICAL LOOPED LAM..ARABIC MATHEMATICAL LOOPED GHAIN
+ {0x1EEA1, 0x1EEA3, prN}, // Lo [3] ARABIC MATHEMATICAL DOUBLE-STRUCK BEH..ARABIC MATHEMATICAL DOUBLE-STRUCK DAL
+ {0x1EEA5, 0x1EEA9, prN}, // Lo [5] ARABIC MATHEMATICAL DOUBLE-STRUCK WAW..ARABIC MATHEMATICAL DOUBLE-STRUCK YEH
+ {0x1EEAB, 0x1EEBB, prN}, // Lo [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN
+ {0x1EEF0, 0x1EEF1, prN}, // Sm [2] ARABIC MATHEMATICAL OPERATOR MEEM WITH HAH WITH TATWEEL..ARABIC MATHEMATICAL OPERATOR HAH WITH DAL
+ {0x1F000, 0x1F003, prN}, // So [4] MAHJONG TILE EAST WIND..MAHJONG TILE NORTH WIND
+ {0x1F004, 0x1F004, prW}, // So MAHJONG TILE RED DRAGON
+ {0x1F005, 0x1F02B, prN}, // So [39] MAHJONG TILE GREEN DRAGON..MAHJONG TILE BACK
+ {0x1F030, 0x1F093, prN}, // So [100] DOMINO TILE HORIZONTAL BACK..DOMINO TILE VERTICAL-06-06
+ {0x1F0A0, 0x1F0AE, prN}, // So [15] PLAYING CARD BACK..PLAYING CARD KING OF SPADES
+ {0x1F0B1, 0x1F0BF, prN}, // So [15] PLAYING CARD ACE OF HEARTS..PLAYING CARD RED JOKER
+ {0x1F0C1, 0x1F0CE, prN}, // So [14] PLAYING CARD ACE OF DIAMONDS..PLAYING CARD KING OF DIAMONDS
+ {0x1F0CF, 0x1F0CF, prW}, // So PLAYING CARD BLACK JOKER
+ {0x1F0D1, 0x1F0F5, prN}, // So [37] PLAYING CARD ACE OF CLUBS..PLAYING CARD TRUMP-21
+ {0x1F100, 0x1F10A, prA}, // No [11] DIGIT ZERO FULL STOP..DIGIT NINE COMMA
+ {0x1F10B, 0x1F10C, prN}, // No [2] DINGBAT CIRCLED SANS-SERIF DIGIT ZERO..DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ZERO
+ {0x1F10D, 0x1F10F, prN}, // So [3] CIRCLED ZERO WITH SLASH..CIRCLED DOLLAR SIGN WITH OVERLAID BACKSLASH
+ {0x1F110, 0x1F12D, prA}, // So [30] PARENTHESIZED LATIN CAPITAL LETTER A..CIRCLED CD
+ {0x1F12E, 0x1F12F, prN}, // So [2] CIRCLED WZ..COPYLEFT SYMBOL
+ {0x1F130, 0x1F169, prA}, // So [58] SQUARED LATIN CAPITAL LETTER A..NEGATIVE CIRCLED LATIN CAPITAL LETTER Z
+ {0x1F16A, 0x1F16F, prN}, // So [6] RAISED MC SIGN..CIRCLED HUMAN FIGURE
+ {0x1F170, 0x1F18D, prA}, // So [30] NEGATIVE SQUARED LATIN CAPITAL LETTER A..NEGATIVE SQUARED SA
+ {0x1F18E, 0x1F18E, prW}, // So NEGATIVE SQUARED AB
+ {0x1F18F, 0x1F190, prA}, // So [2] NEGATIVE SQUARED WC..SQUARE DJ
+ {0x1F191, 0x1F19A, prW}, // So [10] SQUARED CL..SQUARED VS
+ {0x1F19B, 0x1F1AC, prA}, // So [18] SQUARED THREE D..SQUARED VOD
+ {0x1F1AD, 0x1F1AD, prN}, // So MASK WORK SYMBOL
+ {0x1F1E6, 0x1F1FF, prN}, // So [26] REGIONAL INDICATOR SYMBOL LETTER A..REGIONAL INDICATOR SYMBOL LETTER Z
+ {0x1F200, 0x1F202, prW}, // So [3] SQUARE HIRAGANA HOKA..SQUARED KATAKANA SA
+ {0x1F210, 0x1F23B, prW}, // So [44] SQUARED CJK UNIFIED IDEOGRAPH-624B..SQUARED CJK UNIFIED IDEOGRAPH-914D
+ {0x1F240, 0x1F248, prW}, // So [9] TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-672C..TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557
+ {0x1F250, 0x1F251, prW}, // So [2] CIRCLED IDEOGRAPH ADVANTAGE..CIRCLED IDEOGRAPH ACCEPT
+ {0x1F260, 0x1F265, prW}, // So [6] ROUNDED SYMBOL FOR FU..ROUNDED SYMBOL FOR CAI
+ {0x1F300, 0x1F320, prW}, // So [33] CYCLONE..SHOOTING STAR
+ {0x1F321, 0x1F32C, prN}, // So [12] THERMOMETER..WIND BLOWING FACE
+ {0x1F32D, 0x1F335, prW}, // So [9] HOT DOG..CACTUS
+ {0x1F336, 0x1F336, prN}, // So HOT PEPPER
+ {0x1F337, 0x1F37C, prW}, // So [70] TULIP..BABY BOTTLE
+ {0x1F37D, 0x1F37D, prN}, // So FORK AND KNIFE WITH PLATE
+ {0x1F37E, 0x1F393, prW}, // So [22] BOTTLE WITH POPPING CORK..GRADUATION CAP
+ {0x1F394, 0x1F39F, prN}, // So [12] HEART WITH TIP ON THE LEFT..ADMISSION TICKETS
+ {0x1F3A0, 0x1F3CA, prW}, // So [43] CAROUSEL HORSE..SWIMMER
+ {0x1F3CB, 0x1F3CE, prN}, // So [4] WEIGHT LIFTER..RACING CAR
+ {0x1F3CF, 0x1F3D3, prW}, // So [5] CRICKET BAT AND BALL..TABLE TENNIS PADDLE AND BALL
+ {0x1F3D4, 0x1F3DF, prN}, // So [12] SNOW CAPPED MOUNTAIN..STADIUM
+ {0x1F3E0, 0x1F3F0, prW}, // So [17] HOUSE BUILDING..EUROPEAN CASTLE
+ {0x1F3F1, 0x1F3F3, prN}, // So [3] WHITE PENNANT..WAVING WHITE FLAG
+ {0x1F3F4, 0x1F3F4, prW}, // So WAVING BLACK FLAG
+ {0x1F3F5, 0x1F3F7, prN}, // So [3] ROSETTE..LABEL
+ {0x1F3F8, 0x1F3FA, prW}, // So [3] BADMINTON RACQUET AND SHUTTLECOCK..AMPHORA
+ {0x1F3FB, 0x1F3FF, prW}, // Sk [5] EMOJI MODIFIER FITZPATRICK TYPE-1-2..EMOJI MODIFIER FITZPATRICK TYPE-6
+ {0x1F400, 0x1F43E, prW}, // So [63] RAT..PAW PRINTS
+ {0x1F43F, 0x1F43F, prN}, // So CHIPMUNK
+ {0x1F440, 0x1F440, prW}, // So EYES
+ {0x1F441, 0x1F441, prN}, // So EYE
+ {0x1F442, 0x1F4FC, prW}, // So [187] EAR..VIDEOCASSETTE
+ {0x1F4FD, 0x1F4FE, prN}, // So [2] FILM PROJECTOR..PORTABLE STEREO
+ {0x1F4FF, 0x1F53D, prW}, // So [63] PRAYER BEADS..DOWN-POINTING SMALL RED TRIANGLE
+ {0x1F53E, 0x1F54A, prN}, // So [13] LOWER RIGHT SHADOWED WHITE CIRCLE..DOVE OF PEACE
+ {0x1F54B, 0x1F54E, prW}, // So [4] KAABA..MENORAH WITH NINE BRANCHES
+ {0x1F54F, 0x1F54F, prN}, // So BOWL OF HYGIEIA
+ {0x1F550, 0x1F567, prW}, // So [24] CLOCK FACE ONE OCLOCK..CLOCK FACE TWELVE-THIRTY
+ {0x1F568, 0x1F579, prN}, // So [18] RIGHT SPEAKER..JOYSTICK
+ {0x1F57A, 0x1F57A, prW}, // So MAN DANCING
+ {0x1F57B, 0x1F594, prN}, // So [26] LEFT HAND TELEPHONE RECEIVER..REVERSED VICTORY HAND
+ {0x1F595, 0x1F596, prW}, // So [2] REVERSED HAND WITH MIDDLE FINGER EXTENDED..RAISED HAND WITH PART BETWEEN MIDDLE AND RING FINGERS
+ {0x1F597, 0x1F5A3, prN}, // So [13] WHITE DOWN POINTING LEFT HAND INDEX..BLACK DOWN POINTING BACKHAND INDEX
+ {0x1F5A4, 0x1F5A4, prW}, // So BLACK HEART
+ {0x1F5A5, 0x1F5FA, prN}, // So [86] DESKTOP COMPUTER..WORLD MAP
+ {0x1F5FB, 0x1F5FF, prW}, // So [5] MOUNT FUJI..MOYAI
+ {0x1F600, 0x1F64F, prW}, // So [80] GRINNING FACE..PERSON WITH FOLDED HANDS
+ {0x1F650, 0x1F67F, prN}, // So [48] NORTH WEST POINTING LEAF..REVERSE CHECKER BOARD
+ {0x1F680, 0x1F6C5, prW}, // So [70] ROCKET..LEFT LUGGAGE
+ {0x1F6C6, 0x1F6CB, prN}, // So [6] TRIANGLE WITH ROUNDED CORNERS..COUCH AND LAMP
+ {0x1F6CC, 0x1F6CC, prW}, // So SLEEPING ACCOMMODATION
+ {0x1F6CD, 0x1F6CF, prN}, // So [3] SHOPPING BAGS..BED
+ {0x1F6D0, 0x1F6D2, prW}, // So [3] PLACE OF WORSHIP..SHOPPING TROLLEY
+ {0x1F6D3, 0x1F6D4, prN}, // So [2] STUPA..PAGODA
+ {0x1F6D5, 0x1F6D7, prW}, // So [3] HINDU TEMPLE..ELEVATOR
+ {0x1F6DC, 0x1F6DF, prW}, // So [4] WIRELESS..RING BUOY
+ {0x1F6E0, 0x1F6EA, prN}, // So [11] HAMMER AND WRENCH..NORTHEAST-POINTING AIRPLANE
+ {0x1F6EB, 0x1F6EC, prW}, // So [2] AIRPLANE DEPARTURE..AIRPLANE ARRIVING
+ {0x1F6F0, 0x1F6F3, prN}, // So [4] SATELLITE..PASSENGER SHIP
+ {0x1F6F4, 0x1F6FC, prW}, // So [9] SCOOTER..ROLLER SKATE
+ {0x1F700, 0x1F776, prN}, // So [119] ALCHEMICAL SYMBOL FOR QUINTESSENCE..LUNAR ECLIPSE
+ {0x1F77B, 0x1F77F, prN}, // So [5] HAUMEA..ORCUS
+ {0x1F780, 0x1F7D9, prN}, // So [90] BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE..NINE POINTED WHITE STAR
+ {0x1F7E0, 0x1F7EB, prW}, // So [12] LARGE ORANGE CIRCLE..LARGE BROWN SQUARE
+ {0x1F7F0, 0x1F7F0, prW}, // So HEAVY EQUALS SIGN
+ {0x1F800, 0x1F80B, prN}, // So [12] LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD..DOWNWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD
+ {0x1F810, 0x1F847, prN}, // So [56] LEFTWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD..DOWNWARDS HEAVY ARROW
+ {0x1F850, 0x1F859, prN}, // So [10] LEFTWARDS SANS-SERIF ARROW..UP DOWN SANS-SERIF ARROW
+ {0x1F860, 0x1F887, prN}, // So [40] WIDE-HEADED LEFTWARDS LIGHT BARB ARROW..WIDE-HEADED SOUTH WEST VERY HEAVY BARB ARROW
+ {0x1F890, 0x1F8AD, prN}, // So [30] LEFTWARDS TRIANGLE ARROWHEAD..WHITE ARROW SHAFT WIDTH TWO THIRDS
+ {0x1F8B0, 0x1F8B1, prN}, // So [2] ARROW POINTING UPWARDS THEN NORTH WEST..ARROW POINTING RIGHTWARDS THEN CURVING SOUTH WEST
+ {0x1F900, 0x1F90B, prN}, // So [12] CIRCLED CROSS FORMEE WITH FOUR DOTS..DOWNWARD FACING NOTCHED HOOK WITH DOT
+ {0x1F90C, 0x1F93A, prW}, // So [47] PINCHED FINGERS..FENCER
+ {0x1F93B, 0x1F93B, prN}, // So MODERN PENTATHLON
+ {0x1F93C, 0x1F945, prW}, // So [10] WRESTLERS..GOAL NET
+ {0x1F946, 0x1F946, prN}, // So RIFLE
+ {0x1F947, 0x1F9FF, prW}, // So [185] FIRST PLACE MEDAL..NAZAR AMULET
+ {0x1FA00, 0x1FA53, prN}, // So [84] NEUTRAL CHESS KING..BLACK CHESS KNIGHT-BISHOP
+ {0x1FA60, 0x1FA6D, prN}, // So [14] XIANGQI RED GENERAL..XIANGQI BLACK SOLDIER
+ {0x1FA70, 0x1FA7C, prW}, // So [13] BALLET SHOES..CRUTCH
+ {0x1FA80, 0x1FA88, prW}, // So [9] YO-YO..FLUTE
+ {0x1FA90, 0x1FABD, prW}, // So [46] RINGED PLANET..WING
+ {0x1FABF, 0x1FAC5, prW}, // So [7] GOOSE..PERSON WITH CROWN
+ {0x1FACE, 0x1FADB, prW}, // So [14] MOOSE..PEA POD
+ {0x1FAE0, 0x1FAE8, prW}, // So [9] MELTING FACE..SHAKING FACE
+ {0x1FAF0, 0x1FAF8, prW}, // So [9] HAND WITH INDEX FINGER AND THUMB CROSSED..RIGHTWARDS PUSHING HAND
+ {0x1FB00, 0x1FB92, prN}, // So [147] BLOCK SEXTANT-1..UPPER HALF INVERSE MEDIUM SHADE AND LOWER HALF BLOCK
+ {0x1FB94, 0x1FBCA, prN}, // So [55] LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK..WHITE UP-POINTING CHEVRON
+ {0x1FBF0, 0x1FBF9, prN}, // Nd [10] SEGMENTED DIGIT ZERO..SEGMENTED DIGIT NINE
+ {0x20000, 0x2A6DF, prW}, // Lo [42720] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DF
+ {0x2A6E0, 0x2A6FF, prW}, // Cn [32] ..
+ {0x2A700, 0x2B739, prW}, // Lo [4154] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B739
+ {0x2B73A, 0x2B73F, prW}, // Cn [6] ..
+ {0x2B740, 0x2B81D, prW}, // Lo [222] CJK UNIFIED IDEOGRAPH-2B740..CJK UNIFIED IDEOGRAPH-2B81D
+ {0x2B81E, 0x2B81F, prW}, // Cn [2] ..
+ {0x2B820, 0x2CEA1, prW}, // Lo [5762] CJK UNIFIED IDEOGRAPH-2B820..CJK UNIFIED IDEOGRAPH-2CEA1
+ {0x2CEA2, 0x2CEAF, prW}, // Cn [14] ..
+ {0x2CEB0, 0x2EBE0, prW}, // Lo [7473] CJK UNIFIED IDEOGRAPH-2CEB0..CJK UNIFIED IDEOGRAPH-2EBE0
+ {0x2EBE1, 0x2F7FF, prW}, // Cn [3103] ..
+ {0x2F800, 0x2FA1D, prW}, // Lo [542] CJK COMPATIBILITY IDEOGRAPH-2F800..CJK COMPATIBILITY IDEOGRAPH-2FA1D
+ {0x2FA1E, 0x2FA1F, prW}, // Cn [2] ..
+ {0x2FA20, 0x2FFFD, prW}, // Cn [1502] ..
+ {0x30000, 0x3134A, prW}, // Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A
+ {0x3134B, 0x3134F, prW}, // Cn [5] ..
+ {0x31350, 0x323AF, prW}, // Lo [4192] CJK UNIFIED IDEOGRAPH-31350..CJK UNIFIED IDEOGRAPH-323AF
+ {0x323B0, 0x3FFFD, prW}, // Cn [56398] ..
+ {0xE0001, 0xE0001, prN}, // Cf LANGUAGE TAG
+ {0xE0020, 0xE007F, prN}, // Cf [96] TAG SPACE..CANCEL TAG
+ {0xE0100, 0xE01EF, prA}, // Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
+ {0xF0000, 0xFFFFD, prA}, // Co [65534] ..
+ {0x100000, 0x10FFFD, prA}, // Co [65534] ..
+}
diff --git a/vendor/github.com/rivo/uniseg/emojipresentation.go b/vendor/github.com/rivo/uniseg/emojipresentation.go
new file mode 100644
index 000000000..9b5f499c4
--- /dev/null
+++ b/vendor/github.com/rivo/uniseg/emojipresentation.go
@@ -0,0 +1,295 @@
+// Code generated via go generate from gen_properties.go. DO NOT EDIT.
+
+package uniseg
+
+// emojiPresentation are taken from
+//
+// and
+// https://unicode.org/Public/15.0.0/ucd/emoji/emoji-data.txt
+// ("Extended_Pictographic" only)
+// on September 5, 2023. See https://www.unicode.org/license.html for the Unicode
+// license agreement.
+var emojiPresentation = [][3]int{
+ {0x231A, 0x231B, prEmojiPresentation}, // E0.6 [2] (⌚..⌛) watch..hourglass done
+ {0x23E9, 0x23EC, prEmojiPresentation}, // E0.6 [4] (⏩..⏬) fast-forward button..fast down button
+ {0x23F0, 0x23F0, prEmojiPresentation}, // E0.6 [1] (⏰) alarm clock
+ {0x23F3, 0x23F3, prEmojiPresentation}, // E0.6 [1] (⏳) hourglass not done
+ {0x25FD, 0x25FE, prEmojiPresentation}, // E0.6 [2] (◽..◾) white medium-small square..black medium-small square
+ {0x2614, 0x2615, prEmojiPresentation}, // E0.6 [2] (☔..☕) umbrella with rain drops..hot beverage
+ {0x2648, 0x2653, prEmojiPresentation}, // E0.6 [12] (♈..♓) Aries..Pisces
+ {0x267F, 0x267F, prEmojiPresentation}, // E0.6 [1] (♿) wheelchair symbol
+ {0x2693, 0x2693, prEmojiPresentation}, // E0.6 [1] (⚓) anchor
+ {0x26A1, 0x26A1, prEmojiPresentation}, // E0.6 [1] (⚡) high voltage
+ {0x26AA, 0x26AB, prEmojiPresentation}, // E0.6 [2] (⚪..⚫) white circle..black circle
+ {0x26BD, 0x26BE, prEmojiPresentation}, // E0.6 [2] (⚽..⚾) soccer ball..baseball
+ {0x26C4, 0x26C5, prEmojiPresentation}, // E0.6 [2] (⛄..⛅) snowman without snow..sun behind cloud
+ {0x26CE, 0x26CE, prEmojiPresentation}, // E0.6 [1] (⛎) Ophiuchus
+ {0x26D4, 0x26D4, prEmojiPresentation}, // E0.6 [1] (⛔) no entry
+ {0x26EA, 0x26EA, prEmojiPresentation}, // E0.6 [1] (⛪) church
+ {0x26F2, 0x26F3, prEmojiPresentation}, // E0.6 [2] (⛲..⛳) fountain..flag in hole
+ {0x26F5, 0x26F5, prEmojiPresentation}, // E0.6 [1] (⛵) sailboat
+ {0x26FA, 0x26FA, prEmojiPresentation}, // E0.6 [1] (⛺) tent
+ {0x26FD, 0x26FD, prEmojiPresentation}, // E0.6 [1] (⛽) fuel pump
+ {0x2705, 0x2705, prEmojiPresentation}, // E0.6 [1] (✅) check mark button
+ {0x270A, 0x270B, prEmojiPresentation}, // E0.6 [2] (✊..✋) raised fist..raised hand
+ {0x2728, 0x2728, prEmojiPresentation}, // E0.6 [1] (✨) sparkles
+ {0x274C, 0x274C, prEmojiPresentation}, // E0.6 [1] (❌) cross mark
+ {0x274E, 0x274E, prEmojiPresentation}, // E0.6 [1] (❎) cross mark button
+ {0x2753, 0x2755, prEmojiPresentation}, // E0.6 [3] (❓..❕) red question mark..white exclamation mark
+ {0x2757, 0x2757, prEmojiPresentation}, // E0.6 [1] (❗) red exclamation mark
+ {0x2795, 0x2797, prEmojiPresentation}, // E0.6 [3] (➕..➗) plus..divide
+ {0x27B0, 0x27B0, prEmojiPresentation}, // E0.6 [1] (➰) curly loop
+ {0x27BF, 0x27BF, prEmojiPresentation}, // E1.0 [1] (➿) double curly loop
+ {0x2B1B, 0x2B1C, prEmojiPresentation}, // E0.6 [2] (⬛..⬜) black large square..white large square
+ {0x2B50, 0x2B50, prEmojiPresentation}, // E0.6 [1] (⭐) star
+ {0x2B55, 0x2B55, prEmojiPresentation}, // E0.6 [1] (⭕) hollow red circle
+ {0x1F004, 0x1F004, prEmojiPresentation}, // E0.6 [1] (🀄) mahjong red dragon
+ {0x1F0CF, 0x1F0CF, prEmojiPresentation}, // E0.6 [1] (🃏) joker
+ {0x1F18E, 0x1F18E, prEmojiPresentation}, // E0.6 [1] (🆎) AB button (blood type)
+ {0x1F191, 0x1F19A, prEmojiPresentation}, // E0.6 [10] (🆑..🆚) CL button..VS button
+ {0x1F1E6, 0x1F1FF, prEmojiPresentation}, // E0.0 [26] (🇦..🇿) regional indicator symbol letter a..regional indicator symbol letter z
+ {0x1F201, 0x1F201, prEmojiPresentation}, // E0.6 [1] (🈁) Japanese “here” button
+ {0x1F21A, 0x1F21A, prEmojiPresentation}, // E0.6 [1] (🈚) Japanese “free of charge” button
+ {0x1F22F, 0x1F22F, prEmojiPresentation}, // E0.6 [1] (🈯) Japanese “reserved” button
+ {0x1F232, 0x1F236, prEmojiPresentation}, // E0.6 [5] (🈲..🈶) Japanese “prohibited” button..Japanese “not free of charge” button
+ {0x1F238, 0x1F23A, prEmojiPresentation}, // E0.6 [3] (🈸..🈺) Japanese “application” button..Japanese “open for business” button
+ {0x1F250, 0x1F251, prEmojiPresentation}, // E0.6 [2] (🉐..🉑) Japanese “bargain” button..Japanese “acceptable” button
+ {0x1F300, 0x1F30C, prEmojiPresentation}, // E0.6 [13] (🌀..🌌) cyclone..milky way
+ {0x1F30D, 0x1F30E, prEmojiPresentation}, // E0.7 [2] (🌍..🌎) globe showing Europe-Africa..globe showing Americas
+ {0x1F30F, 0x1F30F, prEmojiPresentation}, // E0.6 [1] (🌏) globe showing Asia-Australia
+ {0x1F310, 0x1F310, prEmojiPresentation}, // E1.0 [1] (🌐) globe with meridians
+ {0x1F311, 0x1F311, prEmojiPresentation}, // E0.6 [1] (🌑) new moon
+ {0x1F312, 0x1F312, prEmojiPresentation}, // E1.0 [1] (🌒) waxing crescent moon
+ {0x1F313, 0x1F315, prEmojiPresentation}, // E0.6 [3] (🌓..🌕) first quarter moon..full moon
+ {0x1F316, 0x1F318, prEmojiPresentation}, // E1.0 [3] (🌖..🌘) waning gibbous moon..waning crescent moon
+ {0x1F319, 0x1F319, prEmojiPresentation}, // E0.6 [1] (🌙) crescent moon
+ {0x1F31A, 0x1F31A, prEmojiPresentation}, // E1.0 [1] (🌚) new moon face
+ {0x1F31B, 0x1F31B, prEmojiPresentation}, // E0.6 [1] (🌛) first quarter moon face
+ {0x1F31C, 0x1F31C, prEmojiPresentation}, // E0.7 [1] (🌜) last quarter moon face
+ {0x1F31D, 0x1F31E, prEmojiPresentation}, // E1.0 [2] (🌝..🌞) full moon face..sun with face
+ {0x1F31F, 0x1F320, prEmojiPresentation}, // E0.6 [2] (🌟..🌠) glowing star..shooting star
+ {0x1F32D, 0x1F32F, prEmojiPresentation}, // E1.0 [3] (🌭..🌯) hot dog..burrito
+ {0x1F330, 0x1F331, prEmojiPresentation}, // E0.6 [2] (🌰..🌱) chestnut..seedling
+ {0x1F332, 0x1F333, prEmojiPresentation}, // E1.0 [2] (🌲..🌳) evergreen tree..deciduous tree
+ {0x1F334, 0x1F335, prEmojiPresentation}, // E0.6 [2] (🌴..🌵) palm tree..cactus
+ {0x1F337, 0x1F34A, prEmojiPresentation}, // E0.6 [20] (🌷..🍊) tulip..tangerine
+ {0x1F34B, 0x1F34B, prEmojiPresentation}, // E1.0 [1] (🍋) lemon
+ {0x1F34C, 0x1F34F, prEmojiPresentation}, // E0.6 [4] (🍌..🍏) banana..green apple
+ {0x1F350, 0x1F350, prEmojiPresentation}, // E1.0 [1] (🍐) pear
+ {0x1F351, 0x1F37B, prEmojiPresentation}, // E0.6 [43] (🍑..🍻) peach..clinking beer mugs
+ {0x1F37C, 0x1F37C, prEmojiPresentation}, // E1.0 [1] (🍼) baby bottle
+ {0x1F37E, 0x1F37F, prEmojiPresentation}, // E1.0 [2] (🍾..🍿) bottle with popping cork..popcorn
+ {0x1F380, 0x1F393, prEmojiPresentation}, // E0.6 [20] (🎀..🎓) ribbon..graduation cap
+ {0x1F3A0, 0x1F3C4, prEmojiPresentation}, // E0.6 [37] (🎠..🏄) carousel horse..person surfing
+ {0x1F3C5, 0x1F3C5, prEmojiPresentation}, // E1.0 [1] (🏅) sports medal
+ {0x1F3C6, 0x1F3C6, prEmojiPresentation}, // E0.6 [1] (🏆) trophy
+ {0x1F3C7, 0x1F3C7, prEmojiPresentation}, // E1.0 [1] (🏇) horse racing
+ {0x1F3C8, 0x1F3C8, prEmojiPresentation}, // E0.6 [1] (🏈) american football
+ {0x1F3C9, 0x1F3C9, prEmojiPresentation}, // E1.0 [1] (🏉) rugby football
+ {0x1F3CA, 0x1F3CA, prEmojiPresentation}, // E0.6 [1] (🏊) person swimming
+ {0x1F3CF, 0x1F3D3, prEmojiPresentation}, // E1.0 [5] (🏏..🏓) cricket game..ping pong
+ {0x1F3E0, 0x1F3E3, prEmojiPresentation}, // E0.6 [4] (🏠..🏣) house..Japanese post office
+ {0x1F3E4, 0x1F3E4, prEmojiPresentation}, // E1.0 [1] (🏤) post office
+ {0x1F3E5, 0x1F3F0, prEmojiPresentation}, // E0.6 [12] (🏥..🏰) hospital..castle
+ {0x1F3F4, 0x1F3F4, prEmojiPresentation}, // E1.0 [1] (🏴) black flag
+ {0x1F3F8, 0x1F407, prEmojiPresentation}, // E1.0 [16] (🏸..🐇) badminton..rabbit
+ {0x1F408, 0x1F408, prEmojiPresentation}, // E0.7 [1] (🐈) cat
+ {0x1F409, 0x1F40B, prEmojiPresentation}, // E1.0 [3] (🐉..🐋) dragon..whale
+ {0x1F40C, 0x1F40E, prEmojiPresentation}, // E0.6 [3] (🐌..🐎) snail..horse
+ {0x1F40F, 0x1F410, prEmojiPresentation}, // E1.0 [2] (🐏..🐐) ram..goat
+ {0x1F411, 0x1F412, prEmojiPresentation}, // E0.6 [2] (🐑..🐒) ewe..monkey
+ {0x1F413, 0x1F413, prEmojiPresentation}, // E1.0 [1] (🐓) rooster
+ {0x1F414, 0x1F414, prEmojiPresentation}, // E0.6 [1] (🐔) chicken
+ {0x1F415, 0x1F415, prEmojiPresentation}, // E0.7 [1] (🐕) dog
+ {0x1F416, 0x1F416, prEmojiPresentation}, // E1.0 [1] (🐖) pig
+ {0x1F417, 0x1F429, prEmojiPresentation}, // E0.6 [19] (🐗..🐩) boar..poodle
+ {0x1F42A, 0x1F42A, prEmojiPresentation}, // E1.0 [1] (🐪) camel
+ {0x1F42B, 0x1F43E, prEmojiPresentation}, // E0.6 [20] (🐫..🐾) two-hump camel..paw prints
+ {0x1F440, 0x1F440, prEmojiPresentation}, // E0.6 [1] (👀) eyes
+ {0x1F442, 0x1F464, prEmojiPresentation}, // E0.6 [35] (👂..👤) ear..bust in silhouette
+ {0x1F465, 0x1F465, prEmojiPresentation}, // E1.0 [1] (👥) busts in silhouette
+ {0x1F466, 0x1F46B, prEmojiPresentation}, // E0.6 [6] (👦..👫) boy..woman and man holding hands
+ {0x1F46C, 0x1F46D, prEmojiPresentation}, // E1.0 [2] (👬..👭) men holding hands..women holding hands
+ {0x1F46E, 0x1F4AC, prEmojiPresentation}, // E0.6 [63] (👮..💬) police officer..speech balloon
+ {0x1F4AD, 0x1F4AD, prEmojiPresentation}, // E1.0 [1] (💭) thought balloon
+ {0x1F4AE, 0x1F4B5, prEmojiPresentation}, // E0.6 [8] (💮..💵) white flower..dollar banknote
+ {0x1F4B6, 0x1F4B7, prEmojiPresentation}, // E1.0 [2] (💶..💷) euro banknote..pound banknote
+ {0x1F4B8, 0x1F4EB, prEmojiPresentation}, // E0.6 [52] (💸..📫) money with wings..closed mailbox with raised flag
+ {0x1F4EC, 0x1F4ED, prEmojiPresentation}, // E0.7 [2] (📬..📭) open mailbox with raised flag..open mailbox with lowered flag
+ {0x1F4EE, 0x1F4EE, prEmojiPresentation}, // E0.6 [1] (📮) postbox
+ {0x1F4EF, 0x1F4EF, prEmojiPresentation}, // E1.0 [1] (📯) postal horn
+ {0x1F4F0, 0x1F4F4, prEmojiPresentation}, // E0.6 [5] (📰..📴) newspaper..mobile phone off
+ {0x1F4F5, 0x1F4F5, prEmojiPresentation}, // E1.0 [1] (📵) no mobile phones
+ {0x1F4F6, 0x1F4F7, prEmojiPresentation}, // E0.6 [2] (📶..📷) antenna bars..camera
+ {0x1F4F8, 0x1F4F8, prEmojiPresentation}, // E1.0 [1] (📸) camera with flash
+ {0x1F4F9, 0x1F4FC, prEmojiPresentation}, // E0.6 [4] (📹..📼) video camera..videocassette
+ {0x1F4FF, 0x1F502, prEmojiPresentation}, // E1.0 [4] (📿..🔂) prayer beads..repeat single button
+ {0x1F503, 0x1F503, prEmojiPresentation}, // E0.6 [1] (🔃) clockwise vertical arrows
+ {0x1F504, 0x1F507, prEmojiPresentation}, // E1.0 [4] (🔄..🔇) counterclockwise arrows button..muted speaker
+ {0x1F508, 0x1F508, prEmojiPresentation}, // E0.7 [1] (🔈) speaker low volume
+ {0x1F509, 0x1F509, prEmojiPresentation}, // E1.0 [1] (🔉) speaker medium volume
+ {0x1F50A, 0x1F514, prEmojiPresentation}, // E0.6 [11] (🔊..🔔) speaker high volume..bell
+ {0x1F515, 0x1F515, prEmojiPresentation}, // E1.0 [1] (🔕) bell with slash
+ {0x1F516, 0x1F52B, prEmojiPresentation}, // E0.6 [22] (🔖..🔫) bookmark..water pistol
+ {0x1F52C, 0x1F52D, prEmojiPresentation}, // E1.0 [2] (🔬..🔭) microscope..telescope
+ {0x1F52E, 0x1F53D, prEmojiPresentation}, // E0.6 [16] (🔮..🔽) crystal ball..downwards button
+ {0x1F54B, 0x1F54E, prEmojiPresentation}, // E1.0 [4] (🕋..🕎) kaaba..menorah
+ {0x1F550, 0x1F55B, prEmojiPresentation}, // E0.6 [12] (🕐..🕛) one o’clock..twelve o’clock
+ {0x1F55C, 0x1F567, prEmojiPresentation}, // E0.7 [12] (🕜..🕧) one-thirty..twelve-thirty
+ {0x1F57A, 0x1F57A, prEmojiPresentation}, // E3.0 [1] (🕺) man dancing
+ {0x1F595, 0x1F596, prEmojiPresentation}, // E1.0 [2] (🖕..🖖) middle finger..vulcan salute
+ {0x1F5A4, 0x1F5A4, prEmojiPresentation}, // E3.0 [1] (🖤) black heart
+ {0x1F5FB, 0x1F5FF, prEmojiPresentation}, // E0.6 [5] (🗻..🗿) mount fuji..moai
+ {0x1F600, 0x1F600, prEmojiPresentation}, // E1.0 [1] (😀) grinning face
+ {0x1F601, 0x1F606, prEmojiPresentation}, // E0.6 [6] (😁..😆) beaming face with smiling eyes..grinning squinting face
+ {0x1F607, 0x1F608, prEmojiPresentation}, // E1.0 [2] (😇..😈) smiling face with halo..smiling face with horns
+ {0x1F609, 0x1F60D, prEmojiPresentation}, // E0.6 [5] (😉..😍) winking face..smiling face with heart-eyes
+ {0x1F60E, 0x1F60E, prEmojiPresentation}, // E1.0 [1] (😎) smiling face with sunglasses
+ {0x1F60F, 0x1F60F, prEmojiPresentation}, // E0.6 [1] (😏) smirking face
+ {0x1F610, 0x1F610, prEmojiPresentation}, // E0.7 [1] (😐) neutral face
+ {0x1F611, 0x1F611, prEmojiPresentation}, // E1.0 [1] (😑) expressionless face
+ {0x1F612, 0x1F614, prEmojiPresentation}, // E0.6 [3] (😒..😔) unamused face..pensive face
+ {0x1F615, 0x1F615, prEmojiPresentation}, // E1.0 [1] (😕) confused face
+ {0x1F616, 0x1F616, prEmojiPresentation}, // E0.6 [1] (😖) confounded face
+ {0x1F617, 0x1F617, prEmojiPresentation}, // E1.0 [1] (😗) kissing face
+ {0x1F618, 0x1F618, prEmojiPresentation}, // E0.6 [1] (😘) face blowing a kiss
+ {0x1F619, 0x1F619, prEmojiPresentation}, // E1.0 [1] (😙) kissing face with smiling eyes
+ {0x1F61A, 0x1F61A, prEmojiPresentation}, // E0.6 [1] (😚) kissing face with closed eyes
+ {0x1F61B, 0x1F61B, prEmojiPresentation}, // E1.0 [1] (😛) face with tongue
+ {0x1F61C, 0x1F61E, prEmojiPresentation}, // E0.6 [3] (😜..😞) winking face with tongue..disappointed face
+ {0x1F61F, 0x1F61F, prEmojiPresentation}, // E1.0 [1] (😟) worried face
+ {0x1F620, 0x1F625, prEmojiPresentation}, // E0.6 [6] (😠..😥) angry face..sad but relieved face
+ {0x1F626, 0x1F627, prEmojiPresentation}, // E1.0 [2] (😦..😧) frowning face with open mouth..anguished face
+ {0x1F628, 0x1F62B, prEmojiPresentation}, // E0.6 [4] (😨..😫) fearful face..tired face
+ {0x1F62C, 0x1F62C, prEmojiPresentation}, // E1.0 [1] (😬) grimacing face
+ {0x1F62D, 0x1F62D, prEmojiPresentation}, // E0.6 [1] (😭) loudly crying face
+ {0x1F62E, 0x1F62F, prEmojiPresentation}, // E1.0 [2] (😮..😯) face with open mouth..hushed face
+ {0x1F630, 0x1F633, prEmojiPresentation}, // E0.6 [4] (😰..😳) anxious face with sweat..flushed face
+ {0x1F634, 0x1F634, prEmojiPresentation}, // E1.0 [1] (😴) sleeping face
+ {0x1F635, 0x1F635, prEmojiPresentation}, // E0.6 [1] (😵) face with crossed-out eyes
+ {0x1F636, 0x1F636, prEmojiPresentation}, // E1.0 [1] (😶) face without mouth
+ {0x1F637, 0x1F640, prEmojiPresentation}, // E0.6 [10] (😷..🙀) face with medical mask..weary cat
+ {0x1F641, 0x1F644, prEmojiPresentation}, // E1.0 [4] (🙁..🙄) slightly frowning face..face with rolling eyes
+ {0x1F645, 0x1F64F, prEmojiPresentation}, // E0.6 [11] (🙅..🙏) person gesturing NO..folded hands
+ {0x1F680, 0x1F680, prEmojiPresentation}, // E0.6 [1] (🚀) rocket
+ {0x1F681, 0x1F682, prEmojiPresentation}, // E1.0 [2] (🚁..🚂) helicopter..locomotive
+ {0x1F683, 0x1F685, prEmojiPresentation}, // E0.6 [3] (🚃..🚅) railway car..bullet train
+ {0x1F686, 0x1F686, prEmojiPresentation}, // E1.0 [1] (🚆) train
+ {0x1F687, 0x1F687, prEmojiPresentation}, // E0.6 [1] (🚇) metro
+ {0x1F688, 0x1F688, prEmojiPresentation}, // E1.0 [1] (🚈) light rail
+ {0x1F689, 0x1F689, prEmojiPresentation}, // E0.6 [1] (🚉) station
+ {0x1F68A, 0x1F68B, prEmojiPresentation}, // E1.0 [2] (🚊..🚋) tram..tram car
+ {0x1F68C, 0x1F68C, prEmojiPresentation}, // E0.6 [1] (🚌) bus
+ {0x1F68D, 0x1F68D, prEmojiPresentation}, // E0.7 [1] (🚍) oncoming bus
+ {0x1F68E, 0x1F68E, prEmojiPresentation}, // E1.0 [1] (🚎) trolleybus
+ {0x1F68F, 0x1F68F, prEmojiPresentation}, // E0.6 [1] (🚏) bus stop
+ {0x1F690, 0x1F690, prEmojiPresentation}, // E1.0 [1] (🚐) minibus
+ {0x1F691, 0x1F693, prEmojiPresentation}, // E0.6 [3] (🚑..🚓) ambulance..police car
+ {0x1F694, 0x1F694, prEmojiPresentation}, // E0.7 [1] (🚔) oncoming police car
+ {0x1F695, 0x1F695, prEmojiPresentation}, // E0.6 [1] (🚕) taxi
+ {0x1F696, 0x1F696, prEmojiPresentation}, // E1.0 [1] (🚖) oncoming taxi
+ {0x1F697, 0x1F697, prEmojiPresentation}, // E0.6 [1] (🚗) automobile
+ {0x1F698, 0x1F698, prEmojiPresentation}, // E0.7 [1] (🚘) oncoming automobile
+ {0x1F699, 0x1F69A, prEmojiPresentation}, // E0.6 [2] (🚙..🚚) sport utility vehicle..delivery truck
+ {0x1F69B, 0x1F6A1, prEmojiPresentation}, // E1.0 [7] (🚛..🚡) articulated lorry..aerial tramway
+ {0x1F6A2, 0x1F6A2, prEmojiPresentation}, // E0.6 [1] (🚢) ship
+ {0x1F6A3, 0x1F6A3, prEmojiPresentation}, // E1.0 [1] (🚣) person rowing boat
+ {0x1F6A4, 0x1F6A5, prEmojiPresentation}, // E0.6 [2] (🚤..🚥) speedboat..horizontal traffic light
+ {0x1F6A6, 0x1F6A6, prEmojiPresentation}, // E1.0 [1] (🚦) vertical traffic light
+ {0x1F6A7, 0x1F6AD, prEmojiPresentation}, // E0.6 [7] (🚧..🚭) construction..no smoking
+ {0x1F6AE, 0x1F6B1, prEmojiPresentation}, // E1.0 [4] (🚮..🚱) litter in bin sign..non-potable water
+ {0x1F6B2, 0x1F6B2, prEmojiPresentation}, // E0.6 [1] (🚲) bicycle
+ {0x1F6B3, 0x1F6B5, prEmojiPresentation}, // E1.0 [3] (🚳..🚵) no bicycles..person mountain biking
+ {0x1F6B6, 0x1F6B6, prEmojiPresentation}, // E0.6 [1] (🚶) person walking
+ {0x1F6B7, 0x1F6B8, prEmojiPresentation}, // E1.0 [2] (🚷..🚸) no pedestrians..children crossing
+ {0x1F6B9, 0x1F6BE, prEmojiPresentation}, // E0.6 [6] (🚹..🚾) men’s room..water closet
+ {0x1F6BF, 0x1F6BF, prEmojiPresentation}, // E1.0 [1] (🚿) shower
+ {0x1F6C0, 0x1F6C0, prEmojiPresentation}, // E0.6 [1] (🛀) person taking bath
+ {0x1F6C1, 0x1F6C5, prEmojiPresentation}, // E1.0 [5] (🛁..🛅) bathtub..left luggage
+ {0x1F6CC, 0x1F6CC, prEmojiPresentation}, // E1.0 [1] (🛌) person in bed
+ {0x1F6D0, 0x1F6D0, prEmojiPresentation}, // E1.0 [1] (🛐) place of worship
+ {0x1F6D1, 0x1F6D2, prEmojiPresentation}, // E3.0 [2] (🛑..🛒) stop sign..shopping cart
+ {0x1F6D5, 0x1F6D5, prEmojiPresentation}, // E12.0 [1] (🛕) hindu temple
+ {0x1F6D6, 0x1F6D7, prEmojiPresentation}, // E13.0 [2] (🛖..🛗) hut..elevator
+ {0x1F6DC, 0x1F6DC, prEmojiPresentation}, // E15.0 [1] (🛜) wireless
+ {0x1F6DD, 0x1F6DF, prEmojiPresentation}, // E14.0 [3] (🛝..🛟) playground slide..ring buoy
+ {0x1F6EB, 0x1F6EC, prEmojiPresentation}, // E1.0 [2] (🛫..🛬) airplane departure..airplane arrival
+ {0x1F6F4, 0x1F6F6, prEmojiPresentation}, // E3.0 [3] (🛴..🛶) kick scooter..canoe
+ {0x1F6F7, 0x1F6F8, prEmojiPresentation}, // E5.0 [2] (🛷..🛸) sled..flying saucer
+ {0x1F6F9, 0x1F6F9, prEmojiPresentation}, // E11.0 [1] (🛹) skateboard
+ {0x1F6FA, 0x1F6FA, prEmojiPresentation}, // E12.0 [1] (🛺) auto rickshaw
+ {0x1F6FB, 0x1F6FC, prEmojiPresentation}, // E13.0 [2] (🛻..🛼) pickup truck..roller skate
+ {0x1F7E0, 0x1F7EB, prEmojiPresentation}, // E12.0 [12] (🟠..🟫) orange circle..brown square
+ {0x1F7F0, 0x1F7F0, prEmojiPresentation}, // E14.0 [1] (🟰) heavy equals sign
+ {0x1F90C, 0x1F90C, prEmojiPresentation}, // E13.0 [1] (🤌) pinched fingers
+ {0x1F90D, 0x1F90F, prEmojiPresentation}, // E12.0 [3] (🤍..🤏) white heart..pinching hand
+ {0x1F910, 0x1F918, prEmojiPresentation}, // E1.0 [9] (🤐..🤘) zipper-mouth face..sign of the horns
+ {0x1F919, 0x1F91E, prEmojiPresentation}, // E3.0 [6] (🤙..🤞) call me hand..crossed fingers
+ {0x1F91F, 0x1F91F, prEmojiPresentation}, // E5.0 [1] (🤟) love-you gesture
+ {0x1F920, 0x1F927, prEmojiPresentation}, // E3.0 [8] (🤠..🤧) cowboy hat face..sneezing face
+ {0x1F928, 0x1F92F, prEmojiPresentation}, // E5.0 [8] (🤨..🤯) face with raised eyebrow..exploding head
+ {0x1F930, 0x1F930, prEmojiPresentation}, // E3.0 [1] (🤰) pregnant woman
+ {0x1F931, 0x1F932, prEmojiPresentation}, // E5.0 [2] (🤱..🤲) breast-feeding..palms up together
+ {0x1F933, 0x1F93A, prEmojiPresentation}, // E3.0 [8] (🤳..🤺) selfie..person fencing
+ {0x1F93C, 0x1F93E, prEmojiPresentation}, // E3.0 [3] (🤼..🤾) people wrestling..person playing handball
+ {0x1F93F, 0x1F93F, prEmojiPresentation}, // E12.0 [1] (🤿) diving mask
+ {0x1F940, 0x1F945, prEmojiPresentation}, // E3.0 [6] (🥀..🥅) wilted flower..goal net
+ {0x1F947, 0x1F94B, prEmojiPresentation}, // E3.0 [5] (🥇..🥋) 1st place medal..martial arts uniform
+ {0x1F94C, 0x1F94C, prEmojiPresentation}, // E5.0 [1] (🥌) curling stone
+ {0x1F94D, 0x1F94F, prEmojiPresentation}, // E11.0 [3] (🥍..🥏) lacrosse..flying disc
+ {0x1F950, 0x1F95E, prEmojiPresentation}, // E3.0 [15] (🥐..🥞) croissant..pancakes
+ {0x1F95F, 0x1F96B, prEmojiPresentation}, // E5.0 [13] (🥟..🥫) dumpling..canned food
+ {0x1F96C, 0x1F970, prEmojiPresentation}, // E11.0 [5] (🥬..🥰) leafy green..smiling face with hearts
+ {0x1F971, 0x1F971, prEmojiPresentation}, // E12.0 [1] (🥱) yawning face
+ {0x1F972, 0x1F972, prEmojiPresentation}, // E13.0 [1] (🥲) smiling face with tear
+ {0x1F973, 0x1F976, prEmojiPresentation}, // E11.0 [4] (🥳..🥶) partying face..cold face
+ {0x1F977, 0x1F978, prEmojiPresentation}, // E13.0 [2] (🥷..🥸) ninja..disguised face
+ {0x1F979, 0x1F979, prEmojiPresentation}, // E14.0 [1] (🥹) face holding back tears
+ {0x1F97A, 0x1F97A, prEmojiPresentation}, // E11.0 [1] (🥺) pleading face
+ {0x1F97B, 0x1F97B, prEmojiPresentation}, // E12.0 [1] (🥻) sari
+ {0x1F97C, 0x1F97F, prEmojiPresentation}, // E11.0 [4] (🥼..🥿) lab coat..flat shoe
+ {0x1F980, 0x1F984, prEmojiPresentation}, // E1.0 [5] (🦀..🦄) crab..unicorn
+ {0x1F985, 0x1F991, prEmojiPresentation}, // E3.0 [13] (🦅..🦑) eagle..squid
+ {0x1F992, 0x1F997, prEmojiPresentation}, // E5.0 [6] (🦒..🦗) giraffe..cricket
+ {0x1F998, 0x1F9A2, prEmojiPresentation}, // E11.0 [11] (🦘..🦢) kangaroo..swan
+ {0x1F9A3, 0x1F9A4, prEmojiPresentation}, // E13.0 [2] (🦣..🦤) mammoth..dodo
+ {0x1F9A5, 0x1F9AA, prEmojiPresentation}, // E12.0 [6] (🦥..🦪) sloth..oyster
+ {0x1F9AB, 0x1F9AD, prEmojiPresentation}, // E13.0 [3] (🦫..🦭) beaver..seal
+ {0x1F9AE, 0x1F9AF, prEmojiPresentation}, // E12.0 [2] (🦮..🦯) guide dog..white cane
+ {0x1F9B0, 0x1F9B9, prEmojiPresentation}, // E11.0 [10] (🦰..🦹) red hair..supervillain
+ {0x1F9BA, 0x1F9BF, prEmojiPresentation}, // E12.0 [6] (🦺..🦿) safety vest..mechanical leg
+ {0x1F9C0, 0x1F9C0, prEmojiPresentation}, // E1.0 [1] (🧀) cheese wedge
+ {0x1F9C1, 0x1F9C2, prEmojiPresentation}, // E11.0 [2] (🧁..🧂) cupcake..salt
+ {0x1F9C3, 0x1F9CA, prEmojiPresentation}, // E12.0 [8] (🧃..🧊) beverage box..ice
+ {0x1F9CB, 0x1F9CB, prEmojiPresentation}, // E13.0 [1] (🧋) bubble tea
+ {0x1F9CC, 0x1F9CC, prEmojiPresentation}, // E14.0 [1] (🧌) troll
+ {0x1F9CD, 0x1F9CF, prEmojiPresentation}, // E12.0 [3] (🧍..🧏) person standing..deaf person
+ {0x1F9D0, 0x1F9E6, prEmojiPresentation}, // E5.0 [23] (🧐..🧦) face with monocle..socks
+ {0x1F9E7, 0x1F9FF, prEmojiPresentation}, // E11.0 [25] (🧧..🧿) red envelope..nazar amulet
+ {0x1FA70, 0x1FA73, prEmojiPresentation}, // E12.0 [4] (🩰..🩳) ballet shoes..shorts
+ {0x1FA74, 0x1FA74, prEmojiPresentation}, // E13.0 [1] (🩴) thong sandal
+ {0x1FA75, 0x1FA77, prEmojiPresentation}, // E15.0 [3] (🩵..🩷) light blue heart..pink heart
+ {0x1FA78, 0x1FA7A, prEmojiPresentation}, // E12.0 [3] (🩸..🩺) drop of blood..stethoscope
+ {0x1FA7B, 0x1FA7C, prEmojiPresentation}, // E14.0 [2] (🩻..🩼) x-ray..crutch
+ {0x1FA80, 0x1FA82, prEmojiPresentation}, // E12.0 [3] (🪀..🪂) yo-yo..parachute
+ {0x1FA83, 0x1FA86, prEmojiPresentation}, // E13.0 [4] (🪃..🪆) boomerang..nesting dolls
+ {0x1FA87, 0x1FA88, prEmojiPresentation}, // E15.0 [2] (🪇..🪈) maracas..flute
+ {0x1FA90, 0x1FA95, prEmojiPresentation}, // E12.0 [6] (🪐..🪕) ringed planet..banjo
+ {0x1FA96, 0x1FAA8, prEmojiPresentation}, // E13.0 [19] (🪖..🪨) military helmet..rock
+ {0x1FAA9, 0x1FAAC, prEmojiPresentation}, // E14.0 [4] (🪩..🪬) mirror ball..hamsa
+ {0x1FAAD, 0x1FAAF, prEmojiPresentation}, // E15.0 [3] (🪭..🪯) folding hand fan..khanda
+ {0x1FAB0, 0x1FAB6, prEmojiPresentation}, // E13.0 [7] (🪰..🪶) fly..feather
+ {0x1FAB7, 0x1FABA, prEmojiPresentation}, // E14.0 [4] (🪷..🪺) lotus..nest with eggs
+ {0x1FABB, 0x1FABD, prEmojiPresentation}, // E15.0 [3] (🪻..🪽) hyacinth..wing
+ {0x1FABF, 0x1FABF, prEmojiPresentation}, // E15.0 [1] (🪿) goose
+ {0x1FAC0, 0x1FAC2, prEmojiPresentation}, // E13.0 [3] (🫀..🫂) anatomical heart..people hugging
+ {0x1FAC3, 0x1FAC5, prEmojiPresentation}, // E14.0 [3] (🫃..🫅) pregnant man..person with crown
+ {0x1FACE, 0x1FACF, prEmojiPresentation}, // E15.0 [2] (🫎..🫏) moose..donkey
+ {0x1FAD0, 0x1FAD6, prEmojiPresentation}, // E13.0 [7] (🫐..🫖) blueberries..teapot
+ {0x1FAD7, 0x1FAD9, prEmojiPresentation}, // E14.0 [3] (🫗..🫙) pouring liquid..jar
+ {0x1FADA, 0x1FADB, prEmojiPresentation}, // E15.0 [2] (🫚..🫛) ginger root..pea pod
+ {0x1FAE0, 0x1FAE7, prEmojiPresentation}, // E14.0 [8] (🫠..🫧) melting face..bubbles
+ {0x1FAE8, 0x1FAE8, prEmojiPresentation}, // E15.0 [1] (🫨) shaking face
+ {0x1FAF0, 0x1FAF6, prEmojiPresentation}, // E14.0 [7] (🫰..🫶) hand with index finger and thumb crossed..heart hands
+ {0x1FAF7, 0x1FAF8, prEmojiPresentation}, // E15.0 [2] (🫷..🫸) leftwards pushing hand..rightwards pushing hand
+}
diff --git a/vendor/github.com/rivo/uniseg/gen_breaktest.go b/vendor/github.com/rivo/uniseg/gen_breaktest.go
new file mode 100644
index 000000000..6bfbeb5e7
--- /dev/null
+++ b/vendor/github.com/rivo/uniseg/gen_breaktest.go
@@ -0,0 +1,215 @@
+//go:build generate
+
+// This program generates a Go containing a slice of test cases based on the
+// Unicode Character Database auxiliary data files. The command line arguments
+// are as follows:
+//
+// 1. The name of the Unicode data file (just the filename, without extension).
+// 2. The name of the locally generated Go file.
+// 3. The name of the slice containing the test cases.
+// 4. The name of the generator, for logging purposes.
+//
+//go:generate go run gen_breaktest.go GraphemeBreakTest graphemebreak_test.go graphemeBreakTestCases graphemes
+//go:generate go run gen_breaktest.go WordBreakTest wordbreak_test.go wordBreakTestCases words
+//go:generate go run gen_breaktest.go SentenceBreakTest sentencebreak_test.go sentenceBreakTestCases sentences
+//go:generate go run gen_breaktest.go LineBreakTest linebreak_test.go lineBreakTestCases lines
+
+package main
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "fmt"
+ "go/format"
+ "io/ioutil"
+ "log"
+ "net/http"
+ "os"
+ "time"
+)
+
+// We want to test against a specific version rather than the latest. When the
+// package is upgraded to a new version, change these to generate new tests.
+const (
+ testCaseURL = `https://www.unicode.org/Public/15.0.0/ucd/auxiliary/%s.txt`
+)
+
+func main() {
+ if len(os.Args) < 5 {
+ fmt.Println("Not enough arguments, see code for details")
+ os.Exit(1)
+ }
+
+ log.SetPrefix("gen_breaktest (" + os.Args[4] + "): ")
+ log.SetFlags(0)
+
+ // Read text of testcases and parse into Go source code.
+ src, err := parse(fmt.Sprintf(testCaseURL, os.Args[1]))
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // Format the Go code.
+ formatted, err := format.Source(src)
+ if err != nil {
+ log.Fatalln("gofmt:", err)
+ }
+
+ // Write it out.
+ log.Print("Writing to ", os.Args[2])
+ if err := ioutil.WriteFile(os.Args[2], formatted, 0644); err != nil {
+ log.Fatal(err)
+ }
+}
+
+// parse reads a break text file, either from a local file or from a URL. It
+// parses the file data into Go source code representing the test cases.
+func parse(url string) ([]byte, error) {
+ log.Printf("Parsing %s", url)
+ res, err := http.Get(url)
+ if err != nil {
+ return nil, err
+ }
+ body := res.Body
+ defer body.Close()
+
+ buf := new(bytes.Buffer)
+ buf.Grow(120 << 10)
+ buf.WriteString(`// Code generated via go generate from gen_breaktest.go. DO NOT EDIT.
+
+package uniseg
+
+// ` + os.Args[3] + ` are Grapheme testcases taken from
+// ` + url + `
+// on ` + time.Now().Format("January 2, 2006") + `. See
+// https://www.unicode.org/license.html for the Unicode license agreement.
+var ` + os.Args[3] + ` = []testCase {
+`)
+
+ sc := bufio.NewScanner(body)
+ num := 1
+ var line []byte
+ original := make([]byte, 0, 64)
+ expected := make([]byte, 0, 64)
+ for sc.Scan() {
+ num++
+ line = sc.Bytes()
+ if len(line) == 0 || line[0] == '#' {
+ continue
+ }
+ var comment []byte
+ if i := bytes.IndexByte(line, '#'); i >= 0 {
+ comment = bytes.TrimSpace(line[i+1:])
+ line = bytes.TrimSpace(line[:i])
+ }
+ original, expected, err := parseRuneSequence(line, original[:0], expected[:0])
+ if err != nil {
+ return nil, fmt.Errorf(`line %d: %v: %q`, num, err, line)
+ }
+ fmt.Fprintf(buf, "\t{original: \"%s\", expected: %s}, // %s\n", original, expected, comment)
+ }
+ if err := sc.Err(); err != nil {
+ return nil, err
+ }
+
+ // Check for final "# EOF", useful check if we're streaming via HTTP
+ if !bytes.Equal(line, []byte("# EOF")) {
+ return nil, fmt.Errorf(`line %d: exected "# EOF" as final line, got %q`, num, line)
+ }
+ buf.WriteString("}\n")
+ return buf.Bytes(), nil
+}
+
+// Used by parseRuneSequence to match input via bytes.HasPrefix.
+var (
+ prefixBreak = []byte("÷ ")
+ prefixDontBreak = []byte("× ")
+ breakOk = []byte("÷")
+ breakNo = []byte("×")
+)
+
+// parseRuneSequence parses a rune + breaking opportunity sequence from b
+// and appends the Go code for testcase.original to orig
+// and appends the Go code for testcase.expected to exp.
+// It retuns the new orig and exp slices.
+//
+// E.g. for the input b="÷ 0020 × 0308 ÷ 1F1E6 ÷"
+// it will append
+//
+// "\u0020\u0308\U0001F1E6"
+//
+// and "[][]rune{{0x0020,0x0308},{0x1F1E6},}"
+// to orig and exp respectively.
+//
+// The formatting of exp is expected to be cleaned up by gofmt or format.Source.
+// Note we explicitly require the sequence to start with ÷ and we implicitly
+// require it to end with ÷.
+func parseRuneSequence(b, orig, exp []byte) ([]byte, []byte, error) {
+ // Check for and remove first ÷ or ×.
+ if !bytes.HasPrefix(b, prefixBreak) && !bytes.HasPrefix(b, prefixDontBreak) {
+ return nil, nil, errors.New("expected ÷ or × as first character")
+ }
+ if bytes.HasPrefix(b, prefixBreak) {
+ b = b[len(prefixBreak):]
+ } else {
+ b = b[len(prefixDontBreak):]
+ }
+
+ boundary := true
+ exp = append(exp, "[][]rune{"...)
+ for len(b) > 0 {
+ if boundary {
+ exp = append(exp, '{')
+ }
+ exp = append(exp, "0x"...)
+ // Find end of hex digits.
+ var i int
+ for i = 0; i < len(b) && b[i] != ' '; i++ {
+ if d := b[i]; ('0' <= d || d <= '9') ||
+ ('A' <= d || d <= 'F') ||
+ ('a' <= d || d <= 'f') {
+ continue
+ }
+ return nil, nil, errors.New("bad hex digit")
+ }
+ switch i {
+ case 4:
+ orig = append(orig, "\\u"...)
+ case 5:
+ orig = append(orig, "\\U000"...)
+ default:
+ return nil, nil, errors.New("unsupport code point hex length")
+ }
+ orig = append(orig, b[:i]...)
+ exp = append(exp, b[:i]...)
+ b = b[i:]
+
+ // Check for space between hex and ÷ or ×.
+ if len(b) < 1 || b[0] != ' ' {
+ return nil, nil, errors.New("bad input")
+ }
+ b = b[1:]
+
+ // Check for next boundary.
+ switch {
+ case bytes.HasPrefix(b, breakOk):
+ boundary = true
+ b = b[len(breakOk):]
+ case bytes.HasPrefix(b, breakNo):
+ boundary = false
+ b = b[len(breakNo):]
+ default:
+ return nil, nil, errors.New("missing ÷ or ×")
+ }
+ if boundary {
+ exp = append(exp, '}')
+ }
+ exp = append(exp, ',')
+ if len(b) > 0 && b[0] == ' ' {
+ b = b[1:]
+ }
+ }
+ exp = append(exp, '}')
+ return orig, exp, nil
+}
diff --git a/vendor/github.com/rivo/uniseg/gen_properties.go b/vendor/github.com/rivo/uniseg/gen_properties.go
new file mode 100644
index 000000000..8992d2c5f
--- /dev/null
+++ b/vendor/github.com/rivo/uniseg/gen_properties.go
@@ -0,0 +1,261 @@
+//go:build generate
+
+// This program generates a property file in Go file from Unicode Character
+// Database auxiliary data files. The command line arguments are as follows:
+//
+// 1. The name of the Unicode data file (just the filename, without extension).
+// Can be "-" (to skip) if the emoji flag is included.
+// 2. The name of the locally generated Go file.
+// 3. The name of the slice mapping code points to properties.
+// 4. The name of the generator, for logging purposes.
+// 5. (Optional) Flags, comma-separated. The following flags are available:
+// - "emojis=": include the specified emoji properties (e.g.
+// "Extended_Pictographic").
+// - "gencat": include general category properties.
+//
+//go:generate go run gen_properties.go auxiliary/GraphemeBreakProperty graphemeproperties.go graphemeCodePoints graphemes emojis=Extended_Pictographic
+//go:generate go run gen_properties.go auxiliary/WordBreakProperty wordproperties.go workBreakCodePoints words emojis=Extended_Pictographic
+//go:generate go run gen_properties.go auxiliary/SentenceBreakProperty sentenceproperties.go sentenceBreakCodePoints sentences
+//go:generate go run gen_properties.go LineBreak lineproperties.go lineBreakCodePoints lines gencat
+//go:generate go run gen_properties.go EastAsianWidth eastasianwidth.go eastAsianWidth eastasianwidth
+//go:generate go run gen_properties.go - emojipresentation.go emojiPresentation emojipresentation emojis=Emoji_Presentation
+package main
+
+import (
+ "bufio"
+ "bytes"
+ "errors"
+ "fmt"
+ "go/format"
+ "io/ioutil"
+ "log"
+ "net/http"
+ "os"
+ "regexp"
+ "sort"
+ "strconv"
+ "strings"
+ "time"
+)
+
+// We want to test against a specific version rather than the latest. When the
+// package is upgraded to a new version, change these to generate new tests.
+const (
+ propertyURL = `https://www.unicode.org/Public/15.0.0/ucd/%s.txt`
+ emojiURL = `https://unicode.org/Public/15.0.0/ucd/emoji/emoji-data.txt`
+)
+
+// The regular expression for a line containing a code point range property.
+var propertyPattern = regexp.MustCompile(`^([0-9A-F]{4,6})(\.\.([0-9A-F]{4,6}))?\s*;\s*([A-Za-z0-9_]+)\s*#\s(.+)$`)
+
+func main() {
+ if len(os.Args) < 5 {
+ fmt.Println("Not enough arguments, see code for details")
+ os.Exit(1)
+ }
+
+ log.SetPrefix("gen_properties (" + os.Args[4] + "): ")
+ log.SetFlags(0)
+
+ // Parse flags.
+ flags := make(map[string]string)
+ if len(os.Args) >= 6 {
+ for _, flag := range strings.Split(os.Args[5], ",") {
+ flagFields := strings.Split(flag, "=")
+ if len(flagFields) == 1 {
+ flags[flagFields[0]] = "yes"
+ } else {
+ flags[flagFields[0]] = flagFields[1]
+ }
+ }
+ }
+
+ // Parse the text file and generate Go source code from it.
+ _, includeGeneralCategory := flags["gencat"]
+ var mainURL string
+ if os.Args[1] != "-" {
+ mainURL = fmt.Sprintf(propertyURL, os.Args[1])
+ }
+ src, err := parse(mainURL, flags["emojis"], includeGeneralCategory)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ // Format the Go code.
+ formatted, err := format.Source([]byte(src))
+ if err != nil {
+ log.Fatal("gofmt:", err)
+ }
+
+ // Save it to the (local) target file.
+ log.Print("Writing to ", os.Args[2])
+ if err := ioutil.WriteFile(os.Args[2], formatted, 0644); err != nil {
+ log.Fatal(err)
+ }
+}
+
+// parse parses the Unicode Properties text files located at the given URLs and
+// returns their equivalent Go source code to be used in the uniseg package. If
+// "emojiProperty" is not an empty string, emoji code points for that emoji
+// property (e.g. "Extended_Pictographic") will be included. In those cases, you
+// may pass an empty "propertyURL" to skip parsing the main properties file. If
+// "includeGeneralCategory" is true, the Unicode General Category property will
+// be extracted from the comments and included in the output.
+func parse(propertyURL, emojiProperty string, includeGeneralCategory bool) (string, error) {
+ if propertyURL == "" && emojiProperty == "" {
+ return "", errors.New("no properties to parse")
+ }
+
+ // Temporary buffer to hold properties.
+ var properties [][4]string
+
+ // Open the first URL.
+ if propertyURL != "" {
+ log.Printf("Parsing %s", propertyURL)
+ res, err := http.Get(propertyURL)
+ if err != nil {
+ return "", err
+ }
+ in1 := res.Body
+ defer in1.Close()
+
+ // Parse it.
+ scanner := bufio.NewScanner(in1)
+ num := 0
+ for scanner.Scan() {
+ num++
+ line := strings.TrimSpace(scanner.Text())
+
+ // Skip comments and empty lines.
+ if strings.HasPrefix(line, "#") || line == "" {
+ continue
+ }
+
+ // Everything else must be a code point range, a property and a comment.
+ from, to, property, comment, err := parseProperty(line)
+ if err != nil {
+ return "", fmt.Errorf("%s line %d: %v", os.Args[4], num, err)
+ }
+ properties = append(properties, [4]string{from, to, property, comment})
+ }
+ if err := scanner.Err(); err != nil {
+ return "", err
+ }
+ }
+
+ // Open the second URL.
+ if emojiProperty != "" {
+ log.Printf("Parsing %s", emojiURL)
+ res, err := http.Get(emojiURL)
+ if err != nil {
+ return "", err
+ }
+ in2 := res.Body
+ defer in2.Close()
+
+ // Parse it.
+ scanner := bufio.NewScanner(in2)
+ num := 0
+ for scanner.Scan() {
+ num++
+ line := scanner.Text()
+
+ // Skip comments, empty lines, and everything not containing
+ // "Extended_Pictographic".
+ if strings.HasPrefix(line, "#") || line == "" || !strings.Contains(line, emojiProperty) {
+ continue
+ }
+
+ // Everything else must be a code point range, a property and a comment.
+ from, to, property, comment, err := parseProperty(line)
+ if err != nil {
+ return "", fmt.Errorf("emojis line %d: %v", num, err)
+ }
+ properties = append(properties, [4]string{from, to, property, comment})
+ }
+ if err := scanner.Err(); err != nil {
+ return "", err
+ }
+ }
+
+ // Avoid overflow during binary search.
+ if len(properties) >= 1<<31 {
+ return "", errors.New("too many properties")
+ }
+
+ // Sort properties.
+ sort.Slice(properties, func(i, j int) bool {
+ left, _ := strconv.ParseUint(properties[i][0], 16, 64)
+ right, _ := strconv.ParseUint(properties[j][0], 16, 64)
+ return left < right
+ })
+
+ // Header.
+ var (
+ buf bytes.Buffer
+ emojiComment string
+ )
+ columns := 3
+ if includeGeneralCategory {
+ columns = 4
+ }
+ if emojiURL != "" {
+ emojiComment = `
+// and
+// ` + emojiURL + `
+// ("Extended_Pictographic" only)`
+ }
+ buf.WriteString(`// Code generated via go generate from gen_properties.go. DO NOT EDIT.
+
+package uniseg
+
+// ` + os.Args[3] + ` are taken from
+// ` + propertyURL + emojiComment + `
+// on ` + time.Now().Format("January 2, 2006") + `. See https://www.unicode.org/license.html for the Unicode
+// license agreement.
+var ` + os.Args[3] + ` = [][` + strconv.Itoa(columns) + `]int{
+ `)
+
+ // Properties.
+ for _, prop := range properties {
+ if includeGeneralCategory {
+ generalCategory := "gc" + prop[3][:2]
+ if generalCategory == "gcL&" {
+ generalCategory = "gcLC"
+ }
+ prop[3] = prop[3][3:]
+ fmt.Fprintf(&buf, "{0x%s,0x%s,%s,%s}, // %s\n", prop[0], prop[1], translateProperty("pr", prop[2]), generalCategory, prop[3])
+ } else {
+ fmt.Fprintf(&buf, "{0x%s,0x%s,%s}, // %s\n", prop[0], prop[1], translateProperty("pr", prop[2]), prop[3])
+ }
+ }
+
+ // Tail.
+ buf.WriteString("}")
+
+ return buf.String(), nil
+}
+
+// parseProperty parses a line of the Unicode properties text file containing a
+// property for a code point range and returns it along with its comment.
+func parseProperty(line string) (from, to, property, comment string, err error) {
+ fields := propertyPattern.FindStringSubmatch(line)
+ if fields == nil {
+ err = errors.New("no property found")
+ return
+ }
+ from = fields[1]
+ to = fields[3]
+ if to == "" {
+ to = from
+ }
+ property = fields[4]
+ comment = fields[5]
+ return
+}
+
+// translateProperty translates a property name as used in the Unicode data file
+// to a variable used in the Go code.
+func translateProperty(prefix, property string) string {
+ return prefix + strings.ReplaceAll(property, "_", "")
+}
diff --git a/vendor/github.com/rivo/uniseg/grapheme.go b/vendor/github.com/rivo/uniseg/grapheme.go
new file mode 100644
index 000000000..b12403d43
--- /dev/null
+++ b/vendor/github.com/rivo/uniseg/grapheme.go
@@ -0,0 +1,331 @@
+package uniseg
+
+import "unicode/utf8"
+
+// Graphemes implements an iterator over Unicode grapheme clusters, or
+// user-perceived characters. While iterating, it also provides information
+// about word boundaries, sentence boundaries, line breaks, and monospace
+// character widths.
+//
+// After constructing the class via [NewGraphemes] for a given string "str",
+// [Graphemes.Next] is called for every grapheme cluster in a loop until it
+// returns false. Inside the loop, information about the grapheme cluster as
+// well as boundary information and character width is available via the various
+// methods (see examples below).
+//
+// This class basically wraps the [StepString] parser and provides a convenient
+// interface to it. If you are only interested in some parts of this package's
+// functionality, using the specialized functions starting with "First" is
+// almost always faster.
+type Graphemes struct {
+ // The original string.
+ original string
+
+ // The remaining string to be parsed.
+ remaining string
+
+ // The current grapheme cluster.
+ cluster string
+
+ // The byte offset of the current grapheme cluster relative to the original
+ // string.
+ offset int
+
+ // The current boundary information of the [Step] parser.
+ boundaries int
+
+ // The current state of the [Step] parser.
+ state int
+}
+
+// NewGraphemes returns a new grapheme cluster iterator.
+func NewGraphemes(str string) *Graphemes {
+ return &Graphemes{
+ original: str,
+ remaining: str,
+ state: -1,
+ }
+}
+
+// Next advances the iterator by one grapheme cluster and returns false if no
+// clusters are left. This function must be called before the first cluster is
+// accessed.
+func (g *Graphemes) Next() bool {
+ if len(g.remaining) == 0 {
+ // We're already past the end.
+ g.state = -2
+ g.cluster = ""
+ return false
+ }
+ g.offset += len(g.cluster)
+ g.cluster, g.remaining, g.boundaries, g.state = StepString(g.remaining, g.state)
+ return true
+}
+
+// Runes returns a slice of runes (code points) which corresponds to the current
+// grapheme cluster. If the iterator is already past the end or [Graphemes.Next]
+// has not yet been called, nil is returned.
+func (g *Graphemes) Runes() []rune {
+ if g.state < 0 {
+ return nil
+ }
+ return []rune(g.cluster)
+}
+
+// Str returns a substring of the original string which corresponds to the
+// current grapheme cluster. If the iterator is already past the end or
+// [Graphemes.Next] has not yet been called, an empty string is returned.
+func (g *Graphemes) Str() string {
+ return g.cluster
+}
+
+// Bytes returns a byte slice which corresponds to the current grapheme cluster.
+// If the iterator is already past the end or [Graphemes.Next] has not yet been
+// called, nil is returned.
+func (g *Graphemes) Bytes() []byte {
+ if g.state < 0 {
+ return nil
+ }
+ return []byte(g.cluster)
+}
+
+// Positions returns the interval of the current grapheme cluster as byte
+// positions into the original string. The first returned value "from" indexes
+// the first byte and the second returned value "to" indexes the first byte that
+// is not included anymore, i.e. str[from:to] is the current grapheme cluster of
+// the original string "str". If [Graphemes.Next] has not yet been called, both
+// values are 0. If the iterator is already past the end, both values are 1.
+func (g *Graphemes) Positions() (int, int) {
+ if g.state == -1 {
+ return 0, 0
+ } else if g.state == -2 {
+ return 1, 1
+ }
+ return g.offset, g.offset + len(g.cluster)
+}
+
+// IsWordBoundary returns true if a word ends after the current grapheme
+// cluster.
+func (g *Graphemes) IsWordBoundary() bool {
+ if g.state < 0 {
+ return true
+ }
+ return g.boundaries&MaskWord != 0
+}
+
+// IsSentenceBoundary returns true if a sentence ends after the current
+// grapheme cluster.
+func (g *Graphemes) IsSentenceBoundary() bool {
+ if g.state < 0 {
+ return true
+ }
+ return g.boundaries&MaskSentence != 0
+}
+
+// LineBreak returns whether the line can be broken after the current grapheme
+// cluster. A value of [LineDontBreak] means the line may not be broken, a value
+// of [LineMustBreak] means the line must be broken, and a value of
+// [LineCanBreak] means the line may or may not be broken.
+func (g *Graphemes) LineBreak() int {
+ if g.state == -1 {
+ return LineDontBreak
+ }
+ if g.state == -2 {
+ return LineMustBreak
+ }
+ return g.boundaries & MaskLine
+}
+
+// Width returns the monospace width of the current grapheme cluster.
+func (g *Graphemes) Width() int {
+ if g.state < 0 {
+ return 0
+ }
+ return g.boundaries >> ShiftWidth
+}
+
+// Reset puts the iterator into its initial state such that the next call to
+// [Graphemes.Next] sets it to the first grapheme cluster again.
+func (g *Graphemes) Reset() {
+ g.state = -1
+ g.offset = 0
+ g.cluster = ""
+ g.remaining = g.original
+}
+
+// GraphemeClusterCount returns the number of user-perceived characters
+// (grapheme clusters) for the given string.
+func GraphemeClusterCount(s string) (n int) {
+ state := -1
+ for len(s) > 0 {
+ _, s, _, state = FirstGraphemeClusterInString(s, state)
+ n++
+ }
+ return
+}
+
+// ReverseString reverses the given string while observing grapheme cluster
+// boundaries.
+func ReverseString(s string) string {
+ str := []byte(s)
+ reversed := make([]byte, len(str))
+ state := -1
+ index := len(str)
+ for len(str) > 0 {
+ var cluster []byte
+ cluster, str, _, state = FirstGraphemeCluster(str, state)
+ index -= len(cluster)
+ copy(reversed[index:], cluster)
+ if index <= len(str)/2 {
+ break
+ }
+ }
+ return string(reversed)
+}
+
+// The number of bits the grapheme property must be shifted to make place for
+// grapheme states.
+const shiftGraphemePropState = 4
+
+// FirstGraphemeCluster returns the first grapheme cluster found in the given
+// byte slice according to the rules of [Unicode Standard Annex #29, Grapheme
+// Cluster Boundaries]. This function can be called continuously to extract all
+// grapheme clusters from a byte slice, as illustrated in the example below.
+//
+// If you don't know the current state, for example when calling the function
+// for the first time, you must pass -1. For consecutive calls, pass the state
+// and rest slice returned by the previous call.
+//
+// The "rest" slice is the sub-slice of the original byte slice "b" starting
+// after the last byte of the identified grapheme cluster. If the length of the
+// "rest" slice is 0, the entire byte slice "b" has been processed. The
+// "cluster" byte slice is the sub-slice of the input slice containing the
+// identified grapheme cluster.
+//
+// The returned width is the width of the grapheme cluster for most monospace
+// fonts where a value of 1 represents one character cell.
+//
+// Given an empty byte slice "b", the function returns nil values.
+//
+// While slightly less convenient than using the Graphemes class, this function
+// has much better performance and makes no allocations. It lends itself well to
+// large byte slices.
+//
+// [Unicode Standard Annex #29, Grapheme Cluster Boundaries]: http://unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries
+func FirstGraphemeCluster(b []byte, state int) (cluster, rest []byte, width, newState int) {
+ // An empty byte slice returns nothing.
+ if len(b) == 0 {
+ return
+ }
+
+ // Extract the first rune.
+ r, length := utf8.DecodeRune(b)
+ if len(b) <= length { // If we're already past the end, there is nothing else to parse.
+ var prop int
+ if state < 0 {
+ prop = propertyGraphemes(r)
+ } else {
+ prop = state >> shiftGraphemePropState
+ }
+ return b, nil, runeWidth(r, prop), grAny | (prop << shiftGraphemePropState)
+ }
+
+ // If we don't know the state, determine it now.
+ var firstProp int
+ if state < 0 {
+ state, firstProp, _ = transitionGraphemeState(state, r)
+ } else {
+ firstProp = state >> shiftGraphemePropState
+ }
+ width += runeWidth(r, firstProp)
+
+ // Transition until we find a boundary.
+ for {
+ var (
+ prop int
+ boundary bool
+ )
+
+ r, l := utf8.DecodeRune(b[length:])
+ state, prop, boundary = transitionGraphemeState(state&maskGraphemeState, r)
+
+ if boundary {
+ return b[:length], b[length:], width, state | (prop << shiftGraphemePropState)
+ }
+
+ if firstProp == prExtendedPictographic {
+ if r == vs15 {
+ width = 1
+ } else if r == vs16 {
+ width = 2
+ }
+ } else if firstProp != prRegionalIndicator && firstProp != prL {
+ width += runeWidth(r, prop)
+ }
+
+ length += l
+ if len(b) <= length {
+ return b, nil, width, grAny | (prop << shiftGraphemePropState)
+ }
+ }
+}
+
+// FirstGraphemeClusterInString is like [FirstGraphemeCluster] but its input and
+// outputs are strings.
+func FirstGraphemeClusterInString(str string, state int) (cluster, rest string, width, newState int) {
+ // An empty string returns nothing.
+ if len(str) == 0 {
+ return
+ }
+
+ // Extract the first rune.
+ r, length := utf8.DecodeRuneInString(str)
+ if len(str) <= length { // If we're already past the end, there is nothing else to parse.
+ var prop int
+ if state < 0 {
+ prop = propertyGraphemes(r)
+ } else {
+ prop = state >> shiftGraphemePropState
+ }
+ return str, "", runeWidth(r, prop), grAny | (prop << shiftGraphemePropState)
+ }
+
+ // If we don't know the state, determine it now.
+ var firstProp int
+ if state < 0 {
+ state, firstProp, _ = transitionGraphemeState(state, r)
+ } else {
+ firstProp = state >> shiftGraphemePropState
+ }
+ width += runeWidth(r, firstProp)
+
+ // Transition until we find a boundary.
+ for {
+ var (
+ prop int
+ boundary bool
+ )
+
+ r, l := utf8.DecodeRuneInString(str[length:])
+ state, prop, boundary = transitionGraphemeState(state&maskGraphemeState, r)
+
+ if boundary {
+ return str[:length], str[length:], width, state | (prop << shiftGraphemePropState)
+ }
+
+ if firstProp == prExtendedPictographic {
+ if r == vs15 {
+ width = 1
+ } else if r == vs16 {
+ width = 2
+ }
+ } else if firstProp != prRegionalIndicator && firstProp != prL {
+ width += runeWidth(r, prop)
+ }
+
+ length += l
+ if len(str) <= length {
+ return str, "", width, grAny | (prop << shiftGraphemePropState)
+ }
+ }
+}
diff --git a/vendor/github.com/rivo/uniseg/graphemeproperties.go b/vendor/github.com/rivo/uniseg/graphemeproperties.go
new file mode 100644
index 000000000..0aff4a619
--- /dev/null
+++ b/vendor/github.com/rivo/uniseg/graphemeproperties.go
@@ -0,0 +1,1915 @@
+// Code generated via go generate from gen_properties.go. DO NOT EDIT.
+
+package uniseg
+
+// graphemeCodePoints are taken from
+// https://www.unicode.org/Public/15.0.0/ucd/auxiliary/GraphemeBreakProperty.txt
+// and
+// https://unicode.org/Public/15.0.0/ucd/emoji/emoji-data.txt
+// ("Extended_Pictographic" only)
+// on September 5, 2023. See https://www.unicode.org/license.html for the Unicode
+// license agreement.
+var graphemeCodePoints = [][3]int{
+ {0x0000, 0x0009, prControl}, // Cc [10] ..
+ {0x000A, 0x000A, prLF}, // Cc
+ {0x000B, 0x000C, prControl}, // Cc [2] ..
+ {0x000D, 0x000D, prCR}, // Cc
+ {0x000E, 0x001F, prControl}, // Cc [18] ..
+ {0x007F, 0x009F, prControl}, // Cc [33] ..
+ {0x00A9, 0x00A9, prExtendedPictographic}, // E0.6 [1] (©️) copyright
+ {0x00AD, 0x00AD, prControl}, // Cf SOFT HYPHEN
+ {0x00AE, 0x00AE, prExtendedPictographic}, // E0.6 [1] (®️) registered
+ {0x0300, 0x036F, prExtend}, // Mn [112] COMBINING GRAVE ACCENT..COMBINING LATIN SMALL LETTER X
+ {0x0483, 0x0487, prExtend}, // Mn [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE
+ {0x0488, 0x0489, prExtend}, // Me [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN
+ {0x0591, 0x05BD, prExtend}, // Mn [45] HEBREW ACCENT ETNAHTA..HEBREW POINT METEG
+ {0x05BF, 0x05BF, prExtend}, // Mn HEBREW POINT RAFE
+ {0x05C1, 0x05C2, prExtend}, // Mn [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT
+ {0x05C4, 0x05C5, prExtend}, // Mn [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT
+ {0x05C7, 0x05C7, prExtend}, // Mn HEBREW POINT QAMATS QATAN
+ {0x0600, 0x0605, prPrepend}, // Cf [6] ARABIC NUMBER SIGN..ARABIC NUMBER MARK ABOVE
+ {0x0610, 0x061A, prExtend}, // Mn [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA
+ {0x061C, 0x061C, prControl}, // Cf ARABIC LETTER MARK
+ {0x064B, 0x065F, prExtend}, // Mn [21] ARABIC FATHATAN..ARABIC WAVY HAMZA BELOW
+ {0x0670, 0x0670, prExtend}, // Mn ARABIC LETTER SUPERSCRIPT ALEF
+ {0x06D6, 0x06DC, prExtend}, // Mn [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN
+ {0x06DD, 0x06DD, prPrepend}, // Cf ARABIC END OF AYAH
+ {0x06DF, 0x06E4, prExtend}, // Mn [6] ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MADDA
+ {0x06E7, 0x06E8, prExtend}, // Mn [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON
+ {0x06EA, 0x06ED, prExtend}, // Mn [4] ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM
+ {0x070F, 0x070F, prPrepend}, // Cf SYRIAC ABBREVIATION MARK
+ {0x0711, 0x0711, prExtend}, // Mn SYRIAC LETTER SUPERSCRIPT ALAPH
+ {0x0730, 0x074A, prExtend}, // Mn [27] SYRIAC PTHAHA ABOVE..SYRIAC BARREKH
+ {0x07A6, 0x07B0, prExtend}, // Mn [11] THAANA ABAFILI..THAANA SUKUN
+ {0x07EB, 0x07F3, prExtend}, // Mn [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE
+ {0x07FD, 0x07FD, prExtend}, // Mn NKO DANTAYALAN
+ {0x0816, 0x0819, prExtend}, // Mn [4] SAMARITAN MARK IN..SAMARITAN MARK DAGESH
+ {0x081B, 0x0823, prExtend}, // Mn [9] SAMARITAN MARK EPENTHETIC YUT..SAMARITAN VOWEL SIGN A
+ {0x0825, 0x0827, prExtend}, // Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U
+ {0x0829, 0x082D, prExtend}, // Mn [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA
+ {0x0859, 0x085B, prExtend}, // Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK
+ {0x0890, 0x0891, prPrepend}, // Cf [2] ARABIC POUND MARK ABOVE..ARABIC PIASTRE MARK ABOVE
+ {0x0898, 0x089F, prExtend}, // Mn [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA
+ {0x08CA, 0x08E1, prExtend}, // Mn [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA
+ {0x08E2, 0x08E2, prPrepend}, // Cf ARABIC DISPUTED END OF AYAH
+ {0x08E3, 0x0902, prExtend}, // Mn [32] ARABIC TURNED DAMMA BELOW..DEVANAGARI SIGN ANUSVARA
+ {0x0903, 0x0903, prSpacingMark}, // Mc DEVANAGARI SIGN VISARGA
+ {0x093A, 0x093A, prExtend}, // Mn DEVANAGARI VOWEL SIGN OE
+ {0x093B, 0x093B, prSpacingMark}, // Mc DEVANAGARI VOWEL SIGN OOE
+ {0x093C, 0x093C, prExtend}, // Mn DEVANAGARI SIGN NUKTA
+ {0x093E, 0x0940, prSpacingMark}, // Mc [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II
+ {0x0941, 0x0948, prExtend}, // Mn [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI
+ {0x0949, 0x094C, prSpacingMark}, // Mc [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU
+ {0x094D, 0x094D, prExtend}, // Mn DEVANAGARI SIGN VIRAMA
+ {0x094E, 0x094F, prSpacingMark}, // Mc [2] DEVANAGARI VOWEL SIGN PRISHTHAMATRA E..DEVANAGARI VOWEL SIGN AW
+ {0x0951, 0x0957, prExtend}, // Mn [7] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI VOWEL SIGN UUE
+ {0x0962, 0x0963, prExtend}, // Mn [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL
+ {0x0981, 0x0981, prExtend}, // Mn BENGALI SIGN CANDRABINDU
+ {0x0982, 0x0983, prSpacingMark}, // Mc [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA
+ {0x09BC, 0x09BC, prExtend}, // Mn BENGALI SIGN NUKTA
+ {0x09BE, 0x09BE, prExtend}, // Mc BENGALI VOWEL SIGN AA
+ {0x09BF, 0x09C0, prSpacingMark}, // Mc [2] BENGALI VOWEL SIGN I..BENGALI VOWEL SIGN II
+ {0x09C1, 0x09C4, prExtend}, // Mn [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR
+ {0x09C7, 0x09C8, prSpacingMark}, // Mc [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI
+ {0x09CB, 0x09CC, prSpacingMark}, // Mc [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU
+ {0x09CD, 0x09CD, prExtend}, // Mn BENGALI SIGN VIRAMA
+ {0x09D7, 0x09D7, prExtend}, // Mc BENGALI AU LENGTH MARK
+ {0x09E2, 0x09E3, prExtend}, // Mn [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL
+ {0x09FE, 0x09FE, prExtend}, // Mn BENGALI SANDHI MARK
+ {0x0A01, 0x0A02, prExtend}, // Mn [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI
+ {0x0A03, 0x0A03, prSpacingMark}, // Mc GURMUKHI SIGN VISARGA
+ {0x0A3C, 0x0A3C, prExtend}, // Mn GURMUKHI SIGN NUKTA
+ {0x0A3E, 0x0A40, prSpacingMark}, // Mc [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II
+ {0x0A41, 0x0A42, prExtend}, // Mn [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU
+ {0x0A47, 0x0A48, prExtend}, // Mn [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI
+ {0x0A4B, 0x0A4D, prExtend}, // Mn [3] GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA
+ {0x0A51, 0x0A51, prExtend}, // Mn GURMUKHI SIGN UDAAT
+ {0x0A70, 0x0A71, prExtend}, // Mn [2] GURMUKHI TIPPI..GURMUKHI ADDAK
+ {0x0A75, 0x0A75, prExtend}, // Mn GURMUKHI SIGN YAKASH
+ {0x0A81, 0x0A82, prExtend}, // Mn [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA
+ {0x0A83, 0x0A83, prSpacingMark}, // Mc GUJARATI SIGN VISARGA
+ {0x0ABC, 0x0ABC, prExtend}, // Mn GUJARATI SIGN NUKTA
+ {0x0ABE, 0x0AC0, prSpacingMark}, // Mc [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II
+ {0x0AC1, 0x0AC5, prExtend}, // Mn [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E
+ {0x0AC7, 0x0AC8, prExtend}, // Mn [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI
+ {0x0AC9, 0x0AC9, prSpacingMark}, // Mc GUJARATI VOWEL SIGN CANDRA O
+ {0x0ACB, 0x0ACC, prSpacingMark}, // Mc [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU
+ {0x0ACD, 0x0ACD, prExtend}, // Mn GUJARATI SIGN VIRAMA
+ {0x0AE2, 0x0AE3, prExtend}, // Mn [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL
+ {0x0AFA, 0x0AFF, prExtend}, // Mn [6] GUJARATI SIGN SUKUN..GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE
+ {0x0B01, 0x0B01, prExtend}, // Mn ORIYA SIGN CANDRABINDU
+ {0x0B02, 0x0B03, prSpacingMark}, // Mc [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA
+ {0x0B3C, 0x0B3C, prExtend}, // Mn ORIYA SIGN NUKTA
+ {0x0B3E, 0x0B3E, prExtend}, // Mc ORIYA VOWEL SIGN AA
+ {0x0B3F, 0x0B3F, prExtend}, // Mn ORIYA VOWEL SIGN I
+ {0x0B40, 0x0B40, prSpacingMark}, // Mc ORIYA VOWEL SIGN II
+ {0x0B41, 0x0B44, prExtend}, // Mn [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR
+ {0x0B47, 0x0B48, prSpacingMark}, // Mc [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI
+ {0x0B4B, 0x0B4C, prSpacingMark}, // Mc [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU
+ {0x0B4D, 0x0B4D, prExtend}, // Mn ORIYA SIGN VIRAMA
+ {0x0B55, 0x0B56, prExtend}, // Mn [2] ORIYA SIGN OVERLINE..ORIYA AI LENGTH MARK
+ {0x0B57, 0x0B57, prExtend}, // Mc ORIYA AU LENGTH MARK
+ {0x0B62, 0x0B63, prExtend}, // Mn [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL
+ {0x0B82, 0x0B82, prExtend}, // Mn TAMIL SIGN ANUSVARA
+ {0x0BBE, 0x0BBE, prExtend}, // Mc TAMIL VOWEL SIGN AA
+ {0x0BBF, 0x0BBF, prSpacingMark}, // Mc TAMIL VOWEL SIGN I
+ {0x0BC0, 0x0BC0, prExtend}, // Mn TAMIL VOWEL SIGN II
+ {0x0BC1, 0x0BC2, prSpacingMark}, // Mc [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU
+ {0x0BC6, 0x0BC8, prSpacingMark}, // Mc [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI
+ {0x0BCA, 0x0BCC, prSpacingMark}, // Mc [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU
+ {0x0BCD, 0x0BCD, prExtend}, // Mn TAMIL SIGN VIRAMA
+ {0x0BD7, 0x0BD7, prExtend}, // Mc TAMIL AU LENGTH MARK
+ {0x0C00, 0x0C00, prExtend}, // Mn TELUGU SIGN COMBINING CANDRABINDU ABOVE
+ {0x0C01, 0x0C03, prSpacingMark}, // Mc [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA
+ {0x0C04, 0x0C04, prExtend}, // Mn TELUGU SIGN COMBINING ANUSVARA ABOVE
+ {0x0C3C, 0x0C3C, prExtend}, // Mn TELUGU SIGN NUKTA
+ {0x0C3E, 0x0C40, prExtend}, // Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II
+ {0x0C41, 0x0C44, prSpacingMark}, // Mc [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR
+ {0x0C46, 0x0C48, prExtend}, // Mn [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI
+ {0x0C4A, 0x0C4D, prExtend}, // Mn [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA
+ {0x0C55, 0x0C56, prExtend}, // Mn [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK
+ {0x0C62, 0x0C63, prExtend}, // Mn [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL
+ {0x0C81, 0x0C81, prExtend}, // Mn KANNADA SIGN CANDRABINDU
+ {0x0C82, 0x0C83, prSpacingMark}, // Mc [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA
+ {0x0CBC, 0x0CBC, prExtend}, // Mn KANNADA SIGN NUKTA
+ {0x0CBE, 0x0CBE, prSpacingMark}, // Mc KANNADA VOWEL SIGN AA
+ {0x0CBF, 0x0CBF, prExtend}, // Mn KANNADA VOWEL SIGN I
+ {0x0CC0, 0x0CC1, prSpacingMark}, // Mc [2] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN U
+ {0x0CC2, 0x0CC2, prExtend}, // Mc KANNADA VOWEL SIGN UU
+ {0x0CC3, 0x0CC4, prSpacingMark}, // Mc [2] KANNADA VOWEL SIGN VOCALIC R..KANNADA VOWEL SIGN VOCALIC RR
+ {0x0CC6, 0x0CC6, prExtend}, // Mn KANNADA VOWEL SIGN E
+ {0x0CC7, 0x0CC8, prSpacingMark}, // Mc [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI
+ {0x0CCA, 0x0CCB, prSpacingMark}, // Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO
+ {0x0CCC, 0x0CCD, prExtend}, // Mn [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA
+ {0x0CD5, 0x0CD6, prExtend}, // Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK
+ {0x0CE2, 0x0CE3, prExtend}, // Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL
+ {0x0CF3, 0x0CF3, prSpacingMark}, // Mc KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT
+ {0x0D00, 0x0D01, prExtend}, // Mn [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU
+ {0x0D02, 0x0D03, prSpacingMark}, // Mc [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA
+ {0x0D3B, 0x0D3C, prExtend}, // Mn [2] MALAYALAM SIGN VERTICAL BAR VIRAMA..MALAYALAM SIGN CIRCULAR VIRAMA
+ {0x0D3E, 0x0D3E, prExtend}, // Mc MALAYALAM VOWEL SIGN AA
+ {0x0D3F, 0x0D40, prSpacingMark}, // Mc [2] MALAYALAM VOWEL SIGN I..MALAYALAM VOWEL SIGN II
+ {0x0D41, 0x0D44, prExtend}, // Mn [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR
+ {0x0D46, 0x0D48, prSpacingMark}, // Mc [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI
+ {0x0D4A, 0x0D4C, prSpacingMark}, // Mc [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU
+ {0x0D4D, 0x0D4D, prExtend}, // Mn MALAYALAM SIGN VIRAMA
+ {0x0D4E, 0x0D4E, prPrepend}, // Lo MALAYALAM LETTER DOT REPH
+ {0x0D57, 0x0D57, prExtend}, // Mc MALAYALAM AU LENGTH MARK
+ {0x0D62, 0x0D63, prExtend}, // Mn [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL
+ {0x0D81, 0x0D81, prExtend}, // Mn SINHALA SIGN CANDRABINDU
+ {0x0D82, 0x0D83, prSpacingMark}, // Mc [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA
+ {0x0DCA, 0x0DCA, prExtend}, // Mn SINHALA SIGN AL-LAKUNA
+ {0x0DCF, 0x0DCF, prExtend}, // Mc SINHALA VOWEL SIGN AELA-PILLA
+ {0x0DD0, 0x0DD1, prSpacingMark}, // Mc [2] SINHALA VOWEL SIGN KETTI AEDA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA
+ {0x0DD2, 0x0DD4, prExtend}, // Mn [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA
+ {0x0DD6, 0x0DD6, prExtend}, // Mn SINHALA VOWEL SIGN DIGA PAA-PILLA
+ {0x0DD8, 0x0DDE, prSpacingMark}, // Mc [7] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA
+ {0x0DDF, 0x0DDF, prExtend}, // Mc SINHALA VOWEL SIGN GAYANUKITTA
+ {0x0DF2, 0x0DF3, prSpacingMark}, // Mc [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA
+ {0x0E31, 0x0E31, prExtend}, // Mn THAI CHARACTER MAI HAN-AKAT
+ {0x0E33, 0x0E33, prSpacingMark}, // Lo THAI CHARACTER SARA AM
+ {0x0E34, 0x0E3A, prExtend}, // Mn [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU
+ {0x0E47, 0x0E4E, prExtend}, // Mn [8] THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN
+ {0x0EB1, 0x0EB1, prExtend}, // Mn LAO VOWEL SIGN MAI KAN
+ {0x0EB3, 0x0EB3, prSpacingMark}, // Lo LAO VOWEL SIGN AM
+ {0x0EB4, 0x0EBC, prExtend}, // Mn [9] LAO VOWEL SIGN I..LAO SEMIVOWEL SIGN LO
+ {0x0EC8, 0x0ECE, prExtend}, // Mn [7] LAO TONE MAI EK..LAO YAMAKKAN
+ {0x0F18, 0x0F19, prExtend}, // Mn [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS
+ {0x0F35, 0x0F35, prExtend}, // Mn TIBETAN MARK NGAS BZUNG NYI ZLA
+ {0x0F37, 0x0F37, prExtend}, // Mn TIBETAN MARK NGAS BZUNG SGOR RTAGS
+ {0x0F39, 0x0F39, prExtend}, // Mn TIBETAN MARK TSA -PHRU
+ {0x0F3E, 0x0F3F, prSpacingMark}, // Mc [2] TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES
+ {0x0F71, 0x0F7E, prExtend}, // Mn [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO
+ {0x0F7F, 0x0F7F, prSpacingMark}, // Mc TIBETAN SIGN RNAM BCAD
+ {0x0F80, 0x0F84, prExtend}, // Mn [5] TIBETAN VOWEL SIGN REVERSED I..TIBETAN MARK HALANTA
+ {0x0F86, 0x0F87, prExtend}, // Mn [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS
+ {0x0F8D, 0x0F97, prExtend}, // Mn [11] TIBETAN SUBJOINED SIGN LCE TSA CAN..TIBETAN SUBJOINED LETTER JA
+ {0x0F99, 0x0FBC, prExtend}, // Mn [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA
+ {0x0FC6, 0x0FC6, prExtend}, // Mn TIBETAN SYMBOL PADMA GDAN
+ {0x102D, 0x1030, prExtend}, // Mn [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU
+ {0x1031, 0x1031, prSpacingMark}, // Mc MYANMAR VOWEL SIGN E
+ {0x1032, 0x1037, prExtend}, // Mn [6] MYANMAR VOWEL SIGN AI..MYANMAR SIGN DOT BELOW
+ {0x1039, 0x103A, prExtend}, // Mn [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT
+ {0x103B, 0x103C, prSpacingMark}, // Mc [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA
+ {0x103D, 0x103E, prExtend}, // Mn [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA
+ {0x1056, 0x1057, prSpacingMark}, // Mc [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR
+ {0x1058, 0x1059, prExtend}, // Mn [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL
+ {0x105E, 0x1060, prExtend}, // Mn [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA
+ {0x1071, 0x1074, prExtend}, // Mn [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE
+ {0x1082, 0x1082, prExtend}, // Mn MYANMAR CONSONANT SIGN SHAN MEDIAL WA
+ {0x1084, 0x1084, prSpacingMark}, // Mc MYANMAR VOWEL SIGN SHAN E
+ {0x1085, 0x1086, prExtend}, // Mn [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y
+ {0x108D, 0x108D, prExtend}, // Mn MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE
+ {0x109D, 0x109D, prExtend}, // Mn MYANMAR VOWEL SIGN AITON AI
+ {0x1100, 0x115F, prL}, // Lo [96] HANGUL CHOSEONG KIYEOK..HANGUL CHOSEONG FILLER
+ {0x1160, 0x11A7, prV}, // Lo [72] HANGUL JUNGSEONG FILLER..HANGUL JUNGSEONG O-YAE
+ {0x11A8, 0x11FF, prT}, // Lo [88] HANGUL JONGSEONG KIYEOK..HANGUL JONGSEONG SSANGNIEUN
+ {0x135D, 0x135F, prExtend}, // Mn [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK
+ {0x1712, 0x1714, prExtend}, // Mn [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA
+ {0x1715, 0x1715, prSpacingMark}, // Mc TAGALOG SIGN PAMUDPOD
+ {0x1732, 0x1733, prExtend}, // Mn [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U
+ {0x1734, 0x1734, prSpacingMark}, // Mc HANUNOO SIGN PAMUDPOD
+ {0x1752, 0x1753, prExtend}, // Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U
+ {0x1772, 0x1773, prExtend}, // Mn [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U
+ {0x17B4, 0x17B5, prExtend}, // Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA
+ {0x17B6, 0x17B6, prSpacingMark}, // Mc KHMER VOWEL SIGN AA
+ {0x17B7, 0x17BD, prExtend}, // Mn [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA
+ {0x17BE, 0x17C5, prSpacingMark}, // Mc [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU
+ {0x17C6, 0x17C6, prExtend}, // Mn KHMER SIGN NIKAHIT
+ {0x17C7, 0x17C8, prSpacingMark}, // Mc [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU
+ {0x17C9, 0x17D3, prExtend}, // Mn [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT
+ {0x17DD, 0x17DD, prExtend}, // Mn KHMER SIGN ATTHACAN
+ {0x180B, 0x180D, prExtend}, // Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE
+ {0x180E, 0x180E, prControl}, // Cf MONGOLIAN VOWEL SEPARATOR
+ {0x180F, 0x180F, prExtend}, // Mn MONGOLIAN FREE VARIATION SELECTOR FOUR
+ {0x1885, 0x1886, prExtend}, // Mn [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA
+ {0x18A9, 0x18A9, prExtend}, // Mn MONGOLIAN LETTER ALI GALI DAGALGA
+ {0x1920, 0x1922, prExtend}, // Mn [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U
+ {0x1923, 0x1926, prSpacingMark}, // Mc [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU
+ {0x1927, 0x1928, prExtend}, // Mn [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O
+ {0x1929, 0x192B, prSpacingMark}, // Mc [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA
+ {0x1930, 0x1931, prSpacingMark}, // Mc [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA
+ {0x1932, 0x1932, prExtend}, // Mn LIMBU SMALL LETTER ANUSVARA
+ {0x1933, 0x1938, prSpacingMark}, // Mc [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA
+ {0x1939, 0x193B, prExtend}, // Mn [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I
+ {0x1A17, 0x1A18, prExtend}, // Mn [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U
+ {0x1A19, 0x1A1A, prSpacingMark}, // Mc [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O
+ {0x1A1B, 0x1A1B, prExtend}, // Mn BUGINESE VOWEL SIGN AE
+ {0x1A55, 0x1A55, prSpacingMark}, // Mc TAI THAM CONSONANT SIGN MEDIAL RA
+ {0x1A56, 0x1A56, prExtend}, // Mn TAI THAM CONSONANT SIGN MEDIAL LA
+ {0x1A57, 0x1A57, prSpacingMark}, // Mc TAI THAM CONSONANT SIGN LA TANG LAI
+ {0x1A58, 0x1A5E, prExtend}, // Mn [7] TAI THAM SIGN MAI KANG LAI..TAI THAM CONSONANT SIGN SA
+ {0x1A60, 0x1A60, prExtend}, // Mn TAI THAM SIGN SAKOT
+ {0x1A62, 0x1A62, prExtend}, // Mn TAI THAM VOWEL SIGN MAI SAT
+ {0x1A65, 0x1A6C, prExtend}, // Mn [8] TAI THAM VOWEL SIGN I..TAI THAM VOWEL SIGN OA BELOW
+ {0x1A6D, 0x1A72, prSpacingMark}, // Mc [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI
+ {0x1A73, 0x1A7C, prExtend}, // Mn [10] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN KHUEN-LUE KARAN
+ {0x1A7F, 0x1A7F, prExtend}, // Mn TAI THAM COMBINING CRYPTOGRAMMIC DOT
+ {0x1AB0, 0x1ABD, prExtend}, // Mn [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW
+ {0x1ABE, 0x1ABE, prExtend}, // Me COMBINING PARENTHESES OVERLAY
+ {0x1ABF, 0x1ACE, prExtend}, // Mn [16] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER INSULAR T
+ {0x1B00, 0x1B03, prExtend}, // Mn [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG
+ {0x1B04, 0x1B04, prSpacingMark}, // Mc BALINESE SIGN BISAH
+ {0x1B34, 0x1B34, prExtend}, // Mn BALINESE SIGN REREKAN
+ {0x1B35, 0x1B35, prExtend}, // Mc BALINESE VOWEL SIGN TEDUNG
+ {0x1B36, 0x1B3A, prExtend}, // Mn [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA
+ {0x1B3B, 0x1B3B, prSpacingMark}, // Mc BALINESE VOWEL SIGN RA REPA TEDUNG
+ {0x1B3C, 0x1B3C, prExtend}, // Mn BALINESE VOWEL SIGN LA LENGA
+ {0x1B3D, 0x1B41, prSpacingMark}, // Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG
+ {0x1B42, 0x1B42, prExtend}, // Mn BALINESE VOWEL SIGN PEPET
+ {0x1B43, 0x1B44, prSpacingMark}, // Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG
+ {0x1B6B, 0x1B73, prExtend}, // Mn [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG
+ {0x1B80, 0x1B81, prExtend}, // Mn [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR
+ {0x1B82, 0x1B82, prSpacingMark}, // Mc SUNDANESE SIGN PANGWISAD
+ {0x1BA1, 0x1BA1, prSpacingMark}, // Mc SUNDANESE CONSONANT SIGN PAMINGKAL
+ {0x1BA2, 0x1BA5, prExtend}, // Mn [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU
+ {0x1BA6, 0x1BA7, prSpacingMark}, // Mc [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG
+ {0x1BA8, 0x1BA9, prExtend}, // Mn [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG
+ {0x1BAA, 0x1BAA, prSpacingMark}, // Mc SUNDANESE SIGN PAMAAEH
+ {0x1BAB, 0x1BAD, prExtend}, // Mn [3] SUNDANESE SIGN VIRAMA..SUNDANESE CONSONANT SIGN PASANGAN WA
+ {0x1BE6, 0x1BE6, prExtend}, // Mn BATAK SIGN TOMPI
+ {0x1BE7, 0x1BE7, prSpacingMark}, // Mc BATAK VOWEL SIGN E
+ {0x1BE8, 0x1BE9, prExtend}, // Mn [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE
+ {0x1BEA, 0x1BEC, prSpacingMark}, // Mc [3] BATAK VOWEL SIGN I..BATAK VOWEL SIGN O
+ {0x1BED, 0x1BED, prExtend}, // Mn BATAK VOWEL SIGN KARO O
+ {0x1BEE, 0x1BEE, prSpacingMark}, // Mc BATAK VOWEL SIGN U
+ {0x1BEF, 0x1BF1, prExtend}, // Mn [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H
+ {0x1BF2, 0x1BF3, prSpacingMark}, // Mc [2] BATAK PANGOLAT..BATAK PANONGONAN
+ {0x1C24, 0x1C2B, prSpacingMark}, // Mc [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU
+ {0x1C2C, 0x1C33, prExtend}, // Mn [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T
+ {0x1C34, 0x1C35, prSpacingMark}, // Mc [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG
+ {0x1C36, 0x1C37, prExtend}, // Mn [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA
+ {0x1CD0, 0x1CD2, prExtend}, // Mn [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA
+ {0x1CD4, 0x1CE0, prExtend}, // Mn [13] VEDIC SIGN YAJURVEDIC MIDLINE SVARITA..VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA
+ {0x1CE1, 0x1CE1, prSpacingMark}, // Mc VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA
+ {0x1CE2, 0x1CE8, prExtend}, // Mn [7] VEDIC SIGN VISARGA SVARITA..VEDIC SIGN VISARGA ANUDATTA WITH TAIL
+ {0x1CED, 0x1CED, prExtend}, // Mn VEDIC SIGN TIRYAK
+ {0x1CF4, 0x1CF4, prExtend}, // Mn VEDIC TONE CANDRA ABOVE
+ {0x1CF7, 0x1CF7, prSpacingMark}, // Mc VEDIC SIGN ATIKRAMA
+ {0x1CF8, 0x1CF9, prExtend}, // Mn [2] VEDIC TONE RING ABOVE..VEDIC TONE DOUBLE RING ABOVE
+ {0x1DC0, 0x1DFF, prExtend}, // Mn [64] COMBINING DOTTED GRAVE ACCENT..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW
+ {0x200B, 0x200B, prControl}, // Cf ZERO WIDTH SPACE
+ {0x200C, 0x200C, prExtend}, // Cf ZERO WIDTH NON-JOINER
+ {0x200D, 0x200D, prZWJ}, // Cf ZERO WIDTH JOINER
+ {0x200E, 0x200F, prControl}, // Cf [2] LEFT-TO-RIGHT MARK..RIGHT-TO-LEFT MARK
+ {0x2028, 0x2028, prControl}, // Zl LINE SEPARATOR
+ {0x2029, 0x2029, prControl}, // Zp PARAGRAPH SEPARATOR
+ {0x202A, 0x202E, prControl}, // Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE
+ {0x203C, 0x203C, prExtendedPictographic}, // E0.6 [1] (‼️) double exclamation mark
+ {0x2049, 0x2049, prExtendedPictographic}, // E0.6 [1] (⁉️) exclamation question mark
+ {0x2060, 0x2064, prControl}, // Cf [5] WORD JOINER..INVISIBLE PLUS
+ {0x2065, 0x2065, prControl}, // Cn
+ {0x2066, 0x206F, prControl}, // Cf [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES
+ {0x20D0, 0x20DC, prExtend}, // Mn [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE
+ {0x20DD, 0x20E0, prExtend}, // Me [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH
+ {0x20E1, 0x20E1, prExtend}, // Mn COMBINING LEFT RIGHT ARROW ABOVE
+ {0x20E2, 0x20E4, prExtend}, // Me [3] COMBINING ENCLOSING SCREEN..COMBINING ENCLOSING UPWARD POINTING TRIANGLE
+ {0x20E5, 0x20F0, prExtend}, // Mn [12] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING ASTERISK ABOVE
+ {0x2122, 0x2122, prExtendedPictographic}, // E0.6 [1] (™️) trade mark
+ {0x2139, 0x2139, prExtendedPictographic}, // E0.6 [1] (ℹ️) information
+ {0x2194, 0x2199, prExtendedPictographic}, // E0.6 [6] (↔️..↙️) left-right arrow..down-left arrow
+ {0x21A9, 0x21AA, prExtendedPictographic}, // E0.6 [2] (↩️..↪️) right arrow curving left..left arrow curving right
+ {0x231A, 0x231B, prExtendedPictographic}, // E0.6 [2] (⌚..⌛) watch..hourglass done
+ {0x2328, 0x2328, prExtendedPictographic}, // E1.0 [1] (⌨️) keyboard
+ {0x2388, 0x2388, prExtendedPictographic}, // E0.0 [1] (⎈) HELM SYMBOL
+ {0x23CF, 0x23CF, prExtendedPictographic}, // E1.0 [1] (⏏️) eject button
+ {0x23E9, 0x23EC, prExtendedPictographic}, // E0.6 [4] (⏩..⏬) fast-forward button..fast down button
+ {0x23ED, 0x23EE, prExtendedPictographic}, // E0.7 [2] (⏭️..⏮️) next track button..last track button
+ {0x23EF, 0x23EF, prExtendedPictographic}, // E1.0 [1] (⏯️) play or pause button
+ {0x23F0, 0x23F0, prExtendedPictographic}, // E0.6 [1] (⏰) alarm clock
+ {0x23F1, 0x23F2, prExtendedPictographic}, // E1.0 [2] (⏱️..⏲️) stopwatch..timer clock
+ {0x23F3, 0x23F3, prExtendedPictographic}, // E0.6 [1] (⏳) hourglass not done
+ {0x23F8, 0x23FA, prExtendedPictographic}, // E0.7 [3] (⏸️..⏺️) pause button..record button
+ {0x24C2, 0x24C2, prExtendedPictographic}, // E0.6 [1] (Ⓜ️) circled M
+ {0x25AA, 0x25AB, prExtendedPictographic}, // E0.6 [2] (▪️..▫️) black small square..white small square
+ {0x25B6, 0x25B6, prExtendedPictographic}, // E0.6 [1] (▶️) play button
+ {0x25C0, 0x25C0, prExtendedPictographic}, // E0.6 [1] (◀️) reverse button
+ {0x25FB, 0x25FE, prExtendedPictographic}, // E0.6 [4] (◻️..◾) white medium square..black medium-small square
+ {0x2600, 0x2601, prExtendedPictographic}, // E0.6 [2] (☀️..☁️) sun..cloud
+ {0x2602, 0x2603, prExtendedPictographic}, // E0.7 [2] (☂️..☃️) umbrella..snowman
+ {0x2604, 0x2604, prExtendedPictographic}, // E1.0 [1] (☄️) comet
+ {0x2605, 0x2605, prExtendedPictographic}, // E0.0 [1] (★) BLACK STAR
+ {0x2607, 0x260D, prExtendedPictographic}, // E0.0 [7] (☇..☍) LIGHTNING..OPPOSITION
+ {0x260E, 0x260E, prExtendedPictographic}, // E0.6 [1] (☎️) telephone
+ {0x260F, 0x2610, prExtendedPictographic}, // E0.0 [2] (☏..☐) WHITE TELEPHONE..BALLOT BOX
+ {0x2611, 0x2611, prExtendedPictographic}, // E0.6 [1] (☑️) check box with check
+ {0x2612, 0x2612, prExtendedPictographic}, // E0.0 [1] (☒) BALLOT BOX WITH X
+ {0x2614, 0x2615, prExtendedPictographic}, // E0.6 [2] (☔..☕) umbrella with rain drops..hot beverage
+ {0x2616, 0x2617, prExtendedPictographic}, // E0.0 [2] (☖..☗) WHITE SHOGI PIECE..BLACK SHOGI PIECE
+ {0x2618, 0x2618, prExtendedPictographic}, // E1.0 [1] (☘️) shamrock
+ {0x2619, 0x261C, prExtendedPictographic}, // E0.0 [4] (☙..☜) REVERSED ROTATED FLORAL HEART BULLET..WHITE LEFT POINTING INDEX
+ {0x261D, 0x261D, prExtendedPictographic}, // E0.6 [1] (☝️) index pointing up
+ {0x261E, 0x261F, prExtendedPictographic}, // E0.0 [2] (☞..☟) WHITE RIGHT POINTING INDEX..WHITE DOWN POINTING INDEX
+ {0x2620, 0x2620, prExtendedPictographic}, // E1.0 [1] (☠️) skull and crossbones
+ {0x2621, 0x2621, prExtendedPictographic}, // E0.0 [1] (☡) CAUTION SIGN
+ {0x2622, 0x2623, prExtendedPictographic}, // E1.0 [2] (☢️..☣️) radioactive..biohazard
+ {0x2624, 0x2625, prExtendedPictographic}, // E0.0 [2] (☤..☥) CADUCEUS..ANKH
+ {0x2626, 0x2626, prExtendedPictographic}, // E1.0 [1] (☦️) orthodox cross
+ {0x2627, 0x2629, prExtendedPictographic}, // E0.0 [3] (☧..☩) CHI RHO..CROSS OF JERUSALEM
+ {0x262A, 0x262A, prExtendedPictographic}, // E0.7 [1] (☪️) star and crescent
+ {0x262B, 0x262D, prExtendedPictographic}, // E0.0 [3] (☫..☭) FARSI SYMBOL..HAMMER AND SICKLE
+ {0x262E, 0x262E, prExtendedPictographic}, // E1.0 [1] (☮️) peace symbol
+ {0x262F, 0x262F, prExtendedPictographic}, // E0.7 [1] (☯️) yin yang
+ {0x2630, 0x2637, prExtendedPictographic}, // E0.0 [8] (☰..☷) TRIGRAM FOR HEAVEN..TRIGRAM FOR EARTH
+ {0x2638, 0x2639, prExtendedPictographic}, // E0.7 [2] (☸️..☹️) wheel of dharma..frowning face
+ {0x263A, 0x263A, prExtendedPictographic}, // E0.6 [1] (☺️) smiling face
+ {0x263B, 0x263F, prExtendedPictographic}, // E0.0 [5] (☻..☿) BLACK SMILING FACE..MERCURY
+ {0x2640, 0x2640, prExtendedPictographic}, // E4.0 [1] (♀️) female sign
+ {0x2641, 0x2641, prExtendedPictographic}, // E0.0 [1] (♁) EARTH
+ {0x2642, 0x2642, prExtendedPictographic}, // E4.0 [1] (♂️) male sign
+ {0x2643, 0x2647, prExtendedPictographic}, // E0.0 [5] (♃..♇) JUPITER..PLUTO
+ {0x2648, 0x2653, prExtendedPictographic}, // E0.6 [12] (♈..♓) Aries..Pisces
+ {0x2654, 0x265E, prExtendedPictographic}, // E0.0 [11] (♔..♞) WHITE CHESS KING..BLACK CHESS KNIGHT
+ {0x265F, 0x265F, prExtendedPictographic}, // E11.0 [1] (♟️) chess pawn
+ {0x2660, 0x2660, prExtendedPictographic}, // E0.6 [1] (♠️) spade suit
+ {0x2661, 0x2662, prExtendedPictographic}, // E0.0 [2] (♡..♢) WHITE HEART SUIT..WHITE DIAMOND SUIT
+ {0x2663, 0x2663, prExtendedPictographic}, // E0.6 [1] (♣️) club suit
+ {0x2664, 0x2664, prExtendedPictographic}, // E0.0 [1] (♤) WHITE SPADE SUIT
+ {0x2665, 0x2666, prExtendedPictographic}, // E0.6 [2] (♥️..♦️) heart suit..diamond suit
+ {0x2667, 0x2667, prExtendedPictographic}, // E0.0 [1] (♧) WHITE CLUB SUIT
+ {0x2668, 0x2668, prExtendedPictographic}, // E0.6 [1] (♨️) hot springs
+ {0x2669, 0x267A, prExtendedPictographic}, // E0.0 [18] (♩..♺) QUARTER NOTE..RECYCLING SYMBOL FOR GENERIC MATERIALS
+ {0x267B, 0x267B, prExtendedPictographic}, // E0.6 [1] (♻️) recycling symbol
+ {0x267C, 0x267D, prExtendedPictographic}, // E0.0 [2] (♼..♽) RECYCLED PAPER SYMBOL..PARTIALLY-RECYCLED PAPER SYMBOL
+ {0x267E, 0x267E, prExtendedPictographic}, // E11.0 [1] (♾️) infinity
+ {0x267F, 0x267F, prExtendedPictographic}, // E0.6 [1] (♿) wheelchair symbol
+ {0x2680, 0x2685, prExtendedPictographic}, // E0.0 [6] (⚀..⚅) DIE FACE-1..DIE FACE-6
+ {0x2690, 0x2691, prExtendedPictographic}, // E0.0 [2] (⚐..⚑) WHITE FLAG..BLACK FLAG
+ {0x2692, 0x2692, prExtendedPictographic}, // E1.0 [1] (⚒️) hammer and pick
+ {0x2693, 0x2693, prExtendedPictographic}, // E0.6 [1] (⚓) anchor
+ {0x2694, 0x2694, prExtendedPictographic}, // E1.0 [1] (⚔️) crossed swords
+ {0x2695, 0x2695, prExtendedPictographic}, // E4.0 [1] (⚕️) medical symbol
+ {0x2696, 0x2697, prExtendedPictographic}, // E1.0 [2] (⚖️..⚗️) balance scale..alembic
+ {0x2698, 0x2698, prExtendedPictographic}, // E0.0 [1] (⚘) FLOWER
+ {0x2699, 0x2699, prExtendedPictographic}, // E1.0 [1] (⚙️) gear
+ {0x269A, 0x269A, prExtendedPictographic}, // E0.0 [1] (⚚) STAFF OF HERMES
+ {0x269B, 0x269C, prExtendedPictographic}, // E1.0 [2] (⚛️..⚜️) atom symbol..fleur-de-lis
+ {0x269D, 0x269F, prExtendedPictographic}, // E0.0 [3] (⚝..⚟) OUTLINED WHITE STAR..THREE LINES CONVERGING LEFT
+ {0x26A0, 0x26A1, prExtendedPictographic}, // E0.6 [2] (⚠️..⚡) warning..high voltage
+ {0x26A2, 0x26A6, prExtendedPictographic}, // E0.0 [5] (⚢..⚦) DOUBLED FEMALE SIGN..MALE WITH STROKE SIGN
+ {0x26A7, 0x26A7, prExtendedPictographic}, // E13.0 [1] (⚧️) transgender symbol
+ {0x26A8, 0x26A9, prExtendedPictographic}, // E0.0 [2] (⚨..⚩) VERTICAL MALE WITH STROKE SIGN..HORIZONTAL MALE WITH STROKE SIGN
+ {0x26AA, 0x26AB, prExtendedPictographic}, // E0.6 [2] (⚪..⚫) white circle..black circle
+ {0x26AC, 0x26AF, prExtendedPictographic}, // E0.0 [4] (⚬..⚯) MEDIUM SMALL WHITE CIRCLE..UNMARRIED PARTNERSHIP SYMBOL
+ {0x26B0, 0x26B1, prExtendedPictographic}, // E1.0 [2] (⚰️..⚱️) coffin..funeral urn
+ {0x26B2, 0x26BC, prExtendedPictographic}, // E0.0 [11] (⚲..⚼) NEUTER..SESQUIQUADRATE
+ {0x26BD, 0x26BE, prExtendedPictographic}, // E0.6 [2] (⚽..⚾) soccer ball..baseball
+ {0x26BF, 0x26C3, prExtendedPictographic}, // E0.0 [5] (⚿..⛃) SQUARED KEY..BLACK DRAUGHTS KING
+ {0x26C4, 0x26C5, prExtendedPictographic}, // E0.6 [2] (⛄..⛅) snowman without snow..sun behind cloud
+ {0x26C6, 0x26C7, prExtendedPictographic}, // E0.0 [2] (⛆..⛇) RAIN..BLACK SNOWMAN
+ {0x26C8, 0x26C8, prExtendedPictographic}, // E0.7 [1] (⛈️) cloud with lightning and rain
+ {0x26C9, 0x26CD, prExtendedPictographic}, // E0.0 [5] (⛉..⛍) TURNED WHITE SHOGI PIECE..DISABLED CAR
+ {0x26CE, 0x26CE, prExtendedPictographic}, // E0.6 [1] (⛎) Ophiuchus
+ {0x26CF, 0x26CF, prExtendedPictographic}, // E0.7 [1] (⛏️) pick
+ {0x26D0, 0x26D0, prExtendedPictographic}, // E0.0 [1] (⛐) CAR SLIDING
+ {0x26D1, 0x26D1, prExtendedPictographic}, // E0.7 [1] (⛑️) rescue worker’s helmet
+ {0x26D2, 0x26D2, prExtendedPictographic}, // E0.0 [1] (⛒) CIRCLED CROSSING LANES
+ {0x26D3, 0x26D3, prExtendedPictographic}, // E0.7 [1] (⛓️) chains
+ {0x26D4, 0x26D4, prExtendedPictographic}, // E0.6 [1] (⛔) no entry
+ {0x26D5, 0x26E8, prExtendedPictographic}, // E0.0 [20] (⛕..⛨) ALTERNATE ONE-WAY LEFT WAY TRAFFIC..BLACK CROSS ON SHIELD
+ {0x26E9, 0x26E9, prExtendedPictographic}, // E0.7 [1] (⛩️) shinto shrine
+ {0x26EA, 0x26EA, prExtendedPictographic}, // E0.6 [1] (⛪) church
+ {0x26EB, 0x26EF, prExtendedPictographic}, // E0.0 [5] (⛫..⛯) CASTLE..MAP SYMBOL FOR LIGHTHOUSE
+ {0x26F0, 0x26F1, prExtendedPictographic}, // E0.7 [2] (⛰️..⛱️) mountain..umbrella on ground
+ {0x26F2, 0x26F3, prExtendedPictographic}, // E0.6 [2] (⛲..⛳) fountain..flag in hole
+ {0x26F4, 0x26F4, prExtendedPictographic}, // E0.7 [1] (⛴️) ferry
+ {0x26F5, 0x26F5, prExtendedPictographic}, // E0.6 [1] (⛵) sailboat
+ {0x26F6, 0x26F6, prExtendedPictographic}, // E0.0 [1] (⛶) SQUARE FOUR CORNERS
+ {0x26F7, 0x26F9, prExtendedPictographic}, // E0.7 [3] (⛷️..⛹️) skier..person bouncing ball
+ {0x26FA, 0x26FA, prExtendedPictographic}, // E0.6 [1] (⛺) tent
+ {0x26FB, 0x26FC, prExtendedPictographic}, // E0.0 [2] (⛻..⛼) JAPANESE BANK SYMBOL..HEADSTONE GRAVEYARD SYMBOL
+ {0x26FD, 0x26FD, prExtendedPictographic}, // E0.6 [1] (⛽) fuel pump
+ {0x26FE, 0x2701, prExtendedPictographic}, // E0.0 [4] (⛾..✁) CUP ON BLACK SQUARE..UPPER BLADE SCISSORS
+ {0x2702, 0x2702, prExtendedPictographic}, // E0.6 [1] (✂️) scissors
+ {0x2703, 0x2704, prExtendedPictographic}, // E0.0 [2] (✃..✄) LOWER BLADE SCISSORS..WHITE SCISSORS
+ {0x2705, 0x2705, prExtendedPictographic}, // E0.6 [1] (✅) check mark button
+ {0x2708, 0x270C, prExtendedPictographic}, // E0.6 [5] (✈️..✌️) airplane..victory hand
+ {0x270D, 0x270D, prExtendedPictographic}, // E0.7 [1] (✍️) writing hand
+ {0x270E, 0x270E, prExtendedPictographic}, // E0.0 [1] (✎) LOWER RIGHT PENCIL
+ {0x270F, 0x270F, prExtendedPictographic}, // E0.6 [1] (✏️) pencil
+ {0x2710, 0x2711, prExtendedPictographic}, // E0.0 [2] (✐..✑) UPPER RIGHT PENCIL..WHITE NIB
+ {0x2712, 0x2712, prExtendedPictographic}, // E0.6 [1] (✒️) black nib
+ {0x2714, 0x2714, prExtendedPictographic}, // E0.6 [1] (✔️) check mark
+ {0x2716, 0x2716, prExtendedPictographic}, // E0.6 [1] (✖️) multiply
+ {0x271D, 0x271D, prExtendedPictographic}, // E0.7 [1] (✝️) latin cross
+ {0x2721, 0x2721, prExtendedPictographic}, // E0.7 [1] (✡️) star of David
+ {0x2728, 0x2728, prExtendedPictographic}, // E0.6 [1] (✨) sparkles
+ {0x2733, 0x2734, prExtendedPictographic}, // E0.6 [2] (✳️..✴️) eight-spoked asterisk..eight-pointed star
+ {0x2744, 0x2744, prExtendedPictographic}, // E0.6 [1] (❄️) snowflake
+ {0x2747, 0x2747, prExtendedPictographic}, // E0.6 [1] (❇️) sparkle
+ {0x274C, 0x274C, prExtendedPictographic}, // E0.6 [1] (❌) cross mark
+ {0x274E, 0x274E, prExtendedPictographic}, // E0.6 [1] (❎) cross mark button
+ {0x2753, 0x2755, prExtendedPictographic}, // E0.6 [3] (❓..❕) red question mark..white exclamation mark
+ {0x2757, 0x2757, prExtendedPictographic}, // E0.6 [1] (❗) red exclamation mark
+ {0x2763, 0x2763, prExtendedPictographic}, // E1.0 [1] (❣️) heart exclamation
+ {0x2764, 0x2764, prExtendedPictographic}, // E0.6 [1] (❤️) red heart
+ {0x2765, 0x2767, prExtendedPictographic}, // E0.0 [3] (❥..❧) ROTATED HEAVY BLACK HEART BULLET..ROTATED FLORAL HEART BULLET
+ {0x2795, 0x2797, prExtendedPictographic}, // E0.6 [3] (➕..➗) plus..divide
+ {0x27A1, 0x27A1, prExtendedPictographic}, // E0.6 [1] (➡️) right arrow
+ {0x27B0, 0x27B0, prExtendedPictographic}, // E0.6 [1] (➰) curly loop
+ {0x27BF, 0x27BF, prExtendedPictographic}, // E1.0 [1] (➿) double curly loop
+ {0x2934, 0x2935, prExtendedPictographic}, // E0.6 [2] (⤴️..⤵️) right arrow curving up..right arrow curving down
+ {0x2B05, 0x2B07, prExtendedPictographic}, // E0.6 [3] (⬅️..⬇️) left arrow..down arrow
+ {0x2B1B, 0x2B1C, prExtendedPictographic}, // E0.6 [2] (⬛..⬜) black large square..white large square
+ {0x2B50, 0x2B50, prExtendedPictographic}, // E0.6 [1] (⭐) star
+ {0x2B55, 0x2B55, prExtendedPictographic}, // E0.6 [1] (⭕) hollow red circle
+ {0x2CEF, 0x2CF1, prExtend}, // Mn [3] COPTIC COMBINING NI ABOVE..COPTIC COMBINING SPIRITUS LENIS
+ {0x2D7F, 0x2D7F, prExtend}, // Mn TIFINAGH CONSONANT JOINER
+ {0x2DE0, 0x2DFF, prExtend}, // Mn [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS
+ {0x302A, 0x302D, prExtend}, // Mn [4] IDEOGRAPHIC LEVEL TONE MARK..IDEOGRAPHIC ENTERING TONE MARK
+ {0x302E, 0x302F, prExtend}, // Mc [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK
+ {0x3030, 0x3030, prExtendedPictographic}, // E0.6 [1] (〰️) wavy dash
+ {0x303D, 0x303D, prExtendedPictographic}, // E0.6 [1] (〽️) part alternation mark
+ {0x3099, 0x309A, prExtend}, // Mn [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+ {0x3297, 0x3297, prExtendedPictographic}, // E0.6 [1] (㊗️) Japanese “congratulations” button
+ {0x3299, 0x3299, prExtendedPictographic}, // E0.6 [1] (㊙️) Japanese “secret” button
+ {0xA66F, 0xA66F, prExtend}, // Mn COMBINING CYRILLIC VZMET
+ {0xA670, 0xA672, prExtend}, // Me [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN
+ {0xA674, 0xA67D, prExtend}, // Mn [10] COMBINING CYRILLIC LETTER UKRAINIAN IE..COMBINING CYRILLIC PAYEROK
+ {0xA69E, 0xA69F, prExtend}, // Mn [2] COMBINING CYRILLIC LETTER EF..COMBINING CYRILLIC LETTER IOTIFIED E
+ {0xA6F0, 0xA6F1, prExtend}, // Mn [2] BAMUM COMBINING MARK KOQNDON..BAMUM COMBINING MARK TUKWENTIS
+ {0xA802, 0xA802, prExtend}, // Mn SYLOTI NAGRI SIGN DVISVARA
+ {0xA806, 0xA806, prExtend}, // Mn SYLOTI NAGRI SIGN HASANTA
+ {0xA80B, 0xA80B, prExtend}, // Mn SYLOTI NAGRI SIGN ANUSVARA
+ {0xA823, 0xA824, prSpacingMark}, // Mc [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I
+ {0xA825, 0xA826, prExtend}, // Mn [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E
+ {0xA827, 0xA827, prSpacingMark}, // Mc SYLOTI NAGRI VOWEL SIGN OO
+ {0xA82C, 0xA82C, prExtend}, // Mn SYLOTI NAGRI SIGN ALTERNATE HASANTA
+ {0xA880, 0xA881, prSpacingMark}, // Mc [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA
+ {0xA8B4, 0xA8C3, prSpacingMark}, // Mc [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU
+ {0xA8C4, 0xA8C5, prExtend}, // Mn [2] SAURASHTRA SIGN VIRAMA..SAURASHTRA SIGN CANDRABINDU
+ {0xA8E0, 0xA8F1, prExtend}, // Mn [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA
+ {0xA8FF, 0xA8FF, prExtend}, // Mn DEVANAGARI VOWEL SIGN AY
+ {0xA926, 0xA92D, prExtend}, // Mn [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU
+ {0xA947, 0xA951, prExtend}, // Mn [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R
+ {0xA952, 0xA953, prSpacingMark}, // Mc [2] REJANG CONSONANT SIGN H..REJANG VIRAMA
+ {0xA960, 0xA97C, prL}, // Lo [29] HANGUL CHOSEONG TIKEUT-MIEUM..HANGUL CHOSEONG SSANGYEORINHIEUH
+ {0xA980, 0xA982, prExtend}, // Mn [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR
+ {0xA983, 0xA983, prSpacingMark}, // Mc JAVANESE SIGN WIGNYAN
+ {0xA9B3, 0xA9B3, prExtend}, // Mn JAVANESE SIGN CECAK TELU
+ {0xA9B4, 0xA9B5, prSpacingMark}, // Mc [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG
+ {0xA9B6, 0xA9B9, prExtend}, // Mn [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT
+ {0xA9BA, 0xA9BB, prSpacingMark}, // Mc [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE
+ {0xA9BC, 0xA9BD, prExtend}, // Mn [2] JAVANESE VOWEL SIGN PEPET..JAVANESE CONSONANT SIGN KERET
+ {0xA9BE, 0xA9C0, prSpacingMark}, // Mc [3] JAVANESE CONSONANT SIGN PENGKAL..JAVANESE PANGKON
+ {0xA9E5, 0xA9E5, prExtend}, // Mn MYANMAR SIGN SHAN SAW
+ {0xAA29, 0xAA2E, prExtend}, // Mn [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE
+ {0xAA2F, 0xAA30, prSpacingMark}, // Mc [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI
+ {0xAA31, 0xAA32, prExtend}, // Mn [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE
+ {0xAA33, 0xAA34, prSpacingMark}, // Mc [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA
+ {0xAA35, 0xAA36, prExtend}, // Mn [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA
+ {0xAA43, 0xAA43, prExtend}, // Mn CHAM CONSONANT SIGN FINAL NG
+ {0xAA4C, 0xAA4C, prExtend}, // Mn CHAM CONSONANT SIGN FINAL M
+ {0xAA4D, 0xAA4D, prSpacingMark}, // Mc CHAM CONSONANT SIGN FINAL H
+ {0xAA7C, 0xAA7C, prExtend}, // Mn MYANMAR SIGN TAI LAING TONE-2
+ {0xAAB0, 0xAAB0, prExtend}, // Mn TAI VIET MAI KANG
+ {0xAAB2, 0xAAB4, prExtend}, // Mn [3] TAI VIET VOWEL I..TAI VIET VOWEL U
+ {0xAAB7, 0xAAB8, prExtend}, // Mn [2] TAI VIET MAI KHIT..TAI VIET VOWEL IA
+ {0xAABE, 0xAABF, prExtend}, // Mn [2] TAI VIET VOWEL AM..TAI VIET TONE MAI EK
+ {0xAAC1, 0xAAC1, prExtend}, // Mn TAI VIET TONE MAI THO
+ {0xAAEB, 0xAAEB, prSpacingMark}, // Mc MEETEI MAYEK VOWEL SIGN II
+ {0xAAEC, 0xAAED, prExtend}, // Mn [2] MEETEI MAYEK VOWEL SIGN UU..MEETEI MAYEK VOWEL SIGN AAI
+ {0xAAEE, 0xAAEF, prSpacingMark}, // Mc [2] MEETEI MAYEK VOWEL SIGN AU..MEETEI MAYEK VOWEL SIGN AAU
+ {0xAAF5, 0xAAF5, prSpacingMark}, // Mc MEETEI MAYEK VOWEL SIGN VISARGA
+ {0xAAF6, 0xAAF6, prExtend}, // Mn MEETEI MAYEK VIRAMA
+ {0xABE3, 0xABE4, prSpacingMark}, // Mc [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP
+ {0xABE5, 0xABE5, prExtend}, // Mn MEETEI MAYEK VOWEL SIGN ANAP
+ {0xABE6, 0xABE7, prSpacingMark}, // Mc [2] MEETEI MAYEK VOWEL SIGN YENAP..MEETEI MAYEK VOWEL SIGN SOUNAP
+ {0xABE8, 0xABE8, prExtend}, // Mn MEETEI MAYEK VOWEL SIGN UNAP
+ {0xABE9, 0xABEA, prSpacingMark}, // Mc [2] MEETEI MAYEK VOWEL SIGN CHEINAP..MEETEI MAYEK VOWEL SIGN NUNG
+ {0xABEC, 0xABEC, prSpacingMark}, // Mc MEETEI MAYEK LUM IYEK
+ {0xABED, 0xABED, prExtend}, // Mn MEETEI MAYEK APUN IYEK
+ {0xAC00, 0xAC00, prLV}, // Lo HANGUL SYLLABLE GA
+ {0xAC01, 0xAC1B, prLVT}, // Lo [27] HANGUL SYLLABLE GAG..HANGUL SYLLABLE GAH
+ {0xAC1C, 0xAC1C, prLV}, // Lo HANGUL SYLLABLE GAE
+ {0xAC1D, 0xAC37, prLVT}, // Lo [27] HANGUL SYLLABLE GAEG..HANGUL SYLLABLE GAEH
+ {0xAC38, 0xAC38, prLV}, // Lo HANGUL SYLLABLE GYA
+ {0xAC39, 0xAC53, prLVT}, // Lo [27] HANGUL SYLLABLE GYAG..HANGUL SYLLABLE GYAH
+ {0xAC54, 0xAC54, prLV}, // Lo HANGUL SYLLABLE GYAE
+ {0xAC55, 0xAC6F, prLVT}, // Lo [27] HANGUL SYLLABLE GYAEG..HANGUL SYLLABLE GYAEH
+ {0xAC70, 0xAC70, prLV}, // Lo HANGUL SYLLABLE GEO
+ {0xAC71, 0xAC8B, prLVT}, // Lo [27] HANGUL SYLLABLE GEOG..HANGUL SYLLABLE GEOH
+ {0xAC8C, 0xAC8C, prLV}, // Lo HANGUL SYLLABLE GE
+ {0xAC8D, 0xACA7, prLVT}, // Lo [27] HANGUL SYLLABLE GEG..HANGUL SYLLABLE GEH
+ {0xACA8, 0xACA8, prLV}, // Lo HANGUL SYLLABLE GYEO
+ {0xACA9, 0xACC3, prLVT}, // Lo [27] HANGUL SYLLABLE GYEOG..HANGUL SYLLABLE GYEOH
+ {0xACC4, 0xACC4, prLV}, // Lo HANGUL SYLLABLE GYE
+ {0xACC5, 0xACDF, prLVT}, // Lo [27] HANGUL SYLLABLE GYEG..HANGUL SYLLABLE GYEH
+ {0xACE0, 0xACE0, prLV}, // Lo HANGUL SYLLABLE GO
+ {0xACE1, 0xACFB, prLVT}, // Lo [27] HANGUL SYLLABLE GOG..HANGUL SYLLABLE GOH
+ {0xACFC, 0xACFC, prLV}, // Lo HANGUL SYLLABLE GWA
+ {0xACFD, 0xAD17, prLVT}, // Lo [27] HANGUL SYLLABLE GWAG..HANGUL SYLLABLE GWAH
+ {0xAD18, 0xAD18, prLV}, // Lo HANGUL SYLLABLE GWAE
+ {0xAD19, 0xAD33, prLVT}, // Lo [27] HANGUL SYLLABLE GWAEG..HANGUL SYLLABLE GWAEH
+ {0xAD34, 0xAD34, prLV}, // Lo HANGUL SYLLABLE GOE
+ {0xAD35, 0xAD4F, prLVT}, // Lo [27] HANGUL SYLLABLE GOEG..HANGUL SYLLABLE GOEH
+ {0xAD50, 0xAD50, prLV}, // Lo HANGUL SYLLABLE GYO
+ {0xAD51, 0xAD6B, prLVT}, // Lo [27] HANGUL SYLLABLE GYOG..HANGUL SYLLABLE GYOH
+ {0xAD6C, 0xAD6C, prLV}, // Lo HANGUL SYLLABLE GU
+ {0xAD6D, 0xAD87, prLVT}, // Lo [27] HANGUL SYLLABLE GUG..HANGUL SYLLABLE GUH
+ {0xAD88, 0xAD88, prLV}, // Lo HANGUL SYLLABLE GWEO
+ {0xAD89, 0xADA3, prLVT}, // Lo [27] HANGUL SYLLABLE GWEOG..HANGUL SYLLABLE GWEOH
+ {0xADA4, 0xADA4, prLV}, // Lo HANGUL SYLLABLE GWE
+ {0xADA5, 0xADBF, prLVT}, // Lo [27] HANGUL SYLLABLE GWEG..HANGUL SYLLABLE GWEH
+ {0xADC0, 0xADC0, prLV}, // Lo HANGUL SYLLABLE GWI
+ {0xADC1, 0xADDB, prLVT}, // Lo [27] HANGUL SYLLABLE GWIG..HANGUL SYLLABLE GWIH
+ {0xADDC, 0xADDC, prLV}, // Lo HANGUL SYLLABLE GYU
+ {0xADDD, 0xADF7, prLVT}, // Lo [27] HANGUL SYLLABLE GYUG..HANGUL SYLLABLE GYUH
+ {0xADF8, 0xADF8, prLV}, // Lo HANGUL SYLLABLE GEU
+ {0xADF9, 0xAE13, prLVT}, // Lo [27] HANGUL SYLLABLE GEUG..HANGUL SYLLABLE GEUH
+ {0xAE14, 0xAE14, prLV}, // Lo HANGUL SYLLABLE GYI
+ {0xAE15, 0xAE2F, prLVT}, // Lo [27] HANGUL SYLLABLE GYIG..HANGUL SYLLABLE GYIH
+ {0xAE30, 0xAE30, prLV}, // Lo HANGUL SYLLABLE GI
+ {0xAE31, 0xAE4B, prLVT}, // Lo [27] HANGUL SYLLABLE GIG..HANGUL SYLLABLE GIH
+ {0xAE4C, 0xAE4C, prLV}, // Lo HANGUL SYLLABLE GGA
+ {0xAE4D, 0xAE67, prLVT}, // Lo [27] HANGUL SYLLABLE GGAG..HANGUL SYLLABLE GGAH
+ {0xAE68, 0xAE68, prLV}, // Lo HANGUL SYLLABLE GGAE
+ {0xAE69, 0xAE83, prLVT}, // Lo [27] HANGUL SYLLABLE GGAEG..HANGUL SYLLABLE GGAEH
+ {0xAE84, 0xAE84, prLV}, // Lo HANGUL SYLLABLE GGYA
+ {0xAE85, 0xAE9F, prLVT}, // Lo [27] HANGUL SYLLABLE GGYAG..HANGUL SYLLABLE GGYAH
+ {0xAEA0, 0xAEA0, prLV}, // Lo HANGUL SYLLABLE GGYAE
+ {0xAEA1, 0xAEBB, prLVT}, // Lo [27] HANGUL SYLLABLE GGYAEG..HANGUL SYLLABLE GGYAEH
+ {0xAEBC, 0xAEBC, prLV}, // Lo HANGUL SYLLABLE GGEO
+ {0xAEBD, 0xAED7, prLVT}, // Lo [27] HANGUL SYLLABLE GGEOG..HANGUL SYLLABLE GGEOH
+ {0xAED8, 0xAED8, prLV}, // Lo HANGUL SYLLABLE GGE
+ {0xAED9, 0xAEF3, prLVT}, // Lo [27] HANGUL SYLLABLE GGEG..HANGUL SYLLABLE GGEH
+ {0xAEF4, 0xAEF4, prLV}, // Lo HANGUL SYLLABLE GGYEO
+ {0xAEF5, 0xAF0F, prLVT}, // Lo [27] HANGUL SYLLABLE GGYEOG..HANGUL SYLLABLE GGYEOH
+ {0xAF10, 0xAF10, prLV}, // Lo HANGUL SYLLABLE GGYE
+ {0xAF11, 0xAF2B, prLVT}, // Lo [27] HANGUL SYLLABLE GGYEG..HANGUL SYLLABLE GGYEH
+ {0xAF2C, 0xAF2C, prLV}, // Lo HANGUL SYLLABLE GGO
+ {0xAF2D, 0xAF47, prLVT}, // Lo [27] HANGUL SYLLABLE GGOG..HANGUL SYLLABLE GGOH
+ {0xAF48, 0xAF48, prLV}, // Lo HANGUL SYLLABLE GGWA
+ {0xAF49, 0xAF63, prLVT}, // Lo [27] HANGUL SYLLABLE GGWAG..HANGUL SYLLABLE GGWAH
+ {0xAF64, 0xAF64, prLV}, // Lo HANGUL SYLLABLE GGWAE
+ {0xAF65, 0xAF7F, prLVT}, // Lo [27] HANGUL SYLLABLE GGWAEG..HANGUL SYLLABLE GGWAEH
+ {0xAF80, 0xAF80, prLV}, // Lo HANGUL SYLLABLE GGOE
+ {0xAF81, 0xAF9B, prLVT}, // Lo [27] HANGUL SYLLABLE GGOEG..HANGUL SYLLABLE GGOEH
+ {0xAF9C, 0xAF9C, prLV}, // Lo HANGUL SYLLABLE GGYO
+ {0xAF9D, 0xAFB7, prLVT}, // Lo [27] HANGUL SYLLABLE GGYOG..HANGUL SYLLABLE GGYOH
+ {0xAFB8, 0xAFB8, prLV}, // Lo HANGUL SYLLABLE GGU
+ {0xAFB9, 0xAFD3, prLVT}, // Lo [27] HANGUL SYLLABLE GGUG..HANGUL SYLLABLE GGUH
+ {0xAFD4, 0xAFD4, prLV}, // Lo HANGUL SYLLABLE GGWEO
+ {0xAFD5, 0xAFEF, prLVT}, // Lo [27] HANGUL SYLLABLE GGWEOG..HANGUL SYLLABLE GGWEOH
+ {0xAFF0, 0xAFF0, prLV}, // Lo HANGUL SYLLABLE GGWE
+ {0xAFF1, 0xB00B, prLVT}, // Lo [27] HANGUL SYLLABLE GGWEG..HANGUL SYLLABLE GGWEH
+ {0xB00C, 0xB00C, prLV}, // Lo HANGUL SYLLABLE GGWI
+ {0xB00D, 0xB027, prLVT}, // Lo [27] HANGUL SYLLABLE GGWIG..HANGUL SYLLABLE GGWIH
+ {0xB028, 0xB028, prLV}, // Lo HANGUL SYLLABLE GGYU
+ {0xB029, 0xB043, prLVT}, // Lo [27] HANGUL SYLLABLE GGYUG..HANGUL SYLLABLE GGYUH
+ {0xB044, 0xB044, prLV}, // Lo HANGUL SYLLABLE GGEU
+ {0xB045, 0xB05F, prLVT}, // Lo [27] HANGUL SYLLABLE GGEUG..HANGUL SYLLABLE GGEUH
+ {0xB060, 0xB060, prLV}, // Lo HANGUL SYLLABLE GGYI
+ {0xB061, 0xB07B, prLVT}, // Lo [27] HANGUL SYLLABLE GGYIG..HANGUL SYLLABLE GGYIH
+ {0xB07C, 0xB07C, prLV}, // Lo HANGUL SYLLABLE GGI
+ {0xB07D, 0xB097, prLVT}, // Lo [27] HANGUL SYLLABLE GGIG..HANGUL SYLLABLE GGIH
+ {0xB098, 0xB098, prLV}, // Lo HANGUL SYLLABLE NA
+ {0xB099, 0xB0B3, prLVT}, // Lo [27] HANGUL SYLLABLE NAG..HANGUL SYLLABLE NAH
+ {0xB0B4, 0xB0B4, prLV}, // Lo HANGUL SYLLABLE NAE
+ {0xB0B5, 0xB0CF, prLVT}, // Lo [27] HANGUL SYLLABLE NAEG..HANGUL SYLLABLE NAEH
+ {0xB0D0, 0xB0D0, prLV}, // Lo HANGUL SYLLABLE NYA
+ {0xB0D1, 0xB0EB, prLVT}, // Lo [27] HANGUL SYLLABLE NYAG..HANGUL SYLLABLE NYAH
+ {0xB0EC, 0xB0EC, prLV}, // Lo HANGUL SYLLABLE NYAE
+ {0xB0ED, 0xB107, prLVT}, // Lo [27] HANGUL SYLLABLE NYAEG..HANGUL SYLLABLE NYAEH
+ {0xB108, 0xB108, prLV}, // Lo HANGUL SYLLABLE NEO
+ {0xB109, 0xB123, prLVT}, // Lo [27] HANGUL SYLLABLE NEOG..HANGUL SYLLABLE NEOH
+ {0xB124, 0xB124, prLV}, // Lo HANGUL SYLLABLE NE
+ {0xB125, 0xB13F, prLVT}, // Lo [27] HANGUL SYLLABLE NEG..HANGUL SYLLABLE NEH
+ {0xB140, 0xB140, prLV}, // Lo HANGUL SYLLABLE NYEO
+ {0xB141, 0xB15B, prLVT}, // Lo [27] HANGUL SYLLABLE NYEOG..HANGUL SYLLABLE NYEOH
+ {0xB15C, 0xB15C, prLV}, // Lo HANGUL SYLLABLE NYE
+ {0xB15D, 0xB177, prLVT}, // Lo [27] HANGUL SYLLABLE NYEG..HANGUL SYLLABLE NYEH
+ {0xB178, 0xB178, prLV}, // Lo HANGUL SYLLABLE NO
+ {0xB179, 0xB193, prLVT}, // Lo [27] HANGUL SYLLABLE NOG..HANGUL SYLLABLE NOH
+ {0xB194, 0xB194, prLV}, // Lo HANGUL SYLLABLE NWA
+ {0xB195, 0xB1AF, prLVT}, // Lo [27] HANGUL SYLLABLE NWAG..HANGUL SYLLABLE NWAH
+ {0xB1B0, 0xB1B0, prLV}, // Lo HANGUL SYLLABLE NWAE
+ {0xB1B1, 0xB1CB, prLVT}, // Lo [27] HANGUL SYLLABLE NWAEG..HANGUL SYLLABLE NWAEH
+ {0xB1CC, 0xB1CC, prLV}, // Lo HANGUL SYLLABLE NOE
+ {0xB1CD, 0xB1E7, prLVT}, // Lo [27] HANGUL SYLLABLE NOEG..HANGUL SYLLABLE NOEH
+ {0xB1E8, 0xB1E8, prLV}, // Lo HANGUL SYLLABLE NYO
+ {0xB1E9, 0xB203, prLVT}, // Lo [27] HANGUL SYLLABLE NYOG..HANGUL SYLLABLE NYOH
+ {0xB204, 0xB204, prLV}, // Lo HANGUL SYLLABLE NU
+ {0xB205, 0xB21F, prLVT}, // Lo [27] HANGUL SYLLABLE NUG..HANGUL SYLLABLE NUH
+ {0xB220, 0xB220, prLV}, // Lo HANGUL SYLLABLE NWEO
+ {0xB221, 0xB23B, prLVT}, // Lo [27] HANGUL SYLLABLE NWEOG..HANGUL SYLLABLE NWEOH
+ {0xB23C, 0xB23C, prLV}, // Lo HANGUL SYLLABLE NWE
+ {0xB23D, 0xB257, prLVT}, // Lo [27] HANGUL SYLLABLE NWEG..HANGUL SYLLABLE NWEH
+ {0xB258, 0xB258, prLV}, // Lo HANGUL SYLLABLE NWI
+ {0xB259, 0xB273, prLVT}, // Lo [27] HANGUL SYLLABLE NWIG..HANGUL SYLLABLE NWIH
+ {0xB274, 0xB274, prLV}, // Lo HANGUL SYLLABLE NYU
+ {0xB275, 0xB28F, prLVT}, // Lo [27] HANGUL SYLLABLE NYUG..HANGUL SYLLABLE NYUH
+ {0xB290, 0xB290, prLV}, // Lo HANGUL SYLLABLE NEU
+ {0xB291, 0xB2AB, prLVT}, // Lo [27] HANGUL SYLLABLE NEUG..HANGUL SYLLABLE NEUH
+ {0xB2AC, 0xB2AC, prLV}, // Lo HANGUL SYLLABLE NYI
+ {0xB2AD, 0xB2C7, prLVT}, // Lo [27] HANGUL SYLLABLE NYIG..HANGUL SYLLABLE NYIH
+ {0xB2C8, 0xB2C8, prLV}, // Lo HANGUL SYLLABLE NI
+ {0xB2C9, 0xB2E3, prLVT}, // Lo [27] HANGUL SYLLABLE NIG..HANGUL SYLLABLE NIH
+ {0xB2E4, 0xB2E4, prLV}, // Lo HANGUL SYLLABLE DA
+ {0xB2E5, 0xB2FF, prLVT}, // Lo [27] HANGUL SYLLABLE DAG..HANGUL SYLLABLE DAH
+ {0xB300, 0xB300, prLV}, // Lo HANGUL SYLLABLE DAE
+ {0xB301, 0xB31B, prLVT}, // Lo [27] HANGUL SYLLABLE DAEG..HANGUL SYLLABLE DAEH
+ {0xB31C, 0xB31C, prLV}, // Lo HANGUL SYLLABLE DYA
+ {0xB31D, 0xB337, prLVT}, // Lo [27] HANGUL SYLLABLE DYAG..HANGUL SYLLABLE DYAH
+ {0xB338, 0xB338, prLV}, // Lo HANGUL SYLLABLE DYAE
+ {0xB339, 0xB353, prLVT}, // Lo [27] HANGUL SYLLABLE DYAEG..HANGUL SYLLABLE DYAEH
+ {0xB354, 0xB354, prLV}, // Lo HANGUL SYLLABLE DEO
+ {0xB355, 0xB36F, prLVT}, // Lo [27] HANGUL SYLLABLE DEOG..HANGUL SYLLABLE DEOH
+ {0xB370, 0xB370, prLV}, // Lo HANGUL SYLLABLE DE
+ {0xB371, 0xB38B, prLVT}, // Lo [27] HANGUL SYLLABLE DEG..HANGUL SYLLABLE DEH
+ {0xB38C, 0xB38C, prLV}, // Lo HANGUL SYLLABLE DYEO
+ {0xB38D, 0xB3A7, prLVT}, // Lo [27] HANGUL SYLLABLE DYEOG..HANGUL SYLLABLE DYEOH
+ {0xB3A8, 0xB3A8, prLV}, // Lo HANGUL SYLLABLE DYE
+ {0xB3A9, 0xB3C3, prLVT}, // Lo [27] HANGUL SYLLABLE DYEG..HANGUL SYLLABLE DYEH
+ {0xB3C4, 0xB3C4, prLV}, // Lo HANGUL SYLLABLE DO
+ {0xB3C5, 0xB3DF, prLVT}, // Lo [27] HANGUL SYLLABLE DOG..HANGUL SYLLABLE DOH
+ {0xB3E0, 0xB3E0, prLV}, // Lo HANGUL SYLLABLE DWA
+ {0xB3E1, 0xB3FB, prLVT}, // Lo [27] HANGUL SYLLABLE DWAG..HANGUL SYLLABLE DWAH
+ {0xB3FC, 0xB3FC, prLV}, // Lo HANGUL SYLLABLE DWAE
+ {0xB3FD, 0xB417, prLVT}, // Lo [27] HANGUL SYLLABLE DWAEG..HANGUL SYLLABLE DWAEH
+ {0xB418, 0xB418, prLV}, // Lo HANGUL SYLLABLE DOE
+ {0xB419, 0xB433, prLVT}, // Lo [27] HANGUL SYLLABLE DOEG..HANGUL SYLLABLE DOEH
+ {0xB434, 0xB434, prLV}, // Lo HANGUL SYLLABLE DYO
+ {0xB435, 0xB44F, prLVT}, // Lo [27] HANGUL SYLLABLE DYOG..HANGUL SYLLABLE DYOH
+ {0xB450, 0xB450, prLV}, // Lo HANGUL SYLLABLE DU
+ {0xB451, 0xB46B, prLVT}, // Lo [27] HANGUL SYLLABLE DUG..HANGUL SYLLABLE DUH
+ {0xB46C, 0xB46C, prLV}, // Lo HANGUL SYLLABLE DWEO
+ {0xB46D, 0xB487, prLVT}, // Lo [27] HANGUL SYLLABLE DWEOG..HANGUL SYLLABLE DWEOH
+ {0xB488, 0xB488, prLV}, // Lo HANGUL SYLLABLE DWE
+ {0xB489, 0xB4A3, prLVT}, // Lo [27] HANGUL SYLLABLE DWEG..HANGUL SYLLABLE DWEH
+ {0xB4A4, 0xB4A4, prLV}, // Lo HANGUL SYLLABLE DWI
+ {0xB4A5, 0xB4BF, prLVT}, // Lo [27] HANGUL SYLLABLE DWIG..HANGUL SYLLABLE DWIH
+ {0xB4C0, 0xB4C0, prLV}, // Lo HANGUL SYLLABLE DYU
+ {0xB4C1, 0xB4DB, prLVT}, // Lo [27] HANGUL SYLLABLE DYUG..HANGUL SYLLABLE DYUH
+ {0xB4DC, 0xB4DC, prLV}, // Lo HANGUL SYLLABLE DEU
+ {0xB4DD, 0xB4F7, prLVT}, // Lo [27] HANGUL SYLLABLE DEUG..HANGUL SYLLABLE DEUH
+ {0xB4F8, 0xB4F8, prLV}, // Lo HANGUL SYLLABLE DYI
+ {0xB4F9, 0xB513, prLVT}, // Lo [27] HANGUL SYLLABLE DYIG..HANGUL SYLLABLE DYIH
+ {0xB514, 0xB514, prLV}, // Lo HANGUL SYLLABLE DI
+ {0xB515, 0xB52F, prLVT}, // Lo [27] HANGUL SYLLABLE DIG..HANGUL SYLLABLE DIH
+ {0xB530, 0xB530, prLV}, // Lo HANGUL SYLLABLE DDA
+ {0xB531, 0xB54B, prLVT}, // Lo [27] HANGUL SYLLABLE DDAG..HANGUL SYLLABLE DDAH
+ {0xB54C, 0xB54C, prLV}, // Lo HANGUL SYLLABLE DDAE
+ {0xB54D, 0xB567, prLVT}, // Lo [27] HANGUL SYLLABLE DDAEG..HANGUL SYLLABLE DDAEH
+ {0xB568, 0xB568, prLV}, // Lo HANGUL SYLLABLE DDYA
+ {0xB569, 0xB583, prLVT}, // Lo [27] HANGUL SYLLABLE DDYAG..HANGUL SYLLABLE DDYAH
+ {0xB584, 0xB584, prLV}, // Lo HANGUL SYLLABLE DDYAE
+ {0xB585, 0xB59F, prLVT}, // Lo [27] HANGUL SYLLABLE DDYAEG..HANGUL SYLLABLE DDYAEH
+ {0xB5A0, 0xB5A0, prLV}, // Lo HANGUL SYLLABLE DDEO
+ {0xB5A1, 0xB5BB, prLVT}, // Lo [27] HANGUL SYLLABLE DDEOG..HANGUL SYLLABLE DDEOH
+ {0xB5BC, 0xB5BC, prLV}, // Lo HANGUL SYLLABLE DDE
+ {0xB5BD, 0xB5D7, prLVT}, // Lo [27] HANGUL SYLLABLE DDEG..HANGUL SYLLABLE DDEH
+ {0xB5D8, 0xB5D8, prLV}, // Lo HANGUL SYLLABLE DDYEO
+ {0xB5D9, 0xB5F3, prLVT}, // Lo [27] HANGUL SYLLABLE DDYEOG..HANGUL SYLLABLE DDYEOH
+ {0xB5F4, 0xB5F4, prLV}, // Lo HANGUL SYLLABLE DDYE
+ {0xB5F5, 0xB60F, prLVT}, // Lo [27] HANGUL SYLLABLE DDYEG..HANGUL SYLLABLE DDYEH
+ {0xB610, 0xB610, prLV}, // Lo HANGUL SYLLABLE DDO
+ {0xB611, 0xB62B, prLVT}, // Lo [27] HANGUL SYLLABLE DDOG..HANGUL SYLLABLE DDOH
+ {0xB62C, 0xB62C, prLV}, // Lo HANGUL SYLLABLE DDWA
+ {0xB62D, 0xB647, prLVT}, // Lo [27] HANGUL SYLLABLE DDWAG..HANGUL SYLLABLE DDWAH
+ {0xB648, 0xB648, prLV}, // Lo HANGUL SYLLABLE DDWAE
+ {0xB649, 0xB663, prLVT}, // Lo [27] HANGUL SYLLABLE DDWAEG..HANGUL SYLLABLE DDWAEH
+ {0xB664, 0xB664, prLV}, // Lo HANGUL SYLLABLE DDOE
+ {0xB665, 0xB67F, prLVT}, // Lo [27] HANGUL SYLLABLE DDOEG..HANGUL SYLLABLE DDOEH
+ {0xB680, 0xB680, prLV}, // Lo HANGUL SYLLABLE DDYO
+ {0xB681, 0xB69B, prLVT}, // Lo [27] HANGUL SYLLABLE DDYOG..HANGUL SYLLABLE DDYOH
+ {0xB69C, 0xB69C, prLV}, // Lo HANGUL SYLLABLE DDU
+ {0xB69D, 0xB6B7, prLVT}, // Lo [27] HANGUL SYLLABLE DDUG..HANGUL SYLLABLE DDUH
+ {0xB6B8, 0xB6B8, prLV}, // Lo HANGUL SYLLABLE DDWEO
+ {0xB6B9, 0xB6D3, prLVT}, // Lo [27] HANGUL SYLLABLE DDWEOG..HANGUL SYLLABLE DDWEOH
+ {0xB6D4, 0xB6D4, prLV}, // Lo HANGUL SYLLABLE DDWE
+ {0xB6D5, 0xB6EF, prLVT}, // Lo [27] HANGUL SYLLABLE DDWEG..HANGUL SYLLABLE DDWEH
+ {0xB6F0, 0xB6F0, prLV}, // Lo HANGUL SYLLABLE DDWI
+ {0xB6F1, 0xB70B, prLVT}, // Lo [27] HANGUL SYLLABLE DDWIG..HANGUL SYLLABLE DDWIH
+ {0xB70C, 0xB70C, prLV}, // Lo HANGUL SYLLABLE DDYU
+ {0xB70D, 0xB727, prLVT}, // Lo [27] HANGUL SYLLABLE DDYUG..HANGUL SYLLABLE DDYUH
+ {0xB728, 0xB728, prLV}, // Lo HANGUL SYLLABLE DDEU
+ {0xB729, 0xB743, prLVT}, // Lo [27] HANGUL SYLLABLE DDEUG..HANGUL SYLLABLE DDEUH
+ {0xB744, 0xB744, prLV}, // Lo HANGUL SYLLABLE DDYI
+ {0xB745, 0xB75F, prLVT}, // Lo [27] HANGUL SYLLABLE DDYIG..HANGUL SYLLABLE DDYIH
+ {0xB760, 0xB760, prLV}, // Lo HANGUL SYLLABLE DDI
+ {0xB761, 0xB77B, prLVT}, // Lo [27] HANGUL SYLLABLE DDIG..HANGUL SYLLABLE DDIH
+ {0xB77C, 0xB77C, prLV}, // Lo HANGUL SYLLABLE RA
+ {0xB77D, 0xB797, prLVT}, // Lo [27] HANGUL SYLLABLE RAG..HANGUL SYLLABLE RAH
+ {0xB798, 0xB798, prLV}, // Lo HANGUL SYLLABLE RAE
+ {0xB799, 0xB7B3, prLVT}, // Lo [27] HANGUL SYLLABLE RAEG..HANGUL SYLLABLE RAEH
+ {0xB7B4, 0xB7B4, prLV}, // Lo HANGUL SYLLABLE RYA
+ {0xB7B5, 0xB7CF, prLVT}, // Lo [27] HANGUL SYLLABLE RYAG..HANGUL SYLLABLE RYAH
+ {0xB7D0, 0xB7D0, prLV}, // Lo HANGUL SYLLABLE RYAE
+ {0xB7D1, 0xB7EB, prLVT}, // Lo [27] HANGUL SYLLABLE RYAEG..HANGUL SYLLABLE RYAEH
+ {0xB7EC, 0xB7EC, prLV}, // Lo HANGUL SYLLABLE REO
+ {0xB7ED, 0xB807, prLVT}, // Lo [27] HANGUL SYLLABLE REOG..HANGUL SYLLABLE REOH
+ {0xB808, 0xB808, prLV}, // Lo HANGUL SYLLABLE RE
+ {0xB809, 0xB823, prLVT}, // Lo [27] HANGUL SYLLABLE REG..HANGUL SYLLABLE REH
+ {0xB824, 0xB824, prLV}, // Lo HANGUL SYLLABLE RYEO
+ {0xB825, 0xB83F, prLVT}, // Lo [27] HANGUL SYLLABLE RYEOG..HANGUL SYLLABLE RYEOH
+ {0xB840, 0xB840, prLV}, // Lo HANGUL SYLLABLE RYE
+ {0xB841, 0xB85B, prLVT}, // Lo [27] HANGUL SYLLABLE RYEG..HANGUL SYLLABLE RYEH
+ {0xB85C, 0xB85C, prLV}, // Lo HANGUL SYLLABLE RO
+ {0xB85D, 0xB877, prLVT}, // Lo [27] HANGUL SYLLABLE ROG..HANGUL SYLLABLE ROH
+ {0xB878, 0xB878, prLV}, // Lo HANGUL SYLLABLE RWA
+ {0xB879, 0xB893, prLVT}, // Lo [27] HANGUL SYLLABLE RWAG..HANGUL SYLLABLE RWAH
+ {0xB894, 0xB894, prLV}, // Lo HANGUL SYLLABLE RWAE
+ {0xB895, 0xB8AF, prLVT}, // Lo [27] HANGUL SYLLABLE RWAEG..HANGUL SYLLABLE RWAEH
+ {0xB8B0, 0xB8B0, prLV}, // Lo HANGUL SYLLABLE ROE
+ {0xB8B1, 0xB8CB, prLVT}, // Lo [27] HANGUL SYLLABLE ROEG..HANGUL SYLLABLE ROEH
+ {0xB8CC, 0xB8CC, prLV}, // Lo HANGUL SYLLABLE RYO
+ {0xB8CD, 0xB8E7, prLVT}, // Lo [27] HANGUL SYLLABLE RYOG..HANGUL SYLLABLE RYOH
+ {0xB8E8, 0xB8E8, prLV}, // Lo HANGUL SYLLABLE RU
+ {0xB8E9, 0xB903, prLVT}, // Lo [27] HANGUL SYLLABLE RUG..HANGUL SYLLABLE RUH
+ {0xB904, 0xB904, prLV}, // Lo HANGUL SYLLABLE RWEO
+ {0xB905, 0xB91F, prLVT}, // Lo [27] HANGUL SYLLABLE RWEOG..HANGUL SYLLABLE RWEOH
+ {0xB920, 0xB920, prLV}, // Lo HANGUL SYLLABLE RWE
+ {0xB921, 0xB93B, prLVT}, // Lo [27] HANGUL SYLLABLE RWEG..HANGUL SYLLABLE RWEH
+ {0xB93C, 0xB93C, prLV}, // Lo HANGUL SYLLABLE RWI
+ {0xB93D, 0xB957, prLVT}, // Lo [27] HANGUL SYLLABLE RWIG..HANGUL SYLLABLE RWIH
+ {0xB958, 0xB958, prLV}, // Lo HANGUL SYLLABLE RYU
+ {0xB959, 0xB973, prLVT}, // Lo [27] HANGUL SYLLABLE RYUG..HANGUL SYLLABLE RYUH
+ {0xB974, 0xB974, prLV}, // Lo HANGUL SYLLABLE REU
+ {0xB975, 0xB98F, prLVT}, // Lo [27] HANGUL SYLLABLE REUG..HANGUL SYLLABLE REUH
+ {0xB990, 0xB990, prLV}, // Lo HANGUL SYLLABLE RYI
+ {0xB991, 0xB9AB, prLVT}, // Lo [27] HANGUL SYLLABLE RYIG..HANGUL SYLLABLE RYIH
+ {0xB9AC, 0xB9AC, prLV}, // Lo HANGUL SYLLABLE RI
+ {0xB9AD, 0xB9C7, prLVT}, // Lo [27] HANGUL SYLLABLE RIG..HANGUL SYLLABLE RIH
+ {0xB9C8, 0xB9C8, prLV}, // Lo HANGUL SYLLABLE MA
+ {0xB9C9, 0xB9E3, prLVT}, // Lo [27] HANGUL SYLLABLE MAG..HANGUL SYLLABLE MAH
+ {0xB9E4, 0xB9E4, prLV}, // Lo HANGUL SYLLABLE MAE
+ {0xB9E5, 0xB9FF, prLVT}, // Lo [27] HANGUL SYLLABLE MAEG..HANGUL SYLLABLE MAEH
+ {0xBA00, 0xBA00, prLV}, // Lo HANGUL SYLLABLE MYA
+ {0xBA01, 0xBA1B, prLVT}, // Lo [27] HANGUL SYLLABLE MYAG..HANGUL SYLLABLE MYAH
+ {0xBA1C, 0xBA1C, prLV}, // Lo HANGUL SYLLABLE MYAE
+ {0xBA1D, 0xBA37, prLVT}, // Lo [27] HANGUL SYLLABLE MYAEG..HANGUL SYLLABLE MYAEH
+ {0xBA38, 0xBA38, prLV}, // Lo HANGUL SYLLABLE MEO
+ {0xBA39, 0xBA53, prLVT}, // Lo [27] HANGUL SYLLABLE MEOG..HANGUL SYLLABLE MEOH
+ {0xBA54, 0xBA54, prLV}, // Lo HANGUL SYLLABLE ME
+ {0xBA55, 0xBA6F, prLVT}, // Lo [27] HANGUL SYLLABLE MEG..HANGUL SYLLABLE MEH
+ {0xBA70, 0xBA70, prLV}, // Lo HANGUL SYLLABLE MYEO
+ {0xBA71, 0xBA8B, prLVT}, // Lo [27] HANGUL SYLLABLE MYEOG..HANGUL SYLLABLE MYEOH
+ {0xBA8C, 0xBA8C, prLV}, // Lo HANGUL SYLLABLE MYE
+ {0xBA8D, 0xBAA7, prLVT}, // Lo [27] HANGUL SYLLABLE MYEG..HANGUL SYLLABLE MYEH
+ {0xBAA8, 0xBAA8, prLV}, // Lo HANGUL SYLLABLE MO
+ {0xBAA9, 0xBAC3, prLVT}, // Lo [27] HANGUL SYLLABLE MOG..HANGUL SYLLABLE MOH
+ {0xBAC4, 0xBAC4, prLV}, // Lo HANGUL SYLLABLE MWA
+ {0xBAC5, 0xBADF, prLVT}, // Lo [27] HANGUL SYLLABLE MWAG..HANGUL SYLLABLE MWAH
+ {0xBAE0, 0xBAE0, prLV}, // Lo HANGUL SYLLABLE MWAE
+ {0xBAE1, 0xBAFB, prLVT}, // Lo [27] HANGUL SYLLABLE MWAEG..HANGUL SYLLABLE MWAEH
+ {0xBAFC, 0xBAFC, prLV}, // Lo HANGUL SYLLABLE MOE
+ {0xBAFD, 0xBB17, prLVT}, // Lo [27] HANGUL SYLLABLE MOEG..HANGUL SYLLABLE MOEH
+ {0xBB18, 0xBB18, prLV}, // Lo HANGUL SYLLABLE MYO
+ {0xBB19, 0xBB33, prLVT}, // Lo [27] HANGUL SYLLABLE MYOG..HANGUL SYLLABLE MYOH
+ {0xBB34, 0xBB34, prLV}, // Lo HANGUL SYLLABLE MU
+ {0xBB35, 0xBB4F, prLVT}, // Lo [27] HANGUL SYLLABLE MUG..HANGUL SYLLABLE MUH
+ {0xBB50, 0xBB50, prLV}, // Lo HANGUL SYLLABLE MWEO
+ {0xBB51, 0xBB6B, prLVT}, // Lo [27] HANGUL SYLLABLE MWEOG..HANGUL SYLLABLE MWEOH
+ {0xBB6C, 0xBB6C, prLV}, // Lo HANGUL SYLLABLE MWE
+ {0xBB6D, 0xBB87, prLVT}, // Lo [27] HANGUL SYLLABLE MWEG..HANGUL SYLLABLE MWEH
+ {0xBB88, 0xBB88, prLV}, // Lo HANGUL SYLLABLE MWI
+ {0xBB89, 0xBBA3, prLVT}, // Lo [27] HANGUL SYLLABLE MWIG..HANGUL SYLLABLE MWIH
+ {0xBBA4, 0xBBA4, prLV}, // Lo HANGUL SYLLABLE MYU
+ {0xBBA5, 0xBBBF, prLVT}, // Lo [27] HANGUL SYLLABLE MYUG..HANGUL SYLLABLE MYUH
+ {0xBBC0, 0xBBC0, prLV}, // Lo HANGUL SYLLABLE MEU
+ {0xBBC1, 0xBBDB, prLVT}, // Lo [27] HANGUL SYLLABLE MEUG..HANGUL SYLLABLE MEUH
+ {0xBBDC, 0xBBDC, prLV}, // Lo HANGUL SYLLABLE MYI
+ {0xBBDD, 0xBBF7, prLVT}, // Lo [27] HANGUL SYLLABLE MYIG..HANGUL SYLLABLE MYIH
+ {0xBBF8, 0xBBF8, prLV}, // Lo HANGUL SYLLABLE MI
+ {0xBBF9, 0xBC13, prLVT}, // Lo [27] HANGUL SYLLABLE MIG..HANGUL SYLLABLE MIH
+ {0xBC14, 0xBC14, prLV}, // Lo HANGUL SYLLABLE BA
+ {0xBC15, 0xBC2F, prLVT}, // Lo [27] HANGUL SYLLABLE BAG..HANGUL SYLLABLE BAH
+ {0xBC30, 0xBC30, prLV}, // Lo HANGUL SYLLABLE BAE
+ {0xBC31, 0xBC4B, prLVT}, // Lo [27] HANGUL SYLLABLE BAEG..HANGUL SYLLABLE BAEH
+ {0xBC4C, 0xBC4C, prLV}, // Lo HANGUL SYLLABLE BYA
+ {0xBC4D, 0xBC67, prLVT}, // Lo [27] HANGUL SYLLABLE BYAG..HANGUL SYLLABLE BYAH
+ {0xBC68, 0xBC68, prLV}, // Lo HANGUL SYLLABLE BYAE
+ {0xBC69, 0xBC83, prLVT}, // Lo [27] HANGUL SYLLABLE BYAEG..HANGUL SYLLABLE BYAEH
+ {0xBC84, 0xBC84, prLV}, // Lo HANGUL SYLLABLE BEO
+ {0xBC85, 0xBC9F, prLVT}, // Lo [27] HANGUL SYLLABLE BEOG..HANGUL SYLLABLE BEOH
+ {0xBCA0, 0xBCA0, prLV}, // Lo HANGUL SYLLABLE BE
+ {0xBCA1, 0xBCBB, prLVT}, // Lo [27] HANGUL SYLLABLE BEG..HANGUL SYLLABLE BEH
+ {0xBCBC, 0xBCBC, prLV}, // Lo HANGUL SYLLABLE BYEO
+ {0xBCBD, 0xBCD7, prLVT}, // Lo [27] HANGUL SYLLABLE BYEOG..HANGUL SYLLABLE BYEOH
+ {0xBCD8, 0xBCD8, prLV}, // Lo HANGUL SYLLABLE BYE
+ {0xBCD9, 0xBCF3, prLVT}, // Lo [27] HANGUL SYLLABLE BYEG..HANGUL SYLLABLE BYEH
+ {0xBCF4, 0xBCF4, prLV}, // Lo HANGUL SYLLABLE BO
+ {0xBCF5, 0xBD0F, prLVT}, // Lo [27] HANGUL SYLLABLE BOG..HANGUL SYLLABLE BOH
+ {0xBD10, 0xBD10, prLV}, // Lo HANGUL SYLLABLE BWA
+ {0xBD11, 0xBD2B, prLVT}, // Lo [27] HANGUL SYLLABLE BWAG..HANGUL SYLLABLE BWAH
+ {0xBD2C, 0xBD2C, prLV}, // Lo HANGUL SYLLABLE BWAE
+ {0xBD2D, 0xBD47, prLVT}, // Lo [27] HANGUL SYLLABLE BWAEG..HANGUL SYLLABLE BWAEH
+ {0xBD48, 0xBD48, prLV}, // Lo HANGUL SYLLABLE BOE
+ {0xBD49, 0xBD63, prLVT}, // Lo [27] HANGUL SYLLABLE BOEG..HANGUL SYLLABLE BOEH
+ {0xBD64, 0xBD64, prLV}, // Lo HANGUL SYLLABLE BYO
+ {0xBD65, 0xBD7F, prLVT}, // Lo [27] HANGUL SYLLABLE BYOG..HANGUL SYLLABLE BYOH
+ {0xBD80, 0xBD80, prLV}, // Lo HANGUL SYLLABLE BU
+ {0xBD81, 0xBD9B, prLVT}, // Lo [27] HANGUL SYLLABLE BUG..HANGUL SYLLABLE BUH
+ {0xBD9C, 0xBD9C, prLV}, // Lo HANGUL SYLLABLE BWEO
+ {0xBD9D, 0xBDB7, prLVT}, // Lo [27] HANGUL SYLLABLE BWEOG..HANGUL SYLLABLE BWEOH
+ {0xBDB8, 0xBDB8, prLV}, // Lo HANGUL SYLLABLE BWE
+ {0xBDB9, 0xBDD3, prLVT}, // Lo [27] HANGUL SYLLABLE BWEG..HANGUL SYLLABLE BWEH
+ {0xBDD4, 0xBDD4, prLV}, // Lo HANGUL SYLLABLE BWI
+ {0xBDD5, 0xBDEF, prLVT}, // Lo [27] HANGUL SYLLABLE BWIG..HANGUL SYLLABLE BWIH
+ {0xBDF0, 0xBDF0, prLV}, // Lo HANGUL SYLLABLE BYU
+ {0xBDF1, 0xBE0B, prLVT}, // Lo [27] HANGUL SYLLABLE BYUG..HANGUL SYLLABLE BYUH
+ {0xBE0C, 0xBE0C, prLV}, // Lo HANGUL SYLLABLE BEU
+ {0xBE0D, 0xBE27, prLVT}, // Lo [27] HANGUL SYLLABLE BEUG..HANGUL SYLLABLE BEUH
+ {0xBE28, 0xBE28, prLV}, // Lo HANGUL SYLLABLE BYI
+ {0xBE29, 0xBE43, prLVT}, // Lo [27] HANGUL SYLLABLE BYIG..HANGUL SYLLABLE BYIH
+ {0xBE44, 0xBE44, prLV}, // Lo HANGUL SYLLABLE BI
+ {0xBE45, 0xBE5F, prLVT}, // Lo [27] HANGUL SYLLABLE BIG..HANGUL SYLLABLE BIH
+ {0xBE60, 0xBE60, prLV}, // Lo HANGUL SYLLABLE BBA
+ {0xBE61, 0xBE7B, prLVT}, // Lo [27] HANGUL SYLLABLE BBAG..HANGUL SYLLABLE BBAH
+ {0xBE7C, 0xBE7C, prLV}, // Lo HANGUL SYLLABLE BBAE
+ {0xBE7D, 0xBE97, prLVT}, // Lo [27] HANGUL SYLLABLE BBAEG..HANGUL SYLLABLE BBAEH
+ {0xBE98, 0xBE98, prLV}, // Lo HANGUL SYLLABLE BBYA
+ {0xBE99, 0xBEB3, prLVT}, // Lo [27] HANGUL SYLLABLE BBYAG..HANGUL SYLLABLE BBYAH
+ {0xBEB4, 0xBEB4, prLV}, // Lo HANGUL SYLLABLE BBYAE
+ {0xBEB5, 0xBECF, prLVT}, // Lo [27] HANGUL SYLLABLE BBYAEG..HANGUL SYLLABLE BBYAEH
+ {0xBED0, 0xBED0, prLV}, // Lo HANGUL SYLLABLE BBEO
+ {0xBED1, 0xBEEB, prLVT}, // Lo [27] HANGUL SYLLABLE BBEOG..HANGUL SYLLABLE BBEOH
+ {0xBEEC, 0xBEEC, prLV}, // Lo HANGUL SYLLABLE BBE
+ {0xBEED, 0xBF07, prLVT}, // Lo [27] HANGUL SYLLABLE BBEG..HANGUL SYLLABLE BBEH
+ {0xBF08, 0xBF08, prLV}, // Lo HANGUL SYLLABLE BBYEO
+ {0xBF09, 0xBF23, prLVT}, // Lo [27] HANGUL SYLLABLE BBYEOG..HANGUL SYLLABLE BBYEOH
+ {0xBF24, 0xBF24, prLV}, // Lo HANGUL SYLLABLE BBYE
+ {0xBF25, 0xBF3F, prLVT}, // Lo [27] HANGUL SYLLABLE BBYEG..HANGUL SYLLABLE BBYEH
+ {0xBF40, 0xBF40, prLV}, // Lo HANGUL SYLLABLE BBO
+ {0xBF41, 0xBF5B, prLVT}, // Lo [27] HANGUL SYLLABLE BBOG..HANGUL SYLLABLE BBOH
+ {0xBF5C, 0xBF5C, prLV}, // Lo HANGUL SYLLABLE BBWA
+ {0xBF5D, 0xBF77, prLVT}, // Lo [27] HANGUL SYLLABLE BBWAG..HANGUL SYLLABLE BBWAH
+ {0xBF78, 0xBF78, prLV}, // Lo HANGUL SYLLABLE BBWAE
+ {0xBF79, 0xBF93, prLVT}, // Lo [27] HANGUL SYLLABLE BBWAEG..HANGUL SYLLABLE BBWAEH
+ {0xBF94, 0xBF94, prLV}, // Lo HANGUL SYLLABLE BBOE
+ {0xBF95, 0xBFAF, prLVT}, // Lo [27] HANGUL SYLLABLE BBOEG..HANGUL SYLLABLE BBOEH
+ {0xBFB0, 0xBFB0, prLV}, // Lo HANGUL SYLLABLE BBYO
+ {0xBFB1, 0xBFCB, prLVT}, // Lo [27] HANGUL SYLLABLE BBYOG..HANGUL SYLLABLE BBYOH
+ {0xBFCC, 0xBFCC, prLV}, // Lo HANGUL SYLLABLE BBU
+ {0xBFCD, 0xBFE7, prLVT}, // Lo [27] HANGUL SYLLABLE BBUG..HANGUL SYLLABLE BBUH
+ {0xBFE8, 0xBFE8, prLV}, // Lo HANGUL SYLLABLE BBWEO
+ {0xBFE9, 0xC003, prLVT}, // Lo [27] HANGUL SYLLABLE BBWEOG..HANGUL SYLLABLE BBWEOH
+ {0xC004, 0xC004, prLV}, // Lo HANGUL SYLLABLE BBWE
+ {0xC005, 0xC01F, prLVT}, // Lo [27] HANGUL SYLLABLE BBWEG..HANGUL SYLLABLE BBWEH
+ {0xC020, 0xC020, prLV}, // Lo HANGUL SYLLABLE BBWI
+ {0xC021, 0xC03B, prLVT}, // Lo [27] HANGUL SYLLABLE BBWIG..HANGUL SYLLABLE BBWIH
+ {0xC03C, 0xC03C, prLV}, // Lo HANGUL SYLLABLE BBYU
+ {0xC03D, 0xC057, prLVT}, // Lo [27] HANGUL SYLLABLE BBYUG..HANGUL SYLLABLE BBYUH
+ {0xC058, 0xC058, prLV}, // Lo HANGUL SYLLABLE BBEU
+ {0xC059, 0xC073, prLVT}, // Lo [27] HANGUL SYLLABLE BBEUG..HANGUL SYLLABLE BBEUH
+ {0xC074, 0xC074, prLV}, // Lo HANGUL SYLLABLE BBYI
+ {0xC075, 0xC08F, prLVT}, // Lo [27] HANGUL SYLLABLE BBYIG..HANGUL SYLLABLE BBYIH
+ {0xC090, 0xC090, prLV}, // Lo HANGUL SYLLABLE BBI
+ {0xC091, 0xC0AB, prLVT}, // Lo [27] HANGUL SYLLABLE BBIG..HANGUL SYLLABLE BBIH
+ {0xC0AC, 0xC0AC, prLV}, // Lo HANGUL SYLLABLE SA
+ {0xC0AD, 0xC0C7, prLVT}, // Lo [27] HANGUL SYLLABLE SAG..HANGUL SYLLABLE SAH
+ {0xC0C8, 0xC0C8, prLV}, // Lo HANGUL SYLLABLE SAE
+ {0xC0C9, 0xC0E3, prLVT}, // Lo [27] HANGUL SYLLABLE SAEG..HANGUL SYLLABLE SAEH
+ {0xC0E4, 0xC0E4, prLV}, // Lo HANGUL SYLLABLE SYA
+ {0xC0E5, 0xC0FF, prLVT}, // Lo [27] HANGUL SYLLABLE SYAG..HANGUL SYLLABLE SYAH
+ {0xC100, 0xC100, prLV}, // Lo HANGUL SYLLABLE SYAE
+ {0xC101, 0xC11B, prLVT}, // Lo [27] HANGUL SYLLABLE SYAEG..HANGUL SYLLABLE SYAEH
+ {0xC11C, 0xC11C, prLV}, // Lo HANGUL SYLLABLE SEO
+ {0xC11D, 0xC137, prLVT}, // Lo [27] HANGUL SYLLABLE SEOG..HANGUL SYLLABLE SEOH
+ {0xC138, 0xC138, prLV}, // Lo HANGUL SYLLABLE SE
+ {0xC139, 0xC153, prLVT}, // Lo [27] HANGUL SYLLABLE SEG..HANGUL SYLLABLE SEH
+ {0xC154, 0xC154, prLV}, // Lo HANGUL SYLLABLE SYEO
+ {0xC155, 0xC16F, prLVT}, // Lo [27] HANGUL SYLLABLE SYEOG..HANGUL SYLLABLE SYEOH
+ {0xC170, 0xC170, prLV}, // Lo HANGUL SYLLABLE SYE
+ {0xC171, 0xC18B, prLVT}, // Lo [27] HANGUL SYLLABLE SYEG..HANGUL SYLLABLE SYEH
+ {0xC18C, 0xC18C, prLV}, // Lo HANGUL SYLLABLE SO
+ {0xC18D, 0xC1A7, prLVT}, // Lo [27] HANGUL SYLLABLE SOG..HANGUL SYLLABLE SOH
+ {0xC1A8, 0xC1A8, prLV}, // Lo HANGUL SYLLABLE SWA
+ {0xC1A9, 0xC1C3, prLVT}, // Lo [27] HANGUL SYLLABLE SWAG..HANGUL SYLLABLE SWAH
+ {0xC1C4, 0xC1C4, prLV}, // Lo HANGUL SYLLABLE SWAE
+ {0xC1C5, 0xC1DF, prLVT}, // Lo [27] HANGUL SYLLABLE SWAEG..HANGUL SYLLABLE SWAEH
+ {0xC1E0, 0xC1E0, prLV}, // Lo HANGUL SYLLABLE SOE
+ {0xC1E1, 0xC1FB, prLVT}, // Lo [27] HANGUL SYLLABLE SOEG..HANGUL SYLLABLE SOEH
+ {0xC1FC, 0xC1FC, prLV}, // Lo HANGUL SYLLABLE SYO
+ {0xC1FD, 0xC217, prLVT}, // Lo [27] HANGUL SYLLABLE SYOG..HANGUL SYLLABLE SYOH
+ {0xC218, 0xC218, prLV}, // Lo HANGUL SYLLABLE SU
+ {0xC219, 0xC233, prLVT}, // Lo [27] HANGUL SYLLABLE SUG..HANGUL SYLLABLE SUH
+ {0xC234, 0xC234, prLV}, // Lo HANGUL SYLLABLE SWEO
+ {0xC235, 0xC24F, prLVT}, // Lo [27] HANGUL SYLLABLE SWEOG..HANGUL SYLLABLE SWEOH
+ {0xC250, 0xC250, prLV}, // Lo HANGUL SYLLABLE SWE
+ {0xC251, 0xC26B, prLVT}, // Lo [27] HANGUL SYLLABLE SWEG..HANGUL SYLLABLE SWEH
+ {0xC26C, 0xC26C, prLV}, // Lo HANGUL SYLLABLE SWI
+ {0xC26D, 0xC287, prLVT}, // Lo [27] HANGUL SYLLABLE SWIG..HANGUL SYLLABLE SWIH
+ {0xC288, 0xC288, prLV}, // Lo HANGUL SYLLABLE SYU
+ {0xC289, 0xC2A3, prLVT}, // Lo [27] HANGUL SYLLABLE SYUG..HANGUL SYLLABLE SYUH
+ {0xC2A4, 0xC2A4, prLV}, // Lo HANGUL SYLLABLE SEU
+ {0xC2A5, 0xC2BF, prLVT}, // Lo [27] HANGUL SYLLABLE SEUG..HANGUL SYLLABLE SEUH
+ {0xC2C0, 0xC2C0, prLV}, // Lo HANGUL SYLLABLE SYI
+ {0xC2C1, 0xC2DB, prLVT}, // Lo [27] HANGUL SYLLABLE SYIG..HANGUL SYLLABLE SYIH
+ {0xC2DC, 0xC2DC, prLV}, // Lo HANGUL SYLLABLE SI
+ {0xC2DD, 0xC2F7, prLVT}, // Lo [27] HANGUL SYLLABLE SIG..HANGUL SYLLABLE SIH
+ {0xC2F8, 0xC2F8, prLV}, // Lo HANGUL SYLLABLE SSA
+ {0xC2F9, 0xC313, prLVT}, // Lo [27] HANGUL SYLLABLE SSAG..HANGUL SYLLABLE SSAH
+ {0xC314, 0xC314, prLV}, // Lo HANGUL SYLLABLE SSAE
+ {0xC315, 0xC32F, prLVT}, // Lo [27] HANGUL SYLLABLE SSAEG..HANGUL SYLLABLE SSAEH
+ {0xC330, 0xC330, prLV}, // Lo HANGUL SYLLABLE SSYA
+ {0xC331, 0xC34B, prLVT}, // Lo [27] HANGUL SYLLABLE SSYAG..HANGUL SYLLABLE SSYAH
+ {0xC34C, 0xC34C, prLV}, // Lo HANGUL SYLLABLE SSYAE
+ {0xC34D, 0xC367, prLVT}, // Lo [27] HANGUL SYLLABLE SSYAEG..HANGUL SYLLABLE SSYAEH
+ {0xC368, 0xC368, prLV}, // Lo HANGUL SYLLABLE SSEO
+ {0xC369, 0xC383, prLVT}, // Lo [27] HANGUL SYLLABLE SSEOG..HANGUL SYLLABLE SSEOH
+ {0xC384, 0xC384, prLV}, // Lo HANGUL SYLLABLE SSE
+ {0xC385, 0xC39F, prLVT}, // Lo [27] HANGUL SYLLABLE SSEG..HANGUL SYLLABLE SSEH
+ {0xC3A0, 0xC3A0, prLV}, // Lo HANGUL SYLLABLE SSYEO
+ {0xC3A1, 0xC3BB, prLVT}, // Lo [27] HANGUL SYLLABLE SSYEOG..HANGUL SYLLABLE SSYEOH
+ {0xC3BC, 0xC3BC, prLV}, // Lo HANGUL SYLLABLE SSYE
+ {0xC3BD, 0xC3D7, prLVT}, // Lo [27] HANGUL SYLLABLE SSYEG..HANGUL SYLLABLE SSYEH
+ {0xC3D8, 0xC3D8, prLV}, // Lo HANGUL SYLLABLE SSO
+ {0xC3D9, 0xC3F3, prLVT}, // Lo [27] HANGUL SYLLABLE SSOG..HANGUL SYLLABLE SSOH
+ {0xC3F4, 0xC3F4, prLV}, // Lo HANGUL SYLLABLE SSWA
+ {0xC3F5, 0xC40F, prLVT}, // Lo [27] HANGUL SYLLABLE SSWAG..HANGUL SYLLABLE SSWAH
+ {0xC410, 0xC410, prLV}, // Lo HANGUL SYLLABLE SSWAE
+ {0xC411, 0xC42B, prLVT}, // Lo [27] HANGUL SYLLABLE SSWAEG..HANGUL SYLLABLE SSWAEH
+ {0xC42C, 0xC42C, prLV}, // Lo HANGUL SYLLABLE SSOE
+ {0xC42D, 0xC447, prLVT}, // Lo [27] HANGUL SYLLABLE SSOEG..HANGUL SYLLABLE SSOEH
+ {0xC448, 0xC448, prLV}, // Lo HANGUL SYLLABLE SSYO
+ {0xC449, 0xC463, prLVT}, // Lo [27] HANGUL SYLLABLE SSYOG..HANGUL SYLLABLE SSYOH
+ {0xC464, 0xC464, prLV}, // Lo HANGUL SYLLABLE SSU
+ {0xC465, 0xC47F, prLVT}, // Lo [27] HANGUL SYLLABLE SSUG..HANGUL SYLLABLE SSUH
+ {0xC480, 0xC480, prLV}, // Lo HANGUL SYLLABLE SSWEO
+ {0xC481, 0xC49B, prLVT}, // Lo [27] HANGUL SYLLABLE SSWEOG..HANGUL SYLLABLE SSWEOH
+ {0xC49C, 0xC49C, prLV}, // Lo HANGUL SYLLABLE SSWE
+ {0xC49D, 0xC4B7, prLVT}, // Lo [27] HANGUL SYLLABLE SSWEG..HANGUL SYLLABLE SSWEH
+ {0xC4B8, 0xC4B8, prLV}, // Lo HANGUL SYLLABLE SSWI
+ {0xC4B9, 0xC4D3, prLVT}, // Lo [27] HANGUL SYLLABLE SSWIG..HANGUL SYLLABLE SSWIH
+ {0xC4D4, 0xC4D4, prLV}, // Lo HANGUL SYLLABLE SSYU
+ {0xC4D5, 0xC4EF, prLVT}, // Lo [27] HANGUL SYLLABLE SSYUG..HANGUL SYLLABLE SSYUH
+ {0xC4F0, 0xC4F0, prLV}, // Lo HANGUL SYLLABLE SSEU
+ {0xC4F1, 0xC50B, prLVT}, // Lo [27] HANGUL SYLLABLE SSEUG..HANGUL SYLLABLE SSEUH
+ {0xC50C, 0xC50C, prLV}, // Lo HANGUL SYLLABLE SSYI
+ {0xC50D, 0xC527, prLVT}, // Lo [27] HANGUL SYLLABLE SSYIG..HANGUL SYLLABLE SSYIH
+ {0xC528, 0xC528, prLV}, // Lo HANGUL SYLLABLE SSI
+ {0xC529, 0xC543, prLVT}, // Lo [27] HANGUL SYLLABLE SSIG..HANGUL SYLLABLE SSIH
+ {0xC544, 0xC544, prLV}, // Lo HANGUL SYLLABLE A
+ {0xC545, 0xC55F, prLVT}, // Lo [27] HANGUL SYLLABLE AG..HANGUL SYLLABLE AH
+ {0xC560, 0xC560, prLV}, // Lo HANGUL SYLLABLE AE
+ {0xC561, 0xC57B, prLVT}, // Lo [27] HANGUL SYLLABLE AEG..HANGUL SYLLABLE AEH
+ {0xC57C, 0xC57C, prLV}, // Lo HANGUL SYLLABLE YA
+ {0xC57D, 0xC597, prLVT}, // Lo [27] HANGUL SYLLABLE YAG..HANGUL SYLLABLE YAH
+ {0xC598, 0xC598, prLV}, // Lo HANGUL SYLLABLE YAE
+ {0xC599, 0xC5B3, prLVT}, // Lo [27] HANGUL SYLLABLE YAEG..HANGUL SYLLABLE YAEH
+ {0xC5B4, 0xC5B4, prLV}, // Lo HANGUL SYLLABLE EO
+ {0xC5B5, 0xC5CF, prLVT}, // Lo [27] HANGUL SYLLABLE EOG..HANGUL SYLLABLE EOH
+ {0xC5D0, 0xC5D0, prLV}, // Lo HANGUL SYLLABLE E
+ {0xC5D1, 0xC5EB, prLVT}, // Lo [27] HANGUL SYLLABLE EG..HANGUL SYLLABLE EH
+ {0xC5EC, 0xC5EC, prLV}, // Lo HANGUL SYLLABLE YEO
+ {0xC5ED, 0xC607, prLVT}, // Lo [27] HANGUL SYLLABLE YEOG..HANGUL SYLLABLE YEOH
+ {0xC608, 0xC608, prLV}, // Lo HANGUL SYLLABLE YE
+ {0xC609, 0xC623, prLVT}, // Lo [27] HANGUL SYLLABLE YEG..HANGUL SYLLABLE YEH
+ {0xC624, 0xC624, prLV}, // Lo HANGUL SYLLABLE O
+ {0xC625, 0xC63F, prLVT}, // Lo [27] HANGUL SYLLABLE OG..HANGUL SYLLABLE OH
+ {0xC640, 0xC640, prLV}, // Lo HANGUL SYLLABLE WA
+ {0xC641, 0xC65B, prLVT}, // Lo [27] HANGUL SYLLABLE WAG..HANGUL SYLLABLE WAH
+ {0xC65C, 0xC65C, prLV}, // Lo HANGUL SYLLABLE WAE
+ {0xC65D, 0xC677, prLVT}, // Lo [27] HANGUL SYLLABLE WAEG..HANGUL SYLLABLE WAEH
+ {0xC678, 0xC678, prLV}, // Lo HANGUL SYLLABLE OE
+ {0xC679, 0xC693, prLVT}, // Lo [27] HANGUL SYLLABLE OEG..HANGUL SYLLABLE OEH
+ {0xC694, 0xC694, prLV}, // Lo HANGUL SYLLABLE YO
+ {0xC695, 0xC6AF, prLVT}, // Lo [27] HANGUL SYLLABLE YOG..HANGUL SYLLABLE YOH
+ {0xC6B0, 0xC6B0, prLV}, // Lo HANGUL SYLLABLE U
+ {0xC6B1, 0xC6CB, prLVT}, // Lo [27] HANGUL SYLLABLE UG..HANGUL SYLLABLE UH
+ {0xC6CC, 0xC6CC, prLV}, // Lo HANGUL SYLLABLE WEO
+ {0xC6CD, 0xC6E7, prLVT}, // Lo [27] HANGUL SYLLABLE WEOG..HANGUL SYLLABLE WEOH
+ {0xC6E8, 0xC6E8, prLV}, // Lo HANGUL SYLLABLE WE
+ {0xC6E9, 0xC703, prLVT}, // Lo [27] HANGUL SYLLABLE WEG..HANGUL SYLLABLE WEH
+ {0xC704, 0xC704, prLV}, // Lo HANGUL SYLLABLE WI
+ {0xC705, 0xC71F, prLVT}, // Lo [27] HANGUL SYLLABLE WIG..HANGUL SYLLABLE WIH
+ {0xC720, 0xC720, prLV}, // Lo HANGUL SYLLABLE YU
+ {0xC721, 0xC73B, prLVT}, // Lo [27] HANGUL SYLLABLE YUG..HANGUL SYLLABLE YUH
+ {0xC73C, 0xC73C, prLV}, // Lo HANGUL SYLLABLE EU
+ {0xC73D, 0xC757, prLVT}, // Lo [27] HANGUL SYLLABLE EUG..HANGUL SYLLABLE EUH
+ {0xC758, 0xC758, prLV}, // Lo HANGUL SYLLABLE YI
+ {0xC759, 0xC773, prLVT}, // Lo [27] HANGUL SYLLABLE YIG..HANGUL SYLLABLE YIH
+ {0xC774, 0xC774, prLV}, // Lo HANGUL SYLLABLE I
+ {0xC775, 0xC78F, prLVT}, // Lo [27] HANGUL SYLLABLE IG..HANGUL SYLLABLE IH
+ {0xC790, 0xC790, prLV}, // Lo HANGUL SYLLABLE JA
+ {0xC791, 0xC7AB, prLVT}, // Lo [27] HANGUL SYLLABLE JAG..HANGUL SYLLABLE JAH
+ {0xC7AC, 0xC7AC, prLV}, // Lo HANGUL SYLLABLE JAE
+ {0xC7AD, 0xC7C7, prLVT}, // Lo [27] HANGUL SYLLABLE JAEG..HANGUL SYLLABLE JAEH
+ {0xC7C8, 0xC7C8, prLV}, // Lo HANGUL SYLLABLE JYA
+ {0xC7C9, 0xC7E3, prLVT}, // Lo [27] HANGUL SYLLABLE JYAG..HANGUL SYLLABLE JYAH
+ {0xC7E4, 0xC7E4, prLV}, // Lo HANGUL SYLLABLE JYAE
+ {0xC7E5, 0xC7FF, prLVT}, // Lo [27] HANGUL SYLLABLE JYAEG..HANGUL SYLLABLE JYAEH
+ {0xC800, 0xC800, prLV}, // Lo HANGUL SYLLABLE JEO
+ {0xC801, 0xC81B, prLVT}, // Lo [27] HANGUL SYLLABLE JEOG..HANGUL SYLLABLE JEOH
+ {0xC81C, 0xC81C, prLV}, // Lo HANGUL SYLLABLE JE
+ {0xC81D, 0xC837, prLVT}, // Lo [27] HANGUL SYLLABLE JEG..HANGUL SYLLABLE JEH
+ {0xC838, 0xC838, prLV}, // Lo HANGUL SYLLABLE JYEO
+ {0xC839, 0xC853, prLVT}, // Lo [27] HANGUL SYLLABLE JYEOG..HANGUL SYLLABLE JYEOH
+ {0xC854, 0xC854, prLV}, // Lo HANGUL SYLLABLE JYE
+ {0xC855, 0xC86F, prLVT}, // Lo [27] HANGUL SYLLABLE JYEG..HANGUL SYLLABLE JYEH
+ {0xC870, 0xC870, prLV}, // Lo HANGUL SYLLABLE JO
+ {0xC871, 0xC88B, prLVT}, // Lo [27] HANGUL SYLLABLE JOG..HANGUL SYLLABLE JOH
+ {0xC88C, 0xC88C, prLV}, // Lo HANGUL SYLLABLE JWA
+ {0xC88D, 0xC8A7, prLVT}, // Lo [27] HANGUL SYLLABLE JWAG..HANGUL SYLLABLE JWAH
+ {0xC8A8, 0xC8A8, prLV}, // Lo HANGUL SYLLABLE JWAE
+ {0xC8A9, 0xC8C3, prLVT}, // Lo [27] HANGUL SYLLABLE JWAEG..HANGUL SYLLABLE JWAEH
+ {0xC8C4, 0xC8C4, prLV}, // Lo HANGUL SYLLABLE JOE
+ {0xC8C5, 0xC8DF, prLVT}, // Lo [27] HANGUL SYLLABLE JOEG..HANGUL SYLLABLE JOEH
+ {0xC8E0, 0xC8E0, prLV}, // Lo HANGUL SYLLABLE JYO
+ {0xC8E1, 0xC8FB, prLVT}, // Lo [27] HANGUL SYLLABLE JYOG..HANGUL SYLLABLE JYOH
+ {0xC8FC, 0xC8FC, prLV}, // Lo HANGUL SYLLABLE JU
+ {0xC8FD, 0xC917, prLVT}, // Lo [27] HANGUL SYLLABLE JUG..HANGUL SYLLABLE JUH
+ {0xC918, 0xC918, prLV}, // Lo HANGUL SYLLABLE JWEO
+ {0xC919, 0xC933, prLVT}, // Lo [27] HANGUL SYLLABLE JWEOG..HANGUL SYLLABLE JWEOH
+ {0xC934, 0xC934, prLV}, // Lo HANGUL SYLLABLE JWE
+ {0xC935, 0xC94F, prLVT}, // Lo [27] HANGUL SYLLABLE JWEG..HANGUL SYLLABLE JWEH
+ {0xC950, 0xC950, prLV}, // Lo HANGUL SYLLABLE JWI
+ {0xC951, 0xC96B, prLVT}, // Lo [27] HANGUL SYLLABLE JWIG..HANGUL SYLLABLE JWIH
+ {0xC96C, 0xC96C, prLV}, // Lo HANGUL SYLLABLE JYU
+ {0xC96D, 0xC987, prLVT}, // Lo [27] HANGUL SYLLABLE JYUG..HANGUL SYLLABLE JYUH
+ {0xC988, 0xC988, prLV}, // Lo HANGUL SYLLABLE JEU
+ {0xC989, 0xC9A3, prLVT}, // Lo [27] HANGUL SYLLABLE JEUG..HANGUL SYLLABLE JEUH
+ {0xC9A4, 0xC9A4, prLV}, // Lo HANGUL SYLLABLE JYI
+ {0xC9A5, 0xC9BF, prLVT}, // Lo [27] HANGUL SYLLABLE JYIG..HANGUL SYLLABLE JYIH
+ {0xC9C0, 0xC9C0, prLV}, // Lo HANGUL SYLLABLE JI
+ {0xC9C1, 0xC9DB, prLVT}, // Lo [27] HANGUL SYLLABLE JIG..HANGUL SYLLABLE JIH
+ {0xC9DC, 0xC9DC, prLV}, // Lo HANGUL SYLLABLE JJA
+ {0xC9DD, 0xC9F7, prLVT}, // Lo [27] HANGUL SYLLABLE JJAG..HANGUL SYLLABLE JJAH
+ {0xC9F8, 0xC9F8, prLV}, // Lo HANGUL SYLLABLE JJAE
+ {0xC9F9, 0xCA13, prLVT}, // Lo [27] HANGUL SYLLABLE JJAEG..HANGUL SYLLABLE JJAEH
+ {0xCA14, 0xCA14, prLV}, // Lo HANGUL SYLLABLE JJYA
+ {0xCA15, 0xCA2F, prLVT}, // Lo [27] HANGUL SYLLABLE JJYAG..HANGUL SYLLABLE JJYAH
+ {0xCA30, 0xCA30, prLV}, // Lo HANGUL SYLLABLE JJYAE
+ {0xCA31, 0xCA4B, prLVT}, // Lo [27] HANGUL SYLLABLE JJYAEG..HANGUL SYLLABLE JJYAEH
+ {0xCA4C, 0xCA4C, prLV}, // Lo HANGUL SYLLABLE JJEO
+ {0xCA4D, 0xCA67, prLVT}, // Lo [27] HANGUL SYLLABLE JJEOG..HANGUL SYLLABLE JJEOH
+ {0xCA68, 0xCA68, prLV}, // Lo HANGUL SYLLABLE JJE
+ {0xCA69, 0xCA83, prLVT}, // Lo [27] HANGUL SYLLABLE JJEG..HANGUL SYLLABLE JJEH
+ {0xCA84, 0xCA84, prLV}, // Lo HANGUL SYLLABLE JJYEO
+ {0xCA85, 0xCA9F, prLVT}, // Lo [27] HANGUL SYLLABLE JJYEOG..HANGUL SYLLABLE JJYEOH
+ {0xCAA0, 0xCAA0, prLV}, // Lo HANGUL SYLLABLE JJYE
+ {0xCAA1, 0xCABB, prLVT}, // Lo [27] HANGUL SYLLABLE JJYEG..HANGUL SYLLABLE JJYEH
+ {0xCABC, 0xCABC, prLV}, // Lo HANGUL SYLLABLE JJO
+ {0xCABD, 0xCAD7, prLVT}, // Lo [27] HANGUL SYLLABLE JJOG..HANGUL SYLLABLE JJOH
+ {0xCAD8, 0xCAD8, prLV}, // Lo HANGUL SYLLABLE JJWA
+ {0xCAD9, 0xCAF3, prLVT}, // Lo [27] HANGUL SYLLABLE JJWAG..HANGUL SYLLABLE JJWAH
+ {0xCAF4, 0xCAF4, prLV}, // Lo HANGUL SYLLABLE JJWAE
+ {0xCAF5, 0xCB0F, prLVT}, // Lo [27] HANGUL SYLLABLE JJWAEG..HANGUL SYLLABLE JJWAEH
+ {0xCB10, 0xCB10, prLV}, // Lo HANGUL SYLLABLE JJOE
+ {0xCB11, 0xCB2B, prLVT}, // Lo [27] HANGUL SYLLABLE JJOEG..HANGUL SYLLABLE JJOEH
+ {0xCB2C, 0xCB2C, prLV}, // Lo HANGUL SYLLABLE JJYO
+ {0xCB2D, 0xCB47, prLVT}, // Lo [27] HANGUL SYLLABLE JJYOG..HANGUL SYLLABLE JJYOH
+ {0xCB48, 0xCB48, prLV}, // Lo HANGUL SYLLABLE JJU
+ {0xCB49, 0xCB63, prLVT}, // Lo [27] HANGUL SYLLABLE JJUG..HANGUL SYLLABLE JJUH
+ {0xCB64, 0xCB64, prLV}, // Lo HANGUL SYLLABLE JJWEO
+ {0xCB65, 0xCB7F, prLVT}, // Lo [27] HANGUL SYLLABLE JJWEOG..HANGUL SYLLABLE JJWEOH
+ {0xCB80, 0xCB80, prLV}, // Lo HANGUL SYLLABLE JJWE
+ {0xCB81, 0xCB9B, prLVT}, // Lo [27] HANGUL SYLLABLE JJWEG..HANGUL SYLLABLE JJWEH
+ {0xCB9C, 0xCB9C, prLV}, // Lo HANGUL SYLLABLE JJWI
+ {0xCB9D, 0xCBB7, prLVT}, // Lo [27] HANGUL SYLLABLE JJWIG..HANGUL SYLLABLE JJWIH
+ {0xCBB8, 0xCBB8, prLV}, // Lo HANGUL SYLLABLE JJYU
+ {0xCBB9, 0xCBD3, prLVT}, // Lo [27] HANGUL SYLLABLE JJYUG..HANGUL SYLLABLE JJYUH
+ {0xCBD4, 0xCBD4, prLV}, // Lo HANGUL SYLLABLE JJEU
+ {0xCBD5, 0xCBEF, prLVT}, // Lo [27] HANGUL SYLLABLE JJEUG..HANGUL SYLLABLE JJEUH
+ {0xCBF0, 0xCBF0, prLV}, // Lo HANGUL SYLLABLE JJYI
+ {0xCBF1, 0xCC0B, prLVT}, // Lo [27] HANGUL SYLLABLE JJYIG..HANGUL SYLLABLE JJYIH
+ {0xCC0C, 0xCC0C, prLV}, // Lo HANGUL SYLLABLE JJI
+ {0xCC0D, 0xCC27, prLVT}, // Lo [27] HANGUL SYLLABLE JJIG..HANGUL SYLLABLE JJIH
+ {0xCC28, 0xCC28, prLV}, // Lo HANGUL SYLLABLE CA
+ {0xCC29, 0xCC43, prLVT}, // Lo [27] HANGUL SYLLABLE CAG..HANGUL SYLLABLE CAH
+ {0xCC44, 0xCC44, prLV}, // Lo HANGUL SYLLABLE CAE
+ {0xCC45, 0xCC5F, prLVT}, // Lo [27] HANGUL SYLLABLE CAEG..HANGUL SYLLABLE CAEH
+ {0xCC60, 0xCC60, prLV}, // Lo HANGUL SYLLABLE CYA
+ {0xCC61, 0xCC7B, prLVT}, // Lo [27] HANGUL SYLLABLE CYAG..HANGUL SYLLABLE CYAH
+ {0xCC7C, 0xCC7C, prLV}, // Lo HANGUL SYLLABLE CYAE
+ {0xCC7D, 0xCC97, prLVT}, // Lo [27] HANGUL SYLLABLE CYAEG..HANGUL SYLLABLE CYAEH
+ {0xCC98, 0xCC98, prLV}, // Lo HANGUL SYLLABLE CEO
+ {0xCC99, 0xCCB3, prLVT}, // Lo [27] HANGUL SYLLABLE CEOG..HANGUL SYLLABLE CEOH
+ {0xCCB4, 0xCCB4, prLV}, // Lo HANGUL SYLLABLE CE
+ {0xCCB5, 0xCCCF, prLVT}, // Lo [27] HANGUL SYLLABLE CEG..HANGUL SYLLABLE CEH
+ {0xCCD0, 0xCCD0, prLV}, // Lo HANGUL SYLLABLE CYEO
+ {0xCCD1, 0xCCEB, prLVT}, // Lo [27] HANGUL SYLLABLE CYEOG..HANGUL SYLLABLE CYEOH
+ {0xCCEC, 0xCCEC, prLV}, // Lo HANGUL SYLLABLE CYE
+ {0xCCED, 0xCD07, prLVT}, // Lo [27] HANGUL SYLLABLE CYEG..HANGUL SYLLABLE CYEH
+ {0xCD08, 0xCD08, prLV}, // Lo HANGUL SYLLABLE CO
+ {0xCD09, 0xCD23, prLVT}, // Lo [27] HANGUL SYLLABLE COG..HANGUL SYLLABLE COH
+ {0xCD24, 0xCD24, prLV}, // Lo HANGUL SYLLABLE CWA
+ {0xCD25, 0xCD3F, prLVT}, // Lo [27] HANGUL SYLLABLE CWAG..HANGUL SYLLABLE CWAH
+ {0xCD40, 0xCD40, prLV}, // Lo HANGUL SYLLABLE CWAE
+ {0xCD41, 0xCD5B, prLVT}, // Lo [27] HANGUL SYLLABLE CWAEG..HANGUL SYLLABLE CWAEH
+ {0xCD5C, 0xCD5C, prLV}, // Lo HANGUL SYLLABLE COE
+ {0xCD5D, 0xCD77, prLVT}, // Lo [27] HANGUL SYLLABLE COEG..HANGUL SYLLABLE COEH
+ {0xCD78, 0xCD78, prLV}, // Lo HANGUL SYLLABLE CYO
+ {0xCD79, 0xCD93, prLVT}, // Lo [27] HANGUL SYLLABLE CYOG..HANGUL SYLLABLE CYOH
+ {0xCD94, 0xCD94, prLV}, // Lo HANGUL SYLLABLE CU
+ {0xCD95, 0xCDAF, prLVT}, // Lo [27] HANGUL SYLLABLE CUG..HANGUL SYLLABLE CUH
+ {0xCDB0, 0xCDB0, prLV}, // Lo HANGUL SYLLABLE CWEO
+ {0xCDB1, 0xCDCB, prLVT}, // Lo [27] HANGUL SYLLABLE CWEOG..HANGUL SYLLABLE CWEOH
+ {0xCDCC, 0xCDCC, prLV}, // Lo HANGUL SYLLABLE CWE
+ {0xCDCD, 0xCDE7, prLVT}, // Lo [27] HANGUL SYLLABLE CWEG..HANGUL SYLLABLE CWEH
+ {0xCDE8, 0xCDE8, prLV}, // Lo HANGUL SYLLABLE CWI
+ {0xCDE9, 0xCE03, prLVT}, // Lo [27] HANGUL SYLLABLE CWIG..HANGUL SYLLABLE CWIH
+ {0xCE04, 0xCE04, prLV}, // Lo HANGUL SYLLABLE CYU
+ {0xCE05, 0xCE1F, prLVT}, // Lo [27] HANGUL SYLLABLE CYUG..HANGUL SYLLABLE CYUH
+ {0xCE20, 0xCE20, prLV}, // Lo HANGUL SYLLABLE CEU
+ {0xCE21, 0xCE3B, prLVT}, // Lo [27] HANGUL SYLLABLE CEUG..HANGUL SYLLABLE CEUH
+ {0xCE3C, 0xCE3C, prLV}, // Lo HANGUL SYLLABLE CYI
+ {0xCE3D, 0xCE57, prLVT}, // Lo [27] HANGUL SYLLABLE CYIG..HANGUL SYLLABLE CYIH
+ {0xCE58, 0xCE58, prLV}, // Lo HANGUL SYLLABLE CI
+ {0xCE59, 0xCE73, prLVT}, // Lo [27] HANGUL SYLLABLE CIG..HANGUL SYLLABLE CIH
+ {0xCE74, 0xCE74, prLV}, // Lo HANGUL SYLLABLE KA
+ {0xCE75, 0xCE8F, prLVT}, // Lo [27] HANGUL SYLLABLE KAG..HANGUL SYLLABLE KAH
+ {0xCE90, 0xCE90, prLV}, // Lo HANGUL SYLLABLE KAE
+ {0xCE91, 0xCEAB, prLVT}, // Lo [27] HANGUL SYLLABLE KAEG..HANGUL SYLLABLE KAEH
+ {0xCEAC, 0xCEAC, prLV}, // Lo HANGUL SYLLABLE KYA
+ {0xCEAD, 0xCEC7, prLVT}, // Lo [27] HANGUL SYLLABLE KYAG..HANGUL SYLLABLE KYAH
+ {0xCEC8, 0xCEC8, prLV}, // Lo HANGUL SYLLABLE KYAE
+ {0xCEC9, 0xCEE3, prLVT}, // Lo [27] HANGUL SYLLABLE KYAEG..HANGUL SYLLABLE KYAEH
+ {0xCEE4, 0xCEE4, prLV}, // Lo HANGUL SYLLABLE KEO
+ {0xCEE5, 0xCEFF, prLVT}, // Lo [27] HANGUL SYLLABLE KEOG..HANGUL SYLLABLE KEOH
+ {0xCF00, 0xCF00, prLV}, // Lo HANGUL SYLLABLE KE
+ {0xCF01, 0xCF1B, prLVT}, // Lo [27] HANGUL SYLLABLE KEG..HANGUL SYLLABLE KEH
+ {0xCF1C, 0xCF1C, prLV}, // Lo HANGUL SYLLABLE KYEO
+ {0xCF1D, 0xCF37, prLVT}, // Lo [27] HANGUL SYLLABLE KYEOG..HANGUL SYLLABLE KYEOH
+ {0xCF38, 0xCF38, prLV}, // Lo HANGUL SYLLABLE KYE
+ {0xCF39, 0xCF53, prLVT}, // Lo [27] HANGUL SYLLABLE KYEG..HANGUL SYLLABLE KYEH
+ {0xCF54, 0xCF54, prLV}, // Lo HANGUL SYLLABLE KO
+ {0xCF55, 0xCF6F, prLVT}, // Lo [27] HANGUL SYLLABLE KOG..HANGUL SYLLABLE KOH
+ {0xCF70, 0xCF70, prLV}, // Lo HANGUL SYLLABLE KWA
+ {0xCF71, 0xCF8B, prLVT}, // Lo [27] HANGUL SYLLABLE KWAG..HANGUL SYLLABLE KWAH
+ {0xCF8C, 0xCF8C, prLV}, // Lo HANGUL SYLLABLE KWAE
+ {0xCF8D, 0xCFA7, prLVT}, // Lo [27] HANGUL SYLLABLE KWAEG..HANGUL SYLLABLE KWAEH
+ {0xCFA8, 0xCFA8, prLV}, // Lo HANGUL SYLLABLE KOE
+ {0xCFA9, 0xCFC3, prLVT}, // Lo [27] HANGUL SYLLABLE KOEG..HANGUL SYLLABLE KOEH
+ {0xCFC4, 0xCFC4, prLV}, // Lo HANGUL SYLLABLE KYO
+ {0xCFC5, 0xCFDF, prLVT}, // Lo [27] HANGUL SYLLABLE KYOG..HANGUL SYLLABLE KYOH
+ {0xCFE0, 0xCFE0, prLV}, // Lo HANGUL SYLLABLE KU
+ {0xCFE1, 0xCFFB, prLVT}, // Lo [27] HANGUL SYLLABLE KUG..HANGUL SYLLABLE KUH
+ {0xCFFC, 0xCFFC, prLV}, // Lo HANGUL SYLLABLE KWEO
+ {0xCFFD, 0xD017, prLVT}, // Lo [27] HANGUL SYLLABLE KWEOG..HANGUL SYLLABLE KWEOH
+ {0xD018, 0xD018, prLV}, // Lo HANGUL SYLLABLE KWE
+ {0xD019, 0xD033, prLVT}, // Lo [27] HANGUL SYLLABLE KWEG..HANGUL SYLLABLE KWEH
+ {0xD034, 0xD034, prLV}, // Lo HANGUL SYLLABLE KWI
+ {0xD035, 0xD04F, prLVT}, // Lo [27] HANGUL SYLLABLE KWIG..HANGUL SYLLABLE KWIH
+ {0xD050, 0xD050, prLV}, // Lo HANGUL SYLLABLE KYU
+ {0xD051, 0xD06B, prLVT}, // Lo [27] HANGUL SYLLABLE KYUG..HANGUL SYLLABLE KYUH
+ {0xD06C, 0xD06C, prLV}, // Lo HANGUL SYLLABLE KEU
+ {0xD06D, 0xD087, prLVT}, // Lo [27] HANGUL SYLLABLE KEUG..HANGUL SYLLABLE KEUH
+ {0xD088, 0xD088, prLV}, // Lo HANGUL SYLLABLE KYI
+ {0xD089, 0xD0A3, prLVT}, // Lo [27] HANGUL SYLLABLE KYIG..HANGUL SYLLABLE KYIH
+ {0xD0A4, 0xD0A4, prLV}, // Lo HANGUL SYLLABLE KI
+ {0xD0A5, 0xD0BF, prLVT}, // Lo [27] HANGUL SYLLABLE KIG..HANGUL SYLLABLE KIH
+ {0xD0C0, 0xD0C0, prLV}, // Lo HANGUL SYLLABLE TA
+ {0xD0C1, 0xD0DB, prLVT}, // Lo [27] HANGUL SYLLABLE TAG..HANGUL SYLLABLE TAH
+ {0xD0DC, 0xD0DC, prLV}, // Lo HANGUL SYLLABLE TAE
+ {0xD0DD, 0xD0F7, prLVT}, // Lo [27] HANGUL SYLLABLE TAEG..HANGUL SYLLABLE TAEH
+ {0xD0F8, 0xD0F8, prLV}, // Lo HANGUL SYLLABLE TYA
+ {0xD0F9, 0xD113, prLVT}, // Lo [27] HANGUL SYLLABLE TYAG..HANGUL SYLLABLE TYAH
+ {0xD114, 0xD114, prLV}, // Lo HANGUL SYLLABLE TYAE
+ {0xD115, 0xD12F, prLVT}, // Lo [27] HANGUL SYLLABLE TYAEG..HANGUL SYLLABLE TYAEH
+ {0xD130, 0xD130, prLV}, // Lo HANGUL SYLLABLE TEO
+ {0xD131, 0xD14B, prLVT}, // Lo [27] HANGUL SYLLABLE TEOG..HANGUL SYLLABLE TEOH
+ {0xD14C, 0xD14C, prLV}, // Lo HANGUL SYLLABLE TE
+ {0xD14D, 0xD167, prLVT}, // Lo [27] HANGUL SYLLABLE TEG..HANGUL SYLLABLE TEH
+ {0xD168, 0xD168, prLV}, // Lo HANGUL SYLLABLE TYEO
+ {0xD169, 0xD183, prLVT}, // Lo [27] HANGUL SYLLABLE TYEOG..HANGUL SYLLABLE TYEOH
+ {0xD184, 0xD184, prLV}, // Lo HANGUL SYLLABLE TYE
+ {0xD185, 0xD19F, prLVT}, // Lo [27] HANGUL SYLLABLE TYEG..HANGUL SYLLABLE TYEH
+ {0xD1A0, 0xD1A0, prLV}, // Lo HANGUL SYLLABLE TO
+ {0xD1A1, 0xD1BB, prLVT}, // Lo [27] HANGUL SYLLABLE TOG..HANGUL SYLLABLE TOH
+ {0xD1BC, 0xD1BC, prLV}, // Lo HANGUL SYLLABLE TWA
+ {0xD1BD, 0xD1D7, prLVT}, // Lo [27] HANGUL SYLLABLE TWAG..HANGUL SYLLABLE TWAH
+ {0xD1D8, 0xD1D8, prLV}, // Lo HANGUL SYLLABLE TWAE
+ {0xD1D9, 0xD1F3, prLVT}, // Lo [27] HANGUL SYLLABLE TWAEG..HANGUL SYLLABLE TWAEH
+ {0xD1F4, 0xD1F4, prLV}, // Lo HANGUL SYLLABLE TOE
+ {0xD1F5, 0xD20F, prLVT}, // Lo [27] HANGUL SYLLABLE TOEG..HANGUL SYLLABLE TOEH
+ {0xD210, 0xD210, prLV}, // Lo HANGUL SYLLABLE TYO
+ {0xD211, 0xD22B, prLVT}, // Lo [27] HANGUL SYLLABLE TYOG..HANGUL SYLLABLE TYOH
+ {0xD22C, 0xD22C, prLV}, // Lo HANGUL SYLLABLE TU
+ {0xD22D, 0xD247, prLVT}, // Lo [27] HANGUL SYLLABLE TUG..HANGUL SYLLABLE TUH
+ {0xD248, 0xD248, prLV}, // Lo HANGUL SYLLABLE TWEO
+ {0xD249, 0xD263, prLVT}, // Lo [27] HANGUL SYLLABLE TWEOG..HANGUL SYLLABLE TWEOH
+ {0xD264, 0xD264, prLV}, // Lo HANGUL SYLLABLE TWE
+ {0xD265, 0xD27F, prLVT}, // Lo [27] HANGUL SYLLABLE TWEG..HANGUL SYLLABLE TWEH
+ {0xD280, 0xD280, prLV}, // Lo HANGUL SYLLABLE TWI
+ {0xD281, 0xD29B, prLVT}, // Lo [27] HANGUL SYLLABLE TWIG..HANGUL SYLLABLE TWIH
+ {0xD29C, 0xD29C, prLV}, // Lo HANGUL SYLLABLE TYU
+ {0xD29D, 0xD2B7, prLVT}, // Lo [27] HANGUL SYLLABLE TYUG..HANGUL SYLLABLE TYUH
+ {0xD2B8, 0xD2B8, prLV}, // Lo HANGUL SYLLABLE TEU
+ {0xD2B9, 0xD2D3, prLVT}, // Lo [27] HANGUL SYLLABLE TEUG..HANGUL SYLLABLE TEUH
+ {0xD2D4, 0xD2D4, prLV}, // Lo HANGUL SYLLABLE TYI
+ {0xD2D5, 0xD2EF, prLVT}, // Lo [27] HANGUL SYLLABLE TYIG..HANGUL SYLLABLE TYIH
+ {0xD2F0, 0xD2F0, prLV}, // Lo HANGUL SYLLABLE TI
+ {0xD2F1, 0xD30B, prLVT}, // Lo [27] HANGUL SYLLABLE TIG..HANGUL SYLLABLE TIH
+ {0xD30C, 0xD30C, prLV}, // Lo HANGUL SYLLABLE PA
+ {0xD30D, 0xD327, prLVT}, // Lo [27] HANGUL SYLLABLE PAG..HANGUL SYLLABLE PAH
+ {0xD328, 0xD328, prLV}, // Lo HANGUL SYLLABLE PAE
+ {0xD329, 0xD343, prLVT}, // Lo [27] HANGUL SYLLABLE PAEG..HANGUL SYLLABLE PAEH
+ {0xD344, 0xD344, prLV}, // Lo HANGUL SYLLABLE PYA
+ {0xD345, 0xD35F, prLVT}, // Lo [27] HANGUL SYLLABLE PYAG..HANGUL SYLLABLE PYAH
+ {0xD360, 0xD360, prLV}, // Lo HANGUL SYLLABLE PYAE
+ {0xD361, 0xD37B, prLVT}, // Lo [27] HANGUL SYLLABLE PYAEG..HANGUL SYLLABLE PYAEH
+ {0xD37C, 0xD37C, prLV}, // Lo HANGUL SYLLABLE PEO
+ {0xD37D, 0xD397, prLVT}, // Lo [27] HANGUL SYLLABLE PEOG..HANGUL SYLLABLE PEOH
+ {0xD398, 0xD398, prLV}, // Lo HANGUL SYLLABLE PE
+ {0xD399, 0xD3B3, prLVT}, // Lo [27] HANGUL SYLLABLE PEG..HANGUL SYLLABLE PEH
+ {0xD3B4, 0xD3B4, prLV}, // Lo HANGUL SYLLABLE PYEO
+ {0xD3B5, 0xD3CF, prLVT}, // Lo [27] HANGUL SYLLABLE PYEOG..HANGUL SYLLABLE PYEOH
+ {0xD3D0, 0xD3D0, prLV}, // Lo HANGUL SYLLABLE PYE
+ {0xD3D1, 0xD3EB, prLVT}, // Lo [27] HANGUL SYLLABLE PYEG..HANGUL SYLLABLE PYEH
+ {0xD3EC, 0xD3EC, prLV}, // Lo HANGUL SYLLABLE PO
+ {0xD3ED, 0xD407, prLVT}, // Lo [27] HANGUL SYLLABLE POG..HANGUL SYLLABLE POH
+ {0xD408, 0xD408, prLV}, // Lo HANGUL SYLLABLE PWA
+ {0xD409, 0xD423, prLVT}, // Lo [27] HANGUL SYLLABLE PWAG..HANGUL SYLLABLE PWAH
+ {0xD424, 0xD424, prLV}, // Lo HANGUL SYLLABLE PWAE
+ {0xD425, 0xD43F, prLVT}, // Lo [27] HANGUL SYLLABLE PWAEG..HANGUL SYLLABLE PWAEH
+ {0xD440, 0xD440, prLV}, // Lo HANGUL SYLLABLE POE
+ {0xD441, 0xD45B, prLVT}, // Lo [27] HANGUL SYLLABLE POEG..HANGUL SYLLABLE POEH
+ {0xD45C, 0xD45C, prLV}, // Lo HANGUL SYLLABLE PYO
+ {0xD45D, 0xD477, prLVT}, // Lo [27] HANGUL SYLLABLE PYOG..HANGUL SYLLABLE PYOH
+ {0xD478, 0xD478, prLV}, // Lo HANGUL SYLLABLE PU
+ {0xD479, 0xD493, prLVT}, // Lo [27] HANGUL SYLLABLE PUG..HANGUL SYLLABLE PUH
+ {0xD494, 0xD494, prLV}, // Lo HANGUL SYLLABLE PWEO
+ {0xD495, 0xD4AF, prLVT}, // Lo [27] HANGUL SYLLABLE PWEOG..HANGUL SYLLABLE PWEOH
+ {0xD4B0, 0xD4B0, prLV}, // Lo HANGUL SYLLABLE PWE
+ {0xD4B1, 0xD4CB, prLVT}, // Lo [27] HANGUL SYLLABLE PWEG..HANGUL SYLLABLE PWEH
+ {0xD4CC, 0xD4CC, prLV}, // Lo HANGUL SYLLABLE PWI
+ {0xD4CD, 0xD4E7, prLVT}, // Lo [27] HANGUL SYLLABLE PWIG..HANGUL SYLLABLE PWIH
+ {0xD4E8, 0xD4E8, prLV}, // Lo HANGUL SYLLABLE PYU
+ {0xD4E9, 0xD503, prLVT}, // Lo [27] HANGUL SYLLABLE PYUG..HANGUL SYLLABLE PYUH
+ {0xD504, 0xD504, prLV}, // Lo HANGUL SYLLABLE PEU
+ {0xD505, 0xD51F, prLVT}, // Lo [27] HANGUL SYLLABLE PEUG..HANGUL SYLLABLE PEUH
+ {0xD520, 0xD520, prLV}, // Lo HANGUL SYLLABLE PYI
+ {0xD521, 0xD53B, prLVT}, // Lo [27] HANGUL SYLLABLE PYIG..HANGUL SYLLABLE PYIH
+ {0xD53C, 0xD53C, prLV}, // Lo HANGUL SYLLABLE PI
+ {0xD53D, 0xD557, prLVT}, // Lo [27] HANGUL SYLLABLE PIG..HANGUL SYLLABLE PIH
+ {0xD558, 0xD558, prLV}, // Lo HANGUL SYLLABLE HA
+ {0xD559, 0xD573, prLVT}, // Lo [27] HANGUL SYLLABLE HAG..HANGUL SYLLABLE HAH
+ {0xD574, 0xD574, prLV}, // Lo HANGUL SYLLABLE HAE
+ {0xD575, 0xD58F, prLVT}, // Lo [27] HANGUL SYLLABLE HAEG..HANGUL SYLLABLE HAEH
+ {0xD590, 0xD590, prLV}, // Lo HANGUL SYLLABLE HYA
+ {0xD591, 0xD5AB, prLVT}, // Lo [27] HANGUL SYLLABLE HYAG..HANGUL SYLLABLE HYAH
+ {0xD5AC, 0xD5AC, prLV}, // Lo HANGUL SYLLABLE HYAE
+ {0xD5AD, 0xD5C7, prLVT}, // Lo [27] HANGUL SYLLABLE HYAEG..HANGUL SYLLABLE HYAEH
+ {0xD5C8, 0xD5C8, prLV}, // Lo HANGUL SYLLABLE HEO
+ {0xD5C9, 0xD5E3, prLVT}, // Lo [27] HANGUL SYLLABLE HEOG..HANGUL SYLLABLE HEOH
+ {0xD5E4, 0xD5E4, prLV}, // Lo HANGUL SYLLABLE HE
+ {0xD5E5, 0xD5FF, prLVT}, // Lo [27] HANGUL SYLLABLE HEG..HANGUL SYLLABLE HEH
+ {0xD600, 0xD600, prLV}, // Lo HANGUL SYLLABLE HYEO
+ {0xD601, 0xD61B, prLVT}, // Lo [27] HANGUL SYLLABLE HYEOG..HANGUL SYLLABLE HYEOH
+ {0xD61C, 0xD61C, prLV}, // Lo HANGUL SYLLABLE HYE
+ {0xD61D, 0xD637, prLVT}, // Lo [27] HANGUL SYLLABLE HYEG..HANGUL SYLLABLE HYEH
+ {0xD638, 0xD638, prLV}, // Lo HANGUL SYLLABLE HO
+ {0xD639, 0xD653, prLVT}, // Lo [27] HANGUL SYLLABLE HOG..HANGUL SYLLABLE HOH
+ {0xD654, 0xD654, prLV}, // Lo HANGUL SYLLABLE HWA
+ {0xD655, 0xD66F, prLVT}, // Lo [27] HANGUL SYLLABLE HWAG..HANGUL SYLLABLE HWAH
+ {0xD670, 0xD670, prLV}, // Lo HANGUL SYLLABLE HWAE
+ {0xD671, 0xD68B, prLVT}, // Lo [27] HANGUL SYLLABLE HWAEG..HANGUL SYLLABLE HWAEH
+ {0xD68C, 0xD68C, prLV}, // Lo HANGUL SYLLABLE HOE
+ {0xD68D, 0xD6A7, prLVT}, // Lo [27] HANGUL SYLLABLE HOEG..HANGUL SYLLABLE HOEH
+ {0xD6A8, 0xD6A8, prLV}, // Lo HANGUL SYLLABLE HYO
+ {0xD6A9, 0xD6C3, prLVT}, // Lo [27] HANGUL SYLLABLE HYOG..HANGUL SYLLABLE HYOH
+ {0xD6C4, 0xD6C4, prLV}, // Lo HANGUL SYLLABLE HU
+ {0xD6C5, 0xD6DF, prLVT}, // Lo [27] HANGUL SYLLABLE HUG..HANGUL SYLLABLE HUH
+ {0xD6E0, 0xD6E0, prLV}, // Lo HANGUL SYLLABLE HWEO
+ {0xD6E1, 0xD6FB, prLVT}, // Lo [27] HANGUL SYLLABLE HWEOG..HANGUL SYLLABLE HWEOH
+ {0xD6FC, 0xD6FC, prLV}, // Lo HANGUL SYLLABLE HWE
+ {0xD6FD, 0xD717, prLVT}, // Lo [27] HANGUL SYLLABLE HWEG..HANGUL SYLLABLE HWEH
+ {0xD718, 0xD718, prLV}, // Lo HANGUL SYLLABLE HWI
+ {0xD719, 0xD733, prLVT}, // Lo [27] HANGUL SYLLABLE HWIG..HANGUL SYLLABLE HWIH
+ {0xD734, 0xD734, prLV}, // Lo HANGUL SYLLABLE HYU
+ {0xD735, 0xD74F, prLVT}, // Lo [27] HANGUL SYLLABLE HYUG..HANGUL SYLLABLE HYUH
+ {0xD750, 0xD750, prLV}, // Lo HANGUL SYLLABLE HEU
+ {0xD751, 0xD76B, prLVT}, // Lo [27] HANGUL SYLLABLE HEUG..HANGUL SYLLABLE HEUH
+ {0xD76C, 0xD76C, prLV}, // Lo HANGUL SYLLABLE HYI
+ {0xD76D, 0xD787, prLVT}, // Lo [27] HANGUL SYLLABLE HYIG..HANGUL SYLLABLE HYIH
+ {0xD788, 0xD788, prLV}, // Lo HANGUL SYLLABLE HI
+ {0xD789, 0xD7A3, prLVT}, // Lo [27] HANGUL SYLLABLE HIG..HANGUL SYLLABLE HIH
+ {0xD7B0, 0xD7C6, prV}, // Lo [23] HANGUL JUNGSEONG O-YEO..HANGUL JUNGSEONG ARAEA-E
+ {0xD7CB, 0xD7FB, prT}, // Lo [49] HANGUL JONGSEONG NIEUN-RIEUL..HANGUL JONGSEONG PHIEUPH-THIEUTH
+ {0xFB1E, 0xFB1E, prExtend}, // Mn HEBREW POINT JUDEO-SPANISH VARIKA
+ {0xFE00, 0xFE0F, prExtend}, // Mn [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16
+ {0xFE20, 0xFE2F, prExtend}, // Mn [16] COMBINING LIGATURE LEFT HALF..COMBINING CYRILLIC TITLO RIGHT HALF
+ {0xFEFF, 0xFEFF, prControl}, // Cf ZERO WIDTH NO-BREAK SPACE
+ {0xFF9E, 0xFF9F, prExtend}, // Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
+ {0xFFF0, 0xFFF8, prControl}, // Cn [9] ..
+ {0xFFF9, 0xFFFB, prControl}, // Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR
+ {0x101FD, 0x101FD, prExtend}, // Mn PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE
+ {0x102E0, 0x102E0, prExtend}, // Mn COPTIC EPACT THOUSANDS MARK
+ {0x10376, 0x1037A, prExtend}, // Mn [5] COMBINING OLD PERMIC LETTER AN..COMBINING OLD PERMIC LETTER SII
+ {0x10A01, 0x10A03, prExtend}, // Mn [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R
+ {0x10A05, 0x10A06, prExtend}, // Mn [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O
+ {0x10A0C, 0x10A0F, prExtend}, // Mn [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA
+ {0x10A38, 0x10A3A, prExtend}, // Mn [3] KHAROSHTHI SIGN BAR ABOVE..KHAROSHTHI SIGN DOT BELOW
+ {0x10A3F, 0x10A3F, prExtend}, // Mn KHAROSHTHI VIRAMA
+ {0x10AE5, 0x10AE6, prExtend}, // Mn [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW
+ {0x10D24, 0x10D27, prExtend}, // Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI
+ {0x10EAB, 0x10EAC, prExtend}, // Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK
+ {0x10EFD, 0x10EFF, prExtend}, // Mn [3] ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA
+ {0x10F46, 0x10F50, prExtend}, // Mn [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW
+ {0x10F82, 0x10F85, prExtend}, // Mn [4] OLD UYGHUR COMBINING DOT ABOVE..OLD UYGHUR COMBINING TWO DOTS BELOW
+ {0x11000, 0x11000, prSpacingMark}, // Mc BRAHMI SIGN CANDRABINDU
+ {0x11001, 0x11001, prExtend}, // Mn BRAHMI SIGN ANUSVARA
+ {0x11002, 0x11002, prSpacingMark}, // Mc BRAHMI SIGN VISARGA
+ {0x11038, 0x11046, prExtend}, // Mn [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA
+ {0x11070, 0x11070, prExtend}, // Mn BRAHMI SIGN OLD TAMIL VIRAMA
+ {0x11073, 0x11074, prExtend}, // Mn [2] BRAHMI VOWEL SIGN OLD TAMIL SHORT E..BRAHMI VOWEL SIGN OLD TAMIL SHORT O
+ {0x1107F, 0x11081, prExtend}, // Mn [3] BRAHMI NUMBER JOINER..KAITHI SIGN ANUSVARA
+ {0x11082, 0x11082, prSpacingMark}, // Mc KAITHI SIGN VISARGA
+ {0x110B0, 0x110B2, prSpacingMark}, // Mc [3] KAITHI VOWEL SIGN AA..KAITHI VOWEL SIGN II
+ {0x110B3, 0x110B6, prExtend}, // Mn [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI
+ {0x110B7, 0x110B8, prSpacingMark}, // Mc [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU
+ {0x110B9, 0x110BA, prExtend}, // Mn [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA
+ {0x110BD, 0x110BD, prPrepend}, // Cf KAITHI NUMBER SIGN
+ {0x110C2, 0x110C2, prExtend}, // Mn KAITHI VOWEL SIGN VOCALIC R
+ {0x110CD, 0x110CD, prPrepend}, // Cf KAITHI NUMBER SIGN ABOVE
+ {0x11100, 0x11102, prExtend}, // Mn [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA
+ {0x11127, 0x1112B, prExtend}, // Mn [5] CHAKMA VOWEL SIGN A..CHAKMA VOWEL SIGN UU
+ {0x1112C, 0x1112C, prSpacingMark}, // Mc CHAKMA VOWEL SIGN E
+ {0x1112D, 0x11134, prExtend}, // Mn [8] CHAKMA VOWEL SIGN AI..CHAKMA MAAYYAA
+ {0x11145, 0x11146, prSpacingMark}, // Mc [2] CHAKMA VOWEL SIGN AA..CHAKMA VOWEL SIGN EI
+ {0x11173, 0x11173, prExtend}, // Mn MAHAJANI SIGN NUKTA
+ {0x11180, 0x11181, prExtend}, // Mn [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA
+ {0x11182, 0x11182, prSpacingMark}, // Mc SHARADA SIGN VISARGA
+ {0x111B3, 0x111B5, prSpacingMark}, // Mc [3] SHARADA VOWEL SIGN AA..SHARADA VOWEL SIGN II
+ {0x111B6, 0x111BE, prExtend}, // Mn [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O
+ {0x111BF, 0x111C0, prSpacingMark}, // Mc [2] SHARADA VOWEL SIGN AU..SHARADA SIGN VIRAMA
+ {0x111C2, 0x111C3, prPrepend}, // Lo [2] SHARADA SIGN JIHVAMULIYA..SHARADA SIGN UPADHMANIYA
+ {0x111C9, 0x111CC, prExtend}, // Mn [4] SHARADA SANDHI MARK..SHARADA EXTRA SHORT VOWEL MARK
+ {0x111CE, 0x111CE, prSpacingMark}, // Mc SHARADA VOWEL SIGN PRISHTHAMATRA E
+ {0x111CF, 0x111CF, prExtend}, // Mn SHARADA SIGN INVERTED CANDRABINDU
+ {0x1122C, 0x1122E, prSpacingMark}, // Mc [3] KHOJKI VOWEL SIGN AA..KHOJKI VOWEL SIGN II
+ {0x1122F, 0x11231, prExtend}, // Mn [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI
+ {0x11232, 0x11233, prSpacingMark}, // Mc [2] KHOJKI VOWEL SIGN O..KHOJKI VOWEL SIGN AU
+ {0x11234, 0x11234, prExtend}, // Mn KHOJKI SIGN ANUSVARA
+ {0x11235, 0x11235, prSpacingMark}, // Mc KHOJKI SIGN VIRAMA
+ {0x11236, 0x11237, prExtend}, // Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA
+ {0x1123E, 0x1123E, prExtend}, // Mn KHOJKI SIGN SUKUN
+ {0x11241, 0x11241, prExtend}, // Mn KHOJKI VOWEL SIGN VOCALIC R
+ {0x112DF, 0x112DF, prExtend}, // Mn KHUDAWADI SIGN ANUSVARA
+ {0x112E0, 0x112E2, prSpacingMark}, // Mc [3] KHUDAWADI VOWEL SIGN AA..KHUDAWADI VOWEL SIGN II
+ {0x112E3, 0x112EA, prExtend}, // Mn [8] KHUDAWADI VOWEL SIGN U..KHUDAWADI SIGN VIRAMA
+ {0x11300, 0x11301, prExtend}, // Mn [2] GRANTHA SIGN COMBINING ANUSVARA ABOVE..GRANTHA SIGN CANDRABINDU
+ {0x11302, 0x11303, prSpacingMark}, // Mc [2] GRANTHA SIGN ANUSVARA..GRANTHA SIGN VISARGA
+ {0x1133B, 0x1133C, prExtend}, // Mn [2] COMBINING BINDU BELOW..GRANTHA SIGN NUKTA
+ {0x1133E, 0x1133E, prExtend}, // Mc GRANTHA VOWEL SIGN AA
+ {0x1133F, 0x1133F, prSpacingMark}, // Mc GRANTHA VOWEL SIGN I
+ {0x11340, 0x11340, prExtend}, // Mn GRANTHA VOWEL SIGN II
+ {0x11341, 0x11344, prSpacingMark}, // Mc [4] GRANTHA VOWEL SIGN U..GRANTHA VOWEL SIGN VOCALIC RR
+ {0x11347, 0x11348, prSpacingMark}, // Mc [2] GRANTHA VOWEL SIGN EE..GRANTHA VOWEL SIGN AI
+ {0x1134B, 0x1134D, prSpacingMark}, // Mc [3] GRANTHA VOWEL SIGN OO..GRANTHA SIGN VIRAMA
+ {0x11357, 0x11357, prExtend}, // Mc GRANTHA AU LENGTH MARK
+ {0x11362, 0x11363, prSpacingMark}, // Mc [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL
+ {0x11366, 0x1136C, prExtend}, // Mn [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX
+ {0x11370, 0x11374, prExtend}, // Mn [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA
+ {0x11435, 0x11437, prSpacingMark}, // Mc [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II
+ {0x11438, 0x1143F, prExtend}, // Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI
+ {0x11440, 0x11441, prSpacingMark}, // Mc [2] NEWA VOWEL SIGN O..NEWA VOWEL SIGN AU
+ {0x11442, 0x11444, prExtend}, // Mn [3] NEWA SIGN VIRAMA..NEWA SIGN ANUSVARA
+ {0x11445, 0x11445, prSpacingMark}, // Mc NEWA SIGN VISARGA
+ {0x11446, 0x11446, prExtend}, // Mn NEWA SIGN NUKTA
+ {0x1145E, 0x1145E, prExtend}, // Mn NEWA SANDHI MARK
+ {0x114B0, 0x114B0, prExtend}, // Mc TIRHUTA VOWEL SIGN AA
+ {0x114B1, 0x114B2, prSpacingMark}, // Mc [2] TIRHUTA VOWEL SIGN I..TIRHUTA VOWEL SIGN II
+ {0x114B3, 0x114B8, prExtend}, // Mn [6] TIRHUTA VOWEL SIGN U..TIRHUTA VOWEL SIGN VOCALIC LL
+ {0x114B9, 0x114B9, prSpacingMark}, // Mc TIRHUTA VOWEL SIGN E
+ {0x114BA, 0x114BA, prExtend}, // Mn TIRHUTA VOWEL SIGN SHORT E
+ {0x114BB, 0x114BC, prSpacingMark}, // Mc [2] TIRHUTA VOWEL SIGN AI..TIRHUTA VOWEL SIGN O
+ {0x114BD, 0x114BD, prExtend}, // Mc TIRHUTA VOWEL SIGN SHORT O
+ {0x114BE, 0x114BE, prSpacingMark}, // Mc TIRHUTA VOWEL SIGN AU
+ {0x114BF, 0x114C0, prExtend}, // Mn [2] TIRHUTA SIGN CANDRABINDU..TIRHUTA SIGN ANUSVARA
+ {0x114C1, 0x114C1, prSpacingMark}, // Mc TIRHUTA SIGN VISARGA
+ {0x114C2, 0x114C3, prExtend}, // Mn [2] TIRHUTA SIGN VIRAMA..TIRHUTA SIGN NUKTA
+ {0x115AF, 0x115AF, prExtend}, // Mc SIDDHAM VOWEL SIGN AA
+ {0x115B0, 0x115B1, prSpacingMark}, // Mc [2] SIDDHAM VOWEL SIGN I..SIDDHAM VOWEL SIGN II
+ {0x115B2, 0x115B5, prExtend}, // Mn [4] SIDDHAM VOWEL SIGN U..SIDDHAM VOWEL SIGN VOCALIC RR
+ {0x115B8, 0x115BB, prSpacingMark}, // Mc [4] SIDDHAM VOWEL SIGN E..SIDDHAM VOWEL SIGN AU
+ {0x115BC, 0x115BD, prExtend}, // Mn [2] SIDDHAM SIGN CANDRABINDU..SIDDHAM SIGN ANUSVARA
+ {0x115BE, 0x115BE, prSpacingMark}, // Mc SIDDHAM SIGN VISARGA
+ {0x115BF, 0x115C0, prExtend}, // Mn [2] SIDDHAM SIGN VIRAMA..SIDDHAM SIGN NUKTA
+ {0x115DC, 0x115DD, prExtend}, // Mn [2] SIDDHAM VOWEL SIGN ALTERNATE U..SIDDHAM VOWEL SIGN ALTERNATE UU
+ {0x11630, 0x11632, prSpacingMark}, // Mc [3] MODI VOWEL SIGN AA..MODI VOWEL SIGN II
+ {0x11633, 0x1163A, prExtend}, // Mn [8] MODI VOWEL SIGN U..MODI VOWEL SIGN AI
+ {0x1163B, 0x1163C, prSpacingMark}, // Mc [2] MODI VOWEL SIGN O..MODI VOWEL SIGN AU
+ {0x1163D, 0x1163D, prExtend}, // Mn MODI SIGN ANUSVARA
+ {0x1163E, 0x1163E, prSpacingMark}, // Mc MODI SIGN VISARGA
+ {0x1163F, 0x11640, prExtend}, // Mn [2] MODI SIGN VIRAMA..MODI SIGN ARDHACANDRA
+ {0x116AB, 0x116AB, prExtend}, // Mn TAKRI SIGN ANUSVARA
+ {0x116AC, 0x116AC, prSpacingMark}, // Mc TAKRI SIGN VISARGA
+ {0x116AD, 0x116AD, prExtend}, // Mn TAKRI VOWEL SIGN AA
+ {0x116AE, 0x116AF, prSpacingMark}, // Mc [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II
+ {0x116B0, 0x116B5, prExtend}, // Mn [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU
+ {0x116B6, 0x116B6, prSpacingMark}, // Mc TAKRI SIGN VIRAMA
+ {0x116B7, 0x116B7, prExtend}, // Mn TAKRI SIGN NUKTA
+ {0x1171D, 0x1171F, prExtend}, // Mn [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA
+ {0x11722, 0x11725, prExtend}, // Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU
+ {0x11726, 0x11726, prSpacingMark}, // Mc AHOM VOWEL SIGN E
+ {0x11727, 0x1172B, prExtend}, // Mn [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER
+ {0x1182C, 0x1182E, prSpacingMark}, // Mc [3] DOGRA VOWEL SIGN AA..DOGRA VOWEL SIGN II
+ {0x1182F, 0x11837, prExtend}, // Mn [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA
+ {0x11838, 0x11838, prSpacingMark}, // Mc DOGRA SIGN VISARGA
+ {0x11839, 0x1183A, prExtend}, // Mn [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA
+ {0x11930, 0x11930, prExtend}, // Mc DIVES AKURU VOWEL SIGN AA
+ {0x11931, 0x11935, prSpacingMark}, // Mc [5] DIVES AKURU VOWEL SIGN I..DIVES AKURU VOWEL SIGN E
+ {0x11937, 0x11938, prSpacingMark}, // Mc [2] DIVES AKURU VOWEL SIGN AI..DIVES AKURU VOWEL SIGN O
+ {0x1193B, 0x1193C, prExtend}, // Mn [2] DIVES AKURU SIGN ANUSVARA..DIVES AKURU SIGN CANDRABINDU
+ {0x1193D, 0x1193D, prSpacingMark}, // Mc DIVES AKURU SIGN HALANTA
+ {0x1193E, 0x1193E, prExtend}, // Mn DIVES AKURU VIRAMA
+ {0x1193F, 0x1193F, prPrepend}, // Lo DIVES AKURU PREFIXED NASAL SIGN
+ {0x11940, 0x11940, prSpacingMark}, // Mc DIVES AKURU MEDIAL YA
+ {0x11941, 0x11941, prPrepend}, // Lo DIVES AKURU INITIAL RA
+ {0x11942, 0x11942, prSpacingMark}, // Mc DIVES AKURU MEDIAL RA
+ {0x11943, 0x11943, prExtend}, // Mn DIVES AKURU SIGN NUKTA
+ {0x119D1, 0x119D3, prSpacingMark}, // Mc [3] NANDINAGARI VOWEL SIGN AA..NANDINAGARI VOWEL SIGN II
+ {0x119D4, 0x119D7, prExtend}, // Mn [4] NANDINAGARI VOWEL SIGN U..NANDINAGARI VOWEL SIGN VOCALIC RR
+ {0x119DA, 0x119DB, prExtend}, // Mn [2] NANDINAGARI VOWEL SIGN E..NANDINAGARI VOWEL SIGN AI
+ {0x119DC, 0x119DF, prSpacingMark}, // Mc [4] NANDINAGARI VOWEL SIGN O..NANDINAGARI SIGN VISARGA
+ {0x119E0, 0x119E0, prExtend}, // Mn NANDINAGARI SIGN VIRAMA
+ {0x119E4, 0x119E4, prSpacingMark}, // Mc NANDINAGARI VOWEL SIGN PRISHTHAMATRA E
+ {0x11A01, 0x11A0A, prExtend}, // Mn [10] ZANABAZAR SQUARE VOWEL SIGN I..ZANABAZAR SQUARE VOWEL LENGTH MARK
+ {0x11A33, 0x11A38, prExtend}, // Mn [6] ZANABAZAR SQUARE FINAL CONSONANT MARK..ZANABAZAR SQUARE SIGN ANUSVARA
+ {0x11A39, 0x11A39, prSpacingMark}, // Mc ZANABAZAR SQUARE SIGN VISARGA
+ {0x11A3A, 0x11A3A, prPrepend}, // Lo ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA
+ {0x11A3B, 0x11A3E, prExtend}, // Mn [4] ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA..ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA
+ {0x11A47, 0x11A47, prExtend}, // Mn ZANABAZAR SQUARE SUBJOINER
+ {0x11A51, 0x11A56, prExtend}, // Mn [6] SOYOMBO VOWEL SIGN I..SOYOMBO VOWEL SIGN OE
+ {0x11A57, 0x11A58, prSpacingMark}, // Mc [2] SOYOMBO VOWEL SIGN AI..SOYOMBO VOWEL SIGN AU
+ {0x11A59, 0x11A5B, prExtend}, // Mn [3] SOYOMBO VOWEL SIGN VOCALIC R..SOYOMBO VOWEL LENGTH MARK
+ {0x11A84, 0x11A89, prPrepend}, // Lo [6] SOYOMBO SIGN JIHVAMULIYA..SOYOMBO CLUSTER-INITIAL LETTER SA
+ {0x11A8A, 0x11A96, prExtend}, // Mn [13] SOYOMBO FINAL CONSONANT SIGN G..SOYOMBO SIGN ANUSVARA
+ {0x11A97, 0x11A97, prSpacingMark}, // Mc SOYOMBO SIGN VISARGA
+ {0x11A98, 0x11A99, prExtend}, // Mn [2] SOYOMBO GEMINATION MARK..SOYOMBO SUBJOINER
+ {0x11C2F, 0x11C2F, prSpacingMark}, // Mc BHAIKSUKI VOWEL SIGN AA
+ {0x11C30, 0x11C36, prExtend}, // Mn [7] BHAIKSUKI VOWEL SIGN I..BHAIKSUKI VOWEL SIGN VOCALIC L
+ {0x11C38, 0x11C3D, prExtend}, // Mn [6] BHAIKSUKI VOWEL SIGN E..BHAIKSUKI SIGN ANUSVARA
+ {0x11C3E, 0x11C3E, prSpacingMark}, // Mc BHAIKSUKI SIGN VISARGA
+ {0x11C3F, 0x11C3F, prExtend}, // Mn BHAIKSUKI SIGN VIRAMA
+ {0x11C92, 0x11CA7, prExtend}, // Mn [22] MARCHEN SUBJOINED LETTER KA..MARCHEN SUBJOINED LETTER ZA
+ {0x11CA9, 0x11CA9, prSpacingMark}, // Mc MARCHEN SUBJOINED LETTER YA
+ {0x11CAA, 0x11CB0, prExtend}, // Mn [7] MARCHEN SUBJOINED LETTER RA..MARCHEN VOWEL SIGN AA
+ {0x11CB1, 0x11CB1, prSpacingMark}, // Mc MARCHEN VOWEL SIGN I
+ {0x11CB2, 0x11CB3, prExtend}, // Mn [2] MARCHEN VOWEL SIGN U..MARCHEN VOWEL SIGN E
+ {0x11CB4, 0x11CB4, prSpacingMark}, // Mc MARCHEN VOWEL SIGN O
+ {0x11CB5, 0x11CB6, prExtend}, // Mn [2] MARCHEN SIGN ANUSVARA..MARCHEN SIGN CANDRABINDU
+ {0x11D31, 0x11D36, prExtend}, // Mn [6] MASARAM GONDI VOWEL SIGN AA..MASARAM GONDI VOWEL SIGN VOCALIC R
+ {0x11D3A, 0x11D3A, prExtend}, // Mn MASARAM GONDI VOWEL SIGN E
+ {0x11D3C, 0x11D3D, prExtend}, // Mn [2] MASARAM GONDI VOWEL SIGN AI..MASARAM GONDI VOWEL SIGN O
+ {0x11D3F, 0x11D45, prExtend}, // Mn [7] MASARAM GONDI VOWEL SIGN AU..MASARAM GONDI VIRAMA
+ {0x11D46, 0x11D46, prPrepend}, // Lo MASARAM GONDI REPHA
+ {0x11D47, 0x11D47, prExtend}, // Mn MASARAM GONDI RA-KARA
+ {0x11D8A, 0x11D8E, prSpacingMark}, // Mc [5] GUNJALA GONDI VOWEL SIGN AA..GUNJALA GONDI VOWEL SIGN UU
+ {0x11D90, 0x11D91, prExtend}, // Mn [2] GUNJALA GONDI VOWEL SIGN EE..GUNJALA GONDI VOWEL SIGN AI
+ {0x11D93, 0x11D94, prSpacingMark}, // Mc [2] GUNJALA GONDI VOWEL SIGN OO..GUNJALA GONDI VOWEL SIGN AU
+ {0x11D95, 0x11D95, prExtend}, // Mn GUNJALA GONDI SIGN ANUSVARA
+ {0x11D96, 0x11D96, prSpacingMark}, // Mc GUNJALA GONDI SIGN VISARGA
+ {0x11D97, 0x11D97, prExtend}, // Mn GUNJALA GONDI VIRAMA
+ {0x11EF3, 0x11EF4, prExtend}, // Mn [2] MAKASAR VOWEL SIGN I..MAKASAR VOWEL SIGN U
+ {0x11EF5, 0x11EF6, prSpacingMark}, // Mc [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O
+ {0x11F00, 0x11F01, prExtend}, // Mn [2] KAWI SIGN CANDRABINDU..KAWI SIGN ANUSVARA
+ {0x11F02, 0x11F02, prPrepend}, // Lo KAWI SIGN REPHA
+ {0x11F03, 0x11F03, prSpacingMark}, // Mc KAWI SIGN VISARGA
+ {0x11F34, 0x11F35, prSpacingMark}, // Mc [2] KAWI VOWEL SIGN AA..KAWI VOWEL SIGN ALTERNATE AA
+ {0x11F36, 0x11F3A, prExtend}, // Mn [5] KAWI VOWEL SIGN I..KAWI VOWEL SIGN VOCALIC R
+ {0x11F3E, 0x11F3F, prSpacingMark}, // Mc [2] KAWI VOWEL SIGN E..KAWI VOWEL SIGN AI
+ {0x11F40, 0x11F40, prExtend}, // Mn KAWI VOWEL SIGN EU
+ {0x11F41, 0x11F41, prSpacingMark}, // Mc KAWI SIGN KILLER
+ {0x11F42, 0x11F42, prExtend}, // Mn KAWI CONJOINER
+ {0x13430, 0x1343F, prControl}, // Cf [16] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH END WALLED ENCLOSURE
+ {0x13440, 0x13440, prExtend}, // Mn EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY
+ {0x13447, 0x13455, prExtend}, // Mn [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED
+ {0x16AF0, 0x16AF4, prExtend}, // Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE
+ {0x16B30, 0x16B36, prExtend}, // Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM
+ {0x16F4F, 0x16F4F, prExtend}, // Mn MIAO SIGN CONSONANT MODIFIER BAR
+ {0x16F51, 0x16F87, prSpacingMark}, // Mc [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI
+ {0x16F8F, 0x16F92, prExtend}, // Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW
+ {0x16FE4, 0x16FE4, prExtend}, // Mn KHITAN SMALL SCRIPT FILLER
+ {0x16FF0, 0x16FF1, prSpacingMark}, // Mc [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY
+ {0x1BC9D, 0x1BC9E, prExtend}, // Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK
+ {0x1BCA0, 0x1BCA3, prControl}, // Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP
+ {0x1CF00, 0x1CF2D, prExtend}, // Mn [46] ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT..ZNAMENNY COMBINING MARK KRYZH ON LEFT
+ {0x1CF30, 0x1CF46, prExtend}, // Mn [23] ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO..ZNAMENNY PRIZNAK MODIFIER ROG
+ {0x1D165, 0x1D165, prExtend}, // Mc MUSICAL SYMBOL COMBINING STEM
+ {0x1D166, 0x1D166, prSpacingMark}, // Mc MUSICAL SYMBOL COMBINING SPRECHGESANG STEM
+ {0x1D167, 0x1D169, prExtend}, // Mn [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3
+ {0x1D16D, 0x1D16D, prSpacingMark}, // Mc MUSICAL SYMBOL COMBINING AUGMENTATION DOT
+ {0x1D16E, 0x1D172, prExtend}, // Mc [5] MUSICAL SYMBOL COMBINING FLAG-1..MUSICAL SYMBOL COMBINING FLAG-5
+ {0x1D173, 0x1D17A, prControl}, // Cf [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE
+ {0x1D17B, 0x1D182, prExtend}, // Mn [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE
+ {0x1D185, 0x1D18B, prExtend}, // Mn [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE
+ {0x1D1AA, 0x1D1AD, prExtend}, // Mn [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO
+ {0x1D242, 0x1D244, prExtend}, // Mn [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME
+ {0x1DA00, 0x1DA36, prExtend}, // Mn [55] SIGNWRITING HEAD RIM..SIGNWRITING AIR SUCKING IN
+ {0x1DA3B, 0x1DA6C, prExtend}, // Mn [50] SIGNWRITING MOUTH CLOSED NEUTRAL..SIGNWRITING EXCITEMENT
+ {0x1DA75, 0x1DA75, prExtend}, // Mn SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS
+ {0x1DA84, 0x1DA84, prExtend}, // Mn SIGNWRITING LOCATION HEAD NECK
+ {0x1DA9B, 0x1DA9F, prExtend}, // Mn [5] SIGNWRITING FILL MODIFIER-2..SIGNWRITING FILL MODIFIER-6
+ {0x1DAA1, 0x1DAAF, prExtend}, // Mn [15] SIGNWRITING ROTATION MODIFIER-2..SIGNWRITING ROTATION MODIFIER-16
+ {0x1E000, 0x1E006, prExtend}, // Mn [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE
+ {0x1E008, 0x1E018, prExtend}, // Mn [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU
+ {0x1E01B, 0x1E021, prExtend}, // Mn [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI
+ {0x1E023, 0x1E024, prExtend}, // Mn [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS
+ {0x1E026, 0x1E02A, prExtend}, // Mn [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA
+ {0x1E08F, 0x1E08F, prExtend}, // Mn COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+ {0x1E130, 0x1E136, prExtend}, // Mn [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D
+ {0x1E2AE, 0x1E2AE, prExtend}, // Mn TOTO SIGN RISING TONE
+ {0x1E2EC, 0x1E2EF, prExtend}, // Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI
+ {0x1E4EC, 0x1E4EF, prExtend}, // Mn [4] NAG MUNDARI SIGN MUHOR..NAG MUNDARI SIGN SUTUH
+ {0x1E8D0, 0x1E8D6, prExtend}, // Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS
+ {0x1E944, 0x1E94A, prExtend}, // Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA
+ {0x1F000, 0x1F003, prExtendedPictographic}, // E0.0 [4] (🀀..🀃) MAHJONG TILE EAST WIND..MAHJONG TILE NORTH WIND
+ {0x1F004, 0x1F004, prExtendedPictographic}, // E0.6 [1] (🀄) mahjong red dragon
+ {0x1F005, 0x1F0CE, prExtendedPictographic}, // E0.0 [202] (🀅..🃎) MAHJONG TILE GREEN DRAGON..PLAYING CARD KING OF DIAMONDS
+ {0x1F0CF, 0x1F0CF, prExtendedPictographic}, // E0.6 [1] (🃏) joker
+ {0x1F0D0, 0x1F0FF, prExtendedPictographic}, // E0.0 [48] (..) ..
+ {0x1F10D, 0x1F10F, prExtendedPictographic}, // E0.0 [3] (🄍..🄏) CIRCLED ZERO WITH SLASH..CIRCLED DOLLAR SIGN WITH OVERLAID BACKSLASH
+ {0x1F12F, 0x1F12F, prExtendedPictographic}, // E0.0 [1] (🄯) COPYLEFT SYMBOL
+ {0x1F16C, 0x1F16F, prExtendedPictographic}, // E0.0 [4] (🅬..🅯) RAISED MR SIGN..CIRCLED HUMAN FIGURE
+ {0x1F170, 0x1F171, prExtendedPictographic}, // E0.6 [2] (🅰️..🅱️) A button (blood type)..B button (blood type)
+ {0x1F17E, 0x1F17F, prExtendedPictographic}, // E0.6 [2] (🅾️..🅿️) O button (blood type)..P button
+ {0x1F18E, 0x1F18E, prExtendedPictographic}, // E0.6 [1] (🆎) AB button (blood type)
+ {0x1F191, 0x1F19A, prExtendedPictographic}, // E0.6 [10] (🆑..🆚) CL button..VS button
+ {0x1F1AD, 0x1F1E5, prExtendedPictographic}, // E0.0 [57] (🆭..) MASK WORK SYMBOL..
+ {0x1F1E6, 0x1F1FF, prRegionalIndicator}, // So [26] REGIONAL INDICATOR SYMBOL LETTER A..REGIONAL INDICATOR SYMBOL LETTER Z
+ {0x1F201, 0x1F202, prExtendedPictographic}, // E0.6 [2] (🈁..🈂️) Japanese “here” button..Japanese “service charge” button
+ {0x1F203, 0x1F20F, prExtendedPictographic}, // E0.0 [13] (..) ..
+ {0x1F21A, 0x1F21A, prExtendedPictographic}, // E0.6 [1] (🈚) Japanese “free of charge” button
+ {0x1F22F, 0x1F22F, prExtendedPictographic}, // E0.6 [1] (🈯) Japanese “reserved” button
+ {0x1F232, 0x1F23A, prExtendedPictographic}, // E0.6 [9] (🈲..🈺) Japanese “prohibited” button..Japanese “open for business” button
+ {0x1F23C, 0x1F23F, prExtendedPictographic}, // E0.0 [4] (..) ..
+ {0x1F249, 0x1F24F, prExtendedPictographic}, // E0.0 [7] (..) ..
+ {0x1F250, 0x1F251, prExtendedPictographic}, // E0.6 [2] (🉐..🉑) Japanese “bargain” button..Japanese “acceptable” button
+ {0x1F252, 0x1F2FF, prExtendedPictographic}, // E0.0 [174] (..) ..
+ {0x1F300, 0x1F30C, prExtendedPictographic}, // E0.6 [13] (🌀..🌌) cyclone..milky way
+ {0x1F30D, 0x1F30E, prExtendedPictographic}, // E0.7 [2] (🌍..🌎) globe showing Europe-Africa..globe showing Americas
+ {0x1F30F, 0x1F30F, prExtendedPictographic}, // E0.6 [1] (🌏) globe showing Asia-Australia
+ {0x1F310, 0x1F310, prExtendedPictographic}, // E1.0 [1] (🌐) globe with meridians
+ {0x1F311, 0x1F311, prExtendedPictographic}, // E0.6 [1] (🌑) new moon
+ {0x1F312, 0x1F312, prExtendedPictographic}, // E1.0 [1] (🌒) waxing crescent moon
+ {0x1F313, 0x1F315, prExtendedPictographic}, // E0.6 [3] (🌓..🌕) first quarter moon..full moon
+ {0x1F316, 0x1F318, prExtendedPictographic}, // E1.0 [3] (🌖..🌘) waning gibbous moon..waning crescent moon
+ {0x1F319, 0x1F319, prExtendedPictographic}, // E0.6 [1] (🌙) crescent moon
+ {0x1F31A, 0x1F31A, prExtendedPictographic}, // E1.0 [1] (🌚) new moon face
+ {0x1F31B, 0x1F31B, prExtendedPictographic}, // E0.6 [1] (🌛) first quarter moon face
+ {0x1F31C, 0x1F31C, prExtendedPictographic}, // E0.7 [1] (🌜) last quarter moon face
+ {0x1F31D, 0x1F31E, prExtendedPictographic}, // E1.0 [2] (🌝..🌞) full moon face..sun with face
+ {0x1F31F, 0x1F320, prExtendedPictographic}, // E0.6 [2] (🌟..🌠) glowing star..shooting star
+ {0x1F321, 0x1F321, prExtendedPictographic}, // E0.7 [1] (🌡️) thermometer
+ {0x1F322, 0x1F323, prExtendedPictographic}, // E0.0 [2] (🌢..🌣) BLACK DROPLET..WHITE SUN
+ {0x1F324, 0x1F32C, prExtendedPictographic}, // E0.7 [9] (🌤️..🌬️) sun behind small cloud..wind face
+ {0x1F32D, 0x1F32F, prExtendedPictographic}, // E1.0 [3] (🌭..🌯) hot dog..burrito
+ {0x1F330, 0x1F331, prExtendedPictographic}, // E0.6 [2] (🌰..🌱) chestnut..seedling
+ {0x1F332, 0x1F333, prExtendedPictographic}, // E1.0 [2] (🌲..🌳) evergreen tree..deciduous tree
+ {0x1F334, 0x1F335, prExtendedPictographic}, // E0.6 [2] (🌴..🌵) palm tree..cactus
+ {0x1F336, 0x1F336, prExtendedPictographic}, // E0.7 [1] (🌶️) hot pepper
+ {0x1F337, 0x1F34A, prExtendedPictographic}, // E0.6 [20] (🌷..🍊) tulip..tangerine
+ {0x1F34B, 0x1F34B, prExtendedPictographic}, // E1.0 [1] (🍋) lemon
+ {0x1F34C, 0x1F34F, prExtendedPictographic}, // E0.6 [4] (🍌..🍏) banana..green apple
+ {0x1F350, 0x1F350, prExtendedPictographic}, // E1.0 [1] (🍐) pear
+ {0x1F351, 0x1F37B, prExtendedPictographic}, // E0.6 [43] (🍑..🍻) peach..clinking beer mugs
+ {0x1F37C, 0x1F37C, prExtendedPictographic}, // E1.0 [1] (🍼) baby bottle
+ {0x1F37D, 0x1F37D, prExtendedPictographic}, // E0.7 [1] (🍽️) fork and knife with plate
+ {0x1F37E, 0x1F37F, prExtendedPictographic}, // E1.0 [2] (🍾..🍿) bottle with popping cork..popcorn
+ {0x1F380, 0x1F393, prExtendedPictographic}, // E0.6 [20] (🎀..🎓) ribbon..graduation cap
+ {0x1F394, 0x1F395, prExtendedPictographic}, // E0.0 [2] (🎔..🎕) HEART WITH TIP ON THE LEFT..BOUQUET OF FLOWERS
+ {0x1F396, 0x1F397, prExtendedPictographic}, // E0.7 [2] (🎖️..🎗️) military medal..reminder ribbon
+ {0x1F398, 0x1F398, prExtendedPictographic}, // E0.0 [1] (🎘) MUSICAL KEYBOARD WITH JACKS
+ {0x1F399, 0x1F39B, prExtendedPictographic}, // E0.7 [3] (🎙️..🎛️) studio microphone..control knobs
+ {0x1F39C, 0x1F39D, prExtendedPictographic}, // E0.0 [2] (🎜..🎝) BEAMED ASCENDING MUSICAL NOTES..BEAMED DESCENDING MUSICAL NOTES
+ {0x1F39E, 0x1F39F, prExtendedPictographic}, // E0.7 [2] (🎞️..🎟️) film frames..admission tickets
+ {0x1F3A0, 0x1F3C4, prExtendedPictographic}, // E0.6 [37] (🎠..🏄) carousel horse..person surfing
+ {0x1F3C5, 0x1F3C5, prExtendedPictographic}, // E1.0 [1] (🏅) sports medal
+ {0x1F3C6, 0x1F3C6, prExtendedPictographic}, // E0.6 [1] (🏆) trophy
+ {0x1F3C7, 0x1F3C7, prExtendedPictographic}, // E1.0 [1] (🏇) horse racing
+ {0x1F3C8, 0x1F3C8, prExtendedPictographic}, // E0.6 [1] (🏈) american football
+ {0x1F3C9, 0x1F3C9, prExtendedPictographic}, // E1.0 [1] (🏉) rugby football
+ {0x1F3CA, 0x1F3CA, prExtendedPictographic}, // E0.6 [1] (🏊) person swimming
+ {0x1F3CB, 0x1F3CE, prExtendedPictographic}, // E0.7 [4] (🏋️..🏎️) person lifting weights..racing car
+ {0x1F3CF, 0x1F3D3, prExtendedPictographic}, // E1.0 [5] (🏏..🏓) cricket game..ping pong
+ {0x1F3D4, 0x1F3DF, prExtendedPictographic}, // E0.7 [12] (🏔️..🏟️) snow-capped mountain..stadium
+ {0x1F3E0, 0x1F3E3, prExtendedPictographic}, // E0.6 [4] (🏠..🏣) house..Japanese post office
+ {0x1F3E4, 0x1F3E4, prExtendedPictographic}, // E1.0 [1] (🏤) post office
+ {0x1F3E5, 0x1F3F0, prExtendedPictographic}, // E0.6 [12] (🏥..🏰) hospital..castle
+ {0x1F3F1, 0x1F3F2, prExtendedPictographic}, // E0.0 [2] (🏱..🏲) WHITE PENNANT..BLACK PENNANT
+ {0x1F3F3, 0x1F3F3, prExtendedPictographic}, // E0.7 [1] (🏳️) white flag
+ {0x1F3F4, 0x1F3F4, prExtendedPictographic}, // E1.0 [1] (🏴) black flag
+ {0x1F3F5, 0x1F3F5, prExtendedPictographic}, // E0.7 [1] (🏵️) rosette
+ {0x1F3F6, 0x1F3F6, prExtendedPictographic}, // E0.0 [1] (🏶) BLACK ROSETTE
+ {0x1F3F7, 0x1F3F7, prExtendedPictographic}, // E0.7 [1] (🏷️) label
+ {0x1F3F8, 0x1F3FA, prExtendedPictographic}, // E1.0 [3] (🏸..🏺) badminton..amphora
+ {0x1F3FB, 0x1F3FF, prExtend}, // Sk [5] EMOJI MODIFIER FITZPATRICK TYPE-1-2..EMOJI MODIFIER FITZPATRICK TYPE-6
+ {0x1F400, 0x1F407, prExtendedPictographic}, // E1.0 [8] (🐀..🐇) rat..rabbit
+ {0x1F408, 0x1F408, prExtendedPictographic}, // E0.7 [1] (🐈) cat
+ {0x1F409, 0x1F40B, prExtendedPictographic}, // E1.0 [3] (🐉..🐋) dragon..whale
+ {0x1F40C, 0x1F40E, prExtendedPictographic}, // E0.6 [3] (🐌..🐎) snail..horse
+ {0x1F40F, 0x1F410, prExtendedPictographic}, // E1.0 [2] (🐏..🐐) ram..goat
+ {0x1F411, 0x1F412, prExtendedPictographic}, // E0.6 [2] (🐑..🐒) ewe..monkey
+ {0x1F413, 0x1F413, prExtendedPictographic}, // E1.0 [1] (🐓) rooster
+ {0x1F414, 0x1F414, prExtendedPictographic}, // E0.6 [1] (🐔) chicken
+ {0x1F415, 0x1F415, prExtendedPictographic}, // E0.7 [1] (🐕) dog
+ {0x1F416, 0x1F416, prExtendedPictographic}, // E1.0 [1] (🐖) pig
+ {0x1F417, 0x1F429, prExtendedPictographic}, // E0.6 [19] (🐗..🐩) boar..poodle
+ {0x1F42A, 0x1F42A, prExtendedPictographic}, // E1.0 [1] (🐪) camel
+ {0x1F42B, 0x1F43E, prExtendedPictographic}, // E0.6 [20] (🐫..🐾) two-hump camel..paw prints
+ {0x1F43F, 0x1F43F, prExtendedPictographic}, // E0.7 [1] (🐿️) chipmunk
+ {0x1F440, 0x1F440, prExtendedPictographic}, // E0.6 [1] (👀) eyes
+ {0x1F441, 0x1F441, prExtendedPictographic}, // E0.7 [1] (👁️) eye
+ {0x1F442, 0x1F464, prExtendedPictographic}, // E0.6 [35] (👂..👤) ear..bust in silhouette
+ {0x1F465, 0x1F465, prExtendedPictographic}, // E1.0 [1] (👥) busts in silhouette
+ {0x1F466, 0x1F46B, prExtendedPictographic}, // E0.6 [6] (👦..👫) boy..woman and man holding hands
+ {0x1F46C, 0x1F46D, prExtendedPictographic}, // E1.0 [2] (👬..👭) men holding hands..women holding hands
+ {0x1F46E, 0x1F4AC, prExtendedPictographic}, // E0.6 [63] (👮..💬) police officer..speech balloon
+ {0x1F4AD, 0x1F4AD, prExtendedPictographic}, // E1.0 [1] (💭) thought balloon
+ {0x1F4AE, 0x1F4B5, prExtendedPictographic}, // E0.6 [8] (💮..💵) white flower..dollar banknote
+ {0x1F4B6, 0x1F4B7, prExtendedPictographic}, // E1.0 [2] (💶..💷) euro banknote..pound banknote
+ {0x1F4B8, 0x1F4EB, prExtendedPictographic}, // E0.6 [52] (💸..📫) money with wings..closed mailbox with raised flag
+ {0x1F4EC, 0x1F4ED, prExtendedPictographic}, // E0.7 [2] (📬..📭) open mailbox with raised flag..open mailbox with lowered flag
+ {0x1F4EE, 0x1F4EE, prExtendedPictographic}, // E0.6 [1] (📮) postbox
+ {0x1F4EF, 0x1F4EF, prExtendedPictographic}, // E1.0 [1] (📯) postal horn
+ {0x1F4F0, 0x1F4F4, prExtendedPictographic}, // E0.6 [5] (📰..📴) newspaper..mobile phone off
+ {0x1F4F5, 0x1F4F5, prExtendedPictographic}, // E1.0 [1] (📵) no mobile phones
+ {0x1F4F6, 0x1F4F7, prExtendedPictographic}, // E0.6 [2] (📶..📷) antenna bars..camera
+ {0x1F4F8, 0x1F4F8, prExtendedPictographic}, // E1.0 [1] (📸) camera with flash
+ {0x1F4F9, 0x1F4FC, prExtendedPictographic}, // E0.6 [4] (📹..📼) video camera..videocassette
+ {0x1F4FD, 0x1F4FD, prExtendedPictographic}, // E0.7 [1] (📽️) film projector
+ {0x1F4FE, 0x1F4FE, prExtendedPictographic}, // E0.0 [1] (📾) PORTABLE STEREO
+ {0x1F4FF, 0x1F502, prExtendedPictographic}, // E1.0 [4] (📿..🔂) prayer beads..repeat single button
+ {0x1F503, 0x1F503, prExtendedPictographic}, // E0.6 [1] (🔃) clockwise vertical arrows
+ {0x1F504, 0x1F507, prExtendedPictographic}, // E1.0 [4] (🔄..🔇) counterclockwise arrows button..muted speaker
+ {0x1F508, 0x1F508, prExtendedPictographic}, // E0.7 [1] (🔈) speaker low volume
+ {0x1F509, 0x1F509, prExtendedPictographic}, // E1.0 [1] (🔉) speaker medium volume
+ {0x1F50A, 0x1F514, prExtendedPictographic}, // E0.6 [11] (🔊..🔔) speaker high volume..bell
+ {0x1F515, 0x1F515, prExtendedPictographic}, // E1.0 [1] (🔕) bell with slash
+ {0x1F516, 0x1F52B, prExtendedPictographic}, // E0.6 [22] (🔖..🔫) bookmark..water pistol
+ {0x1F52C, 0x1F52D, prExtendedPictographic}, // E1.0 [2] (🔬..🔭) microscope..telescope
+ {0x1F52E, 0x1F53D, prExtendedPictographic}, // E0.6 [16] (🔮..🔽) crystal ball..downwards button
+ {0x1F546, 0x1F548, prExtendedPictographic}, // E0.0 [3] (🕆..🕈) WHITE LATIN CROSS..CELTIC CROSS
+ {0x1F549, 0x1F54A, prExtendedPictographic}, // E0.7 [2] (🕉️..🕊️) om..dove
+ {0x1F54B, 0x1F54E, prExtendedPictographic}, // E1.0 [4] (🕋..🕎) kaaba..menorah
+ {0x1F54F, 0x1F54F, prExtendedPictographic}, // E0.0 [1] (🕏) BOWL OF HYGIEIA
+ {0x1F550, 0x1F55B, prExtendedPictographic}, // E0.6 [12] (🕐..🕛) one o’clock..twelve o’clock
+ {0x1F55C, 0x1F567, prExtendedPictographic}, // E0.7 [12] (🕜..🕧) one-thirty..twelve-thirty
+ {0x1F568, 0x1F56E, prExtendedPictographic}, // E0.0 [7] (🕨..🕮) RIGHT SPEAKER..BOOK
+ {0x1F56F, 0x1F570, prExtendedPictographic}, // E0.7 [2] (🕯️..🕰️) candle..mantelpiece clock
+ {0x1F571, 0x1F572, prExtendedPictographic}, // E0.0 [2] (🕱..🕲) BLACK SKULL AND CROSSBONES..NO PIRACY
+ {0x1F573, 0x1F579, prExtendedPictographic}, // E0.7 [7] (🕳️..🕹️) hole..joystick
+ {0x1F57A, 0x1F57A, prExtendedPictographic}, // E3.0 [1] (🕺) man dancing
+ {0x1F57B, 0x1F586, prExtendedPictographic}, // E0.0 [12] (🕻..🖆) LEFT HAND TELEPHONE RECEIVER..PEN OVER STAMPED ENVELOPE
+ {0x1F587, 0x1F587, prExtendedPictographic}, // E0.7 [1] (🖇️) linked paperclips
+ {0x1F588, 0x1F589, prExtendedPictographic}, // E0.0 [2] (🖈..🖉) BLACK PUSHPIN..LOWER LEFT PENCIL
+ {0x1F58A, 0x1F58D, prExtendedPictographic}, // E0.7 [4] (🖊️..🖍️) pen..crayon
+ {0x1F58E, 0x1F58F, prExtendedPictographic}, // E0.0 [2] (🖎..🖏) LEFT WRITING HAND..TURNED OK HAND SIGN
+ {0x1F590, 0x1F590, prExtendedPictographic}, // E0.7 [1] (🖐️) hand with fingers splayed
+ {0x1F591, 0x1F594, prExtendedPictographic}, // E0.0 [4] (🖑..🖔) REVERSED RAISED HAND WITH FINGERS SPLAYED..REVERSED VICTORY HAND
+ {0x1F595, 0x1F596, prExtendedPictographic}, // E1.0 [2] (🖕..🖖) middle finger..vulcan salute
+ {0x1F597, 0x1F5A3, prExtendedPictographic}, // E0.0 [13] (🖗..🖣) WHITE DOWN POINTING LEFT HAND INDEX..BLACK DOWN POINTING BACKHAND INDEX
+ {0x1F5A4, 0x1F5A4, prExtendedPictographic}, // E3.0 [1] (🖤) black heart
+ {0x1F5A5, 0x1F5A5, prExtendedPictographic}, // E0.7 [1] (🖥️) desktop computer
+ {0x1F5A6, 0x1F5A7, prExtendedPictographic}, // E0.0 [2] (🖦..🖧) KEYBOARD AND MOUSE..THREE NETWORKED COMPUTERS
+ {0x1F5A8, 0x1F5A8, prExtendedPictographic}, // E0.7 [1] (🖨️) printer
+ {0x1F5A9, 0x1F5B0, prExtendedPictographic}, // E0.0 [8] (🖩..🖰) POCKET CALCULATOR..TWO BUTTON MOUSE
+ {0x1F5B1, 0x1F5B2, prExtendedPictographic}, // E0.7 [2] (🖱️..🖲️) computer mouse..trackball
+ {0x1F5B3, 0x1F5BB, prExtendedPictographic}, // E0.0 [9] (🖳..🖻) OLD PERSONAL COMPUTER..DOCUMENT WITH PICTURE
+ {0x1F5BC, 0x1F5BC, prExtendedPictographic}, // E0.7 [1] (🖼️) framed picture
+ {0x1F5BD, 0x1F5C1, prExtendedPictographic}, // E0.0 [5] (🖽..🗁) FRAME WITH TILES..OPEN FOLDER
+ {0x1F5C2, 0x1F5C4, prExtendedPictographic}, // E0.7 [3] (🗂️..🗄️) card index dividers..file cabinet
+ {0x1F5C5, 0x1F5D0, prExtendedPictographic}, // E0.0 [12] (🗅..🗐) EMPTY NOTE..PAGES
+ {0x1F5D1, 0x1F5D3, prExtendedPictographic}, // E0.7 [3] (🗑️..🗓️) wastebasket..spiral calendar
+ {0x1F5D4, 0x1F5DB, prExtendedPictographic}, // E0.0 [8] (🗔..🗛) DESKTOP WINDOW..DECREASE FONT SIZE SYMBOL
+ {0x1F5DC, 0x1F5DE, prExtendedPictographic}, // E0.7 [3] (🗜️..🗞️) clamp..rolled-up newspaper
+ {0x1F5DF, 0x1F5E0, prExtendedPictographic}, // E0.0 [2] (🗟..🗠) PAGE WITH CIRCLED TEXT..STOCK CHART
+ {0x1F5E1, 0x1F5E1, prExtendedPictographic}, // E0.7 [1] (🗡️) dagger
+ {0x1F5E2, 0x1F5E2, prExtendedPictographic}, // E0.0 [1] (🗢) LIPS
+ {0x1F5E3, 0x1F5E3, prExtendedPictographic}, // E0.7 [1] (🗣️) speaking head
+ {0x1F5E4, 0x1F5E7, prExtendedPictographic}, // E0.0 [4] (🗤..🗧) THREE RAYS ABOVE..THREE RAYS RIGHT
+ {0x1F5E8, 0x1F5E8, prExtendedPictographic}, // E2.0 [1] (🗨️) left speech bubble
+ {0x1F5E9, 0x1F5EE, prExtendedPictographic}, // E0.0 [6] (🗩..🗮) RIGHT SPEECH BUBBLE..LEFT ANGER BUBBLE
+ {0x1F5EF, 0x1F5EF, prExtendedPictographic}, // E0.7 [1] (🗯️) right anger bubble
+ {0x1F5F0, 0x1F5F2, prExtendedPictographic}, // E0.0 [3] (🗰..🗲) MOOD BUBBLE..LIGHTNING MOOD
+ {0x1F5F3, 0x1F5F3, prExtendedPictographic}, // E0.7 [1] (🗳️) ballot box with ballot
+ {0x1F5F4, 0x1F5F9, prExtendedPictographic}, // E0.0 [6] (🗴..🗹) BALLOT SCRIPT X..BALLOT BOX WITH BOLD CHECK
+ {0x1F5FA, 0x1F5FA, prExtendedPictographic}, // E0.7 [1] (🗺️) world map
+ {0x1F5FB, 0x1F5FF, prExtendedPictographic}, // E0.6 [5] (🗻..🗿) mount fuji..moai
+ {0x1F600, 0x1F600, prExtendedPictographic}, // E1.0 [1] (😀) grinning face
+ {0x1F601, 0x1F606, prExtendedPictographic}, // E0.6 [6] (😁..😆) beaming face with smiling eyes..grinning squinting face
+ {0x1F607, 0x1F608, prExtendedPictographic}, // E1.0 [2] (😇..😈) smiling face with halo..smiling face with horns
+ {0x1F609, 0x1F60D, prExtendedPictographic}, // E0.6 [5] (😉..😍) winking face..smiling face with heart-eyes
+ {0x1F60E, 0x1F60E, prExtendedPictographic}, // E1.0 [1] (😎) smiling face with sunglasses
+ {0x1F60F, 0x1F60F, prExtendedPictographic}, // E0.6 [1] (😏) smirking face
+ {0x1F610, 0x1F610, prExtendedPictographic}, // E0.7 [1] (😐) neutral face
+ {0x1F611, 0x1F611, prExtendedPictographic}, // E1.0 [1] (😑) expressionless face
+ {0x1F612, 0x1F614, prExtendedPictographic}, // E0.6 [3] (😒..😔) unamused face..pensive face
+ {0x1F615, 0x1F615, prExtendedPictographic}, // E1.0 [1] (😕) confused face
+ {0x1F616, 0x1F616, prExtendedPictographic}, // E0.6 [1] (😖) confounded face
+ {0x1F617, 0x1F617, prExtendedPictographic}, // E1.0 [1] (😗) kissing face
+ {0x1F618, 0x1F618, prExtendedPictographic}, // E0.6 [1] (😘) face blowing a kiss
+ {0x1F619, 0x1F619, prExtendedPictographic}, // E1.0 [1] (😙) kissing face with smiling eyes
+ {0x1F61A, 0x1F61A, prExtendedPictographic}, // E0.6 [1] (😚) kissing face with closed eyes
+ {0x1F61B, 0x1F61B, prExtendedPictographic}, // E1.0 [1] (😛) face with tongue
+ {0x1F61C, 0x1F61E, prExtendedPictographic}, // E0.6 [3] (😜..😞) winking face with tongue..disappointed face
+ {0x1F61F, 0x1F61F, prExtendedPictographic}, // E1.0 [1] (😟) worried face
+ {0x1F620, 0x1F625, prExtendedPictographic}, // E0.6 [6] (😠..😥) angry face..sad but relieved face
+ {0x1F626, 0x1F627, prExtendedPictographic}, // E1.0 [2] (😦..😧) frowning face with open mouth..anguished face
+ {0x1F628, 0x1F62B, prExtendedPictographic}, // E0.6 [4] (😨..😫) fearful face..tired face
+ {0x1F62C, 0x1F62C, prExtendedPictographic}, // E1.0 [1] (😬) grimacing face
+ {0x1F62D, 0x1F62D, prExtendedPictographic}, // E0.6 [1] (😭) loudly crying face
+ {0x1F62E, 0x1F62F, prExtendedPictographic}, // E1.0 [2] (😮..😯) face with open mouth..hushed face
+ {0x1F630, 0x1F633, prExtendedPictographic}, // E0.6 [4] (😰..😳) anxious face with sweat..flushed face
+ {0x1F634, 0x1F634, prExtendedPictographic}, // E1.0 [1] (😴) sleeping face
+ {0x1F635, 0x1F635, prExtendedPictographic}, // E0.6 [1] (😵) face with crossed-out eyes
+ {0x1F636, 0x1F636, prExtendedPictographic}, // E1.0 [1] (😶) face without mouth
+ {0x1F637, 0x1F640, prExtendedPictographic}, // E0.6 [10] (😷..🙀) face with medical mask..weary cat
+ {0x1F641, 0x1F644, prExtendedPictographic}, // E1.0 [4] (🙁..🙄) slightly frowning face..face with rolling eyes
+ {0x1F645, 0x1F64F, prExtendedPictographic}, // E0.6 [11] (🙅..🙏) person gesturing NO..folded hands
+ {0x1F680, 0x1F680, prExtendedPictographic}, // E0.6 [1] (🚀) rocket
+ {0x1F681, 0x1F682, prExtendedPictographic}, // E1.0 [2] (🚁..🚂) helicopter..locomotive
+ {0x1F683, 0x1F685, prExtendedPictographic}, // E0.6 [3] (🚃..🚅) railway car..bullet train
+ {0x1F686, 0x1F686, prExtendedPictographic}, // E1.0 [1] (🚆) train
+ {0x1F687, 0x1F687, prExtendedPictographic}, // E0.6 [1] (🚇) metro
+ {0x1F688, 0x1F688, prExtendedPictographic}, // E1.0 [1] (🚈) light rail
+ {0x1F689, 0x1F689, prExtendedPictographic}, // E0.6 [1] (🚉) station
+ {0x1F68A, 0x1F68B, prExtendedPictographic}, // E1.0 [2] (🚊..🚋) tram..tram car
+ {0x1F68C, 0x1F68C, prExtendedPictographic}, // E0.6 [1] (🚌) bus
+ {0x1F68D, 0x1F68D, prExtendedPictographic}, // E0.7 [1] (🚍) oncoming bus
+ {0x1F68E, 0x1F68E, prExtendedPictographic}, // E1.0 [1] (🚎) trolleybus
+ {0x1F68F, 0x1F68F, prExtendedPictographic}, // E0.6 [1] (🚏) bus stop
+ {0x1F690, 0x1F690, prExtendedPictographic}, // E1.0 [1] (🚐) minibus
+ {0x1F691, 0x1F693, prExtendedPictographic}, // E0.6 [3] (🚑..🚓) ambulance..police car
+ {0x1F694, 0x1F694, prExtendedPictographic}, // E0.7 [1] (🚔) oncoming police car
+ {0x1F695, 0x1F695, prExtendedPictographic}, // E0.6 [1] (🚕) taxi
+ {0x1F696, 0x1F696, prExtendedPictographic}, // E1.0 [1] (🚖) oncoming taxi
+ {0x1F697, 0x1F697, prExtendedPictographic}, // E0.6 [1] (🚗) automobile
+ {0x1F698, 0x1F698, prExtendedPictographic}, // E0.7 [1] (🚘) oncoming automobile
+ {0x1F699, 0x1F69A, prExtendedPictographic}, // E0.6 [2] (🚙..🚚) sport utility vehicle..delivery truck
+ {0x1F69B, 0x1F6A1, prExtendedPictographic}, // E1.0 [7] (🚛..🚡) articulated lorry..aerial tramway
+ {0x1F6A2, 0x1F6A2, prExtendedPictographic}, // E0.6 [1] (🚢) ship
+ {0x1F6A3, 0x1F6A3, prExtendedPictographic}, // E1.0 [1] (🚣) person rowing boat
+ {0x1F6A4, 0x1F6A5, prExtendedPictographic}, // E0.6 [2] (🚤..🚥) speedboat..horizontal traffic light
+ {0x1F6A6, 0x1F6A6, prExtendedPictographic}, // E1.0 [1] (🚦) vertical traffic light
+ {0x1F6A7, 0x1F6AD, prExtendedPictographic}, // E0.6 [7] (🚧..🚭) construction..no smoking
+ {0x1F6AE, 0x1F6B1, prExtendedPictographic}, // E1.0 [4] (🚮..🚱) litter in bin sign..non-potable water
+ {0x1F6B2, 0x1F6B2, prExtendedPictographic}, // E0.6 [1] (🚲) bicycle
+ {0x1F6B3, 0x1F6B5, prExtendedPictographic}, // E1.0 [3] (🚳..🚵) no bicycles..person mountain biking
+ {0x1F6B6, 0x1F6B6, prExtendedPictographic}, // E0.6 [1] (🚶) person walking
+ {0x1F6B7, 0x1F6B8, prExtendedPictographic}, // E1.0 [2] (🚷..🚸) no pedestrians..children crossing
+ {0x1F6B9, 0x1F6BE, prExtendedPictographic}, // E0.6 [6] (🚹..🚾) men’s room..water closet
+ {0x1F6BF, 0x1F6BF, prExtendedPictographic}, // E1.0 [1] (🚿) shower
+ {0x1F6C0, 0x1F6C0, prExtendedPictographic}, // E0.6 [1] (🛀) person taking bath
+ {0x1F6C1, 0x1F6C5, prExtendedPictographic}, // E1.0 [5] (🛁..🛅) bathtub..left luggage
+ {0x1F6C6, 0x1F6CA, prExtendedPictographic}, // E0.0 [5] (🛆..🛊) TRIANGLE WITH ROUNDED CORNERS..GIRLS SYMBOL
+ {0x1F6CB, 0x1F6CB, prExtendedPictographic}, // E0.7 [1] (🛋️) couch and lamp
+ {0x1F6CC, 0x1F6CC, prExtendedPictographic}, // E1.0 [1] (🛌) person in bed
+ {0x1F6CD, 0x1F6CF, prExtendedPictographic}, // E0.7 [3] (🛍️..🛏️) shopping bags..bed
+ {0x1F6D0, 0x1F6D0, prExtendedPictographic}, // E1.0 [1] (🛐) place of worship
+ {0x1F6D1, 0x1F6D2, prExtendedPictographic}, // E3.0 [2] (🛑..🛒) stop sign..shopping cart
+ {0x1F6D3, 0x1F6D4, prExtendedPictographic}, // E0.0 [2] (🛓..🛔) STUPA..PAGODA
+ {0x1F6D5, 0x1F6D5, prExtendedPictographic}, // E12.0 [1] (🛕) hindu temple
+ {0x1F6D6, 0x1F6D7, prExtendedPictographic}, // E13.0 [2] (🛖..🛗) hut..elevator
+ {0x1F6D8, 0x1F6DB, prExtendedPictographic}, // E0.0 [4] (..) ..
+ {0x1F6DC, 0x1F6DC, prExtendedPictographic}, // E15.0 [1] (🛜) wireless
+ {0x1F6DD, 0x1F6DF, prExtendedPictographic}, // E14.0 [3] (🛝..🛟) playground slide..ring buoy
+ {0x1F6E0, 0x1F6E5, prExtendedPictographic}, // E0.7 [6] (🛠️..🛥️) hammer and wrench..motor boat
+ {0x1F6E6, 0x1F6E8, prExtendedPictographic}, // E0.0 [3] (🛦..🛨) UP-POINTING MILITARY AIRPLANE..UP-POINTING SMALL AIRPLANE
+ {0x1F6E9, 0x1F6E9, prExtendedPictographic}, // E0.7 [1] (🛩️) small airplane
+ {0x1F6EA, 0x1F6EA, prExtendedPictographic}, // E0.0 [1] (🛪) NORTHEAST-POINTING AIRPLANE
+ {0x1F6EB, 0x1F6EC, prExtendedPictographic}, // E1.0 [2] (🛫..🛬) airplane departure..airplane arrival
+ {0x1F6ED, 0x1F6EF, prExtendedPictographic}, // E0.0 [3] (..) ..
+ {0x1F6F0, 0x1F6F0, prExtendedPictographic}, // E0.7 [1] (🛰️) satellite
+ {0x1F6F1, 0x1F6F2, prExtendedPictographic}, // E0.0 [2] (🛱..🛲) ONCOMING FIRE ENGINE..DIESEL LOCOMOTIVE
+ {0x1F6F3, 0x1F6F3, prExtendedPictographic}, // E0.7 [1] (🛳️) passenger ship
+ {0x1F6F4, 0x1F6F6, prExtendedPictographic}, // E3.0 [3] (🛴..🛶) kick scooter..canoe
+ {0x1F6F7, 0x1F6F8, prExtendedPictographic}, // E5.0 [2] (🛷..🛸) sled..flying saucer
+ {0x1F6F9, 0x1F6F9, prExtendedPictographic}, // E11.0 [1] (🛹) skateboard
+ {0x1F6FA, 0x1F6FA, prExtendedPictographic}, // E12.0 [1] (🛺) auto rickshaw
+ {0x1F6FB, 0x1F6FC, prExtendedPictographic}, // E13.0 [2] (🛻..🛼) pickup truck..roller skate
+ {0x1F6FD, 0x1F6FF, prExtendedPictographic}, // E0.0 [3] (..) ..
+ {0x1F774, 0x1F77F, prExtendedPictographic}, // E0.0 [12] (🝴..🝿) LOT OF FORTUNE..ORCUS
+ {0x1F7D5, 0x1F7DF, prExtendedPictographic}, // E0.0 [11] (🟕..) CIRCLED TRIANGLE..
+ {0x1F7E0, 0x1F7EB, prExtendedPictographic}, // E12.0 [12] (🟠..🟫) orange circle..brown square
+ {0x1F7EC, 0x1F7EF, prExtendedPictographic}, // E0.0 [4] (..) ..
+ {0x1F7F0, 0x1F7F0, prExtendedPictographic}, // E14.0 [1] (🟰) heavy equals sign
+ {0x1F7F1, 0x1F7FF, prExtendedPictographic}, // E0.0 [15] (..) ..
+ {0x1F80C, 0x1F80F, prExtendedPictographic}, // E0.0 [4] (..) ..
+ {0x1F848, 0x1F84F, prExtendedPictographic}, // E0.0 [8] (..) ..
+ {0x1F85A, 0x1F85F, prExtendedPictographic}, // E0.0 [6] (..) ..
+ {0x1F888, 0x1F88F, prExtendedPictographic}, // E0.0 [8] (..) ..
+ {0x1F8AE, 0x1F8FF, prExtendedPictographic}, // E0.0 [82] (..) ..
+ {0x1F90C, 0x1F90C, prExtendedPictographic}, // E13.0 [1] (🤌) pinched fingers
+ {0x1F90D, 0x1F90F, prExtendedPictographic}, // E12.0 [3] (🤍..🤏) white heart..pinching hand
+ {0x1F910, 0x1F918, prExtendedPictographic}, // E1.0 [9] (🤐..🤘) zipper-mouth face..sign of the horns
+ {0x1F919, 0x1F91E, prExtendedPictographic}, // E3.0 [6] (🤙..🤞) call me hand..crossed fingers
+ {0x1F91F, 0x1F91F, prExtendedPictographic}, // E5.0 [1] (🤟) love-you gesture
+ {0x1F920, 0x1F927, prExtendedPictographic}, // E3.0 [8] (🤠..🤧) cowboy hat face..sneezing face
+ {0x1F928, 0x1F92F, prExtendedPictographic}, // E5.0 [8] (🤨..🤯) face with raised eyebrow..exploding head
+ {0x1F930, 0x1F930, prExtendedPictographic}, // E3.0 [1] (🤰) pregnant woman
+ {0x1F931, 0x1F932, prExtendedPictographic}, // E5.0 [2] (🤱..🤲) breast-feeding..palms up together
+ {0x1F933, 0x1F93A, prExtendedPictographic}, // E3.0 [8] (🤳..🤺) selfie..person fencing
+ {0x1F93C, 0x1F93E, prExtendedPictographic}, // E3.0 [3] (🤼..🤾) people wrestling..person playing handball
+ {0x1F93F, 0x1F93F, prExtendedPictographic}, // E12.0 [1] (🤿) diving mask
+ {0x1F940, 0x1F945, prExtendedPictographic}, // E3.0 [6] (🥀..🥅) wilted flower..goal net
+ {0x1F947, 0x1F94B, prExtendedPictographic}, // E3.0 [5] (🥇..🥋) 1st place medal..martial arts uniform
+ {0x1F94C, 0x1F94C, prExtendedPictographic}, // E5.0 [1] (🥌) curling stone
+ {0x1F94D, 0x1F94F, prExtendedPictographic}, // E11.0 [3] (🥍..🥏) lacrosse..flying disc
+ {0x1F950, 0x1F95E, prExtendedPictographic}, // E3.0 [15] (🥐..🥞) croissant..pancakes
+ {0x1F95F, 0x1F96B, prExtendedPictographic}, // E5.0 [13] (🥟..🥫) dumpling..canned food
+ {0x1F96C, 0x1F970, prExtendedPictographic}, // E11.0 [5] (🥬..🥰) leafy green..smiling face with hearts
+ {0x1F971, 0x1F971, prExtendedPictographic}, // E12.0 [1] (🥱) yawning face
+ {0x1F972, 0x1F972, prExtendedPictographic}, // E13.0 [1] (🥲) smiling face with tear
+ {0x1F973, 0x1F976, prExtendedPictographic}, // E11.0 [4] (🥳..🥶) partying face..cold face
+ {0x1F977, 0x1F978, prExtendedPictographic}, // E13.0 [2] (🥷..🥸) ninja..disguised face
+ {0x1F979, 0x1F979, prExtendedPictographic}, // E14.0 [1] (🥹) face holding back tears
+ {0x1F97A, 0x1F97A, prExtendedPictographic}, // E11.0 [1] (🥺) pleading face
+ {0x1F97B, 0x1F97B, prExtendedPictographic}, // E12.0 [1] (🥻) sari
+ {0x1F97C, 0x1F97F, prExtendedPictographic}, // E11.0 [4] (🥼..🥿) lab coat..flat shoe
+ {0x1F980, 0x1F984, prExtendedPictographic}, // E1.0 [5] (🦀..🦄) crab..unicorn
+ {0x1F985, 0x1F991, prExtendedPictographic}, // E3.0 [13] (🦅..🦑) eagle..squid
+ {0x1F992, 0x1F997, prExtendedPictographic}, // E5.0 [6] (🦒..🦗) giraffe..cricket
+ {0x1F998, 0x1F9A2, prExtendedPictographic}, // E11.0 [11] (🦘..🦢) kangaroo..swan
+ {0x1F9A3, 0x1F9A4, prExtendedPictographic}, // E13.0 [2] (🦣..🦤) mammoth..dodo
+ {0x1F9A5, 0x1F9AA, prExtendedPictographic}, // E12.0 [6] (🦥..🦪) sloth..oyster
+ {0x1F9AB, 0x1F9AD, prExtendedPictographic}, // E13.0 [3] (🦫..🦭) beaver..seal
+ {0x1F9AE, 0x1F9AF, prExtendedPictographic}, // E12.0 [2] (🦮..🦯) guide dog..white cane
+ {0x1F9B0, 0x1F9B9, prExtendedPictographic}, // E11.0 [10] (🦰..🦹) red hair..supervillain
+ {0x1F9BA, 0x1F9BF, prExtendedPictographic}, // E12.0 [6] (🦺..🦿) safety vest..mechanical leg
+ {0x1F9C0, 0x1F9C0, prExtendedPictographic}, // E1.0 [1] (🧀) cheese wedge
+ {0x1F9C1, 0x1F9C2, prExtendedPictographic}, // E11.0 [2] (🧁..🧂) cupcake..salt
+ {0x1F9C3, 0x1F9CA, prExtendedPictographic}, // E12.0 [8] (🧃..🧊) beverage box..ice
+ {0x1F9CB, 0x1F9CB, prExtendedPictographic}, // E13.0 [1] (🧋) bubble tea
+ {0x1F9CC, 0x1F9CC, prExtendedPictographic}, // E14.0 [1] (🧌) troll
+ {0x1F9CD, 0x1F9CF, prExtendedPictographic}, // E12.0 [3] (🧍..🧏) person standing..deaf person
+ {0x1F9D0, 0x1F9E6, prExtendedPictographic}, // E5.0 [23] (🧐..🧦) face with monocle..socks
+ {0x1F9E7, 0x1F9FF, prExtendedPictographic}, // E11.0 [25] (🧧..🧿) red envelope..nazar amulet
+ {0x1FA00, 0x1FA6F, prExtendedPictographic}, // E0.0 [112] (🨀..) NEUTRAL CHESS KING..
+ {0x1FA70, 0x1FA73, prExtendedPictographic}, // E12.0 [4] (🩰..🩳) ballet shoes..shorts
+ {0x1FA74, 0x1FA74, prExtendedPictographic}, // E13.0 [1] (🩴) thong sandal
+ {0x1FA75, 0x1FA77, prExtendedPictographic}, // E15.0 [3] (🩵..🩷) light blue heart..pink heart
+ {0x1FA78, 0x1FA7A, prExtendedPictographic}, // E12.0 [3] (🩸..🩺) drop of blood..stethoscope
+ {0x1FA7B, 0x1FA7C, prExtendedPictographic}, // E14.0 [2] (🩻..🩼) x-ray..crutch
+ {0x1FA7D, 0x1FA7F, prExtendedPictographic}, // E0.0 [3] (..) ..
+ {0x1FA80, 0x1FA82, prExtendedPictographic}, // E12.0 [3] (🪀..🪂) yo-yo..parachute
+ {0x1FA83, 0x1FA86, prExtendedPictographic}, // E13.0 [4] (🪃..🪆) boomerang..nesting dolls
+ {0x1FA87, 0x1FA88, prExtendedPictographic}, // E15.0 [2] (🪇..🪈) maracas..flute
+ {0x1FA89, 0x1FA8F, prExtendedPictographic}, // E0.0 [7] (..) ..
+ {0x1FA90, 0x1FA95, prExtendedPictographic}, // E12.0 [6] (🪐..🪕) ringed planet..banjo
+ {0x1FA96, 0x1FAA8, prExtendedPictographic}, // E13.0 [19] (🪖..🪨) military helmet..rock
+ {0x1FAA9, 0x1FAAC, prExtendedPictographic}, // E14.0 [4] (🪩..🪬) mirror ball..hamsa
+ {0x1FAAD, 0x1FAAF, prExtendedPictographic}, // E15.0 [3] (🪭..🪯) folding hand fan..khanda
+ {0x1FAB0, 0x1FAB6, prExtendedPictographic}, // E13.0 [7] (🪰..🪶) fly..feather
+ {0x1FAB7, 0x1FABA, prExtendedPictographic}, // E14.0 [4] (🪷..🪺) lotus..nest with eggs
+ {0x1FABB, 0x1FABD, prExtendedPictographic}, // E15.0 [3] (🪻..🪽) hyacinth..wing
+ {0x1FABE, 0x1FABE, prExtendedPictographic}, // E0.0 [1] ()
+ {0x1FABF, 0x1FABF, prExtendedPictographic}, // E15.0 [1] (🪿) goose
+ {0x1FAC0, 0x1FAC2, prExtendedPictographic}, // E13.0 [3] (🫀..🫂) anatomical heart..people hugging
+ {0x1FAC3, 0x1FAC5, prExtendedPictographic}, // E14.0 [3] (🫃..🫅) pregnant man..person with crown
+ {0x1FAC6, 0x1FACD, prExtendedPictographic}, // E0.0 [8] (..) ..
+ {0x1FACE, 0x1FACF, prExtendedPictographic}, // E15.0 [2] (🫎..🫏) moose..donkey
+ {0x1FAD0, 0x1FAD6, prExtendedPictographic}, // E13.0 [7] (🫐..🫖) blueberries..teapot
+ {0x1FAD7, 0x1FAD9, prExtendedPictographic}, // E14.0 [3] (🫗..🫙) pouring liquid..jar
+ {0x1FADA, 0x1FADB, prExtendedPictographic}, // E15.0 [2] (🫚..🫛) ginger root..pea pod
+ {0x1FADC, 0x1FADF, prExtendedPictographic}, // E0.0 [4] (..) ..
+ {0x1FAE0, 0x1FAE7, prExtendedPictographic}, // E14.0 [8] (🫠..🫧) melting face..bubbles
+ {0x1FAE8, 0x1FAE8, prExtendedPictographic}, // E15.0 [1] (🫨) shaking face
+ {0x1FAE9, 0x1FAEF, prExtendedPictographic}, // E0.0 [7] (..) ..
+ {0x1FAF0, 0x1FAF6, prExtendedPictographic}, // E14.0 [7] (🫰..🫶) hand with index finger and thumb crossed..heart hands
+ {0x1FAF7, 0x1FAF8, prExtendedPictographic}, // E15.0 [2] (🫷..🫸) leftwards pushing hand..rightwards pushing hand
+ {0x1FAF9, 0x1FAFF, prExtendedPictographic}, // E0.0 [7] (..) ..
+ {0x1FC00, 0x1FFFD, prExtendedPictographic}, // E0.0[1022] (..) ..
+ {0xE0000, 0xE0000, prControl}, // Cn
+ {0xE0001, 0xE0001, prControl}, // Cf LANGUAGE TAG
+ {0xE0002, 0xE001F, prControl}, // Cn [30] ..
+ {0xE0020, 0xE007F, prExtend}, // Cf [96] TAG SPACE..CANCEL TAG
+ {0xE0080, 0xE00FF, prControl}, // Cn [128] ..
+ {0xE0100, 0xE01EF, prExtend}, // Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256
+ {0xE01F0, 0xE0FFF, prControl}, // Cn [3600] ..
+}
diff --git a/vendor/github.com/rivo/uniseg/graphemerules.go b/vendor/github.com/rivo/uniseg/graphemerules.go
new file mode 100644
index 000000000..5d399d29c
--- /dev/null
+++ b/vendor/github.com/rivo/uniseg/graphemerules.go
@@ -0,0 +1,176 @@
+package uniseg
+
+// The states of the grapheme cluster parser.
+const (
+ grAny = iota
+ grCR
+ grControlLF
+ grL
+ grLVV
+ grLVTT
+ grPrepend
+ grExtendedPictographic
+ grExtendedPictographicZWJ
+ grRIOdd
+ grRIEven
+)
+
+// The grapheme cluster parser's breaking instructions.
+const (
+ grNoBoundary = iota
+ grBoundary
+)
+
+// grTransitions implements the grapheme cluster parser's state transitions.
+// Maps state and property to a new state, a breaking instruction, and rule
+// number. The breaking instruction always refers to the boundary between the
+// last and next code point. Returns negative values if no transition is found.
+//
+// This function is used as follows:
+//
+// 1. Find specific state + specific property. Stop if found.
+// 2. Find specific state + any property.
+// 3. Find any state + specific property.
+// 4. If only (2) or (3) (but not both) was found, stop.
+// 5. If both (2) and (3) were found, use state from (3) and breaking instruction
+// from the transition with the lower rule number, prefer (3) if rule numbers
+// are equal. Stop.
+// 6. Assume grAny and grBoundary.
+//
+// Unicode version 15.0.0.
+func grTransitions(state, prop int) (newState int, newProp int, boundary int) {
+ // It turns out that using a big switch statement is much faster than using
+ // a map.
+
+ switch uint64(state) | uint64(prop)<<32 {
+ // GB5
+ case grAny | prCR<<32:
+ return grCR, grBoundary, 50
+ case grAny | prLF<<32:
+ return grControlLF, grBoundary, 50
+ case grAny | prControl<<32:
+ return grControlLF, grBoundary, 50
+
+ // GB4
+ case grCR | prAny<<32:
+ return grAny, grBoundary, 40
+ case grControlLF | prAny<<32:
+ return grAny, grBoundary, 40
+
+ // GB3
+ case grCR | prLF<<32:
+ return grControlLF, grNoBoundary, 30
+
+ // GB6
+ case grAny | prL<<32:
+ return grL, grBoundary, 9990
+ case grL | prL<<32:
+ return grL, grNoBoundary, 60
+ case grL | prV<<32:
+ return grLVV, grNoBoundary, 60
+ case grL | prLV<<32:
+ return grLVV, grNoBoundary, 60
+ case grL | prLVT<<32:
+ return grLVTT, grNoBoundary, 60
+
+ // GB7
+ case grAny | prLV<<32:
+ return grLVV, grBoundary, 9990
+ case grAny | prV<<32:
+ return grLVV, grBoundary, 9990
+ case grLVV | prV<<32:
+ return grLVV, grNoBoundary, 70
+ case grLVV | prT<<32:
+ return grLVTT, grNoBoundary, 70
+
+ // GB8
+ case grAny | prLVT<<32:
+ return grLVTT, grBoundary, 9990
+ case grAny | prT<<32:
+ return grLVTT, grBoundary, 9990
+ case grLVTT | prT<<32:
+ return grLVTT, grNoBoundary, 80
+
+ // GB9
+ case grAny | prExtend<<32:
+ return grAny, grNoBoundary, 90
+ case grAny | prZWJ<<32:
+ return grAny, grNoBoundary, 90
+
+ // GB9a
+ case grAny | prSpacingMark<<32:
+ return grAny, grNoBoundary, 91
+
+ // GB9b
+ case grAny | prPrepend<<32:
+ return grPrepend, grBoundary, 9990
+ case grPrepend | prAny<<32:
+ return grAny, grNoBoundary, 92
+
+ // GB11
+ case grAny | prExtendedPictographic<<32:
+ return grExtendedPictographic, grBoundary, 9990
+ case grExtendedPictographic | prExtend<<32:
+ return grExtendedPictographic, grNoBoundary, 110
+ case grExtendedPictographic | prZWJ<<32:
+ return grExtendedPictographicZWJ, grNoBoundary, 110
+ case grExtendedPictographicZWJ | prExtendedPictographic<<32:
+ return grExtendedPictographic, grNoBoundary, 110
+
+ // GB12 / GB13
+ case grAny | prRegionalIndicator<<32:
+ return grRIOdd, grBoundary, 9990
+ case grRIOdd | prRegionalIndicator<<32:
+ return grRIEven, grNoBoundary, 120
+ case grRIEven | prRegionalIndicator<<32:
+ return grRIOdd, grBoundary, 120
+ default:
+ return -1, -1, -1
+ }
+}
+
+// transitionGraphemeState determines the new state of the grapheme cluster
+// parser given the current state and the next code point. It also returns the
+// code point's grapheme property (the value mapped by the [graphemeCodePoints]
+// table) and whether a cluster boundary was detected.
+func transitionGraphemeState(state int, r rune) (newState, prop int, boundary bool) {
+ // Determine the property of the next character.
+ prop = propertyGraphemes(r)
+
+ // Find the applicable transition.
+ nextState, nextProp, _ := grTransitions(state, prop)
+ if nextState >= 0 {
+ // We have a specific transition. We'll use it.
+ return nextState, prop, nextProp == grBoundary
+ }
+
+ // No specific transition found. Try the less specific ones.
+ anyPropState, anyPropProp, anyPropRule := grTransitions(state, prAny)
+ anyStateState, anyStateProp, anyStateRule := grTransitions(grAny, prop)
+ if anyPropState >= 0 && anyStateState >= 0 {
+ // Both apply. We'll use a mix (see comments for grTransitions).
+ newState = anyStateState
+ boundary = anyStateProp == grBoundary
+ if anyPropRule < anyStateRule {
+ boundary = anyPropProp == grBoundary
+ }
+ return
+ }
+
+ if anyPropState >= 0 {
+ // We only have a specific state.
+ return anyPropState, prop, anyPropProp == grBoundary
+ // This branch will probably never be reached because okAnyState will
+ // always be true given the current transition map. But we keep it here
+ // for future modifications to the transition map where this may not be
+ // true anymore.
+ }
+
+ if anyStateState >= 0 {
+ // We only have a specific property.
+ return anyStateState, prop, anyStateProp == grBoundary
+ }
+
+ // No known transition. GB999: Any ÷ Any.
+ return grAny, prop, true
+}
diff --git a/vendor/github.com/rivo/uniseg/line.go b/vendor/github.com/rivo/uniseg/line.go
new file mode 100644
index 000000000..7a46318d9
--- /dev/null
+++ b/vendor/github.com/rivo/uniseg/line.go
@@ -0,0 +1,134 @@
+package uniseg
+
+import "unicode/utf8"
+
+// FirstLineSegment returns the prefix of the given byte slice after which a
+// decision to break the string over to the next line can or must be made,
+// according to the rules of [Unicode Standard Annex #14]. This is used to
+// implement line breaking.
+//
+// Line breaking, also known as word wrapping, is the process of breaking a
+// section of text into lines such that it will fit in the available width of a
+// page, window or other display area.
+//
+// The returned "segment" may not be broken into smaller parts, unless no other
+// breaking opportunities present themselves, in which case you may break by
+// grapheme clusters (using the [FirstGraphemeCluster] function to determine the
+// grapheme clusters).
+//
+// The "mustBreak" flag indicates whether you MUST break the line after the
+// given segment (true), for example after newline characters, or you MAY break
+// the line after the given segment (false).
+//
+// This function can be called continuously to extract all non-breaking sub-sets
+// from a byte slice, as illustrated in the example below.
+//
+// If you don't know the current state, for example when calling the function
+// for the first time, you must pass -1. For consecutive calls, pass the state
+// and rest slice returned by the previous call.
+//
+// The "rest" slice is the sub-slice of the original byte slice "b" starting
+// after the last byte of the identified line segment. If the length of the
+// "rest" slice is 0, the entire byte slice "b" has been processed. The
+// "segment" byte slice is the sub-slice of the input slice containing the
+// identified line segment.
+//
+// Given an empty byte slice "b", the function returns nil values.
+//
+// Note that in accordance with [UAX #14 LB3], the final segment will end with
+// "mustBreak" set to true. You can choose to ignore this by checking if the
+// length of the "rest" slice is 0 and calling [HasTrailingLineBreak] or
+// [HasTrailingLineBreakInString] on the last rune.
+//
+// Note also that this algorithm may break within grapheme clusters. This is
+// addressed in Section 8.2 Example 6 of UAX #14. To avoid this, you can use
+// the [Step] function instead.
+//
+// [Unicode Standard Annex #14]: https://www.unicode.org/reports/tr14/
+// [UAX #14 LB3]: https://www.unicode.org/reports/tr14/#Algorithm
+func FirstLineSegment(b []byte, state int) (segment, rest []byte, mustBreak bool, newState int) {
+ // An empty byte slice returns nothing.
+ if len(b) == 0 {
+ return
+ }
+
+ // Extract the first rune.
+ r, length := utf8.DecodeRune(b)
+ if len(b) <= length { // If we're already past the end, there is nothing else to parse.
+ return b, nil, true, lbAny // LB3.
+ }
+
+ // If we don't know the state, determine it now.
+ if state < 0 {
+ state, _ = transitionLineBreakState(state, r, b[length:], "")
+ }
+
+ // Transition until we find a boundary.
+ var boundary int
+ for {
+ r, l := utf8.DecodeRune(b[length:])
+ state, boundary = transitionLineBreakState(state, r, b[length+l:], "")
+
+ if boundary != LineDontBreak {
+ return b[:length], b[length:], boundary == LineMustBreak, state
+ }
+
+ length += l
+ if len(b) <= length {
+ return b, nil, true, lbAny // LB3
+ }
+ }
+}
+
+// FirstLineSegmentInString is like [FirstLineSegment] but its input and outputs
+// are strings.
+func FirstLineSegmentInString(str string, state int) (segment, rest string, mustBreak bool, newState int) {
+ // An empty byte slice returns nothing.
+ if len(str) == 0 {
+ return
+ }
+
+ // Extract the first rune.
+ r, length := utf8.DecodeRuneInString(str)
+ if len(str) <= length { // If we're already past the end, there is nothing else to parse.
+ return str, "", true, lbAny // LB3.
+ }
+
+ // If we don't know the state, determine it now.
+ if state < 0 {
+ state, _ = transitionLineBreakState(state, r, nil, str[length:])
+ }
+
+ // Transition until we find a boundary.
+ var boundary int
+ for {
+ r, l := utf8.DecodeRuneInString(str[length:])
+ state, boundary = transitionLineBreakState(state, r, nil, str[length+l:])
+
+ if boundary != LineDontBreak {
+ return str[:length], str[length:], boundary == LineMustBreak, state
+ }
+
+ length += l
+ if len(str) <= length {
+ return str, "", true, lbAny // LB3.
+ }
+ }
+}
+
+// HasTrailingLineBreak returns true if the last rune in the given byte slice is
+// one of the hard line break code points defined in LB4 and LB5 of [UAX #14].
+//
+// [UAX #14]: https://www.unicode.org/reports/tr14/#Algorithm
+func HasTrailingLineBreak(b []byte) bool {
+ r, _ := utf8.DecodeLastRune(b)
+ property, _ := propertyLineBreak(r)
+ return property == prBK || property == prCR || property == prLF || property == prNL
+}
+
+// HasTrailingLineBreakInString is like [HasTrailingLineBreak] but for a string.
+func HasTrailingLineBreakInString(str string) bool {
+ r, _ := utf8.DecodeLastRuneInString(str)
+ property, _ := propertyLineBreak(r)
+ return property == prBK || property == prCR || property == prLF || property == prNL
+}
diff --git a/vendor/github.com/rivo/uniseg/lineproperties.go b/vendor/github.com/rivo/uniseg/lineproperties.go
new file mode 100644
index 000000000..ac7fac4c0
--- /dev/null
+++ b/vendor/github.com/rivo/uniseg/lineproperties.go
@@ -0,0 +1,3554 @@
+// Code generated via go generate from gen_properties.go. DO NOT EDIT.
+
+package uniseg
+
+// lineBreakCodePoints are taken from
+// https://www.unicode.org/Public/15.0.0/ucd/LineBreak.txt
+// and
+// https://unicode.org/Public/15.0.0/ucd/emoji/emoji-data.txt
+// ("Extended_Pictographic" only)
+// on September 5, 2023. See https://www.unicode.org/license.html for the Unicode
+// license agreement.
+var lineBreakCodePoints = [][4]int{
+ {0x0000, 0x0008, prCM, gcCc}, // [9] ..
+ {0x0009, 0x0009, prBA, gcCc}, //
+ {0x000A, 0x000A, prLF, gcCc}, //
+ {0x000B, 0x000C, prBK, gcCc}, // [2] ..
+ {0x000D, 0x000D, prCR, gcCc}, //
+ {0x000E, 0x001F, prCM, gcCc}, // [18] ..
+ {0x0020, 0x0020, prSP, gcZs}, // SPACE
+ {0x0021, 0x0021, prEX, gcPo}, // EXCLAMATION MARK
+ {0x0022, 0x0022, prQU, gcPo}, // QUOTATION MARK
+ {0x0023, 0x0023, prAL, gcPo}, // NUMBER SIGN
+ {0x0024, 0x0024, prPR, gcSc}, // DOLLAR SIGN
+ {0x0025, 0x0025, prPO, gcPo}, // PERCENT SIGN
+ {0x0026, 0x0026, prAL, gcPo}, // AMPERSAND
+ {0x0027, 0x0027, prQU, gcPo}, // APOSTROPHE
+ {0x0028, 0x0028, prOP, gcPs}, // LEFT PARENTHESIS
+ {0x0029, 0x0029, prCP, gcPe}, // RIGHT PARENTHESIS
+ {0x002A, 0x002A, prAL, gcPo}, // ASTERISK
+ {0x002B, 0x002B, prPR, gcSm}, // PLUS SIGN
+ {0x002C, 0x002C, prIS, gcPo}, // COMMA
+ {0x002D, 0x002D, prHY, gcPd}, // HYPHEN-MINUS
+ {0x002E, 0x002E, prIS, gcPo}, // FULL STOP
+ {0x002F, 0x002F, prSY, gcPo}, // SOLIDUS
+ {0x0030, 0x0039, prNU, gcNd}, // [10] DIGIT ZERO..DIGIT NINE
+ {0x003A, 0x003B, prIS, gcPo}, // [2] COLON..SEMICOLON
+ {0x003C, 0x003E, prAL, gcSm}, // [3] LESS-THAN SIGN..GREATER-THAN SIGN
+ {0x003F, 0x003F, prEX, gcPo}, // QUESTION MARK
+ {0x0040, 0x0040, prAL, gcPo}, // COMMERCIAL AT
+ {0x0041, 0x005A, prAL, gcLu}, // [26] LATIN CAPITAL LETTER A..LATIN CAPITAL LETTER Z
+ {0x005B, 0x005B, prOP, gcPs}, // LEFT SQUARE BRACKET
+ {0x005C, 0x005C, prPR, gcPo}, // REVERSE SOLIDUS
+ {0x005D, 0x005D, prCP, gcPe}, // RIGHT SQUARE BRACKET
+ {0x005E, 0x005E, prAL, gcSk}, // CIRCUMFLEX ACCENT
+ {0x005F, 0x005F, prAL, gcPc}, // LOW LINE
+ {0x0060, 0x0060, prAL, gcSk}, // GRAVE ACCENT
+ {0x0061, 0x007A, prAL, gcLl}, // [26] LATIN SMALL LETTER A..LATIN SMALL LETTER Z
+ {0x007B, 0x007B, prOP, gcPs}, // LEFT CURLY BRACKET
+ {0x007C, 0x007C, prBA, gcSm}, // VERTICAL LINE
+ {0x007D, 0x007D, prCL, gcPe}, // RIGHT CURLY BRACKET
+ {0x007E, 0x007E, prAL, gcSm}, // TILDE
+ {0x007F, 0x007F, prCM, gcCc}, //
+ {0x0080, 0x0084, prCM, gcCc}, // [5] ..
+ {0x0085, 0x0085, prNL, gcCc}, //
+ {0x0086, 0x009F, prCM, gcCc}, // [26] ..
+ {0x00A0, 0x00A0, prGL, gcZs}, // NO-BREAK SPACE
+ {0x00A1, 0x00A1, prOP, gcPo}, // INVERTED EXCLAMATION MARK
+ {0x00A2, 0x00A2, prPO, gcSc}, // CENT SIGN
+ {0x00A3, 0x00A5, prPR, gcSc}, // [3] POUND SIGN..YEN SIGN
+ {0x00A6, 0x00A6, prAL, gcSo}, // BROKEN BAR
+ {0x00A7, 0x00A7, prAI, gcPo}, // SECTION SIGN
+ {0x00A8, 0x00A8, prAI, gcSk}, // DIAERESIS
+ {0x00A9, 0x00A9, prAL, gcSo}, // COPYRIGHT SIGN
+ {0x00AA, 0x00AA, prAI, gcLo}, // FEMININE ORDINAL INDICATOR
+ {0x00AB, 0x00AB, prQU, gcPi}, // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+ {0x00AC, 0x00AC, prAL, gcSm}, // NOT SIGN
+ {0x00AD, 0x00AD, prBA, gcCf}, // SOFT HYPHEN
+ {0x00AE, 0x00AE, prAL, gcSo}, // REGISTERED SIGN
+ {0x00AF, 0x00AF, prAL, gcSk}, // MACRON
+ {0x00B0, 0x00B0, prPO, gcSo}, // DEGREE SIGN
+ {0x00B1, 0x00B1, prPR, gcSm}, // PLUS-MINUS SIGN
+ {0x00B2, 0x00B3, prAI, gcNo}, // [2] SUPERSCRIPT TWO..SUPERSCRIPT THREE
+ {0x00B4, 0x00B4, prBB, gcSk}, // ACUTE ACCENT
+ {0x00B5, 0x00B5, prAL, gcLl}, // MICRO SIGN
+ {0x00B6, 0x00B7, prAI, gcPo}, // [2] PILCROW SIGN..MIDDLE DOT
+ {0x00B8, 0x00B8, prAI, gcSk}, // CEDILLA
+ {0x00B9, 0x00B9, prAI, gcNo}, // SUPERSCRIPT ONE
+ {0x00BA, 0x00BA, prAI, gcLo}, // MASCULINE ORDINAL INDICATOR
+ {0x00BB, 0x00BB, prQU, gcPf}, // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+ {0x00BC, 0x00BE, prAI, gcNo}, // [3] VULGAR FRACTION ONE QUARTER..VULGAR FRACTION THREE QUARTERS
+ {0x00BF, 0x00BF, prOP, gcPo}, // INVERTED QUESTION MARK
+ {0x00C0, 0x00D6, prAL, gcLu}, // [23] LATIN CAPITAL LETTER A WITH GRAVE..LATIN CAPITAL LETTER O WITH DIAERESIS
+ {0x00D7, 0x00D7, prAI, gcSm}, // MULTIPLICATION SIGN
+ {0x00D8, 0x00F6, prAL, gcLC}, // [31] LATIN CAPITAL LETTER O WITH STROKE..LATIN SMALL LETTER O WITH DIAERESIS
+ {0x00F7, 0x00F7, prAI, gcSm}, // DIVISION SIGN
+ {0x00F8, 0x00FF, prAL, gcLl}, // [8] LATIN SMALL LETTER O WITH STROKE..LATIN SMALL LETTER Y WITH DIAERESIS
+ {0x0100, 0x017F, prAL, gcLC}, // [128] LATIN CAPITAL LETTER A WITH MACRON..LATIN SMALL LETTER LONG S
+ {0x0180, 0x01BA, prAL, gcLC}, // [59] LATIN SMALL LETTER B WITH STROKE..LATIN SMALL LETTER EZH WITH TAIL
+ {0x01BB, 0x01BB, prAL, gcLo}, // LATIN LETTER TWO WITH STROKE
+ {0x01BC, 0x01BF, prAL, gcLC}, // [4] LATIN CAPITAL LETTER TONE FIVE..LATIN LETTER WYNN
+ {0x01C0, 0x01C3, prAL, gcLo}, // [4] LATIN LETTER DENTAL CLICK..LATIN LETTER RETROFLEX CLICK
+ {0x01C4, 0x024F, prAL, gcLC}, // [140] LATIN CAPITAL LETTER DZ WITH CARON..LATIN SMALL LETTER Y WITH STROKE
+ {0x0250, 0x0293, prAL, gcLl}, // [68] LATIN SMALL LETTER TURNED A..LATIN SMALL LETTER EZH WITH CURL
+ {0x0294, 0x0294, prAL, gcLo}, // LATIN LETTER GLOTTAL STOP
+ {0x0295, 0x02AF, prAL, gcLl}, // [27] LATIN LETTER PHARYNGEAL VOICED FRICATIVE..LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL
+ {0x02B0, 0x02C1, prAL, gcLm}, // [18] MODIFIER LETTER SMALL H..MODIFIER LETTER REVERSED GLOTTAL STOP
+ {0x02C2, 0x02C5, prAL, gcSk}, // [4] MODIFIER LETTER LEFT ARROWHEAD..MODIFIER LETTER DOWN ARROWHEAD
+ {0x02C6, 0x02C6, prAL, gcLm}, // MODIFIER LETTER CIRCUMFLEX ACCENT
+ {0x02C7, 0x02C7, prAI, gcLm}, // CARON
+ {0x02C8, 0x02C8, prBB, gcLm}, // MODIFIER LETTER VERTICAL LINE
+ {0x02C9, 0x02CB, prAI, gcLm}, // [3] MODIFIER LETTER MACRON..MODIFIER LETTER GRAVE ACCENT
+ {0x02CC, 0x02CC, prBB, gcLm}, // MODIFIER LETTER LOW VERTICAL LINE
+ {0x02CD, 0x02CD, prAI, gcLm}, // MODIFIER LETTER LOW MACRON
+ {0x02CE, 0x02CF, prAL, gcLm}, // [2] MODIFIER LETTER LOW GRAVE ACCENT..MODIFIER LETTER LOW ACUTE ACCENT
+ {0x02D0, 0x02D0, prAI, gcLm}, // MODIFIER LETTER TRIANGULAR COLON
+ {0x02D1, 0x02D1, prAL, gcLm}, // MODIFIER LETTER HALF TRIANGULAR COLON
+ {0x02D2, 0x02D7, prAL, gcSk}, // [6] MODIFIER LETTER CENTRED RIGHT HALF RING..MODIFIER LETTER MINUS SIGN
+ {0x02D8, 0x02DB, prAI, gcSk}, // [4] BREVE..OGONEK
+ {0x02DC, 0x02DC, prAL, gcSk}, // SMALL TILDE
+ {0x02DD, 0x02DD, prAI, gcSk}, // DOUBLE ACUTE ACCENT
+ {0x02DE, 0x02DE, prAL, gcSk}, // MODIFIER LETTER RHOTIC HOOK
+ {0x02DF, 0x02DF, prBB, gcSk}, // MODIFIER LETTER CROSS ACCENT
+ {0x02E0, 0x02E4, prAL, gcLm}, // [5] MODIFIER LETTER SMALL GAMMA..MODIFIER LETTER SMALL REVERSED GLOTTAL STOP
+ {0x02E5, 0x02EB, prAL, gcSk}, // [7] MODIFIER LETTER EXTRA-HIGH TONE BAR..MODIFIER LETTER YANG DEPARTING TONE MARK
+ {0x02EC, 0x02EC, prAL, gcLm}, // MODIFIER LETTER VOICING
+ {0x02ED, 0x02ED, prAL, gcSk}, // MODIFIER LETTER UNASPIRATED
+ {0x02EE, 0x02EE, prAL, gcLm}, // MODIFIER LETTER DOUBLE APOSTROPHE
+ {0x02EF, 0x02FF, prAL, gcSk}, // [17] MODIFIER LETTER LOW DOWN ARROWHEAD..MODIFIER LETTER LOW LEFT ARROW
+ {0x0300, 0x034E, prCM, gcMn}, // [79] COMBINING GRAVE ACCENT..COMBINING UPWARDS ARROW BELOW
+ {0x034F, 0x034F, prGL, gcMn}, // COMBINING GRAPHEME JOINER
+ {0x0350, 0x035B, prCM, gcMn}, // [12] COMBINING RIGHT ARROWHEAD ABOVE..COMBINING ZIGZAG ABOVE
+ {0x035C, 0x0362, prGL, gcMn}, // [7] COMBINING DOUBLE BREVE BELOW..COMBINING DOUBLE RIGHTWARDS ARROW BELOW
+ {0x0363, 0x036F, prCM, gcMn}, // [13] COMBINING LATIN SMALL LETTER A..COMBINING LATIN SMALL LETTER X
+ {0x0370, 0x0373, prAL, gcLC}, // [4] GREEK CAPITAL LETTER HETA..GREEK SMALL LETTER ARCHAIC SAMPI
+ {0x0374, 0x0374, prAL, gcLm}, // GREEK NUMERAL SIGN
+ {0x0375, 0x0375, prAL, gcSk}, // GREEK LOWER NUMERAL SIGN
+ {0x0376, 0x0377, prAL, gcLC}, // [2] GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA..GREEK SMALL LETTER PAMPHYLIAN DIGAMMA
+ {0x037A, 0x037A, prAL, gcLm}, // GREEK YPOGEGRAMMENI
+ {0x037B, 0x037D, prAL, gcLl}, // [3] GREEK SMALL REVERSED LUNATE SIGMA SYMBOL..GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL
+ {0x037E, 0x037E, prIS, gcPo}, // GREEK QUESTION MARK
+ {0x037F, 0x037F, prAL, gcLu}, // GREEK CAPITAL LETTER YOT
+ {0x0384, 0x0385, prAL, gcSk}, // [2] GREEK TONOS..GREEK DIALYTIKA TONOS
+ {0x0386, 0x0386, prAL, gcLu}, // GREEK CAPITAL LETTER ALPHA WITH TONOS
+ {0x0387, 0x0387, prAL, gcPo}, // GREEK ANO TELEIA
+ {0x0388, 0x038A, prAL, gcLu}, // [3] GREEK CAPITAL LETTER EPSILON WITH TONOS..GREEK CAPITAL LETTER IOTA WITH TONOS
+ {0x038C, 0x038C, prAL, gcLu}, // GREEK CAPITAL LETTER OMICRON WITH TONOS
+ {0x038E, 0x03A1, prAL, gcLC}, // [20] GREEK CAPITAL LETTER UPSILON WITH TONOS..GREEK CAPITAL LETTER RHO
+ {0x03A3, 0x03F5, prAL, gcLC}, // [83] GREEK CAPITAL LETTER SIGMA..GREEK LUNATE EPSILON SYMBOL
+ {0x03F6, 0x03F6, prAL, gcSm}, // GREEK REVERSED LUNATE EPSILON SYMBOL
+ {0x03F7, 0x03FF, prAL, gcLC}, // [9] GREEK CAPITAL LETTER SHO..GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL
+ {0x0400, 0x0481, prAL, gcLC}, // [130] CYRILLIC CAPITAL LETTER IE WITH GRAVE..CYRILLIC SMALL LETTER KOPPA
+ {0x0482, 0x0482, prAL, gcSo}, // CYRILLIC THOUSANDS SIGN
+ {0x0483, 0x0487, prCM, gcMn}, // [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE
+ {0x0488, 0x0489, prCM, gcMe}, // [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN
+ {0x048A, 0x04FF, prAL, gcLC}, // [118] CYRILLIC CAPITAL LETTER SHORT I WITH TAIL..CYRILLIC SMALL LETTER HA WITH STROKE
+ {0x0500, 0x052F, prAL, gcLC}, // [48] CYRILLIC CAPITAL LETTER KOMI DE..CYRILLIC SMALL LETTER EL WITH DESCENDER
+ {0x0531, 0x0556, prAL, gcLu}, // [38] ARMENIAN CAPITAL LETTER AYB..ARMENIAN CAPITAL LETTER FEH
+ {0x0559, 0x0559, prAL, gcLm}, // ARMENIAN MODIFIER LETTER LEFT HALF RING
+ {0x055A, 0x055F, prAL, gcPo}, // [6] ARMENIAN APOSTROPHE..ARMENIAN ABBREVIATION MARK
+ {0x0560, 0x0588, prAL, gcLl}, // [41] ARMENIAN SMALL LETTER TURNED AYB..ARMENIAN SMALL LETTER YI WITH STROKE
+ {0x0589, 0x0589, prIS, gcPo}, // ARMENIAN FULL STOP
+ {0x058A, 0x058A, prBA, gcPd}, // ARMENIAN HYPHEN
+ {0x058D, 0x058E, prAL, gcSo}, // [2] RIGHT-FACING ARMENIAN ETERNITY SIGN..LEFT-FACING ARMENIAN ETERNITY SIGN
+ {0x058F, 0x058F, prPR, gcSc}, // ARMENIAN DRAM SIGN
+ {0x0591, 0x05BD, prCM, gcMn}, // [45] HEBREW ACCENT ETNAHTA..HEBREW POINT METEG
+ {0x05BE, 0x05BE, prBA, gcPd}, // HEBREW PUNCTUATION MAQAF
+ {0x05BF, 0x05BF, prCM, gcMn}, // HEBREW POINT RAFE
+ {0x05C0, 0x05C0, prAL, gcPo}, // HEBREW PUNCTUATION PASEQ
+ {0x05C1, 0x05C2, prCM, gcMn}, // [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT
+ {0x05C3, 0x05C3, prAL, gcPo}, // HEBREW PUNCTUATION SOF PASUQ
+ {0x05C4, 0x05C5, prCM, gcMn}, // [2] HEBREW MARK UPPER DOT..HEBREW MARK LOWER DOT
+ {0x05C6, 0x05C6, prEX, gcPo}, // HEBREW PUNCTUATION NUN HAFUKHA
+ {0x05C7, 0x05C7, prCM, gcMn}, // HEBREW POINT QAMATS QATAN
+ {0x05D0, 0x05EA, prHL, gcLo}, // [27] HEBREW LETTER ALEF..HEBREW LETTER TAV
+ {0x05EF, 0x05F2, prHL, gcLo}, // [4] HEBREW YOD TRIANGLE..HEBREW LIGATURE YIDDISH DOUBLE YOD
+ {0x05F3, 0x05F4, prAL, gcPo}, // [2] HEBREW PUNCTUATION GERESH..HEBREW PUNCTUATION GERSHAYIM
+ {0x0600, 0x0605, prAL, gcCf}, // [6] ARABIC NUMBER SIGN..ARABIC NUMBER MARK ABOVE
+ {0x0606, 0x0608, prAL, gcSm}, // [3] ARABIC-INDIC CUBE ROOT..ARABIC RAY
+ {0x0609, 0x060A, prPO, gcPo}, // [2] ARABIC-INDIC PER MILLE SIGN..ARABIC-INDIC PER TEN THOUSAND SIGN
+ {0x060B, 0x060B, prPO, gcSc}, // AFGHANI SIGN
+ {0x060C, 0x060D, prIS, gcPo}, // [2] ARABIC COMMA..ARABIC DATE SEPARATOR
+ {0x060E, 0x060F, prAL, gcSo}, // [2] ARABIC POETIC VERSE SIGN..ARABIC SIGN MISRA
+ {0x0610, 0x061A, prCM, gcMn}, // [11] ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM..ARABIC SMALL KASRA
+ {0x061B, 0x061B, prEX, gcPo}, // ARABIC SEMICOLON
+ {0x061C, 0x061C, prCM, gcCf}, // ARABIC LETTER MARK
+ {0x061D, 0x061F, prEX, gcPo}, // [3] ARABIC END OF TEXT MARK..ARABIC QUESTION MARK
+ {0x0620, 0x063F, prAL, gcLo}, // [32] ARABIC LETTER KASHMIRI YEH..ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE
+ {0x0640, 0x0640, prAL, gcLm}, // ARABIC TATWEEL
+ {0x0641, 0x064A, prAL, gcLo}, // [10] ARABIC LETTER FEH..ARABIC LETTER YEH
+ {0x064B, 0x065F, prCM, gcMn}, // [21] ARABIC FATHATAN..ARABIC WAVY HAMZA BELOW
+ {0x0660, 0x0669, prNU, gcNd}, // [10] ARABIC-INDIC DIGIT ZERO..ARABIC-INDIC DIGIT NINE
+ {0x066A, 0x066A, prPO, gcPo}, // ARABIC PERCENT SIGN
+ {0x066B, 0x066C, prNU, gcPo}, // [2] ARABIC DECIMAL SEPARATOR..ARABIC THOUSANDS SEPARATOR
+ {0x066D, 0x066D, prAL, gcPo}, // ARABIC FIVE POINTED STAR
+ {0x066E, 0x066F, prAL, gcLo}, // [2] ARABIC LETTER DOTLESS BEH..ARABIC LETTER DOTLESS QAF
+ {0x0670, 0x0670, prCM, gcMn}, // ARABIC LETTER SUPERSCRIPT ALEF
+ {0x0671, 0x06D3, prAL, gcLo}, // [99] ARABIC LETTER ALEF WASLA..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE
+ {0x06D4, 0x06D4, prEX, gcPo}, // ARABIC FULL STOP
+ {0x06D5, 0x06D5, prAL, gcLo}, // ARABIC LETTER AE
+ {0x06D6, 0x06DC, prCM, gcMn}, // [7] ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA..ARABIC SMALL HIGH SEEN
+ {0x06DD, 0x06DD, prAL, gcCf}, // ARABIC END OF AYAH
+ {0x06DE, 0x06DE, prAL, gcSo}, // ARABIC START OF RUB EL HIZB
+ {0x06DF, 0x06E4, prCM, gcMn}, // [6] ARABIC SMALL HIGH ROUNDED ZERO..ARABIC SMALL HIGH MADDA
+ {0x06E5, 0x06E6, prAL, gcLm}, // [2] ARABIC SMALL WAW..ARABIC SMALL YEH
+ {0x06E7, 0x06E8, prCM, gcMn}, // [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON
+ {0x06E9, 0x06E9, prAL, gcSo}, // ARABIC PLACE OF SAJDAH
+ {0x06EA, 0x06ED, prCM, gcMn}, // [4] ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM
+ {0x06EE, 0x06EF, prAL, gcLo}, // [2] ARABIC LETTER DAL WITH INVERTED V..ARABIC LETTER REH WITH INVERTED V
+ {0x06F0, 0x06F9, prNU, gcNd}, // [10] EXTENDED ARABIC-INDIC DIGIT ZERO..EXTENDED ARABIC-INDIC DIGIT NINE
+ {0x06FA, 0x06FC, prAL, gcLo}, // [3] ARABIC LETTER SHEEN WITH DOT BELOW..ARABIC LETTER GHAIN WITH DOT BELOW
+ {0x06FD, 0x06FE, prAL, gcSo}, // [2] ARABIC SIGN SINDHI AMPERSAND..ARABIC SIGN SINDHI POSTPOSITION MEN
+ {0x06FF, 0x06FF, prAL, gcLo}, // ARABIC LETTER HEH WITH INVERTED V
+ {0x0700, 0x070D, prAL, gcPo}, // [14] SYRIAC END OF PARAGRAPH..SYRIAC HARKLEAN ASTERISCUS
+ {0x070F, 0x070F, prAL, gcCf}, // SYRIAC ABBREVIATION MARK
+ {0x0710, 0x0710, prAL, gcLo}, // SYRIAC LETTER ALAPH
+ {0x0711, 0x0711, prCM, gcMn}, // SYRIAC LETTER SUPERSCRIPT ALAPH
+ {0x0712, 0x072F, prAL, gcLo}, // [30] SYRIAC LETTER BETH..SYRIAC LETTER PERSIAN DHALATH
+ {0x0730, 0x074A, prCM, gcMn}, // [27] SYRIAC PTHAHA ABOVE..SYRIAC BARREKH
+ {0x074D, 0x074F, prAL, gcLo}, // [3] SYRIAC LETTER SOGDIAN ZHAIN..SYRIAC LETTER SOGDIAN FE
+ {0x0750, 0x077F, prAL, gcLo}, // [48] ARABIC LETTER BEH WITH THREE DOTS HORIZONTALLY BELOW..ARABIC LETTER KAF WITH TWO DOTS ABOVE
+ {0x0780, 0x07A5, prAL, gcLo}, // [38] THAANA LETTER HAA..THAANA LETTER WAAVU
+ {0x07A6, 0x07B0, prCM, gcMn}, // [11] THAANA ABAFILI..THAANA SUKUN
+ {0x07B1, 0x07B1, prAL, gcLo}, // THAANA LETTER NAA
+ {0x07C0, 0x07C9, prNU, gcNd}, // [10] NKO DIGIT ZERO..NKO DIGIT NINE
+ {0x07CA, 0x07EA, prAL, gcLo}, // [33] NKO LETTER A..NKO LETTER JONA RA
+ {0x07EB, 0x07F3, prCM, gcMn}, // [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE
+ {0x07F4, 0x07F5, prAL, gcLm}, // [2] NKO HIGH TONE APOSTROPHE..NKO LOW TONE APOSTROPHE
+ {0x07F6, 0x07F6, prAL, gcSo}, // NKO SYMBOL OO DENNEN
+ {0x07F7, 0x07F7, prAL, gcPo}, // NKO SYMBOL GBAKURUNEN
+ {0x07F8, 0x07F8, prIS, gcPo}, // NKO COMMA
+ {0x07F9, 0x07F9, prEX, gcPo}, // NKO EXCLAMATION MARK
+ {0x07FA, 0x07FA, prAL, gcLm}, // NKO LAJANYALAN
+ {0x07FD, 0x07FD, prCM, gcMn}, // NKO DANTAYALAN
+ {0x07FE, 0x07FF, prPR, gcSc}, // [2] NKO DOROME SIGN..NKO TAMAN SIGN
+ {0x0800, 0x0815, prAL, gcLo}, // [22] SAMARITAN LETTER ALAF..SAMARITAN LETTER TAAF
+ {0x0816, 0x0819, prCM, gcMn}, // [4] SAMARITAN MARK IN..SAMARITAN MARK DAGESH
+ {0x081A, 0x081A, prAL, gcLm}, // SAMARITAN MODIFIER LETTER EPENTHETIC YUT
+ {0x081B, 0x0823, prCM, gcMn}, // [9] SAMARITAN MARK EPENTHETIC YUT..SAMARITAN VOWEL SIGN A
+ {0x0824, 0x0824, prAL, gcLm}, // SAMARITAN MODIFIER LETTER SHORT A
+ {0x0825, 0x0827, prCM, gcMn}, // [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U
+ {0x0828, 0x0828, prAL, gcLm}, // SAMARITAN MODIFIER LETTER I
+ {0x0829, 0x082D, prCM, gcMn}, // [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA
+ {0x0830, 0x083E, prAL, gcPo}, // [15] SAMARITAN PUNCTUATION NEQUDAA..SAMARITAN PUNCTUATION ANNAAU
+ {0x0840, 0x0858, prAL, gcLo}, // [25] MANDAIC LETTER HALQA..MANDAIC LETTER AIN
+ {0x0859, 0x085B, prCM, gcMn}, // [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK
+ {0x085E, 0x085E, prAL, gcPo}, // MANDAIC PUNCTUATION
+ {0x0860, 0x086A, prAL, gcLo}, // [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA
+ {0x0870, 0x0887, prAL, gcLo}, // [24] ARABIC LETTER ALEF WITH ATTACHED FATHA..ARABIC BASELINE ROUND DOT
+ {0x0888, 0x0888, prAL, gcSk}, // ARABIC RAISED ROUND DOT
+ {0x0889, 0x088E, prAL, gcLo}, // [6] ARABIC LETTER NOON WITH INVERTED SMALL V..ARABIC VERTICAL TAIL
+ {0x0890, 0x0891, prAL, gcCf}, // [2] ARABIC POUND MARK ABOVE..ARABIC PIASTRE MARK ABOVE
+ {0x0898, 0x089F, prCM, gcMn}, // [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA
+ {0x08A0, 0x08C8, prAL, gcLo}, // [41] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER GRAF
+ {0x08C9, 0x08C9, prAL, gcLm}, // ARABIC SMALL FARSI YEH
+ {0x08CA, 0x08E1, prCM, gcMn}, // [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA
+ {0x08E2, 0x08E2, prAL, gcCf}, // ARABIC DISPUTED END OF AYAH
+ {0x08E3, 0x08FF, prCM, gcMn}, // [29] ARABIC TURNED DAMMA BELOW..ARABIC MARK SIDEWAYS NOON GHUNNA
+ {0x0900, 0x0902, prCM, gcMn}, // [3] DEVANAGARI SIGN INVERTED CANDRABINDU..DEVANAGARI SIGN ANUSVARA
+ {0x0903, 0x0903, prCM, gcMc}, // DEVANAGARI SIGN VISARGA
+ {0x0904, 0x0939, prAL, gcLo}, // [54] DEVANAGARI LETTER SHORT A..DEVANAGARI LETTER HA
+ {0x093A, 0x093A, prCM, gcMn}, // DEVANAGARI VOWEL SIGN OE
+ {0x093B, 0x093B, prCM, gcMc}, // DEVANAGARI VOWEL SIGN OOE
+ {0x093C, 0x093C, prCM, gcMn}, // DEVANAGARI SIGN NUKTA
+ {0x093D, 0x093D, prAL, gcLo}, // DEVANAGARI SIGN AVAGRAHA
+ {0x093E, 0x0940, prCM, gcMc}, // [3] DEVANAGARI VOWEL SIGN AA..DEVANAGARI VOWEL SIGN II
+ {0x0941, 0x0948, prCM, gcMn}, // [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI
+ {0x0949, 0x094C, prCM, gcMc}, // [4] DEVANAGARI VOWEL SIGN CANDRA O..DEVANAGARI VOWEL SIGN AU
+ {0x094D, 0x094D, prCM, gcMn}, // DEVANAGARI SIGN VIRAMA
+ {0x094E, 0x094F, prCM, gcMc}, // [2] DEVANAGARI VOWEL SIGN PRISHTHAMATRA E..DEVANAGARI VOWEL SIGN AW
+ {0x0950, 0x0950, prAL, gcLo}, // DEVANAGARI OM
+ {0x0951, 0x0957, prCM, gcMn}, // [7] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI VOWEL SIGN UUE
+ {0x0958, 0x0961, prAL, gcLo}, // [10] DEVANAGARI LETTER QA..DEVANAGARI LETTER VOCALIC LL
+ {0x0962, 0x0963, prCM, gcMn}, // [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL
+ {0x0964, 0x0965, prBA, gcPo}, // [2] DEVANAGARI DANDA..DEVANAGARI DOUBLE DANDA
+ {0x0966, 0x096F, prNU, gcNd}, // [10] DEVANAGARI DIGIT ZERO..DEVANAGARI DIGIT NINE
+ {0x0970, 0x0970, prAL, gcPo}, // DEVANAGARI ABBREVIATION SIGN
+ {0x0971, 0x0971, prAL, gcLm}, // DEVANAGARI SIGN HIGH SPACING DOT
+ {0x0972, 0x097F, prAL, gcLo}, // [14] DEVANAGARI LETTER CANDRA A..DEVANAGARI LETTER BBA
+ {0x0980, 0x0980, prAL, gcLo}, // BENGALI ANJI
+ {0x0981, 0x0981, prCM, gcMn}, // BENGALI SIGN CANDRABINDU
+ {0x0982, 0x0983, prCM, gcMc}, // [2] BENGALI SIGN ANUSVARA..BENGALI SIGN VISARGA
+ {0x0985, 0x098C, prAL, gcLo}, // [8] BENGALI LETTER A..BENGALI LETTER VOCALIC L
+ {0x098F, 0x0990, prAL, gcLo}, // [2] BENGALI LETTER E..BENGALI LETTER AI
+ {0x0993, 0x09A8, prAL, gcLo}, // [22] BENGALI LETTER O..BENGALI LETTER NA
+ {0x09AA, 0x09B0, prAL, gcLo}, // [7] BENGALI LETTER PA..BENGALI LETTER RA
+ {0x09B2, 0x09B2, prAL, gcLo}, // BENGALI LETTER LA
+ {0x09B6, 0x09B9, prAL, gcLo}, // [4] BENGALI LETTER SHA..BENGALI LETTER HA
+ {0x09BC, 0x09BC, prCM, gcMn}, // BENGALI SIGN NUKTA
+ {0x09BD, 0x09BD, prAL, gcLo}, // BENGALI SIGN AVAGRAHA
+ {0x09BE, 0x09C0, prCM, gcMc}, // [3] BENGALI VOWEL SIGN AA..BENGALI VOWEL SIGN II
+ {0x09C1, 0x09C4, prCM, gcMn}, // [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR
+ {0x09C7, 0x09C8, prCM, gcMc}, // [2] BENGALI VOWEL SIGN E..BENGALI VOWEL SIGN AI
+ {0x09CB, 0x09CC, prCM, gcMc}, // [2] BENGALI VOWEL SIGN O..BENGALI VOWEL SIGN AU
+ {0x09CD, 0x09CD, prCM, gcMn}, // BENGALI SIGN VIRAMA
+ {0x09CE, 0x09CE, prAL, gcLo}, // BENGALI LETTER KHANDA TA
+ {0x09D7, 0x09D7, prCM, gcMc}, // BENGALI AU LENGTH MARK
+ {0x09DC, 0x09DD, prAL, gcLo}, // [2] BENGALI LETTER RRA..BENGALI LETTER RHA
+ {0x09DF, 0x09E1, prAL, gcLo}, // [3] BENGALI LETTER YYA..BENGALI LETTER VOCALIC LL
+ {0x09E2, 0x09E3, prCM, gcMn}, // [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL
+ {0x09E6, 0x09EF, prNU, gcNd}, // [10] BENGALI DIGIT ZERO..BENGALI DIGIT NINE
+ {0x09F0, 0x09F1, prAL, gcLo}, // [2] BENGALI LETTER RA WITH MIDDLE DIAGONAL..BENGALI LETTER RA WITH LOWER DIAGONAL
+ {0x09F2, 0x09F3, prPO, gcSc}, // [2] BENGALI RUPEE MARK..BENGALI RUPEE SIGN
+ {0x09F4, 0x09F8, prAL, gcNo}, // [5] BENGALI CURRENCY NUMERATOR ONE..BENGALI CURRENCY NUMERATOR ONE LESS THAN THE DENOMINATOR
+ {0x09F9, 0x09F9, prPO, gcNo}, // BENGALI CURRENCY DENOMINATOR SIXTEEN
+ {0x09FA, 0x09FA, prAL, gcSo}, // BENGALI ISSHAR
+ {0x09FB, 0x09FB, prPR, gcSc}, // BENGALI GANDA MARK
+ {0x09FC, 0x09FC, prAL, gcLo}, // BENGALI LETTER VEDIC ANUSVARA
+ {0x09FD, 0x09FD, prAL, gcPo}, // BENGALI ABBREVIATION SIGN
+ {0x09FE, 0x09FE, prCM, gcMn}, // BENGALI SANDHI MARK
+ {0x0A01, 0x0A02, prCM, gcMn}, // [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI
+ {0x0A03, 0x0A03, prCM, gcMc}, // GURMUKHI SIGN VISARGA
+ {0x0A05, 0x0A0A, prAL, gcLo}, // [6] GURMUKHI LETTER A..GURMUKHI LETTER UU
+ {0x0A0F, 0x0A10, prAL, gcLo}, // [2] GURMUKHI LETTER EE..GURMUKHI LETTER AI
+ {0x0A13, 0x0A28, prAL, gcLo}, // [22] GURMUKHI LETTER OO..GURMUKHI LETTER NA
+ {0x0A2A, 0x0A30, prAL, gcLo}, // [7] GURMUKHI LETTER PA..GURMUKHI LETTER RA
+ {0x0A32, 0x0A33, prAL, gcLo}, // [2] GURMUKHI LETTER LA..GURMUKHI LETTER LLA
+ {0x0A35, 0x0A36, prAL, gcLo}, // [2] GURMUKHI LETTER VA..GURMUKHI LETTER SHA
+ {0x0A38, 0x0A39, prAL, gcLo}, // [2] GURMUKHI LETTER SA..GURMUKHI LETTER HA
+ {0x0A3C, 0x0A3C, prCM, gcMn}, // GURMUKHI SIGN NUKTA
+ {0x0A3E, 0x0A40, prCM, gcMc}, // [3] GURMUKHI VOWEL SIGN AA..GURMUKHI VOWEL SIGN II
+ {0x0A41, 0x0A42, prCM, gcMn}, // [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU
+ {0x0A47, 0x0A48, prCM, gcMn}, // [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI
+ {0x0A4B, 0x0A4D, prCM, gcMn}, // [3] GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA
+ {0x0A51, 0x0A51, prCM, gcMn}, // GURMUKHI SIGN UDAAT
+ {0x0A59, 0x0A5C, prAL, gcLo}, // [4] GURMUKHI LETTER KHHA..GURMUKHI LETTER RRA
+ {0x0A5E, 0x0A5E, prAL, gcLo}, // GURMUKHI LETTER FA
+ {0x0A66, 0x0A6F, prNU, gcNd}, // [10] GURMUKHI DIGIT ZERO..GURMUKHI DIGIT NINE
+ {0x0A70, 0x0A71, prCM, gcMn}, // [2] GURMUKHI TIPPI..GURMUKHI ADDAK
+ {0x0A72, 0x0A74, prAL, gcLo}, // [3] GURMUKHI IRI..GURMUKHI EK ONKAR
+ {0x0A75, 0x0A75, prCM, gcMn}, // GURMUKHI SIGN YAKASH
+ {0x0A76, 0x0A76, prAL, gcPo}, // GURMUKHI ABBREVIATION SIGN
+ {0x0A81, 0x0A82, prCM, gcMn}, // [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA
+ {0x0A83, 0x0A83, prCM, gcMc}, // GUJARATI SIGN VISARGA
+ {0x0A85, 0x0A8D, prAL, gcLo}, // [9] GUJARATI LETTER A..GUJARATI VOWEL CANDRA E
+ {0x0A8F, 0x0A91, prAL, gcLo}, // [3] GUJARATI LETTER E..GUJARATI VOWEL CANDRA O
+ {0x0A93, 0x0AA8, prAL, gcLo}, // [22] GUJARATI LETTER O..GUJARATI LETTER NA
+ {0x0AAA, 0x0AB0, prAL, gcLo}, // [7] GUJARATI LETTER PA..GUJARATI LETTER RA
+ {0x0AB2, 0x0AB3, prAL, gcLo}, // [2] GUJARATI LETTER LA..GUJARATI LETTER LLA
+ {0x0AB5, 0x0AB9, prAL, gcLo}, // [5] GUJARATI LETTER VA..GUJARATI LETTER HA
+ {0x0ABC, 0x0ABC, prCM, gcMn}, // GUJARATI SIGN NUKTA
+ {0x0ABD, 0x0ABD, prAL, gcLo}, // GUJARATI SIGN AVAGRAHA
+ {0x0ABE, 0x0AC0, prCM, gcMc}, // [3] GUJARATI VOWEL SIGN AA..GUJARATI VOWEL SIGN II
+ {0x0AC1, 0x0AC5, prCM, gcMn}, // [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E
+ {0x0AC7, 0x0AC8, prCM, gcMn}, // [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI
+ {0x0AC9, 0x0AC9, prCM, gcMc}, // GUJARATI VOWEL SIGN CANDRA O
+ {0x0ACB, 0x0ACC, prCM, gcMc}, // [2] GUJARATI VOWEL SIGN O..GUJARATI VOWEL SIGN AU
+ {0x0ACD, 0x0ACD, prCM, gcMn}, // GUJARATI SIGN VIRAMA
+ {0x0AD0, 0x0AD0, prAL, gcLo}, // GUJARATI OM
+ {0x0AE0, 0x0AE1, prAL, gcLo}, // [2] GUJARATI LETTER VOCALIC RR..GUJARATI LETTER VOCALIC LL
+ {0x0AE2, 0x0AE3, prCM, gcMn}, // [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL
+ {0x0AE6, 0x0AEF, prNU, gcNd}, // [10] GUJARATI DIGIT ZERO..GUJARATI DIGIT NINE
+ {0x0AF0, 0x0AF0, prAL, gcPo}, // GUJARATI ABBREVIATION SIGN
+ {0x0AF1, 0x0AF1, prPR, gcSc}, // GUJARATI RUPEE SIGN
+ {0x0AF9, 0x0AF9, prAL, gcLo}, // GUJARATI LETTER ZHA
+ {0x0AFA, 0x0AFF, prCM, gcMn}, // [6] GUJARATI SIGN SUKUN..GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE
+ {0x0B01, 0x0B01, prCM, gcMn}, // ORIYA SIGN CANDRABINDU
+ {0x0B02, 0x0B03, prCM, gcMc}, // [2] ORIYA SIGN ANUSVARA..ORIYA SIGN VISARGA
+ {0x0B05, 0x0B0C, prAL, gcLo}, // [8] ORIYA LETTER A..ORIYA LETTER VOCALIC L
+ {0x0B0F, 0x0B10, prAL, gcLo}, // [2] ORIYA LETTER E..ORIYA LETTER AI
+ {0x0B13, 0x0B28, prAL, gcLo}, // [22] ORIYA LETTER O..ORIYA LETTER NA
+ {0x0B2A, 0x0B30, prAL, gcLo}, // [7] ORIYA LETTER PA..ORIYA LETTER RA
+ {0x0B32, 0x0B33, prAL, gcLo}, // [2] ORIYA LETTER LA..ORIYA LETTER LLA
+ {0x0B35, 0x0B39, prAL, gcLo}, // [5] ORIYA LETTER VA..ORIYA LETTER HA
+ {0x0B3C, 0x0B3C, prCM, gcMn}, // ORIYA SIGN NUKTA
+ {0x0B3D, 0x0B3D, prAL, gcLo}, // ORIYA SIGN AVAGRAHA
+ {0x0B3E, 0x0B3E, prCM, gcMc}, // ORIYA VOWEL SIGN AA
+ {0x0B3F, 0x0B3F, prCM, gcMn}, // ORIYA VOWEL SIGN I
+ {0x0B40, 0x0B40, prCM, gcMc}, // ORIYA VOWEL SIGN II
+ {0x0B41, 0x0B44, prCM, gcMn}, // [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR
+ {0x0B47, 0x0B48, prCM, gcMc}, // [2] ORIYA VOWEL SIGN E..ORIYA VOWEL SIGN AI
+ {0x0B4B, 0x0B4C, prCM, gcMc}, // [2] ORIYA VOWEL SIGN O..ORIYA VOWEL SIGN AU
+ {0x0B4D, 0x0B4D, prCM, gcMn}, // ORIYA SIGN VIRAMA
+ {0x0B55, 0x0B56, prCM, gcMn}, // [2] ORIYA SIGN OVERLINE..ORIYA AI LENGTH MARK
+ {0x0B57, 0x0B57, prCM, gcMc}, // ORIYA AU LENGTH MARK
+ {0x0B5C, 0x0B5D, prAL, gcLo}, // [2] ORIYA LETTER RRA..ORIYA LETTER RHA
+ {0x0B5F, 0x0B61, prAL, gcLo}, // [3] ORIYA LETTER YYA..ORIYA LETTER VOCALIC LL
+ {0x0B62, 0x0B63, prCM, gcMn}, // [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL
+ {0x0B66, 0x0B6F, prNU, gcNd}, // [10] ORIYA DIGIT ZERO..ORIYA DIGIT NINE
+ {0x0B70, 0x0B70, prAL, gcSo}, // ORIYA ISSHAR
+ {0x0B71, 0x0B71, prAL, gcLo}, // ORIYA LETTER WA
+ {0x0B72, 0x0B77, prAL, gcNo}, // [6] ORIYA FRACTION ONE QUARTER..ORIYA FRACTION THREE SIXTEENTHS
+ {0x0B82, 0x0B82, prCM, gcMn}, // TAMIL SIGN ANUSVARA
+ {0x0B83, 0x0B83, prAL, gcLo}, // TAMIL SIGN VISARGA
+ {0x0B85, 0x0B8A, prAL, gcLo}, // [6] TAMIL LETTER A..TAMIL LETTER UU
+ {0x0B8E, 0x0B90, prAL, gcLo}, // [3] TAMIL LETTER E..TAMIL LETTER AI
+ {0x0B92, 0x0B95, prAL, gcLo}, // [4] TAMIL LETTER O..TAMIL LETTER KA
+ {0x0B99, 0x0B9A, prAL, gcLo}, // [2] TAMIL LETTER NGA..TAMIL LETTER CA
+ {0x0B9C, 0x0B9C, prAL, gcLo}, // TAMIL LETTER JA
+ {0x0B9E, 0x0B9F, prAL, gcLo}, // [2] TAMIL LETTER NYA..TAMIL LETTER TTA
+ {0x0BA3, 0x0BA4, prAL, gcLo}, // [2] TAMIL LETTER NNA..TAMIL LETTER TA
+ {0x0BA8, 0x0BAA, prAL, gcLo}, // [3] TAMIL LETTER NA..TAMIL LETTER PA
+ {0x0BAE, 0x0BB9, prAL, gcLo}, // [12] TAMIL LETTER MA..TAMIL LETTER HA
+ {0x0BBE, 0x0BBF, prCM, gcMc}, // [2] TAMIL VOWEL SIGN AA..TAMIL VOWEL SIGN I
+ {0x0BC0, 0x0BC0, prCM, gcMn}, // TAMIL VOWEL SIGN II
+ {0x0BC1, 0x0BC2, prCM, gcMc}, // [2] TAMIL VOWEL SIGN U..TAMIL VOWEL SIGN UU
+ {0x0BC6, 0x0BC8, prCM, gcMc}, // [3] TAMIL VOWEL SIGN E..TAMIL VOWEL SIGN AI
+ {0x0BCA, 0x0BCC, prCM, gcMc}, // [3] TAMIL VOWEL SIGN O..TAMIL VOWEL SIGN AU
+ {0x0BCD, 0x0BCD, prCM, gcMn}, // TAMIL SIGN VIRAMA
+ {0x0BD0, 0x0BD0, prAL, gcLo}, // TAMIL OM
+ {0x0BD7, 0x0BD7, prCM, gcMc}, // TAMIL AU LENGTH MARK
+ {0x0BE6, 0x0BEF, prNU, gcNd}, // [10] TAMIL DIGIT ZERO..TAMIL DIGIT NINE
+ {0x0BF0, 0x0BF2, prAL, gcNo}, // [3] TAMIL NUMBER TEN..TAMIL NUMBER ONE THOUSAND
+ {0x0BF3, 0x0BF8, prAL, gcSo}, // [6] TAMIL DAY SIGN..TAMIL AS ABOVE SIGN
+ {0x0BF9, 0x0BF9, prPR, gcSc}, // TAMIL RUPEE SIGN
+ {0x0BFA, 0x0BFA, prAL, gcSo}, // TAMIL NUMBER SIGN
+ {0x0C00, 0x0C00, prCM, gcMn}, // TELUGU SIGN COMBINING CANDRABINDU ABOVE
+ {0x0C01, 0x0C03, prCM, gcMc}, // [3] TELUGU SIGN CANDRABINDU..TELUGU SIGN VISARGA
+ {0x0C04, 0x0C04, prCM, gcMn}, // TELUGU SIGN COMBINING ANUSVARA ABOVE
+ {0x0C05, 0x0C0C, prAL, gcLo}, // [8] TELUGU LETTER A..TELUGU LETTER VOCALIC L
+ {0x0C0E, 0x0C10, prAL, gcLo}, // [3] TELUGU LETTER E..TELUGU LETTER AI
+ {0x0C12, 0x0C28, prAL, gcLo}, // [23] TELUGU LETTER O..TELUGU LETTER NA
+ {0x0C2A, 0x0C39, prAL, gcLo}, // [16] TELUGU LETTER PA..TELUGU LETTER HA
+ {0x0C3C, 0x0C3C, prCM, gcMn}, // TELUGU SIGN NUKTA
+ {0x0C3D, 0x0C3D, prAL, gcLo}, // TELUGU SIGN AVAGRAHA
+ {0x0C3E, 0x0C40, prCM, gcMn}, // [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II
+ {0x0C41, 0x0C44, prCM, gcMc}, // [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR
+ {0x0C46, 0x0C48, prCM, gcMn}, // [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI
+ {0x0C4A, 0x0C4D, prCM, gcMn}, // [4] TELUGU VOWEL SIGN O..TELUGU SIGN VIRAMA
+ {0x0C55, 0x0C56, prCM, gcMn}, // [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK
+ {0x0C58, 0x0C5A, prAL, gcLo}, // [3] TELUGU LETTER TSA..TELUGU LETTER RRRA
+ {0x0C5D, 0x0C5D, prAL, gcLo}, // TELUGU LETTER NAKAARA POLLU
+ {0x0C60, 0x0C61, prAL, gcLo}, // [2] TELUGU LETTER VOCALIC RR..TELUGU LETTER VOCALIC LL
+ {0x0C62, 0x0C63, prCM, gcMn}, // [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL
+ {0x0C66, 0x0C6F, prNU, gcNd}, // [10] TELUGU DIGIT ZERO..TELUGU DIGIT NINE
+ {0x0C77, 0x0C77, prBB, gcPo}, // TELUGU SIGN SIDDHAM
+ {0x0C78, 0x0C7E, prAL, gcNo}, // [7] TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR..TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR
+ {0x0C7F, 0x0C7F, prAL, gcSo}, // TELUGU SIGN TUUMU
+ {0x0C80, 0x0C80, prAL, gcLo}, // KANNADA SIGN SPACING CANDRABINDU
+ {0x0C81, 0x0C81, prCM, gcMn}, // KANNADA SIGN CANDRABINDU
+ {0x0C82, 0x0C83, prCM, gcMc}, // [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA
+ {0x0C84, 0x0C84, prBB, gcPo}, // KANNADA SIGN SIDDHAM
+ {0x0C85, 0x0C8C, prAL, gcLo}, // [8] KANNADA LETTER A..KANNADA LETTER VOCALIC L
+ {0x0C8E, 0x0C90, prAL, gcLo}, // [3] KANNADA LETTER E..KANNADA LETTER AI
+ {0x0C92, 0x0CA8, prAL, gcLo}, // [23] KANNADA LETTER O..KANNADA LETTER NA
+ {0x0CAA, 0x0CB3, prAL, gcLo}, // [10] KANNADA LETTER PA..KANNADA LETTER LLA
+ {0x0CB5, 0x0CB9, prAL, gcLo}, // [5] KANNADA LETTER VA..KANNADA LETTER HA
+ {0x0CBC, 0x0CBC, prCM, gcMn}, // KANNADA SIGN NUKTA
+ {0x0CBD, 0x0CBD, prAL, gcLo}, // KANNADA SIGN AVAGRAHA
+ {0x0CBE, 0x0CBE, prCM, gcMc}, // KANNADA VOWEL SIGN AA
+ {0x0CBF, 0x0CBF, prCM, gcMn}, // KANNADA VOWEL SIGN I
+ {0x0CC0, 0x0CC4, prCM, gcMc}, // [5] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN VOCALIC RR
+ {0x0CC6, 0x0CC6, prCM, gcMn}, // KANNADA VOWEL SIGN E
+ {0x0CC7, 0x0CC8, prCM, gcMc}, // [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI
+ {0x0CCA, 0x0CCB, prCM, gcMc}, // [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO
+ {0x0CCC, 0x0CCD, prCM, gcMn}, // [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA
+ {0x0CD5, 0x0CD6, prCM, gcMc}, // [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK
+ {0x0CDD, 0x0CDE, prAL, gcLo}, // [2] KANNADA LETTER NAKAARA POLLU..KANNADA LETTER FA
+ {0x0CE0, 0x0CE1, prAL, gcLo}, // [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL
+ {0x0CE2, 0x0CE3, prCM, gcMn}, // [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL
+ {0x0CE6, 0x0CEF, prNU, gcNd}, // [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE
+ {0x0CF1, 0x0CF2, prAL, gcLo}, // [2] KANNADA SIGN JIHVAMULIYA..KANNADA SIGN UPADHMANIYA
+ {0x0CF3, 0x0CF3, prCM, gcMc}, // KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT
+ {0x0D00, 0x0D01, prCM, gcMn}, // [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU
+ {0x0D02, 0x0D03, prCM, gcMc}, // [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA
+ {0x0D04, 0x0D0C, prAL, gcLo}, // [9] MALAYALAM LETTER VEDIC ANUSVARA..MALAYALAM LETTER VOCALIC L
+ {0x0D0E, 0x0D10, prAL, gcLo}, // [3] MALAYALAM LETTER E..MALAYALAM LETTER AI
+ {0x0D12, 0x0D3A, prAL, gcLo}, // [41] MALAYALAM LETTER O..MALAYALAM LETTER TTTA
+ {0x0D3B, 0x0D3C, prCM, gcMn}, // [2] MALAYALAM SIGN VERTICAL BAR VIRAMA..MALAYALAM SIGN CIRCULAR VIRAMA
+ {0x0D3D, 0x0D3D, prAL, gcLo}, // MALAYALAM SIGN AVAGRAHA
+ {0x0D3E, 0x0D40, prCM, gcMc}, // [3] MALAYALAM VOWEL SIGN AA..MALAYALAM VOWEL SIGN II
+ {0x0D41, 0x0D44, prCM, gcMn}, // [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR
+ {0x0D46, 0x0D48, prCM, gcMc}, // [3] MALAYALAM VOWEL SIGN E..MALAYALAM VOWEL SIGN AI
+ {0x0D4A, 0x0D4C, prCM, gcMc}, // [3] MALAYALAM VOWEL SIGN O..MALAYALAM VOWEL SIGN AU
+ {0x0D4D, 0x0D4D, prCM, gcMn}, // MALAYALAM SIGN VIRAMA
+ {0x0D4E, 0x0D4E, prAL, gcLo}, // MALAYALAM LETTER DOT REPH
+ {0x0D4F, 0x0D4F, prAL, gcSo}, // MALAYALAM SIGN PARA
+ {0x0D54, 0x0D56, prAL, gcLo}, // [3] MALAYALAM LETTER CHILLU M..MALAYALAM LETTER CHILLU LLL
+ {0x0D57, 0x0D57, prCM, gcMc}, // MALAYALAM AU LENGTH MARK
+ {0x0D58, 0x0D5E, prAL, gcNo}, // [7] MALAYALAM FRACTION ONE ONE-HUNDRED-AND-SIXTIETH..MALAYALAM FRACTION ONE FIFTH
+ {0x0D5F, 0x0D61, prAL, gcLo}, // [3] MALAYALAM LETTER ARCHAIC II..MALAYALAM LETTER VOCALIC LL
+ {0x0D62, 0x0D63, prCM, gcMn}, // [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL
+ {0x0D66, 0x0D6F, prNU, gcNd}, // [10] MALAYALAM DIGIT ZERO..MALAYALAM DIGIT NINE
+ {0x0D70, 0x0D78, prAL, gcNo}, // [9] MALAYALAM NUMBER TEN..MALAYALAM FRACTION THREE SIXTEENTHS
+ {0x0D79, 0x0D79, prPO, gcSo}, // MALAYALAM DATE MARK
+ {0x0D7A, 0x0D7F, prAL, gcLo}, // [6] MALAYALAM LETTER CHILLU NN..MALAYALAM LETTER CHILLU K
+ {0x0D81, 0x0D81, prCM, gcMn}, // SINHALA SIGN CANDRABINDU
+ {0x0D82, 0x0D83, prCM, gcMc}, // [2] SINHALA SIGN ANUSVARAYA..SINHALA SIGN VISARGAYA
+ {0x0D85, 0x0D96, prAL, gcLo}, // [18] SINHALA LETTER AYANNA..SINHALA LETTER AUYANNA
+ {0x0D9A, 0x0DB1, prAL, gcLo}, // [24] SINHALA LETTER ALPAPRAANA KAYANNA..SINHALA LETTER DANTAJA NAYANNA
+ {0x0DB3, 0x0DBB, prAL, gcLo}, // [9] SINHALA LETTER SANYAKA DAYANNA..SINHALA LETTER RAYANNA
+ {0x0DBD, 0x0DBD, prAL, gcLo}, // SINHALA LETTER DANTAJA LAYANNA
+ {0x0DC0, 0x0DC6, prAL, gcLo}, // [7] SINHALA LETTER VAYANNA..SINHALA LETTER FAYANNA
+ {0x0DCA, 0x0DCA, prCM, gcMn}, // SINHALA SIGN AL-LAKUNA
+ {0x0DCF, 0x0DD1, prCM, gcMc}, // [3] SINHALA VOWEL SIGN AELA-PILLA..SINHALA VOWEL SIGN DIGA AEDA-PILLA
+ {0x0DD2, 0x0DD4, prCM, gcMn}, // [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA
+ {0x0DD6, 0x0DD6, prCM, gcMn}, // SINHALA VOWEL SIGN DIGA PAA-PILLA
+ {0x0DD8, 0x0DDF, prCM, gcMc}, // [8] SINHALA VOWEL SIGN GAETTA-PILLA..SINHALA VOWEL SIGN GAYANUKITTA
+ {0x0DE6, 0x0DEF, prNU, gcNd}, // [10] SINHALA LITH DIGIT ZERO..SINHALA LITH DIGIT NINE
+ {0x0DF2, 0x0DF3, prCM, gcMc}, // [2] SINHALA VOWEL SIGN DIGA GAETTA-PILLA..SINHALA VOWEL SIGN DIGA GAYANUKITTA
+ {0x0DF4, 0x0DF4, prAL, gcPo}, // SINHALA PUNCTUATION KUNDDALIYA
+ {0x0E01, 0x0E30, prSA, gcLo}, // [48] THAI CHARACTER KO KAI..THAI CHARACTER SARA A
+ {0x0E31, 0x0E31, prSA, gcMn}, // THAI CHARACTER MAI HAN-AKAT
+ {0x0E32, 0x0E33, prSA, gcLo}, // [2] THAI CHARACTER SARA AA..THAI CHARACTER SARA AM
+ {0x0E34, 0x0E3A, prSA, gcMn}, // [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU
+ {0x0E3F, 0x0E3F, prPR, gcSc}, // THAI CURRENCY SYMBOL BAHT
+ {0x0E40, 0x0E45, prSA, gcLo}, // [6] THAI CHARACTER SARA E..THAI CHARACTER LAKKHANGYAO
+ {0x0E46, 0x0E46, prSA, gcLm}, // THAI CHARACTER MAIYAMOK
+ {0x0E47, 0x0E4E, prSA, gcMn}, // [8] THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN
+ {0x0E4F, 0x0E4F, prAL, gcPo}, // THAI CHARACTER FONGMAN
+ {0x0E50, 0x0E59, prNU, gcNd}, // [10] THAI DIGIT ZERO..THAI DIGIT NINE
+ {0x0E5A, 0x0E5B, prBA, gcPo}, // [2] THAI CHARACTER ANGKHANKHU..THAI CHARACTER KHOMUT
+ {0x0E81, 0x0E82, prSA, gcLo}, // [2] LAO LETTER KO..LAO LETTER KHO SUNG
+ {0x0E84, 0x0E84, prSA, gcLo}, // LAO LETTER KHO TAM
+ {0x0E86, 0x0E8A, prSA, gcLo}, // [5] LAO LETTER PALI GHA..LAO LETTER SO TAM
+ {0x0E8C, 0x0EA3, prSA, gcLo}, // [24] LAO LETTER PALI JHA..LAO LETTER LO LING
+ {0x0EA5, 0x0EA5, prSA, gcLo}, // LAO LETTER LO LOOT
+ {0x0EA7, 0x0EB0, prSA, gcLo}, // [10] LAO LETTER WO..LAO VOWEL SIGN A
+ {0x0EB1, 0x0EB1, prSA, gcMn}, // LAO VOWEL SIGN MAI KAN
+ {0x0EB2, 0x0EB3, prSA, gcLo}, // [2] LAO VOWEL SIGN AA..LAO VOWEL SIGN AM
+ {0x0EB4, 0x0EBC, prSA, gcMn}, // [9] LAO VOWEL SIGN I..LAO SEMIVOWEL SIGN LO
+ {0x0EBD, 0x0EBD, prSA, gcLo}, // LAO SEMIVOWEL SIGN NYO
+ {0x0EC0, 0x0EC4, prSA, gcLo}, // [5] LAO VOWEL SIGN E..LAO VOWEL SIGN AI
+ {0x0EC6, 0x0EC6, prSA, gcLm}, // LAO KO LA
+ {0x0EC8, 0x0ECE, prSA, gcMn}, // [7] LAO TONE MAI EK..LAO YAMAKKAN
+ {0x0ED0, 0x0ED9, prNU, gcNd}, // [10] LAO DIGIT ZERO..LAO DIGIT NINE
+ {0x0EDC, 0x0EDF, prSA, gcLo}, // [4] LAO HO NO..LAO LETTER KHMU NYO
+ {0x0F00, 0x0F00, prAL, gcLo}, // TIBETAN SYLLABLE OM
+ {0x0F01, 0x0F03, prBB, gcSo}, // [3] TIBETAN MARK GTER YIG MGO TRUNCATED A..TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA
+ {0x0F04, 0x0F04, prBB, gcPo}, // TIBETAN MARK INITIAL YIG MGO MDUN MA
+ {0x0F05, 0x0F05, prAL, gcPo}, // TIBETAN MARK CLOSING YIG MGO SGAB MA
+ {0x0F06, 0x0F07, prBB, gcPo}, // [2] TIBETAN MARK CARET YIG MGO PHUR SHAD MA..TIBETAN MARK YIG MGO TSHEG SHAD MA
+ {0x0F08, 0x0F08, prGL, gcPo}, // TIBETAN MARK SBRUL SHAD
+ {0x0F09, 0x0F0A, prBB, gcPo}, // [2] TIBETAN MARK BSKUR YIG MGO..TIBETAN MARK BKA- SHOG YIG MGO
+ {0x0F0B, 0x0F0B, prBA, gcPo}, // TIBETAN MARK INTERSYLLABIC TSHEG
+ {0x0F0C, 0x0F0C, prGL, gcPo}, // TIBETAN MARK DELIMITER TSHEG BSTAR
+ {0x0F0D, 0x0F11, prEX, gcPo}, // [5] TIBETAN MARK SHAD..TIBETAN MARK RIN CHEN SPUNGS SHAD
+ {0x0F12, 0x0F12, prGL, gcPo}, // TIBETAN MARK RGYA GRAM SHAD
+ {0x0F13, 0x0F13, prAL, gcSo}, // TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN
+ {0x0F14, 0x0F14, prEX, gcPo}, // TIBETAN MARK GTER TSHEG
+ {0x0F15, 0x0F17, prAL, gcSo}, // [3] TIBETAN LOGOTYPE SIGN CHAD RTAGS..TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS
+ {0x0F18, 0x0F19, prCM, gcMn}, // [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS
+ {0x0F1A, 0x0F1F, prAL, gcSo}, // [6] TIBETAN SIGN RDEL DKAR GCIG..TIBETAN SIGN RDEL DKAR RDEL NAG
+ {0x0F20, 0x0F29, prNU, gcNd}, // [10] TIBETAN DIGIT ZERO..TIBETAN DIGIT NINE
+ {0x0F2A, 0x0F33, prAL, gcNo}, // [10] TIBETAN DIGIT HALF ONE..TIBETAN DIGIT HALF ZERO
+ {0x0F34, 0x0F34, prBA, gcSo}, // TIBETAN MARK BSDUS RTAGS
+ {0x0F35, 0x0F35, prCM, gcMn}, // TIBETAN MARK NGAS BZUNG NYI ZLA
+ {0x0F36, 0x0F36, prAL, gcSo}, // TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN
+ {0x0F37, 0x0F37, prCM, gcMn}, // TIBETAN MARK NGAS BZUNG SGOR RTAGS
+ {0x0F38, 0x0F38, prAL, gcSo}, // TIBETAN MARK CHE MGO
+ {0x0F39, 0x0F39, prCM, gcMn}, // TIBETAN MARK TSA -PHRU
+ {0x0F3A, 0x0F3A, prOP, gcPs}, // TIBETAN MARK GUG RTAGS GYON
+ {0x0F3B, 0x0F3B, prCL, gcPe}, // TIBETAN MARK GUG RTAGS GYAS
+ {0x0F3C, 0x0F3C, prOP, gcPs}, // TIBETAN MARK ANG KHANG GYON
+ {0x0F3D, 0x0F3D, prCL, gcPe}, // TIBETAN MARK ANG KHANG GYAS
+ {0x0F3E, 0x0F3F, prCM, gcMc}, // [2] TIBETAN SIGN YAR TSHES..TIBETAN SIGN MAR TSHES
+ {0x0F40, 0x0F47, prAL, gcLo}, // [8] TIBETAN LETTER KA..TIBETAN LETTER JA
+ {0x0F49, 0x0F6C, prAL, gcLo}, // [36] TIBETAN LETTER NYA..TIBETAN LETTER RRA
+ {0x0F71, 0x0F7E, prCM, gcMn}, // [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO
+ {0x0F7F, 0x0F7F, prBA, gcMc}, // TIBETAN SIGN RNAM BCAD
+ {0x0F80, 0x0F84, prCM, gcMn}, // [5] TIBETAN VOWEL SIGN REVERSED I..TIBETAN MARK HALANTA
+ {0x0F85, 0x0F85, prBA, gcPo}, // TIBETAN MARK PALUTA
+ {0x0F86, 0x0F87, prCM, gcMn}, // [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS
+ {0x0F88, 0x0F8C, prAL, gcLo}, // [5] TIBETAN SIGN LCE TSA CAN..TIBETAN SIGN INVERTED MCHU CAN
+ {0x0F8D, 0x0F97, prCM, gcMn}, // [11] TIBETAN SUBJOINED SIGN LCE TSA CAN..TIBETAN SUBJOINED LETTER JA
+ {0x0F99, 0x0FBC, prCM, gcMn}, // [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA
+ {0x0FBE, 0x0FBF, prBA, gcSo}, // [2] TIBETAN KU RU KHA..TIBETAN KU RU KHA BZHI MIG CAN
+ {0x0FC0, 0x0FC5, prAL, gcSo}, // [6] TIBETAN CANTILLATION SIGN HEAVY BEAT..TIBETAN SYMBOL RDO RJE
+ {0x0FC6, 0x0FC6, prCM, gcMn}, // TIBETAN SYMBOL PADMA GDAN
+ {0x0FC7, 0x0FCC, prAL, gcSo}, // [6] TIBETAN SYMBOL RDO RJE RGYA GRAM..TIBETAN SYMBOL NOR BU BZHI -KHYIL
+ {0x0FCE, 0x0FCF, prAL, gcSo}, // [2] TIBETAN SIGN RDEL NAG RDEL DKAR..TIBETAN SIGN RDEL NAG GSUM
+ {0x0FD0, 0x0FD1, prBB, gcPo}, // [2] TIBETAN MARK BSKA- SHOG GI MGO RGYAN..TIBETAN MARK MNYAM YIG GI MGO RGYAN
+ {0x0FD2, 0x0FD2, prBA, gcPo}, // TIBETAN MARK NYIS TSHEG
+ {0x0FD3, 0x0FD3, prBB, gcPo}, // TIBETAN MARK INITIAL BRDA RNYING YIG MGO MDUN MA
+ {0x0FD4, 0x0FD4, prAL, gcPo}, // TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA
+ {0x0FD5, 0x0FD8, prAL, gcSo}, // [4] RIGHT-FACING SVASTI SIGN..LEFT-FACING SVASTI SIGN WITH DOTS
+ {0x0FD9, 0x0FDA, prGL, gcPo}, // [2] TIBETAN MARK LEADING MCHAN RTAGS..TIBETAN MARK TRAILING MCHAN RTAGS
+ {0x1000, 0x102A, prSA, gcLo}, // [43] MYANMAR LETTER KA..MYANMAR LETTER AU
+ {0x102B, 0x102C, prSA, gcMc}, // [2] MYANMAR VOWEL SIGN TALL AA..MYANMAR VOWEL SIGN AA
+ {0x102D, 0x1030, prSA, gcMn}, // [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU
+ {0x1031, 0x1031, prSA, gcMc}, // MYANMAR VOWEL SIGN E
+ {0x1032, 0x1037, prSA, gcMn}, // [6] MYANMAR VOWEL SIGN AI..MYANMAR SIGN DOT BELOW
+ {0x1038, 0x1038, prSA, gcMc}, // MYANMAR SIGN VISARGA
+ {0x1039, 0x103A, prSA, gcMn}, // [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT
+ {0x103B, 0x103C, prSA, gcMc}, // [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA
+ {0x103D, 0x103E, prSA, gcMn}, // [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA
+ {0x103F, 0x103F, prSA, gcLo}, // MYANMAR LETTER GREAT SA
+ {0x1040, 0x1049, prNU, gcNd}, // [10] MYANMAR DIGIT ZERO..MYANMAR DIGIT NINE
+ {0x104A, 0x104B, prBA, gcPo}, // [2] MYANMAR SIGN LITTLE SECTION..MYANMAR SIGN SECTION
+ {0x104C, 0x104F, prAL, gcPo}, // [4] MYANMAR SYMBOL LOCATIVE..MYANMAR SYMBOL GENITIVE
+ {0x1050, 0x1055, prSA, gcLo}, // [6] MYANMAR LETTER SHA..MYANMAR LETTER VOCALIC LL
+ {0x1056, 0x1057, prSA, gcMc}, // [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR
+ {0x1058, 0x1059, prSA, gcMn}, // [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL
+ {0x105A, 0x105D, prSA, gcLo}, // [4] MYANMAR LETTER MON NGA..MYANMAR LETTER MON BBE
+ {0x105E, 0x1060, prSA, gcMn}, // [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA
+ {0x1061, 0x1061, prSA, gcLo}, // MYANMAR LETTER SGAW KAREN SHA
+ {0x1062, 0x1064, prSA, gcMc}, // [3] MYANMAR VOWEL SIGN SGAW KAREN EU..MYANMAR TONE MARK SGAW KAREN KE PHO
+ {0x1065, 0x1066, prSA, gcLo}, // [2] MYANMAR LETTER WESTERN PWO KAREN THA..MYANMAR LETTER WESTERN PWO KAREN PWA
+ {0x1067, 0x106D, prSA, gcMc}, // [7] MYANMAR VOWEL SIGN WESTERN PWO KAREN EU..MYANMAR SIGN WESTERN PWO KAREN TONE-5
+ {0x106E, 0x1070, prSA, gcLo}, // [3] MYANMAR LETTER EASTERN PWO KAREN NNA..MYANMAR LETTER EASTERN PWO KAREN GHWA
+ {0x1071, 0x1074, prSA, gcMn}, // [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE
+ {0x1075, 0x1081, prSA, gcLo}, // [13] MYANMAR LETTER SHAN KA..MYANMAR LETTER SHAN HA
+ {0x1082, 0x1082, prSA, gcMn}, // MYANMAR CONSONANT SIGN SHAN MEDIAL WA
+ {0x1083, 0x1084, prSA, gcMc}, // [2] MYANMAR VOWEL SIGN SHAN AA..MYANMAR VOWEL SIGN SHAN E
+ {0x1085, 0x1086, prSA, gcMn}, // [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y
+ {0x1087, 0x108C, prSA, gcMc}, // [6] MYANMAR SIGN SHAN TONE-2..MYANMAR SIGN SHAN COUNCIL TONE-3
+ {0x108D, 0x108D, prSA, gcMn}, // MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE
+ {0x108E, 0x108E, prSA, gcLo}, // MYANMAR LETTER RUMAI PALAUNG FA
+ {0x108F, 0x108F, prSA, gcMc}, // MYANMAR SIGN RUMAI PALAUNG TONE-5
+ {0x1090, 0x1099, prNU, gcNd}, // [10] MYANMAR SHAN DIGIT ZERO..MYANMAR SHAN DIGIT NINE
+ {0x109A, 0x109C, prSA, gcMc}, // [3] MYANMAR SIGN KHAMTI TONE-1..MYANMAR VOWEL SIGN AITON A
+ {0x109D, 0x109D, prSA, gcMn}, // MYANMAR VOWEL SIGN AITON AI
+ {0x109E, 0x109F, prSA, gcSo}, // [2] MYANMAR SYMBOL SHAN ONE..MYANMAR SYMBOL SHAN EXCLAMATION
+ {0x10A0, 0x10C5, prAL, gcLu}, // [38] GEORGIAN CAPITAL LETTER AN..GEORGIAN CAPITAL LETTER HOE
+ {0x10C7, 0x10C7, prAL, gcLu}, // GEORGIAN CAPITAL LETTER YN
+ {0x10CD, 0x10CD, prAL, gcLu}, // GEORGIAN CAPITAL LETTER AEN
+ {0x10D0, 0x10FA, prAL, gcLl}, // [43] GEORGIAN LETTER AN..GEORGIAN LETTER AIN
+ {0x10FB, 0x10FB, prAL, gcPo}, // GEORGIAN PARAGRAPH SEPARATOR
+ {0x10FC, 0x10FC, prAL, gcLm}, // MODIFIER LETTER GEORGIAN NAR
+ {0x10FD, 0x10FF, prAL, gcLl}, // [3] GEORGIAN LETTER AEN..GEORGIAN LETTER LABIAL SIGN
+ {0x1100, 0x115F, prJL, gcLo}, // [96] HANGUL CHOSEONG KIYEOK..HANGUL CHOSEONG FILLER
+ {0x1160, 0x11A7, prJV, gcLo}, // [72] HANGUL JUNGSEONG FILLER..HANGUL JUNGSEONG O-YAE
+ {0x11A8, 0x11FF, prJT, gcLo}, // [88] HANGUL JONGSEONG KIYEOK..HANGUL JONGSEONG SSANGNIEUN
+ {0x1200, 0x1248, prAL, gcLo}, // [73] ETHIOPIC SYLLABLE HA..ETHIOPIC SYLLABLE QWA
+ {0x124A, 0x124D, prAL, gcLo}, // [4] ETHIOPIC SYLLABLE QWI..ETHIOPIC SYLLABLE QWE
+ {0x1250, 0x1256, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE QHA..ETHIOPIC SYLLABLE QHO
+ {0x1258, 0x1258, prAL, gcLo}, // ETHIOPIC SYLLABLE QHWA
+ {0x125A, 0x125D, prAL, gcLo}, // [4] ETHIOPIC SYLLABLE QHWI..ETHIOPIC SYLLABLE QHWE
+ {0x1260, 0x1288, prAL, gcLo}, // [41] ETHIOPIC SYLLABLE BA..ETHIOPIC SYLLABLE XWA
+ {0x128A, 0x128D, prAL, gcLo}, // [4] ETHIOPIC SYLLABLE XWI..ETHIOPIC SYLLABLE XWE
+ {0x1290, 0x12B0, prAL, gcLo}, // [33] ETHIOPIC SYLLABLE NA..ETHIOPIC SYLLABLE KWA
+ {0x12B2, 0x12B5, prAL, gcLo}, // [4] ETHIOPIC SYLLABLE KWI..ETHIOPIC SYLLABLE KWE
+ {0x12B8, 0x12BE, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE KXA..ETHIOPIC SYLLABLE KXO
+ {0x12C0, 0x12C0, prAL, gcLo}, // ETHIOPIC SYLLABLE KXWA
+ {0x12C2, 0x12C5, prAL, gcLo}, // [4] ETHIOPIC SYLLABLE KXWI..ETHIOPIC SYLLABLE KXWE
+ {0x12C8, 0x12D6, prAL, gcLo}, // [15] ETHIOPIC SYLLABLE WA..ETHIOPIC SYLLABLE PHARYNGEAL O
+ {0x12D8, 0x1310, prAL, gcLo}, // [57] ETHIOPIC SYLLABLE ZA..ETHIOPIC SYLLABLE GWA
+ {0x1312, 0x1315, prAL, gcLo}, // [4] ETHIOPIC SYLLABLE GWI..ETHIOPIC SYLLABLE GWE
+ {0x1318, 0x135A, prAL, gcLo}, // [67] ETHIOPIC SYLLABLE GGA..ETHIOPIC SYLLABLE FYA
+ {0x135D, 0x135F, prCM, gcMn}, // [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK
+ {0x1360, 0x1360, prAL, gcPo}, // ETHIOPIC SECTION MARK
+ {0x1361, 0x1361, prBA, gcPo}, // ETHIOPIC WORDSPACE
+ {0x1362, 0x1368, prAL, gcPo}, // [7] ETHIOPIC FULL STOP..ETHIOPIC PARAGRAPH SEPARATOR
+ {0x1369, 0x137C, prAL, gcNo}, // [20] ETHIOPIC DIGIT ONE..ETHIOPIC NUMBER TEN THOUSAND
+ {0x1380, 0x138F, prAL, gcLo}, // [16] ETHIOPIC SYLLABLE SEBATBEIT MWA..ETHIOPIC SYLLABLE PWE
+ {0x1390, 0x1399, prAL, gcSo}, // [10] ETHIOPIC TONAL MARK YIZET..ETHIOPIC TONAL MARK KURT
+ {0x13A0, 0x13F5, prAL, gcLu}, // [86] CHEROKEE LETTER A..CHEROKEE LETTER MV
+ {0x13F8, 0x13FD, prAL, gcLl}, // [6] CHEROKEE SMALL LETTER YE..CHEROKEE SMALL LETTER MV
+ {0x1400, 0x1400, prBA, gcPd}, // CANADIAN SYLLABICS HYPHEN
+ {0x1401, 0x166C, prAL, gcLo}, // [620] CANADIAN SYLLABICS E..CANADIAN SYLLABICS CARRIER TTSA
+ {0x166D, 0x166D, prAL, gcSo}, // CANADIAN SYLLABICS CHI SIGN
+ {0x166E, 0x166E, prAL, gcPo}, // CANADIAN SYLLABICS FULL STOP
+ {0x166F, 0x167F, prAL, gcLo}, // [17] CANADIAN SYLLABICS QAI..CANADIAN SYLLABICS BLACKFOOT W
+ {0x1680, 0x1680, prBA, gcZs}, // OGHAM SPACE MARK
+ {0x1681, 0x169A, prAL, gcLo}, // [26] OGHAM LETTER BEITH..OGHAM LETTER PEITH
+ {0x169B, 0x169B, prOP, gcPs}, // OGHAM FEATHER MARK
+ {0x169C, 0x169C, prCL, gcPe}, // OGHAM REVERSED FEATHER MARK
+ {0x16A0, 0x16EA, prAL, gcLo}, // [75] RUNIC LETTER FEHU FEOH FE F..RUNIC LETTER X
+ {0x16EB, 0x16ED, prBA, gcPo}, // [3] RUNIC SINGLE PUNCTUATION..RUNIC CROSS PUNCTUATION
+ {0x16EE, 0x16F0, prAL, gcNl}, // [3] RUNIC ARLAUG SYMBOL..RUNIC BELGTHOR SYMBOL
+ {0x16F1, 0x16F8, prAL, gcLo}, // [8] RUNIC LETTER K..RUNIC LETTER FRANKS CASKET AESC
+ {0x1700, 0x1711, prAL, gcLo}, // [18] TAGALOG LETTER A..TAGALOG LETTER HA
+ {0x1712, 0x1714, prCM, gcMn}, // [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA
+ {0x1715, 0x1715, prCM, gcMc}, // TAGALOG SIGN PAMUDPOD
+ {0x171F, 0x171F, prAL, gcLo}, // TAGALOG LETTER ARCHAIC RA
+ {0x1720, 0x1731, prAL, gcLo}, // [18] HANUNOO LETTER A..HANUNOO LETTER HA
+ {0x1732, 0x1733, prCM, gcMn}, // [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U
+ {0x1734, 0x1734, prCM, gcMc}, // HANUNOO SIGN PAMUDPOD
+ {0x1735, 0x1736, prBA, gcPo}, // [2] PHILIPPINE SINGLE PUNCTUATION..PHILIPPINE DOUBLE PUNCTUATION
+ {0x1740, 0x1751, prAL, gcLo}, // [18] BUHID LETTER A..BUHID LETTER HA
+ {0x1752, 0x1753, prCM, gcMn}, // [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U
+ {0x1760, 0x176C, prAL, gcLo}, // [13] TAGBANWA LETTER A..TAGBANWA LETTER YA
+ {0x176E, 0x1770, prAL, gcLo}, // [3] TAGBANWA LETTER LA..TAGBANWA LETTER SA
+ {0x1772, 0x1773, prCM, gcMn}, // [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U
+ {0x1780, 0x17B3, prSA, gcLo}, // [52] KHMER LETTER KA..KHMER INDEPENDENT VOWEL QAU
+ {0x17B4, 0x17B5, prSA, gcMn}, // [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA
+ {0x17B6, 0x17B6, prSA, gcMc}, // KHMER VOWEL SIGN AA
+ {0x17B7, 0x17BD, prSA, gcMn}, // [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA
+ {0x17BE, 0x17C5, prSA, gcMc}, // [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU
+ {0x17C6, 0x17C6, prSA, gcMn}, // KHMER SIGN NIKAHIT
+ {0x17C7, 0x17C8, prSA, gcMc}, // [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU
+ {0x17C9, 0x17D3, prSA, gcMn}, // [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT
+ {0x17D4, 0x17D5, prBA, gcPo}, // [2] KHMER SIGN KHAN..KHMER SIGN BARIYOOSAN
+ {0x17D6, 0x17D6, prNS, gcPo}, // KHMER SIGN CAMNUC PII KUUH
+ {0x17D7, 0x17D7, prSA, gcLm}, // KHMER SIGN LEK TOO
+ {0x17D8, 0x17D8, prBA, gcPo}, // KHMER SIGN BEYYAL
+ {0x17D9, 0x17D9, prAL, gcPo}, // KHMER SIGN PHNAEK MUAN
+ {0x17DA, 0x17DA, prBA, gcPo}, // KHMER SIGN KOOMUUT
+ {0x17DB, 0x17DB, prPR, gcSc}, // KHMER CURRENCY SYMBOL RIEL
+ {0x17DC, 0x17DC, prSA, gcLo}, // KHMER SIGN AVAKRAHASANYA
+ {0x17DD, 0x17DD, prSA, gcMn}, // KHMER SIGN ATTHACAN
+ {0x17E0, 0x17E9, prNU, gcNd}, // [10] KHMER DIGIT ZERO..KHMER DIGIT NINE
+ {0x17F0, 0x17F9, prAL, gcNo}, // [10] KHMER SYMBOL LEK ATTAK SON..KHMER SYMBOL LEK ATTAK PRAM-BUON
+ {0x1800, 0x1801, prAL, gcPo}, // [2] MONGOLIAN BIRGA..MONGOLIAN ELLIPSIS
+ {0x1802, 0x1803, prEX, gcPo}, // [2] MONGOLIAN COMMA..MONGOLIAN FULL STOP
+ {0x1804, 0x1805, prBA, gcPo}, // [2] MONGOLIAN COLON..MONGOLIAN FOUR DOTS
+ {0x1806, 0x1806, prBB, gcPd}, // MONGOLIAN TODO SOFT HYPHEN
+ {0x1807, 0x1807, prAL, gcPo}, // MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER
+ {0x1808, 0x1809, prEX, gcPo}, // [2] MONGOLIAN MANCHU COMMA..MONGOLIAN MANCHU FULL STOP
+ {0x180A, 0x180A, prAL, gcPo}, // MONGOLIAN NIRUGU
+ {0x180B, 0x180D, prCM, gcMn}, // [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE
+ {0x180E, 0x180E, prGL, gcCf}, // MONGOLIAN VOWEL SEPARATOR
+ {0x180F, 0x180F, prCM, gcMn}, // MONGOLIAN FREE VARIATION SELECTOR FOUR
+ {0x1810, 0x1819, prNU, gcNd}, // [10] MONGOLIAN DIGIT ZERO..MONGOLIAN DIGIT NINE
+ {0x1820, 0x1842, prAL, gcLo}, // [35] MONGOLIAN LETTER A..MONGOLIAN LETTER CHI
+ {0x1843, 0x1843, prAL, gcLm}, // MONGOLIAN LETTER TODO LONG VOWEL SIGN
+ {0x1844, 0x1878, prAL, gcLo}, // [53] MONGOLIAN LETTER TODO E..MONGOLIAN LETTER CHA WITH TWO DOTS
+ {0x1880, 0x1884, prAL, gcLo}, // [5] MONGOLIAN LETTER ALI GALI ANUSVARA ONE..MONGOLIAN LETTER ALI GALI INVERTED UBADAMA
+ {0x1885, 0x1886, prCM, gcMn}, // [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA
+ {0x1887, 0x18A8, prAL, gcLo}, // [34] MONGOLIAN LETTER ALI GALI A..MONGOLIAN LETTER MANCHU ALI GALI BHA
+ {0x18A9, 0x18A9, prCM, gcMn}, // MONGOLIAN LETTER ALI GALI DAGALGA
+ {0x18AA, 0x18AA, prAL, gcLo}, // MONGOLIAN LETTER MANCHU ALI GALI LHA
+ {0x18B0, 0x18F5, prAL, gcLo}, // [70] CANADIAN SYLLABICS OY..CANADIAN SYLLABICS CARRIER DENTAL S
+ {0x1900, 0x191E, prAL, gcLo}, // [31] LIMBU VOWEL-CARRIER LETTER..LIMBU LETTER TRA
+ {0x1920, 0x1922, prCM, gcMn}, // [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U
+ {0x1923, 0x1926, prCM, gcMc}, // [4] LIMBU VOWEL SIGN EE..LIMBU VOWEL SIGN AU
+ {0x1927, 0x1928, prCM, gcMn}, // [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O
+ {0x1929, 0x192B, prCM, gcMc}, // [3] LIMBU SUBJOINED LETTER YA..LIMBU SUBJOINED LETTER WA
+ {0x1930, 0x1931, prCM, gcMc}, // [2] LIMBU SMALL LETTER KA..LIMBU SMALL LETTER NGA
+ {0x1932, 0x1932, prCM, gcMn}, // LIMBU SMALL LETTER ANUSVARA
+ {0x1933, 0x1938, prCM, gcMc}, // [6] LIMBU SMALL LETTER TA..LIMBU SMALL LETTER LA
+ {0x1939, 0x193B, prCM, gcMn}, // [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I
+ {0x1940, 0x1940, prAL, gcSo}, // LIMBU SIGN LOO
+ {0x1944, 0x1945, prEX, gcPo}, // [2] LIMBU EXCLAMATION MARK..LIMBU QUESTION MARK
+ {0x1946, 0x194F, prNU, gcNd}, // [10] LIMBU DIGIT ZERO..LIMBU DIGIT NINE
+ {0x1950, 0x196D, prSA, gcLo}, // [30] TAI LE LETTER KA..TAI LE LETTER AI
+ {0x1970, 0x1974, prSA, gcLo}, // [5] TAI LE LETTER TONE-2..TAI LE LETTER TONE-6
+ {0x1980, 0x19AB, prSA, gcLo}, // [44] NEW TAI LUE LETTER HIGH QA..NEW TAI LUE LETTER LOW SUA
+ {0x19B0, 0x19C9, prSA, gcLo}, // [26] NEW TAI LUE VOWEL SIGN VOWEL SHORTENER..NEW TAI LUE TONE MARK-2
+ {0x19D0, 0x19D9, prNU, gcNd}, // [10] NEW TAI LUE DIGIT ZERO..NEW TAI LUE DIGIT NINE
+ {0x19DA, 0x19DA, prSA, gcNo}, // NEW TAI LUE THAM DIGIT ONE
+ {0x19DE, 0x19DF, prSA, gcSo}, // [2] NEW TAI LUE SIGN LAE..NEW TAI LUE SIGN LAEV
+ {0x19E0, 0x19FF, prAL, gcSo}, // [32] KHMER SYMBOL PATHAMASAT..KHMER SYMBOL DAP-PRAM ROC
+ {0x1A00, 0x1A16, prAL, gcLo}, // [23] BUGINESE LETTER KA..BUGINESE LETTER HA
+ {0x1A17, 0x1A18, prCM, gcMn}, // [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U
+ {0x1A19, 0x1A1A, prCM, gcMc}, // [2] BUGINESE VOWEL SIGN E..BUGINESE VOWEL SIGN O
+ {0x1A1B, 0x1A1B, prCM, gcMn}, // BUGINESE VOWEL SIGN AE
+ {0x1A1E, 0x1A1F, prAL, gcPo}, // [2] BUGINESE PALLAWA..BUGINESE END OF SECTION
+ {0x1A20, 0x1A54, prSA, gcLo}, // [53] TAI THAM LETTER HIGH KA..TAI THAM LETTER GREAT SA
+ {0x1A55, 0x1A55, prSA, gcMc}, // TAI THAM CONSONANT SIGN MEDIAL RA
+ {0x1A56, 0x1A56, prSA, gcMn}, // TAI THAM CONSONANT SIGN MEDIAL LA
+ {0x1A57, 0x1A57, prSA, gcMc}, // TAI THAM CONSONANT SIGN LA TANG LAI
+ {0x1A58, 0x1A5E, prSA, gcMn}, // [7] TAI THAM SIGN MAI KANG LAI..TAI THAM CONSONANT SIGN SA
+ {0x1A60, 0x1A60, prSA, gcMn}, // TAI THAM SIGN SAKOT
+ {0x1A61, 0x1A61, prSA, gcMc}, // TAI THAM VOWEL SIGN A
+ {0x1A62, 0x1A62, prSA, gcMn}, // TAI THAM VOWEL SIGN MAI SAT
+ {0x1A63, 0x1A64, prSA, gcMc}, // [2] TAI THAM VOWEL SIGN AA..TAI THAM VOWEL SIGN TALL AA
+ {0x1A65, 0x1A6C, prSA, gcMn}, // [8] TAI THAM VOWEL SIGN I..TAI THAM VOWEL SIGN OA BELOW
+ {0x1A6D, 0x1A72, prSA, gcMc}, // [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI
+ {0x1A73, 0x1A7C, prSA, gcMn}, // [10] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN KHUEN-LUE KARAN
+ {0x1A7F, 0x1A7F, prCM, gcMn}, // TAI THAM COMBINING CRYPTOGRAMMIC DOT
+ {0x1A80, 0x1A89, prNU, gcNd}, // [10] TAI THAM HORA DIGIT ZERO..TAI THAM HORA DIGIT NINE
+ {0x1A90, 0x1A99, prNU, gcNd}, // [10] TAI THAM THAM DIGIT ZERO..TAI THAM THAM DIGIT NINE
+ {0x1AA0, 0x1AA6, prSA, gcPo}, // [7] TAI THAM SIGN WIANG..TAI THAM SIGN REVERSED ROTATED RANA
+ {0x1AA7, 0x1AA7, prSA, gcLm}, // TAI THAM SIGN MAI YAMOK
+ {0x1AA8, 0x1AAD, prSA, gcPo}, // [6] TAI THAM SIGN KAAN..TAI THAM SIGN CAANG
+ {0x1AB0, 0x1ABD, prCM, gcMn}, // [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW
+ {0x1ABE, 0x1ABE, prCM, gcMe}, // COMBINING PARENTHESES OVERLAY
+ {0x1ABF, 0x1ACE, prCM, gcMn}, // [16] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER INSULAR T
+ {0x1B00, 0x1B03, prCM, gcMn}, // [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG
+ {0x1B04, 0x1B04, prCM, gcMc}, // BALINESE SIGN BISAH
+ {0x1B05, 0x1B33, prAL, gcLo}, // [47] BALINESE LETTER AKARA..BALINESE LETTER HA
+ {0x1B34, 0x1B34, prCM, gcMn}, // BALINESE SIGN REREKAN
+ {0x1B35, 0x1B35, prCM, gcMc}, // BALINESE VOWEL SIGN TEDUNG
+ {0x1B36, 0x1B3A, prCM, gcMn}, // [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA
+ {0x1B3B, 0x1B3B, prCM, gcMc}, // BALINESE VOWEL SIGN RA REPA TEDUNG
+ {0x1B3C, 0x1B3C, prCM, gcMn}, // BALINESE VOWEL SIGN LA LENGA
+ {0x1B3D, 0x1B41, prCM, gcMc}, // [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG
+ {0x1B42, 0x1B42, prCM, gcMn}, // BALINESE VOWEL SIGN PEPET
+ {0x1B43, 0x1B44, prCM, gcMc}, // [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG
+ {0x1B45, 0x1B4C, prAL, gcLo}, // [8] BALINESE LETTER KAF SASAK..BALINESE LETTER ARCHAIC JNYA
+ {0x1B50, 0x1B59, prNU, gcNd}, // [10] BALINESE DIGIT ZERO..BALINESE DIGIT NINE
+ {0x1B5A, 0x1B5B, prBA, gcPo}, // [2] BALINESE PANTI..BALINESE PAMADA
+ {0x1B5C, 0x1B5C, prAL, gcPo}, // BALINESE WINDU
+ {0x1B5D, 0x1B60, prBA, gcPo}, // [4] BALINESE CARIK PAMUNGKAH..BALINESE PAMENENG
+ {0x1B61, 0x1B6A, prAL, gcSo}, // [10] BALINESE MUSICAL SYMBOL DONG..BALINESE MUSICAL SYMBOL DANG GEDE
+ {0x1B6B, 0x1B73, prCM, gcMn}, // [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG
+ {0x1B74, 0x1B7C, prAL, gcSo}, // [9] BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG..BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING
+ {0x1B7D, 0x1B7E, prBA, gcPo}, // [2] BALINESE PANTI LANTANG..BALINESE PAMADA LANTANG
+ {0x1B80, 0x1B81, prCM, gcMn}, // [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR
+ {0x1B82, 0x1B82, prCM, gcMc}, // SUNDANESE SIGN PANGWISAD
+ {0x1B83, 0x1BA0, prAL, gcLo}, // [30] SUNDANESE LETTER A..SUNDANESE LETTER HA
+ {0x1BA1, 0x1BA1, prCM, gcMc}, // SUNDANESE CONSONANT SIGN PAMINGKAL
+ {0x1BA2, 0x1BA5, prCM, gcMn}, // [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU
+ {0x1BA6, 0x1BA7, prCM, gcMc}, // [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG
+ {0x1BA8, 0x1BA9, prCM, gcMn}, // [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG
+ {0x1BAA, 0x1BAA, prCM, gcMc}, // SUNDANESE SIGN PAMAAEH
+ {0x1BAB, 0x1BAD, prCM, gcMn}, // [3] SUNDANESE SIGN VIRAMA..SUNDANESE CONSONANT SIGN PASANGAN WA
+ {0x1BAE, 0x1BAF, prAL, gcLo}, // [2] SUNDANESE LETTER KHA..SUNDANESE LETTER SYA
+ {0x1BB0, 0x1BB9, prNU, gcNd}, // [10] SUNDANESE DIGIT ZERO..SUNDANESE DIGIT NINE
+ {0x1BBA, 0x1BBF, prAL, gcLo}, // [6] SUNDANESE AVAGRAHA..SUNDANESE LETTER FINAL M
+ {0x1BC0, 0x1BE5, prAL, gcLo}, // [38] BATAK LETTER A..BATAK LETTER U
+ {0x1BE6, 0x1BE6, prCM, gcMn}, // BATAK SIGN TOMPI
+ {0x1BE7, 0x1BE7, prCM, gcMc}, // BATAK VOWEL SIGN E
+ {0x1BE8, 0x1BE9, prCM, gcMn}, // [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE
+ {0x1BEA, 0x1BEC, prCM, gcMc}, // [3] BATAK VOWEL SIGN I..BATAK VOWEL SIGN O
+ {0x1BED, 0x1BED, prCM, gcMn}, // BATAK VOWEL SIGN KARO O
+ {0x1BEE, 0x1BEE, prCM, gcMc}, // BATAK VOWEL SIGN U
+ {0x1BEF, 0x1BF1, prCM, gcMn}, // [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H
+ {0x1BF2, 0x1BF3, prCM, gcMc}, // [2] BATAK PANGOLAT..BATAK PANONGONAN
+ {0x1BFC, 0x1BFF, prAL, gcPo}, // [4] BATAK SYMBOL BINDU NA METEK..BATAK SYMBOL BINDU PANGOLAT
+ {0x1C00, 0x1C23, prAL, gcLo}, // [36] LEPCHA LETTER KA..LEPCHA LETTER A
+ {0x1C24, 0x1C2B, prCM, gcMc}, // [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU
+ {0x1C2C, 0x1C33, prCM, gcMn}, // [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T
+ {0x1C34, 0x1C35, prCM, gcMc}, // [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG
+ {0x1C36, 0x1C37, prCM, gcMn}, // [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA
+ {0x1C3B, 0x1C3F, prBA, gcPo}, // [5] LEPCHA PUNCTUATION TA-ROL..LEPCHA PUNCTUATION TSHOOK
+ {0x1C40, 0x1C49, prNU, gcNd}, // [10] LEPCHA DIGIT ZERO..LEPCHA DIGIT NINE
+ {0x1C4D, 0x1C4F, prAL, gcLo}, // [3] LEPCHA LETTER TTA..LEPCHA LETTER DDA
+ {0x1C50, 0x1C59, prNU, gcNd}, // [10] OL CHIKI DIGIT ZERO..OL CHIKI DIGIT NINE
+ {0x1C5A, 0x1C77, prAL, gcLo}, // [30] OL CHIKI LETTER LA..OL CHIKI LETTER OH
+ {0x1C78, 0x1C7D, prAL, gcLm}, // [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD
+ {0x1C7E, 0x1C7F, prBA, gcPo}, // [2] OL CHIKI PUNCTUATION MUCAAD..OL CHIKI PUNCTUATION DOUBLE MUCAAD
+ {0x1C80, 0x1C88, prAL, gcLl}, // [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK
+ {0x1C90, 0x1CBA, prAL, gcLu}, // [43] GEORGIAN MTAVRULI CAPITAL LETTER AN..GEORGIAN MTAVRULI CAPITAL LETTER AIN
+ {0x1CBD, 0x1CBF, prAL, gcLu}, // [3] GEORGIAN MTAVRULI CAPITAL LETTER AEN..GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN
+ {0x1CC0, 0x1CC7, prAL, gcPo}, // [8] SUNDANESE PUNCTUATION BINDU SURYA..SUNDANESE PUNCTUATION BINDU BA SATANGA
+ {0x1CD0, 0x1CD2, prCM, gcMn}, // [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA
+ {0x1CD3, 0x1CD3, prAL, gcPo}, // VEDIC SIGN NIHSHVASA
+ {0x1CD4, 0x1CE0, prCM, gcMn}, // [13] VEDIC SIGN YAJURVEDIC MIDLINE SVARITA..VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA
+ {0x1CE1, 0x1CE1, prCM, gcMc}, // VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA
+ {0x1CE2, 0x1CE8, prCM, gcMn}, // [7] VEDIC SIGN VISARGA SVARITA..VEDIC SIGN VISARGA ANUDATTA WITH TAIL
+ {0x1CE9, 0x1CEC, prAL, gcLo}, // [4] VEDIC SIGN ANUSVARA ANTARGOMUKHA..VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL
+ {0x1CED, 0x1CED, prCM, gcMn}, // VEDIC SIGN TIRYAK
+ {0x1CEE, 0x1CF3, prAL, gcLo}, // [6] VEDIC SIGN HEXIFORM LONG ANUSVARA..VEDIC SIGN ROTATED ARDHAVISARGA
+ {0x1CF4, 0x1CF4, prCM, gcMn}, // VEDIC TONE CANDRA ABOVE
+ {0x1CF5, 0x1CF6, prAL, gcLo}, // [2] VEDIC SIGN JIHVAMULIYA..VEDIC SIGN UPADHMANIYA
+ {0x1CF7, 0x1CF7, prCM, gcMc}, // VEDIC SIGN ATIKRAMA
+ {0x1CF8, 0x1CF9, prCM, gcMn}, // [2] VEDIC TONE RING ABOVE..VEDIC TONE DOUBLE RING ABOVE
+ {0x1CFA, 0x1CFA, prAL, gcLo}, // VEDIC SIGN DOUBLE ANUSVARA ANTARGOMUKHA
+ {0x1D00, 0x1D2B, prAL, gcLl}, // [44] LATIN LETTER SMALL CAPITAL A..CYRILLIC LETTER SMALL CAPITAL EL
+ {0x1D2C, 0x1D6A, prAL, gcLm}, // [63] MODIFIER LETTER CAPITAL A..GREEK SUBSCRIPT SMALL LETTER CHI
+ {0x1D6B, 0x1D77, prAL, gcLl}, // [13] LATIN SMALL LETTER UE..LATIN SMALL LETTER TURNED G
+ {0x1D78, 0x1D78, prAL, gcLm}, // MODIFIER LETTER CYRILLIC EN
+ {0x1D79, 0x1D7F, prAL, gcLl}, // [7] LATIN SMALL LETTER INSULAR G..LATIN SMALL LETTER UPSILON WITH STROKE
+ {0x1D80, 0x1D9A, prAL, gcLl}, // [27] LATIN SMALL LETTER B WITH PALATAL HOOK..LATIN SMALL LETTER EZH WITH RETROFLEX HOOK
+ {0x1D9B, 0x1DBF, prAL, gcLm}, // [37] MODIFIER LETTER SMALL TURNED ALPHA..MODIFIER LETTER SMALL THETA
+ {0x1DC0, 0x1DCC, prCM, gcMn}, // [13] COMBINING DOTTED GRAVE ACCENT..COMBINING MACRON-BREVE
+ {0x1DCD, 0x1DCD, prGL, gcMn}, // COMBINING DOUBLE CIRCUMFLEX ABOVE
+ {0x1DCE, 0x1DFB, prCM, gcMn}, // [46] COMBINING OGONEK ABOVE..COMBINING DELETION MARK
+ {0x1DFC, 0x1DFC, prGL, gcMn}, // COMBINING DOUBLE INVERTED BREVE BELOW
+ {0x1DFD, 0x1DFF, prCM, gcMn}, // [3] COMBINING ALMOST EQUAL TO BELOW..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW
+ {0x1E00, 0x1EFF, prAL, gcLC}, // [256] LATIN CAPITAL LETTER A WITH RING BELOW..LATIN SMALL LETTER Y WITH LOOP
+ {0x1F00, 0x1F15, prAL, gcLC}, // [22] GREEK SMALL LETTER ALPHA WITH PSILI..GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA
+ {0x1F18, 0x1F1D, prAL, gcLu}, // [6] GREEK CAPITAL LETTER EPSILON WITH PSILI..GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA
+ {0x1F20, 0x1F45, prAL, gcLC}, // [38] GREEK SMALL LETTER ETA WITH PSILI..GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA
+ {0x1F48, 0x1F4D, prAL, gcLu}, // [6] GREEK CAPITAL LETTER OMICRON WITH PSILI..GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA
+ {0x1F50, 0x1F57, prAL, gcLl}, // [8] GREEK SMALL LETTER UPSILON WITH PSILI..GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI
+ {0x1F59, 0x1F59, prAL, gcLu}, // GREEK CAPITAL LETTER UPSILON WITH DASIA
+ {0x1F5B, 0x1F5B, prAL, gcLu}, // GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA
+ {0x1F5D, 0x1F5D, prAL, gcLu}, // GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA
+ {0x1F5F, 0x1F7D, prAL, gcLC}, // [31] GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI..GREEK SMALL LETTER OMEGA WITH OXIA
+ {0x1F80, 0x1FB4, prAL, gcLC}, // [53] GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI..GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI
+ {0x1FB6, 0x1FBC, prAL, gcLC}, // [7] GREEK SMALL LETTER ALPHA WITH PERISPOMENI..GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
+ {0x1FBD, 0x1FBD, prAL, gcSk}, // GREEK KORONIS
+ {0x1FBE, 0x1FBE, prAL, gcLl}, // GREEK PROSGEGRAMMENI
+ {0x1FBF, 0x1FC1, prAL, gcSk}, // [3] GREEK PSILI..GREEK DIALYTIKA AND PERISPOMENI
+ {0x1FC2, 0x1FC4, prAL, gcLl}, // [3] GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI
+ {0x1FC6, 0x1FCC, prAL, gcLC}, // [7] GREEK SMALL LETTER ETA WITH PERISPOMENI..GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
+ {0x1FCD, 0x1FCF, prAL, gcSk}, // [3] GREEK PSILI AND VARIA..GREEK PSILI AND PERISPOMENI
+ {0x1FD0, 0x1FD3, prAL, gcLl}, // [4] GREEK SMALL LETTER IOTA WITH VRACHY..GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
+ {0x1FD6, 0x1FDB, prAL, gcLC}, // [6] GREEK SMALL LETTER IOTA WITH PERISPOMENI..GREEK CAPITAL LETTER IOTA WITH OXIA
+ {0x1FDD, 0x1FDF, prAL, gcSk}, // [3] GREEK DASIA AND VARIA..GREEK DASIA AND PERISPOMENI
+ {0x1FE0, 0x1FEC, prAL, gcLC}, // [13] GREEK SMALL LETTER UPSILON WITH VRACHY..GREEK CAPITAL LETTER RHO WITH DASIA
+ {0x1FED, 0x1FEF, prAL, gcSk}, // [3] GREEK DIALYTIKA AND VARIA..GREEK VARIA
+ {0x1FF2, 0x1FF4, prAL, gcLl}, // [3] GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI..GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI
+ {0x1FF6, 0x1FFC, prAL, gcLC}, // [7] GREEK SMALL LETTER OMEGA WITH PERISPOMENI..GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
+ {0x1FFD, 0x1FFD, prBB, gcSk}, // GREEK OXIA
+ {0x1FFE, 0x1FFE, prAL, gcSk}, // GREEK DASIA
+ {0x2000, 0x2006, prBA, gcZs}, // [7] EN QUAD..SIX-PER-EM SPACE
+ {0x2007, 0x2007, prGL, gcZs}, // FIGURE SPACE
+ {0x2008, 0x200A, prBA, gcZs}, // [3] PUNCTUATION SPACE..HAIR SPACE
+ {0x200B, 0x200B, prZW, gcCf}, // ZERO WIDTH SPACE
+ {0x200C, 0x200C, prCM, gcCf}, // ZERO WIDTH NON-JOINER
+ {0x200D, 0x200D, prZWJ, gcCf}, // ZERO WIDTH JOINER
+ {0x200E, 0x200F, prCM, gcCf}, // [2] LEFT-TO-RIGHT MARK..RIGHT-TO-LEFT MARK
+ {0x2010, 0x2010, prBA, gcPd}, // HYPHEN
+ {0x2011, 0x2011, prGL, gcPd}, // NON-BREAKING HYPHEN
+ {0x2012, 0x2013, prBA, gcPd}, // [2] FIGURE DASH..EN DASH
+ {0x2014, 0x2014, prB2, gcPd}, // EM DASH
+ {0x2015, 0x2015, prAI, gcPd}, // HORIZONTAL BAR
+ {0x2016, 0x2016, prAI, gcPo}, // DOUBLE VERTICAL LINE
+ {0x2017, 0x2017, prAL, gcPo}, // DOUBLE LOW LINE
+ {0x2018, 0x2018, prQU, gcPi}, // LEFT SINGLE QUOTATION MARK
+ {0x2019, 0x2019, prQU, gcPf}, // RIGHT SINGLE QUOTATION MARK
+ {0x201A, 0x201A, prOP, gcPs}, // SINGLE LOW-9 QUOTATION MARK
+ {0x201B, 0x201C, prQU, gcPi}, // [2] SINGLE HIGH-REVERSED-9 QUOTATION MARK..LEFT DOUBLE QUOTATION MARK
+ {0x201D, 0x201D, prQU, gcPf}, // RIGHT DOUBLE QUOTATION MARK
+ {0x201E, 0x201E, prOP, gcPs}, // DOUBLE LOW-9 QUOTATION MARK
+ {0x201F, 0x201F, prQU, gcPi}, // DOUBLE HIGH-REVERSED-9 QUOTATION MARK
+ {0x2020, 0x2021, prAI, gcPo}, // [2] DAGGER..DOUBLE DAGGER
+ {0x2022, 0x2023, prAL, gcPo}, // [2] BULLET..TRIANGULAR BULLET
+ {0x2024, 0x2026, prIN, gcPo}, // [3] ONE DOT LEADER..HORIZONTAL ELLIPSIS
+ {0x2027, 0x2027, prBA, gcPo}, // HYPHENATION POINT
+ {0x2028, 0x2028, prBK, gcZl}, // LINE SEPARATOR
+ {0x2029, 0x2029, prBK, gcZp}, // PARAGRAPH SEPARATOR
+ {0x202A, 0x202E, prCM, gcCf}, // [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE
+ {0x202F, 0x202F, prGL, gcZs}, // NARROW NO-BREAK SPACE
+ {0x2030, 0x2037, prPO, gcPo}, // [8] PER MILLE SIGN..REVERSED TRIPLE PRIME
+ {0x2038, 0x2038, prAL, gcPo}, // CARET
+ {0x2039, 0x2039, prQU, gcPi}, // SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+ {0x203A, 0x203A, prQU, gcPf}, // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+ {0x203B, 0x203B, prAI, gcPo}, // REFERENCE MARK
+ {0x203C, 0x203D, prNS, gcPo}, // [2] DOUBLE EXCLAMATION MARK..INTERROBANG
+ {0x203E, 0x203E, prAL, gcPo}, // OVERLINE
+ {0x203F, 0x2040, prAL, gcPc}, // [2] UNDERTIE..CHARACTER TIE
+ {0x2041, 0x2043, prAL, gcPo}, // [3] CARET INSERTION POINT..HYPHEN BULLET
+ {0x2044, 0x2044, prIS, gcSm}, // FRACTION SLASH
+ {0x2045, 0x2045, prOP, gcPs}, // LEFT SQUARE BRACKET WITH QUILL
+ {0x2046, 0x2046, prCL, gcPe}, // RIGHT SQUARE BRACKET WITH QUILL
+ {0x2047, 0x2049, prNS, gcPo}, // [3] DOUBLE QUESTION MARK..EXCLAMATION QUESTION MARK
+ {0x204A, 0x2051, prAL, gcPo}, // [8] TIRONIAN SIGN ET..TWO ASTERISKS ALIGNED VERTICALLY
+ {0x2052, 0x2052, prAL, gcSm}, // COMMERCIAL MINUS SIGN
+ {0x2053, 0x2053, prAL, gcPo}, // SWUNG DASH
+ {0x2054, 0x2054, prAL, gcPc}, // INVERTED UNDERTIE
+ {0x2055, 0x2055, prAL, gcPo}, // FLOWER PUNCTUATION MARK
+ {0x2056, 0x2056, prBA, gcPo}, // THREE DOT PUNCTUATION
+ {0x2057, 0x2057, prPO, gcPo}, // QUADRUPLE PRIME
+ {0x2058, 0x205B, prBA, gcPo}, // [4] FOUR DOT PUNCTUATION..FOUR DOT MARK
+ {0x205C, 0x205C, prAL, gcPo}, // DOTTED CROSS
+ {0x205D, 0x205E, prBA, gcPo}, // [2] TRICOLON..VERTICAL FOUR DOTS
+ {0x205F, 0x205F, prBA, gcZs}, // MEDIUM MATHEMATICAL SPACE
+ {0x2060, 0x2060, prWJ, gcCf}, // WORD JOINER
+ {0x2061, 0x2064, prAL, gcCf}, // [4] FUNCTION APPLICATION..INVISIBLE PLUS
+ {0x2066, 0x206F, prCM, gcCf}, // [10] LEFT-TO-RIGHT ISOLATE..NOMINAL DIGIT SHAPES
+ {0x2070, 0x2070, prAL, gcNo}, // SUPERSCRIPT ZERO
+ {0x2071, 0x2071, prAL, gcLm}, // SUPERSCRIPT LATIN SMALL LETTER I
+ {0x2074, 0x2074, prAI, gcNo}, // SUPERSCRIPT FOUR
+ {0x2075, 0x2079, prAL, gcNo}, // [5] SUPERSCRIPT FIVE..SUPERSCRIPT NINE
+ {0x207A, 0x207C, prAL, gcSm}, // [3] SUPERSCRIPT PLUS SIGN..SUPERSCRIPT EQUALS SIGN
+ {0x207D, 0x207D, prOP, gcPs}, // SUPERSCRIPT LEFT PARENTHESIS
+ {0x207E, 0x207E, prCL, gcPe}, // SUPERSCRIPT RIGHT PARENTHESIS
+ {0x207F, 0x207F, prAI, gcLm}, // SUPERSCRIPT LATIN SMALL LETTER N
+ {0x2080, 0x2080, prAL, gcNo}, // SUBSCRIPT ZERO
+ {0x2081, 0x2084, prAI, gcNo}, // [4] SUBSCRIPT ONE..SUBSCRIPT FOUR
+ {0x2085, 0x2089, prAL, gcNo}, // [5] SUBSCRIPT FIVE..SUBSCRIPT NINE
+ {0x208A, 0x208C, prAL, gcSm}, // [3] SUBSCRIPT PLUS SIGN..SUBSCRIPT EQUALS SIGN
+ {0x208D, 0x208D, prOP, gcPs}, // SUBSCRIPT LEFT PARENTHESIS
+ {0x208E, 0x208E, prCL, gcPe}, // SUBSCRIPT RIGHT PARENTHESIS
+ {0x2090, 0x209C, prAL, gcLm}, // [13] LATIN SUBSCRIPT SMALL LETTER A..LATIN SUBSCRIPT SMALL LETTER T
+ {0x20A0, 0x20A6, prPR, gcSc}, // [7] EURO-CURRENCY SIGN..NAIRA SIGN
+ {0x20A7, 0x20A7, prPO, gcSc}, // PESETA SIGN
+ {0x20A8, 0x20B5, prPR, gcSc}, // [14] RUPEE SIGN..CEDI SIGN
+ {0x20B6, 0x20B6, prPO, gcSc}, // LIVRE TOURNOIS SIGN
+ {0x20B7, 0x20BA, prPR, gcSc}, // [4] SPESMILO SIGN..TURKISH LIRA SIGN
+ {0x20BB, 0x20BB, prPO, gcSc}, // NORDIC MARK SIGN
+ {0x20BC, 0x20BD, prPR, gcSc}, // [2] MANAT SIGN..RUBLE SIGN
+ {0x20BE, 0x20BE, prPO, gcSc}, // LARI SIGN
+ {0x20BF, 0x20BF, prPR, gcSc}, // BITCOIN SIGN
+ {0x20C0, 0x20C0, prPO, gcSc}, // SOM SIGN
+ {0x20C1, 0x20CF, prPR, gcCn}, // [15] ..
+ {0x20D0, 0x20DC, prCM, gcMn}, // [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE
+ {0x20DD, 0x20E0, prCM, gcMe}, // [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH
+ {0x20E1, 0x20E1, prCM, gcMn}, // COMBINING LEFT RIGHT ARROW ABOVE
+ {0x20E2, 0x20E4, prCM, gcMe}, // [3] COMBINING ENCLOSING SCREEN..COMBINING ENCLOSING UPWARD POINTING TRIANGLE
+ {0x20E5, 0x20F0, prCM, gcMn}, // [12] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING ASTERISK ABOVE
+ {0x2100, 0x2101, prAL, gcSo}, // [2] ACCOUNT OF..ADDRESSED TO THE SUBJECT
+ {0x2102, 0x2102, prAL, gcLu}, // DOUBLE-STRUCK CAPITAL C
+ {0x2103, 0x2103, prPO, gcSo}, // DEGREE CELSIUS
+ {0x2104, 0x2104, prAL, gcSo}, // CENTRE LINE SYMBOL
+ {0x2105, 0x2105, prAI, gcSo}, // CARE OF
+ {0x2106, 0x2106, prAL, gcSo}, // CADA UNA
+ {0x2107, 0x2107, prAL, gcLu}, // EULER CONSTANT
+ {0x2108, 0x2108, prAL, gcSo}, // SCRUPLE
+ {0x2109, 0x2109, prPO, gcSo}, // DEGREE FAHRENHEIT
+ {0x210A, 0x2112, prAL, gcLC}, // [9] SCRIPT SMALL G..SCRIPT CAPITAL L
+ {0x2113, 0x2113, prAI, gcLl}, // SCRIPT SMALL L
+ {0x2114, 0x2114, prAL, gcSo}, // L B BAR SYMBOL
+ {0x2115, 0x2115, prAL, gcLu}, // DOUBLE-STRUCK CAPITAL N
+ {0x2116, 0x2116, prPR, gcSo}, // NUMERO SIGN
+ {0x2117, 0x2117, prAL, gcSo}, // SOUND RECORDING COPYRIGHT
+ {0x2118, 0x2118, prAL, gcSm}, // SCRIPT CAPITAL P
+ {0x2119, 0x211D, prAL, gcLu}, // [5] DOUBLE-STRUCK CAPITAL P..DOUBLE-STRUCK CAPITAL R
+ {0x211E, 0x2120, prAL, gcSo}, // [3] PRESCRIPTION TAKE..SERVICE MARK
+ {0x2121, 0x2122, prAI, gcSo}, // [2] TELEPHONE SIGN..TRADE MARK SIGN
+ {0x2123, 0x2123, prAL, gcSo}, // VERSICLE
+ {0x2124, 0x2124, prAL, gcLu}, // DOUBLE-STRUCK CAPITAL Z
+ {0x2125, 0x2125, prAL, gcSo}, // OUNCE SIGN
+ {0x2126, 0x2126, prAL, gcLu}, // OHM SIGN
+ {0x2127, 0x2127, prAL, gcSo}, // INVERTED OHM SIGN
+ {0x2128, 0x2128, prAL, gcLu}, // BLACK-LETTER CAPITAL Z
+ {0x2129, 0x2129, prAL, gcSo}, // TURNED GREEK SMALL LETTER IOTA
+ {0x212A, 0x212A, prAL, gcLu}, // KELVIN SIGN
+ {0x212B, 0x212B, prAI, gcLu}, // ANGSTROM SIGN
+ {0x212C, 0x212D, prAL, gcLu}, // [2] SCRIPT CAPITAL B..BLACK-LETTER CAPITAL C
+ {0x212E, 0x212E, prAL, gcSo}, // ESTIMATED SYMBOL
+ {0x212F, 0x2134, prAL, gcLC}, // [6] SCRIPT SMALL E..SCRIPT SMALL O
+ {0x2135, 0x2138, prAL, gcLo}, // [4] ALEF SYMBOL..DALET SYMBOL
+ {0x2139, 0x2139, prAL, gcLl}, // INFORMATION SOURCE
+ {0x213A, 0x213B, prAL, gcSo}, // [2] ROTATED CAPITAL Q..FACSIMILE SIGN
+ {0x213C, 0x213F, prAL, gcLC}, // [4] DOUBLE-STRUCK SMALL PI..DOUBLE-STRUCK CAPITAL PI
+ {0x2140, 0x2144, prAL, gcSm}, // [5] DOUBLE-STRUCK N-ARY SUMMATION..TURNED SANS-SERIF CAPITAL Y
+ {0x2145, 0x2149, prAL, gcLC}, // [5] DOUBLE-STRUCK ITALIC CAPITAL D..DOUBLE-STRUCK ITALIC SMALL J
+ {0x214A, 0x214A, prAL, gcSo}, // PROPERTY LINE
+ {0x214B, 0x214B, prAL, gcSm}, // TURNED AMPERSAND
+ {0x214C, 0x214D, prAL, gcSo}, // [2] PER SIGN..AKTIESELSKAB
+ {0x214E, 0x214E, prAL, gcLl}, // TURNED SMALL F
+ {0x214F, 0x214F, prAL, gcSo}, // SYMBOL FOR SAMARITAN SOURCE
+ {0x2150, 0x2153, prAL, gcNo}, // [4] VULGAR FRACTION ONE SEVENTH..VULGAR FRACTION ONE THIRD
+ {0x2154, 0x2155, prAI, gcNo}, // [2] VULGAR FRACTION TWO THIRDS..VULGAR FRACTION ONE FIFTH
+ {0x2156, 0x215A, prAL, gcNo}, // [5] VULGAR FRACTION TWO FIFTHS..VULGAR FRACTION FIVE SIXTHS
+ {0x215B, 0x215B, prAI, gcNo}, // VULGAR FRACTION ONE EIGHTH
+ {0x215C, 0x215D, prAL, gcNo}, // [2] VULGAR FRACTION THREE EIGHTHS..VULGAR FRACTION FIVE EIGHTHS
+ {0x215E, 0x215E, prAI, gcNo}, // VULGAR FRACTION SEVEN EIGHTHS
+ {0x215F, 0x215F, prAL, gcNo}, // FRACTION NUMERATOR ONE
+ {0x2160, 0x216B, prAI, gcNl}, // [12] ROMAN NUMERAL ONE..ROMAN NUMERAL TWELVE
+ {0x216C, 0x216F, prAL, gcNl}, // [4] ROMAN NUMERAL FIFTY..ROMAN NUMERAL ONE THOUSAND
+ {0x2170, 0x2179, prAI, gcNl}, // [10] SMALL ROMAN NUMERAL ONE..SMALL ROMAN NUMERAL TEN
+ {0x217A, 0x2182, prAL, gcNl}, // [9] SMALL ROMAN NUMERAL ELEVEN..ROMAN NUMERAL TEN THOUSAND
+ {0x2183, 0x2184, prAL, gcLC}, // [2] ROMAN NUMERAL REVERSED ONE HUNDRED..LATIN SMALL LETTER REVERSED C
+ {0x2185, 0x2188, prAL, gcNl}, // [4] ROMAN NUMERAL SIX LATE FORM..ROMAN NUMERAL ONE HUNDRED THOUSAND
+ {0x2189, 0x2189, prAI, gcNo}, // VULGAR FRACTION ZERO THIRDS
+ {0x218A, 0x218B, prAL, gcSo}, // [2] TURNED DIGIT TWO..TURNED DIGIT THREE
+ {0x2190, 0x2194, prAI, gcSm}, // [5] LEFTWARDS ARROW..LEFT RIGHT ARROW
+ {0x2195, 0x2199, prAI, gcSo}, // [5] UP DOWN ARROW..SOUTH WEST ARROW
+ {0x219A, 0x219B, prAL, gcSm}, // [2] LEFTWARDS ARROW WITH STROKE..RIGHTWARDS ARROW WITH STROKE
+ {0x219C, 0x219F, prAL, gcSo}, // [4] LEFTWARDS WAVE ARROW..UPWARDS TWO HEADED ARROW
+ {0x21A0, 0x21A0, prAL, gcSm}, // RIGHTWARDS TWO HEADED ARROW
+ {0x21A1, 0x21A2, prAL, gcSo}, // [2] DOWNWARDS TWO HEADED ARROW..LEFTWARDS ARROW WITH TAIL
+ {0x21A3, 0x21A3, prAL, gcSm}, // RIGHTWARDS ARROW WITH TAIL
+ {0x21A4, 0x21A5, prAL, gcSo}, // [2] LEFTWARDS ARROW FROM BAR..UPWARDS ARROW FROM BAR
+ {0x21A6, 0x21A6, prAL, gcSm}, // RIGHTWARDS ARROW FROM BAR
+ {0x21A7, 0x21AD, prAL, gcSo}, // [7] DOWNWARDS ARROW FROM BAR..LEFT RIGHT WAVE ARROW
+ {0x21AE, 0x21AE, prAL, gcSm}, // LEFT RIGHT ARROW WITH STROKE
+ {0x21AF, 0x21CD, prAL, gcSo}, // [31] DOWNWARDS ZIGZAG ARROW..LEFTWARDS DOUBLE ARROW WITH STROKE
+ {0x21CE, 0x21CF, prAL, gcSm}, // [2] LEFT RIGHT DOUBLE ARROW WITH STROKE..RIGHTWARDS DOUBLE ARROW WITH STROKE
+ {0x21D0, 0x21D1, prAL, gcSo}, // [2] LEFTWARDS DOUBLE ARROW..UPWARDS DOUBLE ARROW
+ {0x21D2, 0x21D2, prAI, gcSm}, // RIGHTWARDS DOUBLE ARROW
+ {0x21D3, 0x21D3, prAL, gcSo}, // DOWNWARDS DOUBLE ARROW
+ {0x21D4, 0x21D4, prAI, gcSm}, // LEFT RIGHT DOUBLE ARROW
+ {0x21D5, 0x21F3, prAL, gcSo}, // [31] UP DOWN DOUBLE ARROW..UP DOWN WHITE ARROW
+ {0x21F4, 0x21FF, prAL, gcSm}, // [12] RIGHT ARROW WITH SMALL CIRCLE..LEFT RIGHT OPEN-HEADED ARROW
+ {0x2200, 0x2200, prAI, gcSm}, // FOR ALL
+ {0x2201, 0x2201, prAL, gcSm}, // COMPLEMENT
+ {0x2202, 0x2203, prAI, gcSm}, // [2] PARTIAL DIFFERENTIAL..THERE EXISTS
+ {0x2204, 0x2206, prAL, gcSm}, // [3] THERE DOES NOT EXIST..INCREMENT
+ {0x2207, 0x2208, prAI, gcSm}, // [2] NABLA..ELEMENT OF
+ {0x2209, 0x220A, prAL, gcSm}, // [2] NOT AN ELEMENT OF..SMALL ELEMENT OF
+ {0x220B, 0x220B, prAI, gcSm}, // CONTAINS AS MEMBER
+ {0x220C, 0x220E, prAL, gcSm}, // [3] DOES NOT CONTAIN AS MEMBER..END OF PROOF
+ {0x220F, 0x220F, prAI, gcSm}, // N-ARY PRODUCT
+ {0x2210, 0x2210, prAL, gcSm}, // N-ARY COPRODUCT
+ {0x2211, 0x2211, prAI, gcSm}, // N-ARY SUMMATION
+ {0x2212, 0x2213, prPR, gcSm}, // [2] MINUS SIGN..MINUS-OR-PLUS SIGN
+ {0x2214, 0x2214, prAL, gcSm}, // DOT PLUS
+ {0x2215, 0x2215, prAI, gcSm}, // DIVISION SLASH
+ {0x2216, 0x2219, prAL, gcSm}, // [4] SET MINUS..BULLET OPERATOR
+ {0x221A, 0x221A, prAI, gcSm}, // SQUARE ROOT
+ {0x221B, 0x221C, prAL, gcSm}, // [2] CUBE ROOT..FOURTH ROOT
+ {0x221D, 0x2220, prAI, gcSm}, // [4] PROPORTIONAL TO..ANGLE
+ {0x2221, 0x2222, prAL, gcSm}, // [2] MEASURED ANGLE..SPHERICAL ANGLE
+ {0x2223, 0x2223, prAI, gcSm}, // DIVIDES
+ {0x2224, 0x2224, prAL, gcSm}, // DOES NOT DIVIDE
+ {0x2225, 0x2225, prAI, gcSm}, // PARALLEL TO
+ {0x2226, 0x2226, prAL, gcSm}, // NOT PARALLEL TO
+ {0x2227, 0x222C, prAI, gcSm}, // [6] LOGICAL AND..DOUBLE INTEGRAL
+ {0x222D, 0x222D, prAL, gcSm}, // TRIPLE INTEGRAL
+ {0x222E, 0x222E, prAI, gcSm}, // CONTOUR INTEGRAL
+ {0x222F, 0x2233, prAL, gcSm}, // [5] SURFACE INTEGRAL..ANTICLOCKWISE CONTOUR INTEGRAL
+ {0x2234, 0x2237, prAI, gcSm}, // [4] THEREFORE..PROPORTION
+ {0x2238, 0x223B, prAL, gcSm}, // [4] DOT MINUS..HOMOTHETIC
+ {0x223C, 0x223D, prAI, gcSm}, // [2] TILDE OPERATOR..REVERSED TILDE
+ {0x223E, 0x2247, prAL, gcSm}, // [10] INVERTED LAZY S..NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO
+ {0x2248, 0x2248, prAI, gcSm}, // ALMOST EQUAL TO
+ {0x2249, 0x224B, prAL, gcSm}, // [3] NOT ALMOST EQUAL TO..TRIPLE TILDE
+ {0x224C, 0x224C, prAI, gcSm}, // ALL EQUAL TO
+ {0x224D, 0x2251, prAL, gcSm}, // [5] EQUIVALENT TO..GEOMETRICALLY EQUAL TO
+ {0x2252, 0x2252, prAI, gcSm}, // APPROXIMATELY EQUAL TO OR THE IMAGE OF
+ {0x2253, 0x225F, prAL, gcSm}, // [13] IMAGE OF OR APPROXIMATELY EQUAL TO..QUESTIONED EQUAL TO
+ {0x2260, 0x2261, prAI, gcSm}, // [2] NOT EQUAL TO..IDENTICAL TO
+ {0x2262, 0x2263, prAL, gcSm}, // [2] NOT IDENTICAL TO..STRICTLY EQUIVALENT TO
+ {0x2264, 0x2267, prAI, gcSm}, // [4] LESS-THAN OR EQUAL TO..GREATER-THAN OVER EQUAL TO
+ {0x2268, 0x2269, prAL, gcSm}, // [2] LESS-THAN BUT NOT EQUAL TO..GREATER-THAN BUT NOT EQUAL TO
+ {0x226A, 0x226B, prAI, gcSm}, // [2] MUCH LESS-THAN..MUCH GREATER-THAN
+ {0x226C, 0x226D, prAL, gcSm}, // [2] BETWEEN..NOT EQUIVALENT TO
+ {0x226E, 0x226F, prAI, gcSm}, // [2] NOT LESS-THAN..NOT GREATER-THAN
+ {0x2270, 0x2281, prAL, gcSm}, // [18] NEITHER LESS-THAN NOR EQUAL TO..DOES NOT SUCCEED
+ {0x2282, 0x2283, prAI, gcSm}, // [2] SUBSET OF..SUPERSET OF
+ {0x2284, 0x2285, prAL, gcSm}, // [2] NOT A SUBSET OF..NOT A SUPERSET OF
+ {0x2286, 0x2287, prAI, gcSm}, // [2] SUBSET OF OR EQUAL TO..SUPERSET OF OR EQUAL TO
+ {0x2288, 0x2294, prAL, gcSm}, // [13] NEITHER A SUBSET OF NOR EQUAL TO..SQUARE CUP
+ {0x2295, 0x2295, prAI, gcSm}, // CIRCLED PLUS
+ {0x2296, 0x2298, prAL, gcSm}, // [3] CIRCLED MINUS..CIRCLED DIVISION SLASH
+ {0x2299, 0x2299, prAI, gcSm}, // CIRCLED DOT OPERATOR
+ {0x229A, 0x22A4, prAL, gcSm}, // [11] CIRCLED RING OPERATOR..DOWN TACK
+ {0x22A5, 0x22A5, prAI, gcSm}, // UP TACK
+ {0x22A6, 0x22BE, prAL, gcSm}, // [25] ASSERTION..RIGHT ANGLE WITH ARC
+ {0x22BF, 0x22BF, prAI, gcSm}, // RIGHT TRIANGLE
+ {0x22C0, 0x22EE, prAL, gcSm}, // [47] N-ARY LOGICAL AND..VERTICAL ELLIPSIS
+ {0x22EF, 0x22EF, prIN, gcSm}, // MIDLINE HORIZONTAL ELLIPSIS
+ {0x22F0, 0x22FF, prAL, gcSm}, // [16] UP RIGHT DIAGONAL ELLIPSIS..Z NOTATION BAG MEMBERSHIP
+ {0x2300, 0x2307, prAL, gcSo}, // [8] DIAMETER SIGN..WAVY LINE
+ {0x2308, 0x2308, prOP, gcPs}, // LEFT CEILING
+ {0x2309, 0x2309, prCL, gcPe}, // RIGHT CEILING
+ {0x230A, 0x230A, prOP, gcPs}, // LEFT FLOOR
+ {0x230B, 0x230B, prCL, gcPe}, // RIGHT FLOOR
+ {0x230C, 0x2311, prAL, gcSo}, // [6] BOTTOM RIGHT CROP..SQUARE LOZENGE
+ {0x2312, 0x2312, prAI, gcSo}, // ARC
+ {0x2313, 0x2319, prAL, gcSo}, // [7] SEGMENT..TURNED NOT SIGN
+ {0x231A, 0x231B, prID, gcSo}, // [2] WATCH..HOURGLASS
+ {0x231C, 0x231F, prAL, gcSo}, // [4] TOP LEFT CORNER..BOTTOM RIGHT CORNER
+ {0x2320, 0x2321, prAL, gcSm}, // [2] TOP HALF INTEGRAL..BOTTOM HALF INTEGRAL
+ {0x2322, 0x2328, prAL, gcSo}, // [7] FROWN..KEYBOARD
+ {0x2329, 0x2329, prOP, gcPs}, // LEFT-POINTING ANGLE BRACKET
+ {0x232A, 0x232A, prCL, gcPe}, // RIGHT-POINTING ANGLE BRACKET
+ {0x232B, 0x237B, prAL, gcSo}, // [81] ERASE TO THE LEFT..NOT CHECK MARK
+ {0x237C, 0x237C, prAL, gcSm}, // RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW
+ {0x237D, 0x239A, prAL, gcSo}, // [30] SHOULDERED OPEN BOX..CLEAR SCREEN SYMBOL
+ {0x239B, 0x23B3, prAL, gcSm}, // [25] LEFT PARENTHESIS UPPER HOOK..SUMMATION BOTTOM
+ {0x23B4, 0x23DB, prAL, gcSo}, // [40] TOP SQUARE BRACKET..FUSE
+ {0x23DC, 0x23E1, prAL, gcSm}, // [6] TOP PARENTHESIS..BOTTOM TORTOISE SHELL BRACKET
+ {0x23E2, 0x23EF, prAL, gcSo}, // [14] WHITE TRAPEZIUM..BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR
+ {0x23F0, 0x23F3, prID, gcSo}, // [4] ALARM CLOCK..HOURGLASS WITH FLOWING SAND
+ {0x23F4, 0x23FF, prAL, gcSo}, // [12] BLACK MEDIUM LEFT-POINTING TRIANGLE..OBSERVER EYE SYMBOL
+ {0x2400, 0x2426, prAL, gcSo}, // [39] SYMBOL FOR NULL..SYMBOL FOR SUBSTITUTE FORM TWO
+ {0x2440, 0x244A, prAL, gcSo}, // [11] OCR HOOK..OCR DOUBLE BACKSLASH
+ {0x2460, 0x249B, prAI, gcNo}, // [60] CIRCLED DIGIT ONE..NUMBER TWENTY FULL STOP
+ {0x249C, 0x24E9, prAI, gcSo}, // [78] PARENTHESIZED LATIN SMALL LETTER A..CIRCLED LATIN SMALL LETTER Z
+ {0x24EA, 0x24FE, prAI, gcNo}, // [21] CIRCLED DIGIT ZERO..DOUBLE CIRCLED NUMBER TEN
+ {0x24FF, 0x24FF, prAL, gcNo}, // NEGATIVE CIRCLED DIGIT ZERO
+ {0x2500, 0x254B, prAI, gcSo}, // [76] BOX DRAWINGS LIGHT HORIZONTAL..BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL
+ {0x254C, 0x254F, prAL, gcSo}, // [4] BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL..BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL
+ {0x2550, 0x2574, prAI, gcSo}, // [37] BOX DRAWINGS DOUBLE HORIZONTAL..BOX DRAWINGS LIGHT LEFT
+ {0x2575, 0x257F, prAL, gcSo}, // [11] BOX DRAWINGS LIGHT UP..BOX DRAWINGS HEAVY UP AND LIGHT DOWN
+ {0x2580, 0x258F, prAI, gcSo}, // [16] UPPER HALF BLOCK..LEFT ONE EIGHTH BLOCK
+ {0x2590, 0x2591, prAL, gcSo}, // [2] RIGHT HALF BLOCK..LIGHT SHADE
+ {0x2592, 0x2595, prAI, gcSo}, // [4] MEDIUM SHADE..RIGHT ONE EIGHTH BLOCK
+ {0x2596, 0x259F, prAL, gcSo}, // [10] QUADRANT LOWER LEFT..QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT
+ {0x25A0, 0x25A1, prAI, gcSo}, // [2] BLACK SQUARE..WHITE SQUARE
+ {0x25A2, 0x25A2, prAL, gcSo}, // WHITE SQUARE WITH ROUNDED CORNERS
+ {0x25A3, 0x25A9, prAI, gcSo}, // [7] WHITE SQUARE CONTAINING BLACK SMALL SQUARE..SQUARE WITH DIAGONAL CROSSHATCH FILL
+ {0x25AA, 0x25B1, prAL, gcSo}, // [8] BLACK SMALL SQUARE..WHITE PARALLELOGRAM
+ {0x25B2, 0x25B3, prAI, gcSo}, // [2] BLACK UP-POINTING TRIANGLE..WHITE UP-POINTING TRIANGLE
+ {0x25B4, 0x25B5, prAL, gcSo}, // [2] BLACK UP-POINTING SMALL TRIANGLE..WHITE UP-POINTING SMALL TRIANGLE
+ {0x25B6, 0x25B6, prAI, gcSo}, // BLACK RIGHT-POINTING TRIANGLE
+ {0x25B7, 0x25B7, prAI, gcSm}, // WHITE RIGHT-POINTING TRIANGLE
+ {0x25B8, 0x25BB, prAL, gcSo}, // [4] BLACK RIGHT-POINTING SMALL TRIANGLE..WHITE RIGHT-POINTING POINTER
+ {0x25BC, 0x25BD, prAI, gcSo}, // [2] BLACK DOWN-POINTING TRIANGLE..WHITE DOWN-POINTING TRIANGLE
+ {0x25BE, 0x25BF, prAL, gcSo}, // [2] BLACK DOWN-POINTING SMALL TRIANGLE..WHITE DOWN-POINTING SMALL TRIANGLE
+ {0x25C0, 0x25C0, prAI, gcSo}, // BLACK LEFT-POINTING TRIANGLE
+ {0x25C1, 0x25C1, prAI, gcSm}, // WHITE LEFT-POINTING TRIANGLE
+ {0x25C2, 0x25C5, prAL, gcSo}, // [4] BLACK LEFT-POINTING SMALL TRIANGLE..WHITE LEFT-POINTING POINTER
+ {0x25C6, 0x25C8, prAI, gcSo}, // [3] BLACK DIAMOND..WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND
+ {0x25C9, 0x25CA, prAL, gcSo}, // [2] FISHEYE..LOZENGE
+ {0x25CB, 0x25CB, prAI, gcSo}, // WHITE CIRCLE
+ {0x25CC, 0x25CD, prAL, gcSo}, // [2] DOTTED CIRCLE..CIRCLE WITH VERTICAL FILL
+ {0x25CE, 0x25D1, prAI, gcSo}, // [4] BULLSEYE..CIRCLE WITH RIGHT HALF BLACK
+ {0x25D2, 0x25E1, prAL, gcSo}, // [16] CIRCLE WITH LOWER HALF BLACK..LOWER HALF CIRCLE
+ {0x25E2, 0x25E5, prAI, gcSo}, // [4] BLACK LOWER RIGHT TRIANGLE..BLACK UPPER RIGHT TRIANGLE
+ {0x25E6, 0x25EE, prAL, gcSo}, // [9] WHITE BULLET..UP-POINTING TRIANGLE WITH RIGHT HALF BLACK
+ {0x25EF, 0x25EF, prAI, gcSo}, // LARGE CIRCLE
+ {0x25F0, 0x25F7, prAL, gcSo}, // [8] WHITE SQUARE WITH UPPER LEFT QUADRANT..WHITE CIRCLE WITH UPPER RIGHT QUADRANT
+ {0x25F8, 0x25FF, prAL, gcSm}, // [8] UPPER LEFT TRIANGLE..LOWER RIGHT TRIANGLE
+ {0x2600, 0x2603, prID, gcSo}, // [4] BLACK SUN WITH RAYS..SNOWMAN
+ {0x2604, 0x2604, prAL, gcSo}, // COMET
+ {0x2605, 0x2606, prAI, gcSo}, // [2] BLACK STAR..WHITE STAR
+ {0x2607, 0x2608, prAL, gcSo}, // [2] LIGHTNING..THUNDERSTORM
+ {0x2609, 0x2609, prAI, gcSo}, // SUN
+ {0x260A, 0x260D, prAL, gcSo}, // [4] ASCENDING NODE..OPPOSITION
+ {0x260E, 0x260F, prAI, gcSo}, // [2] BLACK TELEPHONE..WHITE TELEPHONE
+ {0x2610, 0x2613, prAL, gcSo}, // [4] BALLOT BOX..SALTIRE
+ {0x2614, 0x2615, prID, gcSo}, // [2] UMBRELLA WITH RAIN DROPS..HOT BEVERAGE
+ {0x2616, 0x2617, prAI, gcSo}, // [2] WHITE SHOGI PIECE..BLACK SHOGI PIECE
+ {0x2618, 0x2618, prID, gcSo}, // SHAMROCK
+ {0x2619, 0x2619, prAL, gcSo}, // REVERSED ROTATED FLORAL HEART BULLET
+ {0x261A, 0x261C, prID, gcSo}, // [3] BLACK LEFT POINTING INDEX..WHITE LEFT POINTING INDEX
+ {0x261D, 0x261D, prEB, gcSo}, // WHITE UP POINTING INDEX
+ {0x261E, 0x261F, prID, gcSo}, // [2] WHITE RIGHT POINTING INDEX..WHITE DOWN POINTING INDEX
+ {0x2620, 0x2638, prAL, gcSo}, // [25] SKULL AND CROSSBONES..WHEEL OF DHARMA
+ {0x2639, 0x263B, prID, gcSo}, // [3] WHITE FROWNING FACE..BLACK SMILING FACE
+ {0x263C, 0x263F, prAL, gcSo}, // [4] WHITE SUN WITH RAYS..MERCURY
+ {0x2640, 0x2640, prAI, gcSo}, // FEMALE SIGN
+ {0x2641, 0x2641, prAL, gcSo}, // EARTH
+ {0x2642, 0x2642, prAI, gcSo}, // MALE SIGN
+ {0x2643, 0x265F, prAL, gcSo}, // [29] JUPITER..BLACK CHESS PAWN
+ {0x2660, 0x2661, prAI, gcSo}, // [2] BLACK SPADE SUIT..WHITE HEART SUIT
+ {0x2662, 0x2662, prAL, gcSo}, // WHITE DIAMOND SUIT
+ {0x2663, 0x2665, prAI, gcSo}, // [3] BLACK CLUB SUIT..BLACK HEART SUIT
+ {0x2666, 0x2666, prAL, gcSo}, // BLACK DIAMOND SUIT
+ {0x2667, 0x2667, prAI, gcSo}, // WHITE CLUB SUIT
+ {0x2668, 0x2668, prID, gcSo}, // HOT SPRINGS
+ {0x2669, 0x266A, prAI, gcSo}, // [2] QUARTER NOTE..EIGHTH NOTE
+ {0x266B, 0x266B, prAL, gcSo}, // BEAMED EIGHTH NOTES
+ {0x266C, 0x266D, prAI, gcSo}, // [2] BEAMED SIXTEENTH NOTES..MUSIC FLAT SIGN
+ {0x266E, 0x266E, prAL, gcSo}, // MUSIC NATURAL SIGN
+ {0x266F, 0x266F, prAI, gcSm}, // MUSIC SHARP SIGN
+ {0x2670, 0x267E, prAL, gcSo}, // [15] WEST SYRIAC CROSS..PERMANENT PAPER SIGN
+ {0x267F, 0x267F, prID, gcSo}, // WHEELCHAIR SYMBOL
+ {0x2680, 0x269D, prAL, gcSo}, // [30] DIE FACE-1..OUTLINED WHITE STAR
+ {0x269E, 0x269F, prAI, gcSo}, // [2] THREE LINES CONVERGING RIGHT..THREE LINES CONVERGING LEFT
+ {0x26A0, 0x26BC, prAL, gcSo}, // [29] WARNING SIGN..SESQUIQUADRATE
+ {0x26BD, 0x26C8, prID, gcSo}, // [12] SOCCER BALL..THUNDER CLOUD AND RAIN
+ {0x26C9, 0x26CC, prAI, gcSo}, // [4] TURNED WHITE SHOGI PIECE..CROSSING LANES
+ {0x26CD, 0x26CD, prID, gcSo}, // DISABLED CAR
+ {0x26CE, 0x26CE, prAL, gcSo}, // OPHIUCHUS
+ {0x26CF, 0x26D1, prID, gcSo}, // [3] PICK..HELMET WITH WHITE CROSS
+ {0x26D2, 0x26D2, prAI, gcSo}, // CIRCLED CROSSING LANES
+ {0x26D3, 0x26D4, prID, gcSo}, // [2] CHAINS..NO ENTRY
+ {0x26D5, 0x26D7, prAI, gcSo}, // [3] ALTERNATE ONE-WAY LEFT WAY TRAFFIC..WHITE TWO-WAY LEFT WAY TRAFFIC
+ {0x26D8, 0x26D9, prID, gcSo}, // [2] BLACK LEFT LANE MERGE..WHITE LEFT LANE MERGE
+ {0x26DA, 0x26DB, prAI, gcSo}, // [2] DRIVE SLOW SIGN..HEAVY WHITE DOWN-POINTING TRIANGLE
+ {0x26DC, 0x26DC, prID, gcSo}, // LEFT CLOSED ENTRY
+ {0x26DD, 0x26DE, prAI, gcSo}, // [2] SQUARED SALTIRE..FALLING DIAGONAL IN WHITE CIRCLE IN BLACK SQUARE
+ {0x26DF, 0x26E1, prID, gcSo}, // [3] BLACK TRUCK..RESTRICTED LEFT ENTRY-2
+ {0x26E2, 0x26E2, prAL, gcSo}, // ASTRONOMICAL SYMBOL FOR URANUS
+ {0x26E3, 0x26E3, prAI, gcSo}, // HEAVY CIRCLE WITH STROKE AND TWO DOTS ABOVE
+ {0x26E4, 0x26E7, prAL, gcSo}, // [4] PENTAGRAM..INVERTED PENTAGRAM
+ {0x26E8, 0x26E9, prAI, gcSo}, // [2] BLACK CROSS ON SHIELD..SHINTO SHRINE
+ {0x26EA, 0x26EA, prID, gcSo}, // CHURCH
+ {0x26EB, 0x26F0, prAI, gcSo}, // [6] CASTLE..MOUNTAIN
+ {0x26F1, 0x26F5, prID, gcSo}, // [5] UMBRELLA ON GROUND..SAILBOAT
+ {0x26F6, 0x26F6, prAI, gcSo}, // SQUARE FOUR CORNERS
+ {0x26F7, 0x26F8, prID, gcSo}, // [2] SKIER..ICE SKATE
+ {0x26F9, 0x26F9, prEB, gcSo}, // PERSON WITH BALL
+ {0x26FA, 0x26FA, prID, gcSo}, // TENT
+ {0x26FB, 0x26FC, prAI, gcSo}, // [2] JAPANESE BANK SYMBOL..HEADSTONE GRAVEYARD SYMBOL
+ {0x26FD, 0x26FF, prID, gcSo}, // [3] FUEL PUMP..WHITE FLAG WITH HORIZONTAL MIDDLE BLACK STRIPE
+ {0x2700, 0x2704, prID, gcSo}, // [5] BLACK SAFETY SCISSORS..WHITE SCISSORS
+ {0x2705, 0x2707, prAL, gcSo}, // [3] WHITE HEAVY CHECK MARK..TAPE DRIVE
+ {0x2708, 0x2709, prID, gcSo}, // [2] AIRPLANE..ENVELOPE
+ {0x270A, 0x270D, prEB, gcSo}, // [4] RAISED FIST..WRITING HAND
+ {0x270E, 0x2756, prAL, gcSo}, // [73] LOWER RIGHT PENCIL..BLACK DIAMOND MINUS WHITE X
+ {0x2757, 0x2757, prAI, gcSo}, // HEAVY EXCLAMATION MARK SYMBOL
+ {0x2758, 0x275A, prAL, gcSo}, // [3] LIGHT VERTICAL BAR..HEAVY VERTICAL BAR
+ {0x275B, 0x2760, prQU, gcSo}, // [6] HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT..HEAVY LOW DOUBLE COMMA QUOTATION MARK ORNAMENT
+ {0x2761, 0x2761, prAL, gcSo}, // CURVED STEM PARAGRAPH SIGN ORNAMENT
+ {0x2762, 0x2763, prEX, gcSo}, // [2] HEAVY EXCLAMATION MARK ORNAMENT..HEAVY HEART EXCLAMATION MARK ORNAMENT
+ {0x2764, 0x2764, prID, gcSo}, // HEAVY BLACK HEART
+ {0x2765, 0x2767, prAL, gcSo}, // [3] ROTATED HEAVY BLACK HEART BULLET..ROTATED FLORAL HEART BULLET
+ {0x2768, 0x2768, prOP, gcPs}, // MEDIUM LEFT PARENTHESIS ORNAMENT
+ {0x2769, 0x2769, prCL, gcPe}, // MEDIUM RIGHT PARENTHESIS ORNAMENT
+ {0x276A, 0x276A, prOP, gcPs}, // MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT
+ {0x276B, 0x276B, prCL, gcPe}, // MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT
+ {0x276C, 0x276C, prOP, gcPs}, // MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT
+ {0x276D, 0x276D, prCL, gcPe}, // MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT
+ {0x276E, 0x276E, prOP, gcPs}, // HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT
+ {0x276F, 0x276F, prCL, gcPe}, // HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT
+ {0x2770, 0x2770, prOP, gcPs}, // HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT
+ {0x2771, 0x2771, prCL, gcPe}, // HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT
+ {0x2772, 0x2772, prOP, gcPs}, // LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT
+ {0x2773, 0x2773, prCL, gcPe}, // LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT
+ {0x2774, 0x2774, prOP, gcPs}, // MEDIUM LEFT CURLY BRACKET ORNAMENT
+ {0x2775, 0x2775, prCL, gcPe}, // MEDIUM RIGHT CURLY BRACKET ORNAMENT
+ {0x2776, 0x2793, prAI, gcNo}, // [30] DINGBAT NEGATIVE CIRCLED DIGIT ONE..DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN
+ {0x2794, 0x27BF, prAL, gcSo}, // [44] HEAVY WIDE-HEADED RIGHTWARDS ARROW..DOUBLE CURLY LOOP
+ {0x27C0, 0x27C4, prAL, gcSm}, // [5] THREE DIMENSIONAL ANGLE..OPEN SUPERSET
+ {0x27C5, 0x27C5, prOP, gcPs}, // LEFT S-SHAPED BAG DELIMITER
+ {0x27C6, 0x27C6, prCL, gcPe}, // RIGHT S-SHAPED BAG DELIMITER
+ {0x27C7, 0x27E5, prAL, gcSm}, // [31] OR WITH DOT INSIDE..WHITE SQUARE WITH RIGHTWARDS TICK
+ {0x27E6, 0x27E6, prOP, gcPs}, // MATHEMATICAL LEFT WHITE SQUARE BRACKET
+ {0x27E7, 0x27E7, prCL, gcPe}, // MATHEMATICAL RIGHT WHITE SQUARE BRACKET
+ {0x27E8, 0x27E8, prOP, gcPs}, // MATHEMATICAL LEFT ANGLE BRACKET
+ {0x27E9, 0x27E9, prCL, gcPe}, // MATHEMATICAL RIGHT ANGLE BRACKET
+ {0x27EA, 0x27EA, prOP, gcPs}, // MATHEMATICAL LEFT DOUBLE ANGLE BRACKET
+ {0x27EB, 0x27EB, prCL, gcPe}, // MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET
+ {0x27EC, 0x27EC, prOP, gcPs}, // MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET
+ {0x27ED, 0x27ED, prCL, gcPe}, // MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET
+ {0x27EE, 0x27EE, prOP, gcPs}, // MATHEMATICAL LEFT FLATTENED PARENTHESIS
+ {0x27EF, 0x27EF, prCL, gcPe}, // MATHEMATICAL RIGHT FLATTENED PARENTHESIS
+ {0x27F0, 0x27FF, prAL, gcSm}, // [16] UPWARDS QUADRUPLE ARROW..LONG RIGHTWARDS SQUIGGLE ARROW
+ {0x2800, 0x28FF, prAL, gcSo}, // [256] BRAILLE PATTERN BLANK..BRAILLE PATTERN DOTS-12345678
+ {0x2900, 0x297F, prAL, gcSm}, // [128] RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE..DOWN FISH TAIL
+ {0x2980, 0x2982, prAL, gcSm}, // [3] TRIPLE VERTICAL BAR DELIMITER..Z NOTATION TYPE COLON
+ {0x2983, 0x2983, prOP, gcPs}, // LEFT WHITE CURLY BRACKET
+ {0x2984, 0x2984, prCL, gcPe}, // RIGHT WHITE CURLY BRACKET
+ {0x2985, 0x2985, prOP, gcPs}, // LEFT WHITE PARENTHESIS
+ {0x2986, 0x2986, prCL, gcPe}, // RIGHT WHITE PARENTHESIS
+ {0x2987, 0x2987, prOP, gcPs}, // Z NOTATION LEFT IMAGE BRACKET
+ {0x2988, 0x2988, prCL, gcPe}, // Z NOTATION RIGHT IMAGE BRACKET
+ {0x2989, 0x2989, prOP, gcPs}, // Z NOTATION LEFT BINDING BRACKET
+ {0x298A, 0x298A, prCL, gcPe}, // Z NOTATION RIGHT BINDING BRACKET
+ {0x298B, 0x298B, prOP, gcPs}, // LEFT SQUARE BRACKET WITH UNDERBAR
+ {0x298C, 0x298C, prCL, gcPe}, // RIGHT SQUARE BRACKET WITH UNDERBAR
+ {0x298D, 0x298D, prOP, gcPs}, // LEFT SQUARE BRACKET WITH TICK IN TOP CORNER
+ {0x298E, 0x298E, prCL, gcPe}, // RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
+ {0x298F, 0x298F, prOP, gcPs}, // LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER
+ {0x2990, 0x2990, prCL, gcPe}, // RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER
+ {0x2991, 0x2991, prOP, gcPs}, // LEFT ANGLE BRACKET WITH DOT
+ {0x2992, 0x2992, prCL, gcPe}, // RIGHT ANGLE BRACKET WITH DOT
+ {0x2993, 0x2993, prOP, gcPs}, // LEFT ARC LESS-THAN BRACKET
+ {0x2994, 0x2994, prCL, gcPe}, // RIGHT ARC GREATER-THAN BRACKET
+ {0x2995, 0x2995, prOP, gcPs}, // DOUBLE LEFT ARC GREATER-THAN BRACKET
+ {0x2996, 0x2996, prCL, gcPe}, // DOUBLE RIGHT ARC LESS-THAN BRACKET
+ {0x2997, 0x2997, prOP, gcPs}, // LEFT BLACK TORTOISE SHELL BRACKET
+ {0x2998, 0x2998, prCL, gcPe}, // RIGHT BLACK TORTOISE SHELL BRACKET
+ {0x2999, 0x29D7, prAL, gcSm}, // [63] DOTTED FENCE..BLACK HOURGLASS
+ {0x29D8, 0x29D8, prOP, gcPs}, // LEFT WIGGLY FENCE
+ {0x29D9, 0x29D9, prCL, gcPe}, // RIGHT WIGGLY FENCE
+ {0x29DA, 0x29DA, prOP, gcPs}, // LEFT DOUBLE WIGGLY FENCE
+ {0x29DB, 0x29DB, prCL, gcPe}, // RIGHT DOUBLE WIGGLY FENCE
+ {0x29DC, 0x29FB, prAL, gcSm}, // [32] INCOMPLETE INFINITY..TRIPLE PLUS
+ {0x29FC, 0x29FC, prOP, gcPs}, // LEFT-POINTING CURVED ANGLE BRACKET
+ {0x29FD, 0x29FD, prCL, gcPe}, // RIGHT-POINTING CURVED ANGLE BRACKET
+ {0x29FE, 0x29FF, prAL, gcSm}, // [2] TINY..MINY
+ {0x2A00, 0x2AFF, prAL, gcSm}, // [256] N-ARY CIRCLED DOT OPERATOR..N-ARY WHITE VERTICAL BAR
+ {0x2B00, 0x2B2F, prAL, gcSo}, // [48] NORTH EAST WHITE ARROW..WHITE VERTICAL ELLIPSE
+ {0x2B30, 0x2B44, prAL, gcSm}, // [21] LEFT ARROW WITH SMALL CIRCLE..RIGHTWARDS ARROW THROUGH SUPERSET
+ {0x2B45, 0x2B46, prAL, gcSo}, // [2] LEFTWARDS QUADRUPLE ARROW..RIGHTWARDS QUADRUPLE ARROW
+ {0x2B47, 0x2B4C, prAL, gcSm}, // [6] REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW..RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR
+ {0x2B4D, 0x2B54, prAL, gcSo}, // [8] DOWNWARDS TRIANGLE-HEADED ZIGZAG ARROW..WHITE RIGHT-POINTING PENTAGON
+ {0x2B55, 0x2B59, prAI, gcSo}, // [5] HEAVY LARGE CIRCLE..HEAVY CIRCLED SALTIRE
+ {0x2B5A, 0x2B73, prAL, gcSo}, // [26] SLANTED NORTH ARROW WITH HOOKED HEAD..DOWNWARDS TRIANGLE-HEADED ARROW TO BAR
+ {0x2B76, 0x2B95, prAL, gcSo}, // [32] NORTH WEST TRIANGLE-HEADED ARROW TO BAR..RIGHTWARDS BLACK ARROW
+ {0x2B97, 0x2BFF, prAL, gcSo}, // [105] SYMBOL FOR TYPE A ELECTRONICS..HELLSCHREIBER PAUSE SYMBOL
+ {0x2C00, 0x2C5F, prAL, gcLC}, // [96] GLAGOLITIC CAPITAL LETTER AZU..GLAGOLITIC SMALL LETTER CAUDATE CHRIVI
+ {0x2C60, 0x2C7B, prAL, gcLC}, // [28] LATIN CAPITAL LETTER L WITH DOUBLE BAR..LATIN LETTER SMALL CAPITAL TURNED E
+ {0x2C7C, 0x2C7D, prAL, gcLm}, // [2] LATIN SUBSCRIPT SMALL LETTER J..MODIFIER LETTER CAPITAL V
+ {0x2C7E, 0x2C7F, prAL, gcLu}, // [2] LATIN CAPITAL LETTER S WITH SWASH TAIL..LATIN CAPITAL LETTER Z WITH SWASH TAIL
+ {0x2C80, 0x2CE4, prAL, gcLC}, // [101] COPTIC CAPITAL LETTER ALFA..COPTIC SYMBOL KAI
+ {0x2CE5, 0x2CEA, prAL, gcSo}, // [6] COPTIC SYMBOL MI RO..COPTIC SYMBOL SHIMA SIMA
+ {0x2CEB, 0x2CEE, prAL, gcLC}, // [4] COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI..COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA
+ {0x2CEF, 0x2CF1, prCM, gcMn}, // [3] COPTIC COMBINING NI ABOVE..COPTIC COMBINING SPIRITUS LENIS
+ {0x2CF2, 0x2CF3, prAL, gcLC}, // [2] COPTIC CAPITAL LETTER BOHAIRIC KHEI..COPTIC SMALL LETTER BOHAIRIC KHEI
+ {0x2CF9, 0x2CF9, prEX, gcPo}, // COPTIC OLD NUBIAN FULL STOP
+ {0x2CFA, 0x2CFC, prBA, gcPo}, // [3] COPTIC OLD NUBIAN DIRECT QUESTION MARK..COPTIC OLD NUBIAN VERSE DIVIDER
+ {0x2CFD, 0x2CFD, prAL, gcNo}, // COPTIC FRACTION ONE HALF
+ {0x2CFE, 0x2CFE, prEX, gcPo}, // COPTIC FULL STOP
+ {0x2CFF, 0x2CFF, prBA, gcPo}, // COPTIC MORPHOLOGICAL DIVIDER
+ {0x2D00, 0x2D25, prAL, gcLl}, // [38] GEORGIAN SMALL LETTER AN..GEORGIAN SMALL LETTER HOE
+ {0x2D27, 0x2D27, prAL, gcLl}, // GEORGIAN SMALL LETTER YN
+ {0x2D2D, 0x2D2D, prAL, gcLl}, // GEORGIAN SMALL LETTER AEN
+ {0x2D30, 0x2D67, prAL, gcLo}, // [56] TIFINAGH LETTER YA..TIFINAGH LETTER YO
+ {0x2D6F, 0x2D6F, prAL, gcLm}, // TIFINAGH MODIFIER LETTER LABIALIZATION MARK
+ {0x2D70, 0x2D70, prBA, gcPo}, // TIFINAGH SEPARATOR MARK
+ {0x2D7F, 0x2D7F, prCM, gcMn}, // TIFINAGH CONSONANT JOINER
+ {0x2D80, 0x2D96, prAL, gcLo}, // [23] ETHIOPIC SYLLABLE LOA..ETHIOPIC SYLLABLE GGWE
+ {0x2DA0, 0x2DA6, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE SSA..ETHIOPIC SYLLABLE SSO
+ {0x2DA8, 0x2DAE, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE CCA..ETHIOPIC SYLLABLE CCO
+ {0x2DB0, 0x2DB6, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE ZZA..ETHIOPIC SYLLABLE ZZO
+ {0x2DB8, 0x2DBE, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE CCHA..ETHIOPIC SYLLABLE CCHO
+ {0x2DC0, 0x2DC6, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE QYA..ETHIOPIC SYLLABLE QYO
+ {0x2DC8, 0x2DCE, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE KYA..ETHIOPIC SYLLABLE KYO
+ {0x2DD0, 0x2DD6, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE XYA..ETHIOPIC SYLLABLE XYO
+ {0x2DD8, 0x2DDE, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE GYA..ETHIOPIC SYLLABLE GYO
+ {0x2DE0, 0x2DFF, prCM, gcMn}, // [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS
+ {0x2E00, 0x2E01, prQU, gcPo}, // [2] RIGHT ANGLE SUBSTITUTION MARKER..RIGHT ANGLE DOTTED SUBSTITUTION MARKER
+ {0x2E02, 0x2E02, prQU, gcPi}, // LEFT SUBSTITUTION BRACKET
+ {0x2E03, 0x2E03, prQU, gcPf}, // RIGHT SUBSTITUTION BRACKET
+ {0x2E04, 0x2E04, prQU, gcPi}, // LEFT DOTTED SUBSTITUTION BRACKET
+ {0x2E05, 0x2E05, prQU, gcPf}, // RIGHT DOTTED SUBSTITUTION BRACKET
+ {0x2E06, 0x2E08, prQU, gcPo}, // [3] RAISED INTERPOLATION MARKER..DOTTED TRANSPOSITION MARKER
+ {0x2E09, 0x2E09, prQU, gcPi}, // LEFT TRANSPOSITION BRACKET
+ {0x2E0A, 0x2E0A, prQU, gcPf}, // RIGHT TRANSPOSITION BRACKET
+ {0x2E0B, 0x2E0B, prQU, gcPo}, // RAISED SQUARE
+ {0x2E0C, 0x2E0C, prQU, gcPi}, // LEFT RAISED OMISSION BRACKET
+ {0x2E0D, 0x2E0D, prQU, gcPf}, // RIGHT RAISED OMISSION BRACKET
+ {0x2E0E, 0x2E15, prBA, gcPo}, // [8] EDITORIAL CORONIS..UPWARDS ANCORA
+ {0x2E16, 0x2E16, prAL, gcPo}, // DOTTED RIGHT-POINTING ANGLE
+ {0x2E17, 0x2E17, prBA, gcPd}, // DOUBLE OBLIQUE HYPHEN
+ {0x2E18, 0x2E18, prOP, gcPo}, // INVERTED INTERROBANG
+ {0x2E19, 0x2E19, prBA, gcPo}, // PALM BRANCH
+ {0x2E1A, 0x2E1A, prAL, gcPd}, // HYPHEN WITH DIAERESIS
+ {0x2E1B, 0x2E1B, prAL, gcPo}, // TILDE WITH RING ABOVE
+ {0x2E1C, 0x2E1C, prQU, gcPi}, // LEFT LOW PARAPHRASE BRACKET
+ {0x2E1D, 0x2E1D, prQU, gcPf}, // RIGHT LOW PARAPHRASE BRACKET
+ {0x2E1E, 0x2E1F, prAL, gcPo}, // [2] TILDE WITH DOT ABOVE..TILDE WITH DOT BELOW
+ {0x2E20, 0x2E20, prQU, gcPi}, // LEFT VERTICAL BAR WITH QUILL
+ {0x2E21, 0x2E21, prQU, gcPf}, // RIGHT VERTICAL BAR WITH QUILL
+ {0x2E22, 0x2E22, prOP, gcPs}, // TOP LEFT HALF BRACKET
+ {0x2E23, 0x2E23, prCL, gcPe}, // TOP RIGHT HALF BRACKET
+ {0x2E24, 0x2E24, prOP, gcPs}, // BOTTOM LEFT HALF BRACKET
+ {0x2E25, 0x2E25, prCL, gcPe}, // BOTTOM RIGHT HALF BRACKET
+ {0x2E26, 0x2E26, prOP, gcPs}, // LEFT SIDEWAYS U BRACKET
+ {0x2E27, 0x2E27, prCL, gcPe}, // RIGHT SIDEWAYS U BRACKET
+ {0x2E28, 0x2E28, prOP, gcPs}, // LEFT DOUBLE PARENTHESIS
+ {0x2E29, 0x2E29, prCL, gcPe}, // RIGHT DOUBLE PARENTHESIS
+ {0x2E2A, 0x2E2D, prBA, gcPo}, // [4] TWO DOTS OVER ONE DOT PUNCTUATION..FIVE DOT MARK
+ {0x2E2E, 0x2E2E, prEX, gcPo}, // REVERSED QUESTION MARK
+ {0x2E2F, 0x2E2F, prAL, gcLm}, // VERTICAL TILDE
+ {0x2E30, 0x2E31, prBA, gcPo}, // [2] RING POINT..WORD SEPARATOR MIDDLE DOT
+ {0x2E32, 0x2E32, prAL, gcPo}, // TURNED COMMA
+ {0x2E33, 0x2E34, prBA, gcPo}, // [2] RAISED DOT..RAISED COMMA
+ {0x2E35, 0x2E39, prAL, gcPo}, // [5] TURNED SEMICOLON..TOP HALF SECTION SIGN
+ {0x2E3A, 0x2E3B, prB2, gcPd}, // [2] TWO-EM DASH..THREE-EM DASH
+ {0x2E3C, 0x2E3E, prBA, gcPo}, // [3] STENOGRAPHIC FULL STOP..WIGGLY VERTICAL LINE
+ {0x2E3F, 0x2E3F, prAL, gcPo}, // CAPITULUM
+ {0x2E40, 0x2E40, prBA, gcPd}, // DOUBLE HYPHEN
+ {0x2E41, 0x2E41, prBA, gcPo}, // REVERSED COMMA
+ {0x2E42, 0x2E42, prOP, gcPs}, // DOUBLE LOW-REVERSED-9 QUOTATION MARK
+ {0x2E43, 0x2E4A, prBA, gcPo}, // [8] DASH WITH LEFT UPTURN..DOTTED SOLIDUS
+ {0x2E4B, 0x2E4B, prAL, gcPo}, // TRIPLE DAGGER
+ {0x2E4C, 0x2E4C, prBA, gcPo}, // MEDIEVAL COMMA
+ {0x2E4D, 0x2E4D, prAL, gcPo}, // PARAGRAPHUS MARK
+ {0x2E4E, 0x2E4F, prBA, gcPo}, // [2] PUNCTUS ELEVATUS MARK..CORNISH VERSE DIVIDER
+ {0x2E50, 0x2E51, prAL, gcSo}, // [2] CROSS PATTY WITH RIGHT CROSSBAR..CROSS PATTY WITH LEFT CROSSBAR
+ {0x2E52, 0x2E52, prAL, gcPo}, // TIRONIAN SIGN CAPITAL ET
+ {0x2E53, 0x2E54, prEX, gcPo}, // [2] MEDIEVAL EXCLAMATION MARK..MEDIEVAL QUESTION MARK
+ {0x2E55, 0x2E55, prOP, gcPs}, // LEFT SQUARE BRACKET WITH STROKE
+ {0x2E56, 0x2E56, prCL, gcPe}, // RIGHT SQUARE BRACKET WITH STROKE
+ {0x2E57, 0x2E57, prOP, gcPs}, // LEFT SQUARE BRACKET WITH DOUBLE STROKE
+ {0x2E58, 0x2E58, prCL, gcPe}, // RIGHT SQUARE BRACKET WITH DOUBLE STROKE
+ {0x2E59, 0x2E59, prOP, gcPs}, // TOP HALF LEFT PARENTHESIS
+ {0x2E5A, 0x2E5A, prCL, gcPe}, // TOP HALF RIGHT PARENTHESIS
+ {0x2E5B, 0x2E5B, prOP, gcPs}, // BOTTOM HALF LEFT PARENTHESIS
+ {0x2E5C, 0x2E5C, prCL, gcPe}, // BOTTOM HALF RIGHT PARENTHESIS
+ {0x2E5D, 0x2E5D, prBA, gcPd}, // OBLIQUE HYPHEN
+ {0x2E80, 0x2E99, prID, gcSo}, // [26] CJK RADICAL REPEAT..CJK RADICAL RAP
+ {0x2E9B, 0x2EF3, prID, gcSo}, // [89] CJK RADICAL CHOKE..CJK RADICAL C-SIMPLIFIED TURTLE
+ {0x2F00, 0x2FD5, prID, gcSo}, // [214] KANGXI RADICAL ONE..KANGXI RADICAL FLUTE
+ {0x2FF0, 0x2FFB, prID, gcSo}, // [12] IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT..IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID
+ {0x3000, 0x3000, prBA, gcZs}, // IDEOGRAPHIC SPACE
+ {0x3001, 0x3002, prCL, gcPo}, // [2] IDEOGRAPHIC COMMA..IDEOGRAPHIC FULL STOP
+ {0x3003, 0x3003, prID, gcPo}, // DITTO MARK
+ {0x3004, 0x3004, prID, gcSo}, // JAPANESE INDUSTRIAL STANDARD SYMBOL
+ {0x3005, 0x3005, prNS, gcLm}, // IDEOGRAPHIC ITERATION MARK
+ {0x3006, 0x3006, prID, gcLo}, // IDEOGRAPHIC CLOSING MARK
+ {0x3007, 0x3007, prID, gcNl}, // IDEOGRAPHIC NUMBER ZERO
+ {0x3008, 0x3008, prOP, gcPs}, // LEFT ANGLE BRACKET
+ {0x3009, 0x3009, prCL, gcPe}, // RIGHT ANGLE BRACKET
+ {0x300A, 0x300A, prOP, gcPs}, // LEFT DOUBLE ANGLE BRACKET
+ {0x300B, 0x300B, prCL, gcPe}, // RIGHT DOUBLE ANGLE BRACKET
+ {0x300C, 0x300C, prOP, gcPs}, // LEFT CORNER BRACKET
+ {0x300D, 0x300D, prCL, gcPe}, // RIGHT CORNER BRACKET
+ {0x300E, 0x300E, prOP, gcPs}, // LEFT WHITE CORNER BRACKET
+ {0x300F, 0x300F, prCL, gcPe}, // RIGHT WHITE CORNER BRACKET
+ {0x3010, 0x3010, prOP, gcPs}, // LEFT BLACK LENTICULAR BRACKET
+ {0x3011, 0x3011, prCL, gcPe}, // RIGHT BLACK LENTICULAR BRACKET
+ {0x3012, 0x3013, prID, gcSo}, // [2] POSTAL MARK..GETA MARK
+ {0x3014, 0x3014, prOP, gcPs}, // LEFT TORTOISE SHELL BRACKET
+ {0x3015, 0x3015, prCL, gcPe}, // RIGHT TORTOISE SHELL BRACKET
+ {0x3016, 0x3016, prOP, gcPs}, // LEFT WHITE LENTICULAR BRACKET
+ {0x3017, 0x3017, prCL, gcPe}, // RIGHT WHITE LENTICULAR BRACKET
+ {0x3018, 0x3018, prOP, gcPs}, // LEFT WHITE TORTOISE SHELL BRACKET
+ {0x3019, 0x3019, prCL, gcPe}, // RIGHT WHITE TORTOISE SHELL BRACKET
+ {0x301A, 0x301A, prOP, gcPs}, // LEFT WHITE SQUARE BRACKET
+ {0x301B, 0x301B, prCL, gcPe}, // RIGHT WHITE SQUARE BRACKET
+ {0x301C, 0x301C, prNS, gcPd}, // WAVE DASH
+ {0x301D, 0x301D, prOP, gcPs}, // REVERSED DOUBLE PRIME QUOTATION MARK
+ {0x301E, 0x301F, prCL, gcPe}, // [2] DOUBLE PRIME QUOTATION MARK..LOW DOUBLE PRIME QUOTATION MARK
+ {0x3020, 0x3020, prID, gcSo}, // POSTAL MARK FACE
+ {0x3021, 0x3029, prID, gcNl}, // [9] HANGZHOU NUMERAL ONE..HANGZHOU NUMERAL NINE
+ {0x302A, 0x302D, prCM, gcMn}, // [4] IDEOGRAPHIC LEVEL TONE MARK..IDEOGRAPHIC ENTERING TONE MARK
+ {0x302E, 0x302F, prCM, gcMc}, // [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK
+ {0x3030, 0x3030, prID, gcPd}, // WAVY DASH
+ {0x3031, 0x3034, prID, gcLm}, // [4] VERTICAL KANA REPEAT MARK..VERTICAL KANA REPEAT WITH VOICED SOUND MARK UPPER HALF
+ {0x3035, 0x3035, prCM, gcLm}, // VERTICAL KANA REPEAT MARK LOWER HALF
+ {0x3036, 0x3037, prID, gcSo}, // [2] CIRCLED POSTAL MARK..IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL
+ {0x3038, 0x303A, prID, gcNl}, // [3] HANGZHOU NUMERAL TEN..HANGZHOU NUMERAL THIRTY
+ {0x303B, 0x303B, prNS, gcLm}, // VERTICAL IDEOGRAPHIC ITERATION MARK
+ {0x303C, 0x303C, prNS, gcLo}, // MASU MARK
+ {0x303D, 0x303D, prID, gcPo}, // PART ALTERNATION MARK
+ {0x303E, 0x303F, prID, gcSo}, // [2] IDEOGRAPHIC VARIATION INDICATOR..IDEOGRAPHIC HALF FILL SPACE
+ {0x3041, 0x3041, prCJ, gcLo}, // HIRAGANA LETTER SMALL A
+ {0x3042, 0x3042, prID, gcLo}, // HIRAGANA LETTER A
+ {0x3043, 0x3043, prCJ, gcLo}, // HIRAGANA LETTER SMALL I
+ {0x3044, 0x3044, prID, gcLo}, // HIRAGANA LETTER I
+ {0x3045, 0x3045, prCJ, gcLo}, // HIRAGANA LETTER SMALL U
+ {0x3046, 0x3046, prID, gcLo}, // HIRAGANA LETTER U
+ {0x3047, 0x3047, prCJ, gcLo}, // HIRAGANA LETTER SMALL E
+ {0x3048, 0x3048, prID, gcLo}, // HIRAGANA LETTER E
+ {0x3049, 0x3049, prCJ, gcLo}, // HIRAGANA LETTER SMALL O
+ {0x304A, 0x3062, prID, gcLo}, // [25] HIRAGANA LETTER O..HIRAGANA LETTER DI
+ {0x3063, 0x3063, prCJ, gcLo}, // HIRAGANA LETTER SMALL TU
+ {0x3064, 0x3082, prID, gcLo}, // [31] HIRAGANA LETTER TU..HIRAGANA LETTER MO
+ {0x3083, 0x3083, prCJ, gcLo}, // HIRAGANA LETTER SMALL YA
+ {0x3084, 0x3084, prID, gcLo}, // HIRAGANA LETTER YA
+ {0x3085, 0x3085, prCJ, gcLo}, // HIRAGANA LETTER SMALL YU
+ {0x3086, 0x3086, prID, gcLo}, // HIRAGANA LETTER YU
+ {0x3087, 0x3087, prCJ, gcLo}, // HIRAGANA LETTER SMALL YO
+ {0x3088, 0x308D, prID, gcLo}, // [6] HIRAGANA LETTER YO..HIRAGANA LETTER RO
+ {0x308E, 0x308E, prCJ, gcLo}, // HIRAGANA LETTER SMALL WA
+ {0x308F, 0x3094, prID, gcLo}, // [6] HIRAGANA LETTER WA..HIRAGANA LETTER VU
+ {0x3095, 0x3096, prCJ, gcLo}, // [2] HIRAGANA LETTER SMALL KA..HIRAGANA LETTER SMALL KE
+ {0x3099, 0x309A, prCM, gcMn}, // [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+ {0x309B, 0x309C, prNS, gcSk}, // [2] KATAKANA-HIRAGANA VOICED SOUND MARK..KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+ {0x309D, 0x309E, prNS, gcLm}, // [2] HIRAGANA ITERATION MARK..HIRAGANA VOICED ITERATION MARK
+ {0x309F, 0x309F, prID, gcLo}, // HIRAGANA DIGRAPH YORI
+ {0x30A0, 0x30A0, prNS, gcPd}, // KATAKANA-HIRAGANA DOUBLE HYPHEN
+ {0x30A1, 0x30A1, prCJ, gcLo}, // KATAKANA LETTER SMALL A
+ {0x30A2, 0x30A2, prID, gcLo}, // KATAKANA LETTER A
+ {0x30A3, 0x30A3, prCJ, gcLo}, // KATAKANA LETTER SMALL I
+ {0x30A4, 0x30A4, prID, gcLo}, // KATAKANA LETTER I
+ {0x30A5, 0x30A5, prCJ, gcLo}, // KATAKANA LETTER SMALL U
+ {0x30A6, 0x30A6, prID, gcLo}, // KATAKANA LETTER U
+ {0x30A7, 0x30A7, prCJ, gcLo}, // KATAKANA LETTER SMALL E
+ {0x30A8, 0x30A8, prID, gcLo}, // KATAKANA LETTER E
+ {0x30A9, 0x30A9, prCJ, gcLo}, // KATAKANA LETTER SMALL O
+ {0x30AA, 0x30C2, prID, gcLo}, // [25] KATAKANA LETTER O..KATAKANA LETTER DI
+ {0x30C3, 0x30C3, prCJ, gcLo}, // KATAKANA LETTER SMALL TU
+ {0x30C4, 0x30E2, prID, gcLo}, // [31] KATAKANA LETTER TU..KATAKANA LETTER MO
+ {0x30E3, 0x30E3, prCJ, gcLo}, // KATAKANA LETTER SMALL YA
+ {0x30E4, 0x30E4, prID, gcLo}, // KATAKANA LETTER YA
+ {0x30E5, 0x30E5, prCJ, gcLo}, // KATAKANA LETTER SMALL YU
+ {0x30E6, 0x30E6, prID, gcLo}, // KATAKANA LETTER YU
+ {0x30E7, 0x30E7, prCJ, gcLo}, // KATAKANA LETTER SMALL YO
+ {0x30E8, 0x30ED, prID, gcLo}, // [6] KATAKANA LETTER YO..KATAKANA LETTER RO
+ {0x30EE, 0x30EE, prCJ, gcLo}, // KATAKANA LETTER SMALL WA
+ {0x30EF, 0x30F4, prID, gcLo}, // [6] KATAKANA LETTER WA..KATAKANA LETTER VU
+ {0x30F5, 0x30F6, prCJ, gcLo}, // [2] KATAKANA LETTER SMALL KA..KATAKANA LETTER SMALL KE
+ {0x30F7, 0x30FA, prID, gcLo}, // [4] KATAKANA LETTER VA..KATAKANA LETTER VO
+ {0x30FB, 0x30FB, prNS, gcPo}, // KATAKANA MIDDLE DOT
+ {0x30FC, 0x30FC, prCJ, gcLm}, // KATAKANA-HIRAGANA PROLONGED SOUND MARK
+ {0x30FD, 0x30FE, prNS, gcLm}, // [2] KATAKANA ITERATION MARK..KATAKANA VOICED ITERATION MARK
+ {0x30FF, 0x30FF, prID, gcLo}, // KATAKANA DIGRAPH KOTO
+ {0x3105, 0x312F, prID, gcLo}, // [43] BOPOMOFO LETTER B..BOPOMOFO LETTER NN
+ {0x3131, 0x318E, prID, gcLo}, // [94] HANGUL LETTER KIYEOK..HANGUL LETTER ARAEAE
+ {0x3190, 0x3191, prID, gcSo}, // [2] IDEOGRAPHIC ANNOTATION LINKING MARK..IDEOGRAPHIC ANNOTATION REVERSE MARK
+ {0x3192, 0x3195, prID, gcNo}, // [4] IDEOGRAPHIC ANNOTATION ONE MARK..IDEOGRAPHIC ANNOTATION FOUR MARK
+ {0x3196, 0x319F, prID, gcSo}, // [10] IDEOGRAPHIC ANNOTATION TOP MARK..IDEOGRAPHIC ANNOTATION MAN MARK
+ {0x31A0, 0x31BF, prID, gcLo}, // [32] BOPOMOFO LETTER BU..BOPOMOFO LETTER AH
+ {0x31C0, 0x31E3, prID, gcSo}, // [36] CJK STROKE T..CJK STROKE Q
+ {0x31F0, 0x31FF, prCJ, gcLo}, // [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO
+ {0x3200, 0x321E, prID, gcSo}, // [31] PARENTHESIZED HANGUL KIYEOK..PARENTHESIZED KOREAN CHARACTER O HU
+ {0x3220, 0x3229, prID, gcNo}, // [10] PARENTHESIZED IDEOGRAPH ONE..PARENTHESIZED IDEOGRAPH TEN
+ {0x322A, 0x3247, prID, gcSo}, // [30] PARENTHESIZED IDEOGRAPH MOON..CIRCLED IDEOGRAPH KOTO
+ {0x3248, 0x324F, prAI, gcNo}, // [8] CIRCLED NUMBER TEN ON BLACK SQUARE..CIRCLED NUMBER EIGHTY ON BLACK SQUARE
+ {0x3250, 0x3250, prID, gcSo}, // PARTNERSHIP SIGN
+ {0x3251, 0x325F, prID, gcNo}, // [15] CIRCLED NUMBER TWENTY ONE..CIRCLED NUMBER THIRTY FIVE
+ {0x3260, 0x327F, prID, gcSo}, // [32] CIRCLED HANGUL KIYEOK..KOREAN STANDARD SYMBOL
+ {0x3280, 0x3289, prID, gcNo}, // [10] CIRCLED IDEOGRAPH ONE..CIRCLED IDEOGRAPH TEN
+ {0x328A, 0x32B0, prID, gcSo}, // [39] CIRCLED IDEOGRAPH MOON..CIRCLED IDEOGRAPH NIGHT
+ {0x32B1, 0x32BF, prID, gcNo}, // [15] CIRCLED NUMBER THIRTY SIX..CIRCLED NUMBER FIFTY
+ {0x32C0, 0x32FF, prID, gcSo}, // [64] IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY..SQUARE ERA NAME REIWA
+ {0x3300, 0x33FF, prID, gcSo}, // [256] SQUARE APAATO..SQUARE GAL
+ {0x3400, 0x4DBF, prID, gcLo}, // [6592] CJK UNIFIED IDEOGRAPH-3400..CJK UNIFIED IDEOGRAPH-4DBF
+ {0x4DC0, 0x4DFF, prAL, gcSo}, // [64] HEXAGRAM FOR THE CREATIVE HEAVEN..HEXAGRAM FOR BEFORE COMPLETION
+ {0x4E00, 0x9FFF, prID, gcLo}, // [20992] CJK UNIFIED IDEOGRAPH-4E00..CJK UNIFIED IDEOGRAPH-9FFF
+ {0xA000, 0xA014, prID, gcLo}, // [21] YI SYLLABLE IT..YI SYLLABLE E
+ {0xA015, 0xA015, prNS, gcLm}, // YI SYLLABLE WU
+ {0xA016, 0xA48C, prID, gcLo}, // [1143] YI SYLLABLE BIT..YI SYLLABLE YYR
+ {0xA490, 0xA4C6, prID, gcSo}, // [55] YI RADICAL QOT..YI RADICAL KE
+ {0xA4D0, 0xA4F7, prAL, gcLo}, // [40] LISU LETTER BA..LISU LETTER OE
+ {0xA4F8, 0xA4FD, prAL, gcLm}, // [6] LISU LETTER TONE MYA TI..LISU LETTER TONE MYA JEU
+ {0xA4FE, 0xA4FF, prBA, gcPo}, // [2] LISU PUNCTUATION COMMA..LISU PUNCTUATION FULL STOP
+ {0xA500, 0xA60B, prAL, gcLo}, // [268] VAI SYLLABLE EE..VAI SYLLABLE NG
+ {0xA60C, 0xA60C, prAL, gcLm}, // VAI SYLLABLE LENGTHENER
+ {0xA60D, 0xA60D, prBA, gcPo}, // VAI COMMA
+ {0xA60E, 0xA60E, prEX, gcPo}, // VAI FULL STOP
+ {0xA60F, 0xA60F, prBA, gcPo}, // VAI QUESTION MARK
+ {0xA610, 0xA61F, prAL, gcLo}, // [16] VAI SYLLABLE NDOLE FA..VAI SYMBOL JONG
+ {0xA620, 0xA629, prNU, gcNd}, // [10] VAI DIGIT ZERO..VAI DIGIT NINE
+ {0xA62A, 0xA62B, prAL, gcLo}, // [2] VAI SYLLABLE NDOLE MA..VAI SYLLABLE NDOLE DO
+ {0xA640, 0xA66D, prAL, gcLC}, // [46] CYRILLIC CAPITAL LETTER ZEMLYA..CYRILLIC SMALL LETTER DOUBLE MONOCULAR O
+ {0xA66E, 0xA66E, prAL, gcLo}, // CYRILLIC LETTER MULTIOCULAR O
+ {0xA66F, 0xA66F, prCM, gcMn}, // COMBINING CYRILLIC VZMET
+ {0xA670, 0xA672, prCM, gcMe}, // [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN
+ {0xA673, 0xA673, prAL, gcPo}, // SLAVONIC ASTERISK
+ {0xA674, 0xA67D, prCM, gcMn}, // [10] COMBINING CYRILLIC LETTER UKRAINIAN IE..COMBINING CYRILLIC PAYEROK
+ {0xA67E, 0xA67E, prAL, gcPo}, // CYRILLIC KAVYKA
+ {0xA67F, 0xA67F, prAL, gcLm}, // CYRILLIC PAYEROK
+ {0xA680, 0xA69B, prAL, gcLC}, // [28] CYRILLIC CAPITAL LETTER DWE..CYRILLIC SMALL LETTER CROSSED O
+ {0xA69C, 0xA69D, prAL, gcLm}, // [2] MODIFIER LETTER CYRILLIC HARD SIGN..MODIFIER LETTER CYRILLIC SOFT SIGN
+ {0xA69E, 0xA69F, prCM, gcMn}, // [2] COMBINING CYRILLIC LETTER EF..COMBINING CYRILLIC LETTER IOTIFIED E
+ {0xA6A0, 0xA6E5, prAL, gcLo}, // [70] BAMUM LETTER A..BAMUM LETTER KI
+ {0xA6E6, 0xA6EF, prAL, gcNl}, // [10] BAMUM LETTER MO..BAMUM LETTER KOGHOM
+ {0xA6F0, 0xA6F1, prCM, gcMn}, // [2] BAMUM COMBINING MARK KOQNDON..BAMUM COMBINING MARK TUKWENTIS
+ {0xA6F2, 0xA6F2, prAL, gcPo}, // BAMUM NJAEMLI
+ {0xA6F3, 0xA6F7, prBA, gcPo}, // [5] BAMUM FULL STOP..BAMUM QUESTION MARK
+ {0xA700, 0xA716, prAL, gcSk}, // [23] MODIFIER LETTER CHINESE TONE YIN PING..MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR
+ {0xA717, 0xA71F, prAL, gcLm}, // [9] MODIFIER LETTER DOT VERTICAL BAR..MODIFIER LETTER LOW INVERTED EXCLAMATION MARK
+ {0xA720, 0xA721, prAL, gcSk}, // [2] MODIFIER LETTER STRESS AND HIGH TONE..MODIFIER LETTER STRESS AND LOW TONE
+ {0xA722, 0xA76F, prAL, gcLC}, // [78] LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF..LATIN SMALL LETTER CON
+ {0xA770, 0xA770, prAL, gcLm}, // MODIFIER LETTER US
+ {0xA771, 0xA787, prAL, gcLC}, // [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER INSULAR T
+ {0xA788, 0xA788, prAL, gcLm}, // MODIFIER LETTER LOW CIRCUMFLEX ACCENT
+ {0xA789, 0xA78A, prAL, gcSk}, // [2] MODIFIER LETTER COLON..MODIFIER LETTER SHORT EQUALS SIGN
+ {0xA78B, 0xA78E, prAL, gcLC}, // [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT
+ {0xA78F, 0xA78F, prAL, gcLo}, // LATIN LETTER SINOLOGICAL DOT
+ {0xA790, 0xA7CA, prAL, gcLC}, // [59] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY
+ {0xA7D0, 0xA7D1, prAL, gcLC}, // [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G
+ {0xA7D3, 0xA7D3, prAL, gcLl}, // LATIN SMALL LETTER DOUBLE THORN
+ {0xA7D5, 0xA7D9, prAL, gcLC}, // [5] LATIN SMALL LETTER DOUBLE WYNN..LATIN SMALL LETTER SIGMOID S
+ {0xA7F2, 0xA7F4, prAL, gcLm}, // [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q
+ {0xA7F5, 0xA7F6, prAL, gcLC}, // [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H
+ {0xA7F7, 0xA7F7, prAL, gcLo}, // LATIN EPIGRAPHIC LETTER SIDEWAYS I
+ {0xA7F8, 0xA7F9, prAL, gcLm}, // [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE
+ {0xA7FA, 0xA7FA, prAL, gcLl}, // LATIN LETTER SMALL CAPITAL TURNED M
+ {0xA7FB, 0xA7FF, prAL, gcLo}, // [5] LATIN EPIGRAPHIC LETTER REVERSED F..LATIN EPIGRAPHIC LETTER ARCHAIC M
+ {0xA800, 0xA801, prAL, gcLo}, // [2] SYLOTI NAGRI LETTER A..SYLOTI NAGRI LETTER I
+ {0xA802, 0xA802, prCM, gcMn}, // SYLOTI NAGRI SIGN DVISVARA
+ {0xA803, 0xA805, prAL, gcLo}, // [3] SYLOTI NAGRI LETTER U..SYLOTI NAGRI LETTER O
+ {0xA806, 0xA806, prCM, gcMn}, // SYLOTI NAGRI SIGN HASANTA
+ {0xA807, 0xA80A, prAL, gcLo}, // [4] SYLOTI NAGRI LETTER KO..SYLOTI NAGRI LETTER GHO
+ {0xA80B, 0xA80B, prCM, gcMn}, // SYLOTI NAGRI SIGN ANUSVARA
+ {0xA80C, 0xA822, prAL, gcLo}, // [23] SYLOTI NAGRI LETTER CO..SYLOTI NAGRI LETTER HO
+ {0xA823, 0xA824, prCM, gcMc}, // [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI VOWEL SIGN I
+ {0xA825, 0xA826, prCM, gcMn}, // [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E
+ {0xA827, 0xA827, prCM, gcMc}, // SYLOTI NAGRI VOWEL SIGN OO
+ {0xA828, 0xA82B, prAL, gcSo}, // [4] SYLOTI NAGRI POETRY MARK-1..SYLOTI NAGRI POETRY MARK-4
+ {0xA82C, 0xA82C, prCM, gcMn}, // SYLOTI NAGRI SIGN ALTERNATE HASANTA
+ {0xA830, 0xA835, prAL, gcNo}, // [6] NORTH INDIC FRACTION ONE QUARTER..NORTH INDIC FRACTION THREE SIXTEENTHS
+ {0xA836, 0xA837, prAL, gcSo}, // [2] NORTH INDIC QUARTER MARK..NORTH INDIC PLACEHOLDER MARK
+ {0xA838, 0xA838, prPO, gcSc}, // NORTH INDIC RUPEE MARK
+ {0xA839, 0xA839, prAL, gcSo}, // NORTH INDIC QUANTITY MARK
+ {0xA840, 0xA873, prAL, gcLo}, // [52] PHAGS-PA LETTER KA..PHAGS-PA LETTER CANDRABINDU
+ {0xA874, 0xA875, prBB, gcPo}, // [2] PHAGS-PA SINGLE HEAD MARK..PHAGS-PA DOUBLE HEAD MARK
+ {0xA876, 0xA877, prEX, gcPo}, // [2] PHAGS-PA MARK SHAD..PHAGS-PA MARK DOUBLE SHAD
+ {0xA880, 0xA881, prCM, gcMc}, // [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA
+ {0xA882, 0xA8B3, prAL, gcLo}, // [50] SAURASHTRA LETTER A..SAURASHTRA LETTER LLA
+ {0xA8B4, 0xA8C3, prCM, gcMc}, // [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU
+ {0xA8C4, 0xA8C5, prCM, gcMn}, // [2] SAURASHTRA SIGN VIRAMA..SAURASHTRA SIGN CANDRABINDU
+ {0xA8CE, 0xA8CF, prBA, gcPo}, // [2] SAURASHTRA DANDA..SAURASHTRA DOUBLE DANDA
+ {0xA8D0, 0xA8D9, prNU, gcNd}, // [10] SAURASHTRA DIGIT ZERO..SAURASHTRA DIGIT NINE
+ {0xA8E0, 0xA8F1, prCM, gcMn}, // [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA
+ {0xA8F2, 0xA8F7, prAL, gcLo}, // [6] DEVANAGARI SIGN SPACING CANDRABINDU..DEVANAGARI SIGN CANDRABINDU AVAGRAHA
+ {0xA8F8, 0xA8FA, prAL, gcPo}, // [3] DEVANAGARI SIGN PUSHPIKA..DEVANAGARI CARET
+ {0xA8FB, 0xA8FB, prAL, gcLo}, // DEVANAGARI HEADSTROKE
+ {0xA8FC, 0xA8FC, prBB, gcPo}, // DEVANAGARI SIGN SIDDHAM
+ {0xA8FD, 0xA8FE, prAL, gcLo}, // [2] DEVANAGARI JAIN OM..DEVANAGARI LETTER AY
+ {0xA8FF, 0xA8FF, prCM, gcMn}, // DEVANAGARI VOWEL SIGN AY
+ {0xA900, 0xA909, prNU, gcNd}, // [10] KAYAH LI DIGIT ZERO..KAYAH LI DIGIT NINE
+ {0xA90A, 0xA925, prAL, gcLo}, // [28] KAYAH LI LETTER KA..KAYAH LI LETTER OO
+ {0xA926, 0xA92D, prCM, gcMn}, // [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU
+ {0xA92E, 0xA92F, prBA, gcPo}, // [2] KAYAH LI SIGN CWI..KAYAH LI SIGN SHYA
+ {0xA930, 0xA946, prAL, gcLo}, // [23] REJANG LETTER KA..REJANG LETTER A
+ {0xA947, 0xA951, prCM, gcMn}, // [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R
+ {0xA952, 0xA953, prCM, gcMc}, // [2] REJANG CONSONANT SIGN H..REJANG VIRAMA
+ {0xA95F, 0xA95F, prAL, gcPo}, // REJANG SECTION MARK
+ {0xA960, 0xA97C, prJL, gcLo}, // [29] HANGUL CHOSEONG TIKEUT-MIEUM..HANGUL CHOSEONG SSANGYEORINHIEUH
+ {0xA980, 0xA982, prCM, gcMn}, // [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR
+ {0xA983, 0xA983, prCM, gcMc}, // JAVANESE SIGN WIGNYAN
+ {0xA984, 0xA9B2, prAL, gcLo}, // [47] JAVANESE LETTER A..JAVANESE LETTER HA
+ {0xA9B3, 0xA9B3, prCM, gcMn}, // JAVANESE SIGN CECAK TELU
+ {0xA9B4, 0xA9B5, prCM, gcMc}, // [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG
+ {0xA9B6, 0xA9B9, prCM, gcMn}, // [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT
+ {0xA9BA, 0xA9BB, prCM, gcMc}, // [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE
+ {0xA9BC, 0xA9BD, prCM, gcMn}, // [2] JAVANESE VOWEL SIGN PEPET..JAVANESE CONSONANT SIGN KERET
+ {0xA9BE, 0xA9C0, prCM, gcMc}, // [3] JAVANESE CONSONANT SIGN PENGKAL..JAVANESE PANGKON
+ {0xA9C1, 0xA9C6, prAL, gcPo}, // [6] JAVANESE LEFT RERENGGAN..JAVANESE PADA WINDU
+ {0xA9C7, 0xA9C9, prBA, gcPo}, // [3] JAVANESE PADA PANGKAT..JAVANESE PADA LUNGSI
+ {0xA9CA, 0xA9CD, prAL, gcPo}, // [4] JAVANESE PADA ADEG..JAVANESE TURNED PADA PISELEH
+ {0xA9CF, 0xA9CF, prAL, gcLm}, // JAVANESE PANGRANGKEP
+ {0xA9D0, 0xA9D9, prNU, gcNd}, // [10] JAVANESE DIGIT ZERO..JAVANESE DIGIT NINE
+ {0xA9DE, 0xA9DF, prAL, gcPo}, // [2] JAVANESE PADA TIRTA TUMETES..JAVANESE PADA ISEN-ISEN
+ {0xA9E0, 0xA9E4, prSA, gcLo}, // [5] MYANMAR LETTER SHAN GHA..MYANMAR LETTER SHAN BHA
+ {0xA9E5, 0xA9E5, prSA, gcMn}, // MYANMAR SIGN SHAN SAW
+ {0xA9E6, 0xA9E6, prSA, gcLm}, // MYANMAR MODIFIER LETTER SHAN REDUPLICATION
+ {0xA9E7, 0xA9EF, prSA, gcLo}, // [9] MYANMAR LETTER TAI LAING NYA..MYANMAR LETTER TAI LAING NNA
+ {0xA9F0, 0xA9F9, prNU, gcNd}, // [10] MYANMAR TAI LAING DIGIT ZERO..MYANMAR TAI LAING DIGIT NINE
+ {0xA9FA, 0xA9FE, prSA, gcLo}, // [5] MYANMAR LETTER TAI LAING LLA..MYANMAR LETTER TAI LAING BHA
+ {0xAA00, 0xAA28, prAL, gcLo}, // [41] CHAM LETTER A..CHAM LETTER HA
+ {0xAA29, 0xAA2E, prCM, gcMn}, // [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE
+ {0xAA2F, 0xAA30, prCM, gcMc}, // [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI
+ {0xAA31, 0xAA32, prCM, gcMn}, // [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE
+ {0xAA33, 0xAA34, prCM, gcMc}, // [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA
+ {0xAA35, 0xAA36, prCM, gcMn}, // [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA
+ {0xAA40, 0xAA42, prAL, gcLo}, // [3] CHAM LETTER FINAL K..CHAM LETTER FINAL NG
+ {0xAA43, 0xAA43, prCM, gcMn}, // CHAM CONSONANT SIGN FINAL NG
+ {0xAA44, 0xAA4B, prAL, gcLo}, // [8] CHAM LETTER FINAL CH..CHAM LETTER FINAL SS
+ {0xAA4C, 0xAA4C, prCM, gcMn}, // CHAM CONSONANT SIGN FINAL M
+ {0xAA4D, 0xAA4D, prCM, gcMc}, // CHAM CONSONANT SIGN FINAL H
+ {0xAA50, 0xAA59, prNU, gcNd}, // [10] CHAM DIGIT ZERO..CHAM DIGIT NINE
+ {0xAA5C, 0xAA5C, prAL, gcPo}, // CHAM PUNCTUATION SPIRAL
+ {0xAA5D, 0xAA5F, prBA, gcPo}, // [3] CHAM PUNCTUATION DANDA..CHAM PUNCTUATION TRIPLE DANDA
+ {0xAA60, 0xAA6F, prSA, gcLo}, // [16] MYANMAR LETTER KHAMTI GA..MYANMAR LETTER KHAMTI FA
+ {0xAA70, 0xAA70, prSA, gcLm}, // MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION
+ {0xAA71, 0xAA76, prSA, gcLo}, // [6] MYANMAR LETTER KHAMTI XA..MYANMAR LOGOGRAM KHAMTI HM
+ {0xAA77, 0xAA79, prSA, gcSo}, // [3] MYANMAR SYMBOL AITON EXCLAMATION..MYANMAR SYMBOL AITON TWO
+ {0xAA7A, 0xAA7A, prSA, gcLo}, // MYANMAR LETTER AITON RA
+ {0xAA7B, 0xAA7B, prSA, gcMc}, // MYANMAR SIGN PAO KAREN TONE
+ {0xAA7C, 0xAA7C, prSA, gcMn}, // MYANMAR SIGN TAI LAING TONE-2
+ {0xAA7D, 0xAA7D, prSA, gcMc}, // MYANMAR SIGN TAI LAING TONE-5
+ {0xAA7E, 0xAA7F, prSA, gcLo}, // [2] MYANMAR LETTER SHWE PALAUNG CHA..MYANMAR LETTER SHWE PALAUNG SHA
+ {0xAA80, 0xAAAF, prSA, gcLo}, // [48] TAI VIET LETTER LOW KO..TAI VIET LETTER HIGH O
+ {0xAAB0, 0xAAB0, prSA, gcMn}, // TAI VIET MAI KANG
+ {0xAAB1, 0xAAB1, prSA, gcLo}, // TAI VIET VOWEL AA
+ {0xAAB2, 0xAAB4, prSA, gcMn}, // [3] TAI VIET VOWEL I..TAI VIET VOWEL U
+ {0xAAB5, 0xAAB6, prSA, gcLo}, // [2] TAI VIET VOWEL E..TAI VIET VOWEL O
+ {0xAAB7, 0xAAB8, prSA, gcMn}, // [2] TAI VIET MAI KHIT..TAI VIET VOWEL IA
+ {0xAAB9, 0xAABD, prSA, gcLo}, // [5] TAI VIET VOWEL UEA..TAI VIET VOWEL AN
+ {0xAABE, 0xAABF, prSA, gcMn}, // [2] TAI VIET VOWEL AM..TAI VIET TONE MAI EK
+ {0xAAC0, 0xAAC0, prSA, gcLo}, // TAI VIET TONE MAI NUENG
+ {0xAAC1, 0xAAC1, prSA, gcMn}, // TAI VIET TONE MAI THO
+ {0xAAC2, 0xAAC2, prSA, gcLo}, // TAI VIET TONE MAI SONG
+ {0xAADB, 0xAADC, prSA, gcLo}, // [2] TAI VIET SYMBOL KON..TAI VIET SYMBOL NUENG
+ {0xAADD, 0xAADD, prSA, gcLm}, // TAI VIET SYMBOL SAM
+ {0xAADE, 0xAADF, prSA, gcPo}, // [2] TAI VIET SYMBOL HO HOI..TAI VIET SYMBOL KOI KOI
+ {0xAAE0, 0xAAEA, prAL, gcLo}, // [11] MEETEI MAYEK LETTER E..MEETEI MAYEK LETTER SSA
+ {0xAAEB, 0xAAEB, prCM, gcMc}, // MEETEI MAYEK VOWEL SIGN II
+ {0xAAEC, 0xAAED, prCM, gcMn}, // [2] MEETEI MAYEK VOWEL SIGN UU..MEETEI MAYEK VOWEL SIGN AAI
+ {0xAAEE, 0xAAEF, prCM, gcMc}, // [2] MEETEI MAYEK VOWEL SIGN AU..MEETEI MAYEK VOWEL SIGN AAU
+ {0xAAF0, 0xAAF1, prBA, gcPo}, // [2] MEETEI MAYEK CHEIKHAN..MEETEI MAYEK AHANG KHUDAM
+ {0xAAF2, 0xAAF2, prAL, gcLo}, // MEETEI MAYEK ANJI
+ {0xAAF3, 0xAAF4, prAL, gcLm}, // [2] MEETEI MAYEK SYLLABLE REPETITION MARK..MEETEI MAYEK WORD REPETITION MARK
+ {0xAAF5, 0xAAF5, prCM, gcMc}, // MEETEI MAYEK VOWEL SIGN VISARGA
+ {0xAAF6, 0xAAF6, prCM, gcMn}, // MEETEI MAYEK VIRAMA
+ {0xAB01, 0xAB06, prAL, gcLo}, // [6] ETHIOPIC SYLLABLE TTHU..ETHIOPIC SYLLABLE TTHO
+ {0xAB09, 0xAB0E, prAL, gcLo}, // [6] ETHIOPIC SYLLABLE DDHU..ETHIOPIC SYLLABLE DDHO
+ {0xAB11, 0xAB16, prAL, gcLo}, // [6] ETHIOPIC SYLLABLE DZU..ETHIOPIC SYLLABLE DZO
+ {0xAB20, 0xAB26, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE CCHHA..ETHIOPIC SYLLABLE CCHHO
+ {0xAB28, 0xAB2E, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE BBA..ETHIOPIC SYLLABLE BBO
+ {0xAB30, 0xAB5A, prAL, gcLl}, // [43] LATIN SMALL LETTER BARRED ALPHA..LATIN SMALL LETTER Y WITH SHORT RIGHT LEG
+ {0xAB5B, 0xAB5B, prAL, gcSk}, // MODIFIER BREVE WITH INVERTED BREVE
+ {0xAB5C, 0xAB5F, prAL, gcLm}, // [4] MODIFIER LETTER SMALL HENG..MODIFIER LETTER SMALL U WITH LEFT HOOK
+ {0xAB60, 0xAB68, prAL, gcLl}, // [9] LATIN SMALL LETTER SAKHA YAT..LATIN SMALL LETTER TURNED R WITH MIDDLE TILDE
+ {0xAB69, 0xAB69, prAL, gcLm}, // MODIFIER LETTER SMALL TURNED W
+ {0xAB6A, 0xAB6B, prAL, gcSk}, // [2] MODIFIER LETTER LEFT TACK..MODIFIER LETTER RIGHT TACK
+ {0xAB70, 0xABBF, prAL, gcLl}, // [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA
+ {0xABC0, 0xABE2, prAL, gcLo}, // [35] MEETEI MAYEK LETTER KOK..MEETEI MAYEK LETTER I LONSUM
+ {0xABE3, 0xABE4, prCM, gcMc}, // [2] MEETEI MAYEK VOWEL SIGN ONAP..MEETEI MAYEK VOWEL SIGN INAP
+ {0xABE5, 0xABE5, prCM, gcMn}, // MEETEI MAYEK VOWEL SIGN ANAP
+ {0xABE6, 0xABE7, prCM, gcMc}, // [2] MEETEI MAYEK VOWEL SIGN YENAP..MEETEI MAYEK VOWEL SIGN SOUNAP
+ {0xABE8, 0xABE8, prCM, gcMn}, // MEETEI MAYEK VOWEL SIGN UNAP
+ {0xABE9, 0xABEA, prCM, gcMc}, // [2] MEETEI MAYEK VOWEL SIGN CHEINAP..MEETEI MAYEK VOWEL SIGN NUNG
+ {0xABEB, 0xABEB, prBA, gcPo}, // MEETEI MAYEK CHEIKHEI
+ {0xABEC, 0xABEC, prCM, gcMc}, // MEETEI MAYEK LUM IYEK
+ {0xABED, 0xABED, prCM, gcMn}, // MEETEI MAYEK APUN IYEK
+ {0xABF0, 0xABF9, prNU, gcNd}, // [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DIGIT NINE
+ {0xAC00, 0xAC00, prH2, gcLo}, // HANGUL SYLLABLE GA
+ {0xAC01, 0xAC1B, prH3, gcLo}, // [27] HANGUL SYLLABLE GAG..HANGUL SYLLABLE GAH
+ {0xAC1C, 0xAC1C, prH2, gcLo}, // HANGUL SYLLABLE GAE
+ {0xAC1D, 0xAC37, prH3, gcLo}, // [27] HANGUL SYLLABLE GAEG..HANGUL SYLLABLE GAEH
+ {0xAC38, 0xAC38, prH2, gcLo}, // HANGUL SYLLABLE GYA
+ {0xAC39, 0xAC53, prH3, gcLo}, // [27] HANGUL SYLLABLE GYAG..HANGUL SYLLABLE GYAH
+ {0xAC54, 0xAC54, prH2, gcLo}, // HANGUL SYLLABLE GYAE
+ {0xAC55, 0xAC6F, prH3, gcLo}, // [27] HANGUL SYLLABLE GYAEG..HANGUL SYLLABLE GYAEH
+ {0xAC70, 0xAC70, prH2, gcLo}, // HANGUL SYLLABLE GEO
+ {0xAC71, 0xAC8B, prH3, gcLo}, // [27] HANGUL SYLLABLE GEOG..HANGUL SYLLABLE GEOH
+ {0xAC8C, 0xAC8C, prH2, gcLo}, // HANGUL SYLLABLE GE
+ {0xAC8D, 0xACA7, prH3, gcLo}, // [27] HANGUL SYLLABLE GEG..HANGUL SYLLABLE GEH
+ {0xACA8, 0xACA8, prH2, gcLo}, // HANGUL SYLLABLE GYEO
+ {0xACA9, 0xACC3, prH3, gcLo}, // [27] HANGUL SYLLABLE GYEOG..HANGUL SYLLABLE GYEOH
+ {0xACC4, 0xACC4, prH2, gcLo}, // HANGUL SYLLABLE GYE
+ {0xACC5, 0xACDF, prH3, gcLo}, // [27] HANGUL SYLLABLE GYEG..HANGUL SYLLABLE GYEH
+ {0xACE0, 0xACE0, prH2, gcLo}, // HANGUL SYLLABLE GO
+ {0xACE1, 0xACFB, prH3, gcLo}, // [27] HANGUL SYLLABLE GOG..HANGUL SYLLABLE GOH
+ {0xACFC, 0xACFC, prH2, gcLo}, // HANGUL SYLLABLE GWA
+ {0xACFD, 0xAD17, prH3, gcLo}, // [27] HANGUL SYLLABLE GWAG..HANGUL SYLLABLE GWAH
+ {0xAD18, 0xAD18, prH2, gcLo}, // HANGUL SYLLABLE GWAE
+ {0xAD19, 0xAD33, prH3, gcLo}, // [27] HANGUL SYLLABLE GWAEG..HANGUL SYLLABLE GWAEH
+ {0xAD34, 0xAD34, prH2, gcLo}, // HANGUL SYLLABLE GOE
+ {0xAD35, 0xAD4F, prH3, gcLo}, // [27] HANGUL SYLLABLE GOEG..HANGUL SYLLABLE GOEH
+ {0xAD50, 0xAD50, prH2, gcLo}, // HANGUL SYLLABLE GYO
+ {0xAD51, 0xAD6B, prH3, gcLo}, // [27] HANGUL SYLLABLE GYOG..HANGUL SYLLABLE GYOH
+ {0xAD6C, 0xAD6C, prH2, gcLo}, // HANGUL SYLLABLE GU
+ {0xAD6D, 0xAD87, prH3, gcLo}, // [27] HANGUL SYLLABLE GUG..HANGUL SYLLABLE GUH
+ {0xAD88, 0xAD88, prH2, gcLo}, // HANGUL SYLLABLE GWEO
+ {0xAD89, 0xADA3, prH3, gcLo}, // [27] HANGUL SYLLABLE GWEOG..HANGUL SYLLABLE GWEOH
+ {0xADA4, 0xADA4, prH2, gcLo}, // HANGUL SYLLABLE GWE
+ {0xADA5, 0xADBF, prH3, gcLo}, // [27] HANGUL SYLLABLE GWEG..HANGUL SYLLABLE GWEH
+ {0xADC0, 0xADC0, prH2, gcLo}, // HANGUL SYLLABLE GWI
+ {0xADC1, 0xADDB, prH3, gcLo}, // [27] HANGUL SYLLABLE GWIG..HANGUL SYLLABLE GWIH
+ {0xADDC, 0xADDC, prH2, gcLo}, // HANGUL SYLLABLE GYU
+ {0xADDD, 0xADF7, prH3, gcLo}, // [27] HANGUL SYLLABLE GYUG..HANGUL SYLLABLE GYUH
+ {0xADF8, 0xADF8, prH2, gcLo}, // HANGUL SYLLABLE GEU
+ {0xADF9, 0xAE13, prH3, gcLo}, // [27] HANGUL SYLLABLE GEUG..HANGUL SYLLABLE GEUH
+ {0xAE14, 0xAE14, prH2, gcLo}, // HANGUL SYLLABLE GYI
+ {0xAE15, 0xAE2F, prH3, gcLo}, // [27] HANGUL SYLLABLE GYIG..HANGUL SYLLABLE GYIH
+ {0xAE30, 0xAE30, prH2, gcLo}, // HANGUL SYLLABLE GI
+ {0xAE31, 0xAE4B, prH3, gcLo}, // [27] HANGUL SYLLABLE GIG..HANGUL SYLLABLE GIH
+ {0xAE4C, 0xAE4C, prH2, gcLo}, // HANGUL SYLLABLE GGA
+ {0xAE4D, 0xAE67, prH3, gcLo}, // [27] HANGUL SYLLABLE GGAG..HANGUL SYLLABLE GGAH
+ {0xAE68, 0xAE68, prH2, gcLo}, // HANGUL SYLLABLE GGAE
+ {0xAE69, 0xAE83, prH3, gcLo}, // [27] HANGUL SYLLABLE GGAEG..HANGUL SYLLABLE GGAEH
+ {0xAE84, 0xAE84, prH2, gcLo}, // HANGUL SYLLABLE GGYA
+ {0xAE85, 0xAE9F, prH3, gcLo}, // [27] HANGUL SYLLABLE GGYAG..HANGUL SYLLABLE GGYAH
+ {0xAEA0, 0xAEA0, prH2, gcLo}, // HANGUL SYLLABLE GGYAE
+ {0xAEA1, 0xAEBB, prH3, gcLo}, // [27] HANGUL SYLLABLE GGYAEG..HANGUL SYLLABLE GGYAEH
+ {0xAEBC, 0xAEBC, prH2, gcLo}, // HANGUL SYLLABLE GGEO
+ {0xAEBD, 0xAED7, prH3, gcLo}, // [27] HANGUL SYLLABLE GGEOG..HANGUL SYLLABLE GGEOH
+ {0xAED8, 0xAED8, prH2, gcLo}, // HANGUL SYLLABLE GGE
+ {0xAED9, 0xAEF3, prH3, gcLo}, // [27] HANGUL SYLLABLE GGEG..HANGUL SYLLABLE GGEH
+ {0xAEF4, 0xAEF4, prH2, gcLo}, // HANGUL SYLLABLE GGYEO
+ {0xAEF5, 0xAF0F, prH3, gcLo}, // [27] HANGUL SYLLABLE GGYEOG..HANGUL SYLLABLE GGYEOH
+ {0xAF10, 0xAF10, prH2, gcLo}, // HANGUL SYLLABLE GGYE
+ {0xAF11, 0xAF2B, prH3, gcLo}, // [27] HANGUL SYLLABLE GGYEG..HANGUL SYLLABLE GGYEH
+ {0xAF2C, 0xAF2C, prH2, gcLo}, // HANGUL SYLLABLE GGO
+ {0xAF2D, 0xAF47, prH3, gcLo}, // [27] HANGUL SYLLABLE GGOG..HANGUL SYLLABLE GGOH
+ {0xAF48, 0xAF48, prH2, gcLo}, // HANGUL SYLLABLE GGWA
+ {0xAF49, 0xAF63, prH3, gcLo}, // [27] HANGUL SYLLABLE GGWAG..HANGUL SYLLABLE GGWAH
+ {0xAF64, 0xAF64, prH2, gcLo}, // HANGUL SYLLABLE GGWAE
+ {0xAF65, 0xAF7F, prH3, gcLo}, // [27] HANGUL SYLLABLE GGWAEG..HANGUL SYLLABLE GGWAEH
+ {0xAF80, 0xAF80, prH2, gcLo}, // HANGUL SYLLABLE GGOE
+ {0xAF81, 0xAF9B, prH3, gcLo}, // [27] HANGUL SYLLABLE GGOEG..HANGUL SYLLABLE GGOEH
+ {0xAF9C, 0xAF9C, prH2, gcLo}, // HANGUL SYLLABLE GGYO
+ {0xAF9D, 0xAFB7, prH3, gcLo}, // [27] HANGUL SYLLABLE GGYOG..HANGUL SYLLABLE GGYOH
+ {0xAFB8, 0xAFB8, prH2, gcLo}, // HANGUL SYLLABLE GGU
+ {0xAFB9, 0xAFD3, prH3, gcLo}, // [27] HANGUL SYLLABLE GGUG..HANGUL SYLLABLE GGUH
+ {0xAFD4, 0xAFD4, prH2, gcLo}, // HANGUL SYLLABLE GGWEO
+ {0xAFD5, 0xAFEF, prH3, gcLo}, // [27] HANGUL SYLLABLE GGWEOG..HANGUL SYLLABLE GGWEOH
+ {0xAFF0, 0xAFF0, prH2, gcLo}, // HANGUL SYLLABLE GGWE
+ {0xAFF1, 0xB00B, prH3, gcLo}, // [27] HANGUL SYLLABLE GGWEG..HANGUL SYLLABLE GGWEH
+ {0xB00C, 0xB00C, prH2, gcLo}, // HANGUL SYLLABLE GGWI
+ {0xB00D, 0xB027, prH3, gcLo}, // [27] HANGUL SYLLABLE GGWIG..HANGUL SYLLABLE GGWIH
+ {0xB028, 0xB028, prH2, gcLo}, // HANGUL SYLLABLE GGYU
+ {0xB029, 0xB043, prH3, gcLo}, // [27] HANGUL SYLLABLE GGYUG..HANGUL SYLLABLE GGYUH
+ {0xB044, 0xB044, prH2, gcLo}, // HANGUL SYLLABLE GGEU
+ {0xB045, 0xB05F, prH3, gcLo}, // [27] HANGUL SYLLABLE GGEUG..HANGUL SYLLABLE GGEUH
+ {0xB060, 0xB060, prH2, gcLo}, // HANGUL SYLLABLE GGYI
+ {0xB061, 0xB07B, prH3, gcLo}, // [27] HANGUL SYLLABLE GGYIG..HANGUL SYLLABLE GGYIH
+ {0xB07C, 0xB07C, prH2, gcLo}, // HANGUL SYLLABLE GGI
+ {0xB07D, 0xB097, prH3, gcLo}, // [27] HANGUL SYLLABLE GGIG..HANGUL SYLLABLE GGIH
+ {0xB098, 0xB098, prH2, gcLo}, // HANGUL SYLLABLE NA
+ {0xB099, 0xB0B3, prH3, gcLo}, // [27] HANGUL SYLLABLE NAG..HANGUL SYLLABLE NAH
+ {0xB0B4, 0xB0B4, prH2, gcLo}, // HANGUL SYLLABLE NAE
+ {0xB0B5, 0xB0CF, prH3, gcLo}, // [27] HANGUL SYLLABLE NAEG..HANGUL SYLLABLE NAEH
+ {0xB0D0, 0xB0D0, prH2, gcLo}, // HANGUL SYLLABLE NYA
+ {0xB0D1, 0xB0EB, prH3, gcLo}, // [27] HANGUL SYLLABLE NYAG..HANGUL SYLLABLE NYAH
+ {0xB0EC, 0xB0EC, prH2, gcLo}, // HANGUL SYLLABLE NYAE
+ {0xB0ED, 0xB107, prH3, gcLo}, // [27] HANGUL SYLLABLE NYAEG..HANGUL SYLLABLE NYAEH
+ {0xB108, 0xB108, prH2, gcLo}, // HANGUL SYLLABLE NEO
+ {0xB109, 0xB123, prH3, gcLo}, // [27] HANGUL SYLLABLE NEOG..HANGUL SYLLABLE NEOH
+ {0xB124, 0xB124, prH2, gcLo}, // HANGUL SYLLABLE NE
+ {0xB125, 0xB13F, prH3, gcLo}, // [27] HANGUL SYLLABLE NEG..HANGUL SYLLABLE NEH
+ {0xB140, 0xB140, prH2, gcLo}, // HANGUL SYLLABLE NYEO
+ {0xB141, 0xB15B, prH3, gcLo}, // [27] HANGUL SYLLABLE NYEOG..HANGUL SYLLABLE NYEOH
+ {0xB15C, 0xB15C, prH2, gcLo}, // HANGUL SYLLABLE NYE
+ {0xB15D, 0xB177, prH3, gcLo}, // [27] HANGUL SYLLABLE NYEG..HANGUL SYLLABLE NYEH
+ {0xB178, 0xB178, prH2, gcLo}, // HANGUL SYLLABLE NO
+ {0xB179, 0xB193, prH3, gcLo}, // [27] HANGUL SYLLABLE NOG..HANGUL SYLLABLE NOH
+ {0xB194, 0xB194, prH2, gcLo}, // HANGUL SYLLABLE NWA
+ {0xB195, 0xB1AF, prH3, gcLo}, // [27] HANGUL SYLLABLE NWAG..HANGUL SYLLABLE NWAH
+ {0xB1B0, 0xB1B0, prH2, gcLo}, // HANGUL SYLLABLE NWAE
+ {0xB1B1, 0xB1CB, prH3, gcLo}, // [27] HANGUL SYLLABLE NWAEG..HANGUL SYLLABLE NWAEH
+ {0xB1CC, 0xB1CC, prH2, gcLo}, // HANGUL SYLLABLE NOE
+ {0xB1CD, 0xB1E7, prH3, gcLo}, // [27] HANGUL SYLLABLE NOEG..HANGUL SYLLABLE NOEH
+ {0xB1E8, 0xB1E8, prH2, gcLo}, // HANGUL SYLLABLE NYO
+ {0xB1E9, 0xB203, prH3, gcLo}, // [27] HANGUL SYLLABLE NYOG..HANGUL SYLLABLE NYOH
+ {0xB204, 0xB204, prH2, gcLo}, // HANGUL SYLLABLE NU
+ {0xB205, 0xB21F, prH3, gcLo}, // [27] HANGUL SYLLABLE NUG..HANGUL SYLLABLE NUH
+ {0xB220, 0xB220, prH2, gcLo}, // HANGUL SYLLABLE NWEO
+ {0xB221, 0xB23B, prH3, gcLo}, // [27] HANGUL SYLLABLE NWEOG..HANGUL SYLLABLE NWEOH
+ {0xB23C, 0xB23C, prH2, gcLo}, // HANGUL SYLLABLE NWE
+ {0xB23D, 0xB257, prH3, gcLo}, // [27] HANGUL SYLLABLE NWEG..HANGUL SYLLABLE NWEH
+ {0xB258, 0xB258, prH2, gcLo}, // HANGUL SYLLABLE NWI
+ {0xB259, 0xB273, prH3, gcLo}, // [27] HANGUL SYLLABLE NWIG..HANGUL SYLLABLE NWIH
+ {0xB274, 0xB274, prH2, gcLo}, // HANGUL SYLLABLE NYU
+ {0xB275, 0xB28F, prH3, gcLo}, // [27] HANGUL SYLLABLE NYUG..HANGUL SYLLABLE NYUH
+ {0xB290, 0xB290, prH2, gcLo}, // HANGUL SYLLABLE NEU
+ {0xB291, 0xB2AB, prH3, gcLo}, // [27] HANGUL SYLLABLE NEUG..HANGUL SYLLABLE NEUH
+ {0xB2AC, 0xB2AC, prH2, gcLo}, // HANGUL SYLLABLE NYI
+ {0xB2AD, 0xB2C7, prH3, gcLo}, // [27] HANGUL SYLLABLE NYIG..HANGUL SYLLABLE NYIH
+ {0xB2C8, 0xB2C8, prH2, gcLo}, // HANGUL SYLLABLE NI
+ {0xB2C9, 0xB2E3, prH3, gcLo}, // [27] HANGUL SYLLABLE NIG..HANGUL SYLLABLE NIH
+ {0xB2E4, 0xB2E4, prH2, gcLo}, // HANGUL SYLLABLE DA
+ {0xB2E5, 0xB2FF, prH3, gcLo}, // [27] HANGUL SYLLABLE DAG..HANGUL SYLLABLE DAH
+ {0xB300, 0xB300, prH2, gcLo}, // HANGUL SYLLABLE DAE
+ {0xB301, 0xB31B, prH3, gcLo}, // [27] HANGUL SYLLABLE DAEG..HANGUL SYLLABLE DAEH
+ {0xB31C, 0xB31C, prH2, gcLo}, // HANGUL SYLLABLE DYA
+ {0xB31D, 0xB337, prH3, gcLo}, // [27] HANGUL SYLLABLE DYAG..HANGUL SYLLABLE DYAH
+ {0xB338, 0xB338, prH2, gcLo}, // HANGUL SYLLABLE DYAE
+ {0xB339, 0xB353, prH3, gcLo}, // [27] HANGUL SYLLABLE DYAEG..HANGUL SYLLABLE DYAEH
+ {0xB354, 0xB354, prH2, gcLo}, // HANGUL SYLLABLE DEO
+ {0xB355, 0xB36F, prH3, gcLo}, // [27] HANGUL SYLLABLE DEOG..HANGUL SYLLABLE DEOH
+ {0xB370, 0xB370, prH2, gcLo}, // HANGUL SYLLABLE DE
+ {0xB371, 0xB38B, prH3, gcLo}, // [27] HANGUL SYLLABLE DEG..HANGUL SYLLABLE DEH
+ {0xB38C, 0xB38C, prH2, gcLo}, // HANGUL SYLLABLE DYEO
+ {0xB38D, 0xB3A7, prH3, gcLo}, // [27] HANGUL SYLLABLE DYEOG..HANGUL SYLLABLE DYEOH
+ {0xB3A8, 0xB3A8, prH2, gcLo}, // HANGUL SYLLABLE DYE
+ {0xB3A9, 0xB3C3, prH3, gcLo}, // [27] HANGUL SYLLABLE DYEG..HANGUL SYLLABLE DYEH
+ {0xB3C4, 0xB3C4, prH2, gcLo}, // HANGUL SYLLABLE DO
+ {0xB3C5, 0xB3DF, prH3, gcLo}, // [27] HANGUL SYLLABLE DOG..HANGUL SYLLABLE DOH
+ {0xB3E0, 0xB3E0, prH2, gcLo}, // HANGUL SYLLABLE DWA
+ {0xB3E1, 0xB3FB, prH3, gcLo}, // [27] HANGUL SYLLABLE DWAG..HANGUL SYLLABLE DWAH
+ {0xB3FC, 0xB3FC, prH2, gcLo}, // HANGUL SYLLABLE DWAE
+ {0xB3FD, 0xB417, prH3, gcLo}, // [27] HANGUL SYLLABLE DWAEG..HANGUL SYLLABLE DWAEH
+ {0xB418, 0xB418, prH2, gcLo}, // HANGUL SYLLABLE DOE
+ {0xB419, 0xB433, prH3, gcLo}, // [27] HANGUL SYLLABLE DOEG..HANGUL SYLLABLE DOEH
+ {0xB434, 0xB434, prH2, gcLo}, // HANGUL SYLLABLE DYO
+ {0xB435, 0xB44F, prH3, gcLo}, // [27] HANGUL SYLLABLE DYOG..HANGUL SYLLABLE DYOH
+ {0xB450, 0xB450, prH2, gcLo}, // HANGUL SYLLABLE DU
+ {0xB451, 0xB46B, prH3, gcLo}, // [27] HANGUL SYLLABLE DUG..HANGUL SYLLABLE DUH
+ {0xB46C, 0xB46C, prH2, gcLo}, // HANGUL SYLLABLE DWEO
+ {0xB46D, 0xB487, prH3, gcLo}, // [27] HANGUL SYLLABLE DWEOG..HANGUL SYLLABLE DWEOH
+ {0xB488, 0xB488, prH2, gcLo}, // HANGUL SYLLABLE DWE
+ {0xB489, 0xB4A3, prH3, gcLo}, // [27] HANGUL SYLLABLE DWEG..HANGUL SYLLABLE DWEH
+ {0xB4A4, 0xB4A4, prH2, gcLo}, // HANGUL SYLLABLE DWI
+ {0xB4A5, 0xB4BF, prH3, gcLo}, // [27] HANGUL SYLLABLE DWIG..HANGUL SYLLABLE DWIH
+ {0xB4C0, 0xB4C0, prH2, gcLo}, // HANGUL SYLLABLE DYU
+ {0xB4C1, 0xB4DB, prH3, gcLo}, // [27] HANGUL SYLLABLE DYUG..HANGUL SYLLABLE DYUH
+ {0xB4DC, 0xB4DC, prH2, gcLo}, // HANGUL SYLLABLE DEU
+ {0xB4DD, 0xB4F7, prH3, gcLo}, // [27] HANGUL SYLLABLE DEUG..HANGUL SYLLABLE DEUH
+ {0xB4F8, 0xB4F8, prH2, gcLo}, // HANGUL SYLLABLE DYI
+ {0xB4F9, 0xB513, prH3, gcLo}, // [27] HANGUL SYLLABLE DYIG..HANGUL SYLLABLE DYIH
+ {0xB514, 0xB514, prH2, gcLo}, // HANGUL SYLLABLE DI
+ {0xB515, 0xB52F, prH3, gcLo}, // [27] HANGUL SYLLABLE DIG..HANGUL SYLLABLE DIH
+ {0xB530, 0xB530, prH2, gcLo}, // HANGUL SYLLABLE DDA
+ {0xB531, 0xB54B, prH3, gcLo}, // [27] HANGUL SYLLABLE DDAG..HANGUL SYLLABLE DDAH
+ {0xB54C, 0xB54C, prH2, gcLo}, // HANGUL SYLLABLE DDAE
+ {0xB54D, 0xB567, prH3, gcLo}, // [27] HANGUL SYLLABLE DDAEG..HANGUL SYLLABLE DDAEH
+ {0xB568, 0xB568, prH2, gcLo}, // HANGUL SYLLABLE DDYA
+ {0xB569, 0xB583, prH3, gcLo}, // [27] HANGUL SYLLABLE DDYAG..HANGUL SYLLABLE DDYAH
+ {0xB584, 0xB584, prH2, gcLo}, // HANGUL SYLLABLE DDYAE
+ {0xB585, 0xB59F, prH3, gcLo}, // [27] HANGUL SYLLABLE DDYAEG..HANGUL SYLLABLE DDYAEH
+ {0xB5A0, 0xB5A0, prH2, gcLo}, // HANGUL SYLLABLE DDEO
+ {0xB5A1, 0xB5BB, prH3, gcLo}, // [27] HANGUL SYLLABLE DDEOG..HANGUL SYLLABLE DDEOH
+ {0xB5BC, 0xB5BC, prH2, gcLo}, // HANGUL SYLLABLE DDE
+ {0xB5BD, 0xB5D7, prH3, gcLo}, // [27] HANGUL SYLLABLE DDEG..HANGUL SYLLABLE DDEH
+ {0xB5D8, 0xB5D8, prH2, gcLo}, // HANGUL SYLLABLE DDYEO
+ {0xB5D9, 0xB5F3, prH3, gcLo}, // [27] HANGUL SYLLABLE DDYEOG..HANGUL SYLLABLE DDYEOH
+ {0xB5F4, 0xB5F4, prH2, gcLo}, // HANGUL SYLLABLE DDYE
+ {0xB5F5, 0xB60F, prH3, gcLo}, // [27] HANGUL SYLLABLE DDYEG..HANGUL SYLLABLE DDYEH
+ {0xB610, 0xB610, prH2, gcLo}, // HANGUL SYLLABLE DDO
+ {0xB611, 0xB62B, prH3, gcLo}, // [27] HANGUL SYLLABLE DDOG..HANGUL SYLLABLE DDOH
+ {0xB62C, 0xB62C, prH2, gcLo}, // HANGUL SYLLABLE DDWA
+ {0xB62D, 0xB647, prH3, gcLo}, // [27] HANGUL SYLLABLE DDWAG..HANGUL SYLLABLE DDWAH
+ {0xB648, 0xB648, prH2, gcLo}, // HANGUL SYLLABLE DDWAE
+ {0xB649, 0xB663, prH3, gcLo}, // [27] HANGUL SYLLABLE DDWAEG..HANGUL SYLLABLE DDWAEH
+ {0xB664, 0xB664, prH2, gcLo}, // HANGUL SYLLABLE DDOE
+ {0xB665, 0xB67F, prH3, gcLo}, // [27] HANGUL SYLLABLE DDOEG..HANGUL SYLLABLE DDOEH
+ {0xB680, 0xB680, prH2, gcLo}, // HANGUL SYLLABLE DDYO
+ {0xB681, 0xB69B, prH3, gcLo}, // [27] HANGUL SYLLABLE DDYOG..HANGUL SYLLABLE DDYOH
+ {0xB69C, 0xB69C, prH2, gcLo}, // HANGUL SYLLABLE DDU
+ {0xB69D, 0xB6B7, prH3, gcLo}, // [27] HANGUL SYLLABLE DDUG..HANGUL SYLLABLE DDUH
+ {0xB6B8, 0xB6B8, prH2, gcLo}, // HANGUL SYLLABLE DDWEO
+ {0xB6B9, 0xB6D3, prH3, gcLo}, // [27] HANGUL SYLLABLE DDWEOG..HANGUL SYLLABLE DDWEOH
+ {0xB6D4, 0xB6D4, prH2, gcLo}, // HANGUL SYLLABLE DDWE
+ {0xB6D5, 0xB6EF, prH3, gcLo}, // [27] HANGUL SYLLABLE DDWEG..HANGUL SYLLABLE DDWEH
+ {0xB6F0, 0xB6F0, prH2, gcLo}, // HANGUL SYLLABLE DDWI
+ {0xB6F1, 0xB70B, prH3, gcLo}, // [27] HANGUL SYLLABLE DDWIG..HANGUL SYLLABLE DDWIH
+ {0xB70C, 0xB70C, prH2, gcLo}, // HANGUL SYLLABLE DDYU
+ {0xB70D, 0xB727, prH3, gcLo}, // [27] HANGUL SYLLABLE DDYUG..HANGUL SYLLABLE DDYUH
+ {0xB728, 0xB728, prH2, gcLo}, // HANGUL SYLLABLE DDEU
+ {0xB729, 0xB743, prH3, gcLo}, // [27] HANGUL SYLLABLE DDEUG..HANGUL SYLLABLE DDEUH
+ {0xB744, 0xB744, prH2, gcLo}, // HANGUL SYLLABLE DDYI
+ {0xB745, 0xB75F, prH3, gcLo}, // [27] HANGUL SYLLABLE DDYIG..HANGUL SYLLABLE DDYIH
+ {0xB760, 0xB760, prH2, gcLo}, // HANGUL SYLLABLE DDI
+ {0xB761, 0xB77B, prH3, gcLo}, // [27] HANGUL SYLLABLE DDIG..HANGUL SYLLABLE DDIH
+ {0xB77C, 0xB77C, prH2, gcLo}, // HANGUL SYLLABLE RA
+ {0xB77D, 0xB797, prH3, gcLo}, // [27] HANGUL SYLLABLE RAG..HANGUL SYLLABLE RAH
+ {0xB798, 0xB798, prH2, gcLo}, // HANGUL SYLLABLE RAE
+ {0xB799, 0xB7B3, prH3, gcLo}, // [27] HANGUL SYLLABLE RAEG..HANGUL SYLLABLE RAEH
+ {0xB7B4, 0xB7B4, prH2, gcLo}, // HANGUL SYLLABLE RYA
+ {0xB7B5, 0xB7CF, prH3, gcLo}, // [27] HANGUL SYLLABLE RYAG..HANGUL SYLLABLE RYAH
+ {0xB7D0, 0xB7D0, prH2, gcLo}, // HANGUL SYLLABLE RYAE
+ {0xB7D1, 0xB7EB, prH3, gcLo}, // [27] HANGUL SYLLABLE RYAEG..HANGUL SYLLABLE RYAEH
+ {0xB7EC, 0xB7EC, prH2, gcLo}, // HANGUL SYLLABLE REO
+ {0xB7ED, 0xB807, prH3, gcLo}, // [27] HANGUL SYLLABLE REOG..HANGUL SYLLABLE REOH
+ {0xB808, 0xB808, prH2, gcLo}, // HANGUL SYLLABLE RE
+ {0xB809, 0xB823, prH3, gcLo}, // [27] HANGUL SYLLABLE REG..HANGUL SYLLABLE REH
+ {0xB824, 0xB824, prH2, gcLo}, // HANGUL SYLLABLE RYEO
+ {0xB825, 0xB83F, prH3, gcLo}, // [27] HANGUL SYLLABLE RYEOG..HANGUL SYLLABLE RYEOH
+ {0xB840, 0xB840, prH2, gcLo}, // HANGUL SYLLABLE RYE
+ {0xB841, 0xB85B, prH3, gcLo}, // [27] HANGUL SYLLABLE RYEG..HANGUL SYLLABLE RYEH
+ {0xB85C, 0xB85C, prH2, gcLo}, // HANGUL SYLLABLE RO
+ {0xB85D, 0xB877, prH3, gcLo}, // [27] HANGUL SYLLABLE ROG..HANGUL SYLLABLE ROH
+ {0xB878, 0xB878, prH2, gcLo}, // HANGUL SYLLABLE RWA
+ {0xB879, 0xB893, prH3, gcLo}, // [27] HANGUL SYLLABLE RWAG..HANGUL SYLLABLE RWAH
+ {0xB894, 0xB894, prH2, gcLo}, // HANGUL SYLLABLE RWAE
+ {0xB895, 0xB8AF, prH3, gcLo}, // [27] HANGUL SYLLABLE RWAEG..HANGUL SYLLABLE RWAEH
+ {0xB8B0, 0xB8B0, prH2, gcLo}, // HANGUL SYLLABLE ROE
+ {0xB8B1, 0xB8CB, prH3, gcLo}, // [27] HANGUL SYLLABLE ROEG..HANGUL SYLLABLE ROEH
+ {0xB8CC, 0xB8CC, prH2, gcLo}, // HANGUL SYLLABLE RYO
+ {0xB8CD, 0xB8E7, prH3, gcLo}, // [27] HANGUL SYLLABLE RYOG..HANGUL SYLLABLE RYOH
+ {0xB8E8, 0xB8E8, prH2, gcLo}, // HANGUL SYLLABLE RU
+ {0xB8E9, 0xB903, prH3, gcLo}, // [27] HANGUL SYLLABLE RUG..HANGUL SYLLABLE RUH
+ {0xB904, 0xB904, prH2, gcLo}, // HANGUL SYLLABLE RWEO
+ {0xB905, 0xB91F, prH3, gcLo}, // [27] HANGUL SYLLABLE RWEOG..HANGUL SYLLABLE RWEOH
+ {0xB920, 0xB920, prH2, gcLo}, // HANGUL SYLLABLE RWE
+ {0xB921, 0xB93B, prH3, gcLo}, // [27] HANGUL SYLLABLE RWEG..HANGUL SYLLABLE RWEH
+ {0xB93C, 0xB93C, prH2, gcLo}, // HANGUL SYLLABLE RWI
+ {0xB93D, 0xB957, prH3, gcLo}, // [27] HANGUL SYLLABLE RWIG..HANGUL SYLLABLE RWIH
+ {0xB958, 0xB958, prH2, gcLo}, // HANGUL SYLLABLE RYU
+ {0xB959, 0xB973, prH3, gcLo}, // [27] HANGUL SYLLABLE RYUG..HANGUL SYLLABLE RYUH
+ {0xB974, 0xB974, prH2, gcLo}, // HANGUL SYLLABLE REU
+ {0xB975, 0xB98F, prH3, gcLo}, // [27] HANGUL SYLLABLE REUG..HANGUL SYLLABLE REUH
+ {0xB990, 0xB990, prH2, gcLo}, // HANGUL SYLLABLE RYI
+ {0xB991, 0xB9AB, prH3, gcLo}, // [27] HANGUL SYLLABLE RYIG..HANGUL SYLLABLE RYIH
+ {0xB9AC, 0xB9AC, prH2, gcLo}, // HANGUL SYLLABLE RI
+ {0xB9AD, 0xB9C7, prH3, gcLo}, // [27] HANGUL SYLLABLE RIG..HANGUL SYLLABLE RIH
+ {0xB9C8, 0xB9C8, prH2, gcLo}, // HANGUL SYLLABLE MA
+ {0xB9C9, 0xB9E3, prH3, gcLo}, // [27] HANGUL SYLLABLE MAG..HANGUL SYLLABLE MAH
+ {0xB9E4, 0xB9E4, prH2, gcLo}, // HANGUL SYLLABLE MAE
+ {0xB9E5, 0xB9FF, prH3, gcLo}, // [27] HANGUL SYLLABLE MAEG..HANGUL SYLLABLE MAEH
+ {0xBA00, 0xBA00, prH2, gcLo}, // HANGUL SYLLABLE MYA
+ {0xBA01, 0xBA1B, prH3, gcLo}, // [27] HANGUL SYLLABLE MYAG..HANGUL SYLLABLE MYAH
+ {0xBA1C, 0xBA1C, prH2, gcLo}, // HANGUL SYLLABLE MYAE
+ {0xBA1D, 0xBA37, prH3, gcLo}, // [27] HANGUL SYLLABLE MYAEG..HANGUL SYLLABLE MYAEH
+ {0xBA38, 0xBA38, prH2, gcLo}, // HANGUL SYLLABLE MEO
+ {0xBA39, 0xBA53, prH3, gcLo}, // [27] HANGUL SYLLABLE MEOG..HANGUL SYLLABLE MEOH
+ {0xBA54, 0xBA54, prH2, gcLo}, // HANGUL SYLLABLE ME
+ {0xBA55, 0xBA6F, prH3, gcLo}, // [27] HANGUL SYLLABLE MEG..HANGUL SYLLABLE MEH
+ {0xBA70, 0xBA70, prH2, gcLo}, // HANGUL SYLLABLE MYEO
+ {0xBA71, 0xBA8B, prH3, gcLo}, // [27] HANGUL SYLLABLE MYEOG..HANGUL SYLLABLE MYEOH
+ {0xBA8C, 0xBA8C, prH2, gcLo}, // HANGUL SYLLABLE MYE
+ {0xBA8D, 0xBAA7, prH3, gcLo}, // [27] HANGUL SYLLABLE MYEG..HANGUL SYLLABLE MYEH
+ {0xBAA8, 0xBAA8, prH2, gcLo}, // HANGUL SYLLABLE MO
+ {0xBAA9, 0xBAC3, prH3, gcLo}, // [27] HANGUL SYLLABLE MOG..HANGUL SYLLABLE MOH
+ {0xBAC4, 0xBAC4, prH2, gcLo}, // HANGUL SYLLABLE MWA
+ {0xBAC5, 0xBADF, prH3, gcLo}, // [27] HANGUL SYLLABLE MWAG..HANGUL SYLLABLE MWAH
+ {0xBAE0, 0xBAE0, prH2, gcLo}, // HANGUL SYLLABLE MWAE
+ {0xBAE1, 0xBAFB, prH3, gcLo}, // [27] HANGUL SYLLABLE MWAEG..HANGUL SYLLABLE MWAEH
+ {0xBAFC, 0xBAFC, prH2, gcLo}, // HANGUL SYLLABLE MOE
+ {0xBAFD, 0xBB17, prH3, gcLo}, // [27] HANGUL SYLLABLE MOEG..HANGUL SYLLABLE MOEH
+ {0xBB18, 0xBB18, prH2, gcLo}, // HANGUL SYLLABLE MYO
+ {0xBB19, 0xBB33, prH3, gcLo}, // [27] HANGUL SYLLABLE MYOG..HANGUL SYLLABLE MYOH
+ {0xBB34, 0xBB34, prH2, gcLo}, // HANGUL SYLLABLE MU
+ {0xBB35, 0xBB4F, prH3, gcLo}, // [27] HANGUL SYLLABLE MUG..HANGUL SYLLABLE MUH
+ {0xBB50, 0xBB50, prH2, gcLo}, // HANGUL SYLLABLE MWEO
+ {0xBB51, 0xBB6B, prH3, gcLo}, // [27] HANGUL SYLLABLE MWEOG..HANGUL SYLLABLE MWEOH
+ {0xBB6C, 0xBB6C, prH2, gcLo}, // HANGUL SYLLABLE MWE
+ {0xBB6D, 0xBB87, prH3, gcLo}, // [27] HANGUL SYLLABLE MWEG..HANGUL SYLLABLE MWEH
+ {0xBB88, 0xBB88, prH2, gcLo}, // HANGUL SYLLABLE MWI
+ {0xBB89, 0xBBA3, prH3, gcLo}, // [27] HANGUL SYLLABLE MWIG..HANGUL SYLLABLE MWIH
+ {0xBBA4, 0xBBA4, prH2, gcLo}, // HANGUL SYLLABLE MYU
+ {0xBBA5, 0xBBBF, prH3, gcLo}, // [27] HANGUL SYLLABLE MYUG..HANGUL SYLLABLE MYUH
+ {0xBBC0, 0xBBC0, prH2, gcLo}, // HANGUL SYLLABLE MEU
+ {0xBBC1, 0xBBDB, prH3, gcLo}, // [27] HANGUL SYLLABLE MEUG..HANGUL SYLLABLE MEUH
+ {0xBBDC, 0xBBDC, prH2, gcLo}, // HANGUL SYLLABLE MYI
+ {0xBBDD, 0xBBF7, prH3, gcLo}, // [27] HANGUL SYLLABLE MYIG..HANGUL SYLLABLE MYIH
+ {0xBBF8, 0xBBF8, prH2, gcLo}, // HANGUL SYLLABLE MI
+ {0xBBF9, 0xBC13, prH3, gcLo}, // [27] HANGUL SYLLABLE MIG..HANGUL SYLLABLE MIH
+ {0xBC14, 0xBC14, prH2, gcLo}, // HANGUL SYLLABLE BA
+ {0xBC15, 0xBC2F, prH3, gcLo}, // [27] HANGUL SYLLABLE BAG..HANGUL SYLLABLE BAH
+ {0xBC30, 0xBC30, prH2, gcLo}, // HANGUL SYLLABLE BAE
+ {0xBC31, 0xBC4B, prH3, gcLo}, // [27] HANGUL SYLLABLE BAEG..HANGUL SYLLABLE BAEH
+ {0xBC4C, 0xBC4C, prH2, gcLo}, // HANGUL SYLLABLE BYA
+ {0xBC4D, 0xBC67, prH3, gcLo}, // [27] HANGUL SYLLABLE BYAG..HANGUL SYLLABLE BYAH
+ {0xBC68, 0xBC68, prH2, gcLo}, // HANGUL SYLLABLE BYAE
+ {0xBC69, 0xBC83, prH3, gcLo}, // [27] HANGUL SYLLABLE BYAEG..HANGUL SYLLABLE BYAEH
+ {0xBC84, 0xBC84, prH2, gcLo}, // HANGUL SYLLABLE BEO
+ {0xBC85, 0xBC9F, prH3, gcLo}, // [27] HANGUL SYLLABLE BEOG..HANGUL SYLLABLE BEOH
+ {0xBCA0, 0xBCA0, prH2, gcLo}, // HANGUL SYLLABLE BE
+ {0xBCA1, 0xBCBB, prH3, gcLo}, // [27] HANGUL SYLLABLE BEG..HANGUL SYLLABLE BEH
+ {0xBCBC, 0xBCBC, prH2, gcLo}, // HANGUL SYLLABLE BYEO
+ {0xBCBD, 0xBCD7, prH3, gcLo}, // [27] HANGUL SYLLABLE BYEOG..HANGUL SYLLABLE BYEOH
+ {0xBCD8, 0xBCD8, prH2, gcLo}, // HANGUL SYLLABLE BYE
+ {0xBCD9, 0xBCF3, prH3, gcLo}, // [27] HANGUL SYLLABLE BYEG..HANGUL SYLLABLE BYEH
+ {0xBCF4, 0xBCF4, prH2, gcLo}, // HANGUL SYLLABLE BO
+ {0xBCF5, 0xBD0F, prH3, gcLo}, // [27] HANGUL SYLLABLE BOG..HANGUL SYLLABLE BOH
+ {0xBD10, 0xBD10, prH2, gcLo}, // HANGUL SYLLABLE BWA
+ {0xBD11, 0xBD2B, prH3, gcLo}, // [27] HANGUL SYLLABLE BWAG..HANGUL SYLLABLE BWAH
+ {0xBD2C, 0xBD2C, prH2, gcLo}, // HANGUL SYLLABLE BWAE
+ {0xBD2D, 0xBD47, prH3, gcLo}, // [27] HANGUL SYLLABLE BWAEG..HANGUL SYLLABLE BWAEH
+ {0xBD48, 0xBD48, prH2, gcLo}, // HANGUL SYLLABLE BOE
+ {0xBD49, 0xBD63, prH3, gcLo}, // [27] HANGUL SYLLABLE BOEG..HANGUL SYLLABLE BOEH
+ {0xBD64, 0xBD64, prH2, gcLo}, // HANGUL SYLLABLE BYO
+ {0xBD65, 0xBD7F, prH3, gcLo}, // [27] HANGUL SYLLABLE BYOG..HANGUL SYLLABLE BYOH
+ {0xBD80, 0xBD80, prH2, gcLo}, // HANGUL SYLLABLE BU
+ {0xBD81, 0xBD9B, prH3, gcLo}, // [27] HANGUL SYLLABLE BUG..HANGUL SYLLABLE BUH
+ {0xBD9C, 0xBD9C, prH2, gcLo}, // HANGUL SYLLABLE BWEO
+ {0xBD9D, 0xBDB7, prH3, gcLo}, // [27] HANGUL SYLLABLE BWEOG..HANGUL SYLLABLE BWEOH
+ {0xBDB8, 0xBDB8, prH2, gcLo}, // HANGUL SYLLABLE BWE
+ {0xBDB9, 0xBDD3, prH3, gcLo}, // [27] HANGUL SYLLABLE BWEG..HANGUL SYLLABLE BWEH
+ {0xBDD4, 0xBDD4, prH2, gcLo}, // HANGUL SYLLABLE BWI
+ {0xBDD5, 0xBDEF, prH3, gcLo}, // [27] HANGUL SYLLABLE BWIG..HANGUL SYLLABLE BWIH
+ {0xBDF0, 0xBDF0, prH2, gcLo}, // HANGUL SYLLABLE BYU
+ {0xBDF1, 0xBE0B, prH3, gcLo}, // [27] HANGUL SYLLABLE BYUG..HANGUL SYLLABLE BYUH
+ {0xBE0C, 0xBE0C, prH2, gcLo}, // HANGUL SYLLABLE BEU
+ {0xBE0D, 0xBE27, prH3, gcLo}, // [27] HANGUL SYLLABLE BEUG..HANGUL SYLLABLE BEUH
+ {0xBE28, 0xBE28, prH2, gcLo}, // HANGUL SYLLABLE BYI
+ {0xBE29, 0xBE43, prH3, gcLo}, // [27] HANGUL SYLLABLE BYIG..HANGUL SYLLABLE BYIH
+ {0xBE44, 0xBE44, prH2, gcLo}, // HANGUL SYLLABLE BI
+ {0xBE45, 0xBE5F, prH3, gcLo}, // [27] HANGUL SYLLABLE BIG..HANGUL SYLLABLE BIH
+ {0xBE60, 0xBE60, prH2, gcLo}, // HANGUL SYLLABLE BBA
+ {0xBE61, 0xBE7B, prH3, gcLo}, // [27] HANGUL SYLLABLE BBAG..HANGUL SYLLABLE BBAH
+ {0xBE7C, 0xBE7C, prH2, gcLo}, // HANGUL SYLLABLE BBAE
+ {0xBE7D, 0xBE97, prH3, gcLo}, // [27] HANGUL SYLLABLE BBAEG..HANGUL SYLLABLE BBAEH
+ {0xBE98, 0xBE98, prH2, gcLo}, // HANGUL SYLLABLE BBYA
+ {0xBE99, 0xBEB3, prH3, gcLo}, // [27] HANGUL SYLLABLE BBYAG..HANGUL SYLLABLE BBYAH
+ {0xBEB4, 0xBEB4, prH2, gcLo}, // HANGUL SYLLABLE BBYAE
+ {0xBEB5, 0xBECF, prH3, gcLo}, // [27] HANGUL SYLLABLE BBYAEG..HANGUL SYLLABLE BBYAEH
+ {0xBED0, 0xBED0, prH2, gcLo}, // HANGUL SYLLABLE BBEO
+ {0xBED1, 0xBEEB, prH3, gcLo}, // [27] HANGUL SYLLABLE BBEOG..HANGUL SYLLABLE BBEOH
+ {0xBEEC, 0xBEEC, prH2, gcLo}, // HANGUL SYLLABLE BBE
+ {0xBEED, 0xBF07, prH3, gcLo}, // [27] HANGUL SYLLABLE BBEG..HANGUL SYLLABLE BBEH
+ {0xBF08, 0xBF08, prH2, gcLo}, // HANGUL SYLLABLE BBYEO
+ {0xBF09, 0xBF23, prH3, gcLo}, // [27] HANGUL SYLLABLE BBYEOG..HANGUL SYLLABLE BBYEOH
+ {0xBF24, 0xBF24, prH2, gcLo}, // HANGUL SYLLABLE BBYE
+ {0xBF25, 0xBF3F, prH3, gcLo}, // [27] HANGUL SYLLABLE BBYEG..HANGUL SYLLABLE BBYEH
+ {0xBF40, 0xBF40, prH2, gcLo}, // HANGUL SYLLABLE BBO
+ {0xBF41, 0xBF5B, prH3, gcLo}, // [27] HANGUL SYLLABLE BBOG..HANGUL SYLLABLE BBOH
+ {0xBF5C, 0xBF5C, prH2, gcLo}, // HANGUL SYLLABLE BBWA
+ {0xBF5D, 0xBF77, prH3, gcLo}, // [27] HANGUL SYLLABLE BBWAG..HANGUL SYLLABLE BBWAH
+ {0xBF78, 0xBF78, prH2, gcLo}, // HANGUL SYLLABLE BBWAE
+ {0xBF79, 0xBF93, prH3, gcLo}, // [27] HANGUL SYLLABLE BBWAEG..HANGUL SYLLABLE BBWAEH
+ {0xBF94, 0xBF94, prH2, gcLo}, // HANGUL SYLLABLE BBOE
+ {0xBF95, 0xBFAF, prH3, gcLo}, // [27] HANGUL SYLLABLE BBOEG..HANGUL SYLLABLE BBOEH
+ {0xBFB0, 0xBFB0, prH2, gcLo}, // HANGUL SYLLABLE BBYO
+ {0xBFB1, 0xBFCB, prH3, gcLo}, // [27] HANGUL SYLLABLE BBYOG..HANGUL SYLLABLE BBYOH
+ {0xBFCC, 0xBFCC, prH2, gcLo}, // HANGUL SYLLABLE BBU
+ {0xBFCD, 0xBFE7, prH3, gcLo}, // [27] HANGUL SYLLABLE BBUG..HANGUL SYLLABLE BBUH
+ {0xBFE8, 0xBFE8, prH2, gcLo}, // HANGUL SYLLABLE BBWEO
+ {0xBFE9, 0xC003, prH3, gcLo}, // [27] HANGUL SYLLABLE BBWEOG..HANGUL SYLLABLE BBWEOH
+ {0xC004, 0xC004, prH2, gcLo}, // HANGUL SYLLABLE BBWE
+ {0xC005, 0xC01F, prH3, gcLo}, // [27] HANGUL SYLLABLE BBWEG..HANGUL SYLLABLE BBWEH
+ {0xC020, 0xC020, prH2, gcLo}, // HANGUL SYLLABLE BBWI
+ {0xC021, 0xC03B, prH3, gcLo}, // [27] HANGUL SYLLABLE BBWIG..HANGUL SYLLABLE BBWIH
+ {0xC03C, 0xC03C, prH2, gcLo}, // HANGUL SYLLABLE BBYU
+ {0xC03D, 0xC057, prH3, gcLo}, // [27] HANGUL SYLLABLE BBYUG..HANGUL SYLLABLE BBYUH
+ {0xC058, 0xC058, prH2, gcLo}, // HANGUL SYLLABLE BBEU
+ {0xC059, 0xC073, prH3, gcLo}, // [27] HANGUL SYLLABLE BBEUG..HANGUL SYLLABLE BBEUH
+ {0xC074, 0xC074, prH2, gcLo}, // HANGUL SYLLABLE BBYI
+ {0xC075, 0xC08F, prH3, gcLo}, // [27] HANGUL SYLLABLE BBYIG..HANGUL SYLLABLE BBYIH
+ {0xC090, 0xC090, prH2, gcLo}, // HANGUL SYLLABLE BBI
+ {0xC091, 0xC0AB, prH3, gcLo}, // [27] HANGUL SYLLABLE BBIG..HANGUL SYLLABLE BBIH
+ {0xC0AC, 0xC0AC, prH2, gcLo}, // HANGUL SYLLABLE SA
+ {0xC0AD, 0xC0C7, prH3, gcLo}, // [27] HANGUL SYLLABLE SAG..HANGUL SYLLABLE SAH
+ {0xC0C8, 0xC0C8, prH2, gcLo}, // HANGUL SYLLABLE SAE
+ {0xC0C9, 0xC0E3, prH3, gcLo}, // [27] HANGUL SYLLABLE SAEG..HANGUL SYLLABLE SAEH
+ {0xC0E4, 0xC0E4, prH2, gcLo}, // HANGUL SYLLABLE SYA
+ {0xC0E5, 0xC0FF, prH3, gcLo}, // [27] HANGUL SYLLABLE SYAG..HANGUL SYLLABLE SYAH
+ {0xC100, 0xC100, prH2, gcLo}, // HANGUL SYLLABLE SYAE
+ {0xC101, 0xC11B, prH3, gcLo}, // [27] HANGUL SYLLABLE SYAEG..HANGUL SYLLABLE SYAEH
+ {0xC11C, 0xC11C, prH2, gcLo}, // HANGUL SYLLABLE SEO
+ {0xC11D, 0xC137, prH3, gcLo}, // [27] HANGUL SYLLABLE SEOG..HANGUL SYLLABLE SEOH
+ {0xC138, 0xC138, prH2, gcLo}, // HANGUL SYLLABLE SE
+ {0xC139, 0xC153, prH3, gcLo}, // [27] HANGUL SYLLABLE SEG..HANGUL SYLLABLE SEH
+ {0xC154, 0xC154, prH2, gcLo}, // HANGUL SYLLABLE SYEO
+ {0xC155, 0xC16F, prH3, gcLo}, // [27] HANGUL SYLLABLE SYEOG..HANGUL SYLLABLE SYEOH
+ {0xC170, 0xC170, prH2, gcLo}, // HANGUL SYLLABLE SYE
+ {0xC171, 0xC18B, prH3, gcLo}, // [27] HANGUL SYLLABLE SYEG..HANGUL SYLLABLE SYEH
+ {0xC18C, 0xC18C, prH2, gcLo}, // HANGUL SYLLABLE SO
+ {0xC18D, 0xC1A7, prH3, gcLo}, // [27] HANGUL SYLLABLE SOG..HANGUL SYLLABLE SOH
+ {0xC1A8, 0xC1A8, prH2, gcLo}, // HANGUL SYLLABLE SWA
+ {0xC1A9, 0xC1C3, prH3, gcLo}, // [27] HANGUL SYLLABLE SWAG..HANGUL SYLLABLE SWAH
+ {0xC1C4, 0xC1C4, prH2, gcLo}, // HANGUL SYLLABLE SWAE
+ {0xC1C5, 0xC1DF, prH3, gcLo}, // [27] HANGUL SYLLABLE SWAEG..HANGUL SYLLABLE SWAEH
+ {0xC1E0, 0xC1E0, prH2, gcLo}, // HANGUL SYLLABLE SOE
+ {0xC1E1, 0xC1FB, prH3, gcLo}, // [27] HANGUL SYLLABLE SOEG..HANGUL SYLLABLE SOEH
+ {0xC1FC, 0xC1FC, prH2, gcLo}, // HANGUL SYLLABLE SYO
+ {0xC1FD, 0xC217, prH3, gcLo}, // [27] HANGUL SYLLABLE SYOG..HANGUL SYLLABLE SYOH
+ {0xC218, 0xC218, prH2, gcLo}, // HANGUL SYLLABLE SU
+ {0xC219, 0xC233, prH3, gcLo}, // [27] HANGUL SYLLABLE SUG..HANGUL SYLLABLE SUH
+ {0xC234, 0xC234, prH2, gcLo}, // HANGUL SYLLABLE SWEO
+ {0xC235, 0xC24F, prH3, gcLo}, // [27] HANGUL SYLLABLE SWEOG..HANGUL SYLLABLE SWEOH
+ {0xC250, 0xC250, prH2, gcLo}, // HANGUL SYLLABLE SWE
+ {0xC251, 0xC26B, prH3, gcLo}, // [27] HANGUL SYLLABLE SWEG..HANGUL SYLLABLE SWEH
+ {0xC26C, 0xC26C, prH2, gcLo}, // HANGUL SYLLABLE SWI
+ {0xC26D, 0xC287, prH3, gcLo}, // [27] HANGUL SYLLABLE SWIG..HANGUL SYLLABLE SWIH
+ {0xC288, 0xC288, prH2, gcLo}, // HANGUL SYLLABLE SYU
+ {0xC289, 0xC2A3, prH3, gcLo}, // [27] HANGUL SYLLABLE SYUG..HANGUL SYLLABLE SYUH
+ {0xC2A4, 0xC2A4, prH2, gcLo}, // HANGUL SYLLABLE SEU
+ {0xC2A5, 0xC2BF, prH3, gcLo}, // [27] HANGUL SYLLABLE SEUG..HANGUL SYLLABLE SEUH
+ {0xC2C0, 0xC2C0, prH2, gcLo}, // HANGUL SYLLABLE SYI
+ {0xC2C1, 0xC2DB, prH3, gcLo}, // [27] HANGUL SYLLABLE SYIG..HANGUL SYLLABLE SYIH
+ {0xC2DC, 0xC2DC, prH2, gcLo}, // HANGUL SYLLABLE SI
+ {0xC2DD, 0xC2F7, prH3, gcLo}, // [27] HANGUL SYLLABLE SIG..HANGUL SYLLABLE SIH
+ {0xC2F8, 0xC2F8, prH2, gcLo}, // HANGUL SYLLABLE SSA
+ {0xC2F9, 0xC313, prH3, gcLo}, // [27] HANGUL SYLLABLE SSAG..HANGUL SYLLABLE SSAH
+ {0xC314, 0xC314, prH2, gcLo}, // HANGUL SYLLABLE SSAE
+ {0xC315, 0xC32F, prH3, gcLo}, // [27] HANGUL SYLLABLE SSAEG..HANGUL SYLLABLE SSAEH
+ {0xC330, 0xC330, prH2, gcLo}, // HANGUL SYLLABLE SSYA
+ {0xC331, 0xC34B, prH3, gcLo}, // [27] HANGUL SYLLABLE SSYAG..HANGUL SYLLABLE SSYAH
+ {0xC34C, 0xC34C, prH2, gcLo}, // HANGUL SYLLABLE SSYAE
+ {0xC34D, 0xC367, prH3, gcLo}, // [27] HANGUL SYLLABLE SSYAEG..HANGUL SYLLABLE SSYAEH
+ {0xC368, 0xC368, prH2, gcLo}, // HANGUL SYLLABLE SSEO
+ {0xC369, 0xC383, prH3, gcLo}, // [27] HANGUL SYLLABLE SSEOG..HANGUL SYLLABLE SSEOH
+ {0xC384, 0xC384, prH2, gcLo}, // HANGUL SYLLABLE SSE
+ {0xC385, 0xC39F, prH3, gcLo}, // [27] HANGUL SYLLABLE SSEG..HANGUL SYLLABLE SSEH
+ {0xC3A0, 0xC3A0, prH2, gcLo}, // HANGUL SYLLABLE SSYEO
+ {0xC3A1, 0xC3BB, prH3, gcLo}, // [27] HANGUL SYLLABLE SSYEOG..HANGUL SYLLABLE SSYEOH
+ {0xC3BC, 0xC3BC, prH2, gcLo}, // HANGUL SYLLABLE SSYE
+ {0xC3BD, 0xC3D7, prH3, gcLo}, // [27] HANGUL SYLLABLE SSYEG..HANGUL SYLLABLE SSYEH
+ {0xC3D8, 0xC3D8, prH2, gcLo}, // HANGUL SYLLABLE SSO
+ {0xC3D9, 0xC3F3, prH3, gcLo}, // [27] HANGUL SYLLABLE SSOG..HANGUL SYLLABLE SSOH
+ {0xC3F4, 0xC3F4, prH2, gcLo}, // HANGUL SYLLABLE SSWA
+ {0xC3F5, 0xC40F, prH3, gcLo}, // [27] HANGUL SYLLABLE SSWAG..HANGUL SYLLABLE SSWAH
+ {0xC410, 0xC410, prH2, gcLo}, // HANGUL SYLLABLE SSWAE
+ {0xC411, 0xC42B, prH3, gcLo}, // [27] HANGUL SYLLABLE SSWAEG..HANGUL SYLLABLE SSWAEH
+ {0xC42C, 0xC42C, prH2, gcLo}, // HANGUL SYLLABLE SSOE
+ {0xC42D, 0xC447, prH3, gcLo}, // [27] HANGUL SYLLABLE SSOEG..HANGUL SYLLABLE SSOEH
+ {0xC448, 0xC448, prH2, gcLo}, // HANGUL SYLLABLE SSYO
+ {0xC449, 0xC463, prH3, gcLo}, // [27] HANGUL SYLLABLE SSYOG..HANGUL SYLLABLE SSYOH
+ {0xC464, 0xC464, prH2, gcLo}, // HANGUL SYLLABLE SSU
+ {0xC465, 0xC47F, prH3, gcLo}, // [27] HANGUL SYLLABLE SSUG..HANGUL SYLLABLE SSUH
+ {0xC480, 0xC480, prH2, gcLo}, // HANGUL SYLLABLE SSWEO
+ {0xC481, 0xC49B, prH3, gcLo}, // [27] HANGUL SYLLABLE SSWEOG..HANGUL SYLLABLE SSWEOH
+ {0xC49C, 0xC49C, prH2, gcLo}, // HANGUL SYLLABLE SSWE
+ {0xC49D, 0xC4B7, prH3, gcLo}, // [27] HANGUL SYLLABLE SSWEG..HANGUL SYLLABLE SSWEH
+ {0xC4B8, 0xC4B8, prH2, gcLo}, // HANGUL SYLLABLE SSWI
+ {0xC4B9, 0xC4D3, prH3, gcLo}, // [27] HANGUL SYLLABLE SSWIG..HANGUL SYLLABLE SSWIH
+ {0xC4D4, 0xC4D4, prH2, gcLo}, // HANGUL SYLLABLE SSYU
+ {0xC4D5, 0xC4EF, prH3, gcLo}, // [27] HANGUL SYLLABLE SSYUG..HANGUL SYLLABLE SSYUH
+ {0xC4F0, 0xC4F0, prH2, gcLo}, // HANGUL SYLLABLE SSEU
+ {0xC4F1, 0xC50B, prH3, gcLo}, // [27] HANGUL SYLLABLE SSEUG..HANGUL SYLLABLE SSEUH
+ {0xC50C, 0xC50C, prH2, gcLo}, // HANGUL SYLLABLE SSYI
+ {0xC50D, 0xC527, prH3, gcLo}, // [27] HANGUL SYLLABLE SSYIG..HANGUL SYLLABLE SSYIH
+ {0xC528, 0xC528, prH2, gcLo}, // HANGUL SYLLABLE SSI
+ {0xC529, 0xC543, prH3, gcLo}, // [27] HANGUL SYLLABLE SSIG..HANGUL SYLLABLE SSIH
+ {0xC544, 0xC544, prH2, gcLo}, // HANGUL SYLLABLE A
+ {0xC545, 0xC55F, prH3, gcLo}, // [27] HANGUL SYLLABLE AG..HANGUL SYLLABLE AH
+ {0xC560, 0xC560, prH2, gcLo}, // HANGUL SYLLABLE AE
+ {0xC561, 0xC57B, prH3, gcLo}, // [27] HANGUL SYLLABLE AEG..HANGUL SYLLABLE AEH
+ {0xC57C, 0xC57C, prH2, gcLo}, // HANGUL SYLLABLE YA
+ {0xC57D, 0xC597, prH3, gcLo}, // [27] HANGUL SYLLABLE YAG..HANGUL SYLLABLE YAH
+ {0xC598, 0xC598, prH2, gcLo}, // HANGUL SYLLABLE YAE
+ {0xC599, 0xC5B3, prH3, gcLo}, // [27] HANGUL SYLLABLE YAEG..HANGUL SYLLABLE YAEH
+ {0xC5B4, 0xC5B4, prH2, gcLo}, // HANGUL SYLLABLE EO
+ {0xC5B5, 0xC5CF, prH3, gcLo}, // [27] HANGUL SYLLABLE EOG..HANGUL SYLLABLE EOH
+ {0xC5D0, 0xC5D0, prH2, gcLo}, // HANGUL SYLLABLE E
+ {0xC5D1, 0xC5EB, prH3, gcLo}, // [27] HANGUL SYLLABLE EG..HANGUL SYLLABLE EH
+ {0xC5EC, 0xC5EC, prH2, gcLo}, // HANGUL SYLLABLE YEO
+ {0xC5ED, 0xC607, prH3, gcLo}, // [27] HANGUL SYLLABLE YEOG..HANGUL SYLLABLE YEOH
+ {0xC608, 0xC608, prH2, gcLo}, // HANGUL SYLLABLE YE
+ {0xC609, 0xC623, prH3, gcLo}, // [27] HANGUL SYLLABLE YEG..HANGUL SYLLABLE YEH
+ {0xC624, 0xC624, prH2, gcLo}, // HANGUL SYLLABLE O
+ {0xC625, 0xC63F, prH3, gcLo}, // [27] HANGUL SYLLABLE OG..HANGUL SYLLABLE OH
+ {0xC640, 0xC640, prH2, gcLo}, // HANGUL SYLLABLE WA
+ {0xC641, 0xC65B, prH3, gcLo}, // [27] HANGUL SYLLABLE WAG..HANGUL SYLLABLE WAH
+ {0xC65C, 0xC65C, prH2, gcLo}, // HANGUL SYLLABLE WAE
+ {0xC65D, 0xC677, prH3, gcLo}, // [27] HANGUL SYLLABLE WAEG..HANGUL SYLLABLE WAEH
+ {0xC678, 0xC678, prH2, gcLo}, // HANGUL SYLLABLE OE
+ {0xC679, 0xC693, prH3, gcLo}, // [27] HANGUL SYLLABLE OEG..HANGUL SYLLABLE OEH
+ {0xC694, 0xC694, prH2, gcLo}, // HANGUL SYLLABLE YO
+ {0xC695, 0xC6AF, prH3, gcLo}, // [27] HANGUL SYLLABLE YOG..HANGUL SYLLABLE YOH
+ {0xC6B0, 0xC6B0, prH2, gcLo}, // HANGUL SYLLABLE U
+ {0xC6B1, 0xC6CB, prH3, gcLo}, // [27] HANGUL SYLLABLE UG..HANGUL SYLLABLE UH
+ {0xC6CC, 0xC6CC, prH2, gcLo}, // HANGUL SYLLABLE WEO
+ {0xC6CD, 0xC6E7, prH3, gcLo}, // [27] HANGUL SYLLABLE WEOG..HANGUL SYLLABLE WEOH
+ {0xC6E8, 0xC6E8, prH2, gcLo}, // HANGUL SYLLABLE WE
+ {0xC6E9, 0xC703, prH3, gcLo}, // [27] HANGUL SYLLABLE WEG..HANGUL SYLLABLE WEH
+ {0xC704, 0xC704, prH2, gcLo}, // HANGUL SYLLABLE WI
+ {0xC705, 0xC71F, prH3, gcLo}, // [27] HANGUL SYLLABLE WIG..HANGUL SYLLABLE WIH
+ {0xC720, 0xC720, prH2, gcLo}, // HANGUL SYLLABLE YU
+ {0xC721, 0xC73B, prH3, gcLo}, // [27] HANGUL SYLLABLE YUG..HANGUL SYLLABLE YUH
+ {0xC73C, 0xC73C, prH2, gcLo}, // HANGUL SYLLABLE EU
+ {0xC73D, 0xC757, prH3, gcLo}, // [27] HANGUL SYLLABLE EUG..HANGUL SYLLABLE EUH
+ {0xC758, 0xC758, prH2, gcLo}, // HANGUL SYLLABLE YI
+ {0xC759, 0xC773, prH3, gcLo}, // [27] HANGUL SYLLABLE YIG..HANGUL SYLLABLE YIH
+ {0xC774, 0xC774, prH2, gcLo}, // HANGUL SYLLABLE I
+ {0xC775, 0xC78F, prH3, gcLo}, // [27] HANGUL SYLLABLE IG..HANGUL SYLLABLE IH
+ {0xC790, 0xC790, prH2, gcLo}, // HANGUL SYLLABLE JA
+ {0xC791, 0xC7AB, prH3, gcLo}, // [27] HANGUL SYLLABLE JAG..HANGUL SYLLABLE JAH
+ {0xC7AC, 0xC7AC, prH2, gcLo}, // HANGUL SYLLABLE JAE
+ {0xC7AD, 0xC7C7, prH3, gcLo}, // [27] HANGUL SYLLABLE JAEG..HANGUL SYLLABLE JAEH
+ {0xC7C8, 0xC7C8, prH2, gcLo}, // HANGUL SYLLABLE JYA
+ {0xC7C9, 0xC7E3, prH3, gcLo}, // [27] HANGUL SYLLABLE JYAG..HANGUL SYLLABLE JYAH
+ {0xC7E4, 0xC7E4, prH2, gcLo}, // HANGUL SYLLABLE JYAE
+ {0xC7E5, 0xC7FF, prH3, gcLo}, // [27] HANGUL SYLLABLE JYAEG..HANGUL SYLLABLE JYAEH
+ {0xC800, 0xC800, prH2, gcLo}, // HANGUL SYLLABLE JEO
+ {0xC801, 0xC81B, prH3, gcLo}, // [27] HANGUL SYLLABLE JEOG..HANGUL SYLLABLE JEOH
+ {0xC81C, 0xC81C, prH2, gcLo}, // HANGUL SYLLABLE JE
+ {0xC81D, 0xC837, prH3, gcLo}, // [27] HANGUL SYLLABLE JEG..HANGUL SYLLABLE JEH
+ {0xC838, 0xC838, prH2, gcLo}, // HANGUL SYLLABLE JYEO
+ {0xC839, 0xC853, prH3, gcLo}, // [27] HANGUL SYLLABLE JYEOG..HANGUL SYLLABLE JYEOH
+ {0xC854, 0xC854, prH2, gcLo}, // HANGUL SYLLABLE JYE
+ {0xC855, 0xC86F, prH3, gcLo}, // [27] HANGUL SYLLABLE JYEG..HANGUL SYLLABLE JYEH
+ {0xC870, 0xC870, prH2, gcLo}, // HANGUL SYLLABLE JO
+ {0xC871, 0xC88B, prH3, gcLo}, // [27] HANGUL SYLLABLE JOG..HANGUL SYLLABLE JOH
+ {0xC88C, 0xC88C, prH2, gcLo}, // HANGUL SYLLABLE JWA
+ {0xC88D, 0xC8A7, prH3, gcLo}, // [27] HANGUL SYLLABLE JWAG..HANGUL SYLLABLE JWAH
+ {0xC8A8, 0xC8A8, prH2, gcLo}, // HANGUL SYLLABLE JWAE
+ {0xC8A9, 0xC8C3, prH3, gcLo}, // [27] HANGUL SYLLABLE JWAEG..HANGUL SYLLABLE JWAEH
+ {0xC8C4, 0xC8C4, prH2, gcLo}, // HANGUL SYLLABLE JOE
+ {0xC8C5, 0xC8DF, prH3, gcLo}, // [27] HANGUL SYLLABLE JOEG..HANGUL SYLLABLE JOEH
+ {0xC8E0, 0xC8E0, prH2, gcLo}, // HANGUL SYLLABLE JYO
+ {0xC8E1, 0xC8FB, prH3, gcLo}, // [27] HANGUL SYLLABLE JYOG..HANGUL SYLLABLE JYOH
+ {0xC8FC, 0xC8FC, prH2, gcLo}, // HANGUL SYLLABLE JU
+ {0xC8FD, 0xC917, prH3, gcLo}, // [27] HANGUL SYLLABLE JUG..HANGUL SYLLABLE JUH
+ {0xC918, 0xC918, prH2, gcLo}, // HANGUL SYLLABLE JWEO
+ {0xC919, 0xC933, prH3, gcLo}, // [27] HANGUL SYLLABLE JWEOG..HANGUL SYLLABLE JWEOH
+ {0xC934, 0xC934, prH2, gcLo}, // HANGUL SYLLABLE JWE
+ {0xC935, 0xC94F, prH3, gcLo}, // [27] HANGUL SYLLABLE JWEG..HANGUL SYLLABLE JWEH
+ {0xC950, 0xC950, prH2, gcLo}, // HANGUL SYLLABLE JWI
+ {0xC951, 0xC96B, prH3, gcLo}, // [27] HANGUL SYLLABLE JWIG..HANGUL SYLLABLE JWIH
+ {0xC96C, 0xC96C, prH2, gcLo}, // HANGUL SYLLABLE JYU
+ {0xC96D, 0xC987, prH3, gcLo}, // [27] HANGUL SYLLABLE JYUG..HANGUL SYLLABLE JYUH
+ {0xC988, 0xC988, prH2, gcLo}, // HANGUL SYLLABLE JEU
+ {0xC989, 0xC9A3, prH3, gcLo}, // [27] HANGUL SYLLABLE JEUG..HANGUL SYLLABLE JEUH
+ {0xC9A4, 0xC9A4, prH2, gcLo}, // HANGUL SYLLABLE JYI
+ {0xC9A5, 0xC9BF, prH3, gcLo}, // [27] HANGUL SYLLABLE JYIG..HANGUL SYLLABLE JYIH
+ {0xC9C0, 0xC9C0, prH2, gcLo}, // HANGUL SYLLABLE JI
+ {0xC9C1, 0xC9DB, prH3, gcLo}, // [27] HANGUL SYLLABLE JIG..HANGUL SYLLABLE JIH
+ {0xC9DC, 0xC9DC, prH2, gcLo}, // HANGUL SYLLABLE JJA
+ {0xC9DD, 0xC9F7, prH3, gcLo}, // [27] HANGUL SYLLABLE JJAG..HANGUL SYLLABLE JJAH
+ {0xC9F8, 0xC9F8, prH2, gcLo}, // HANGUL SYLLABLE JJAE
+ {0xC9F9, 0xCA13, prH3, gcLo}, // [27] HANGUL SYLLABLE JJAEG..HANGUL SYLLABLE JJAEH
+ {0xCA14, 0xCA14, prH2, gcLo}, // HANGUL SYLLABLE JJYA
+ {0xCA15, 0xCA2F, prH3, gcLo}, // [27] HANGUL SYLLABLE JJYAG..HANGUL SYLLABLE JJYAH
+ {0xCA30, 0xCA30, prH2, gcLo}, // HANGUL SYLLABLE JJYAE
+ {0xCA31, 0xCA4B, prH3, gcLo}, // [27] HANGUL SYLLABLE JJYAEG..HANGUL SYLLABLE JJYAEH
+ {0xCA4C, 0xCA4C, prH2, gcLo}, // HANGUL SYLLABLE JJEO
+ {0xCA4D, 0xCA67, prH3, gcLo}, // [27] HANGUL SYLLABLE JJEOG..HANGUL SYLLABLE JJEOH
+ {0xCA68, 0xCA68, prH2, gcLo}, // HANGUL SYLLABLE JJE
+ {0xCA69, 0xCA83, prH3, gcLo}, // [27] HANGUL SYLLABLE JJEG..HANGUL SYLLABLE JJEH
+ {0xCA84, 0xCA84, prH2, gcLo}, // HANGUL SYLLABLE JJYEO
+ {0xCA85, 0xCA9F, prH3, gcLo}, // [27] HANGUL SYLLABLE JJYEOG..HANGUL SYLLABLE JJYEOH
+ {0xCAA0, 0xCAA0, prH2, gcLo}, // HANGUL SYLLABLE JJYE
+ {0xCAA1, 0xCABB, prH3, gcLo}, // [27] HANGUL SYLLABLE JJYEG..HANGUL SYLLABLE JJYEH
+ {0xCABC, 0xCABC, prH2, gcLo}, // HANGUL SYLLABLE JJO
+ {0xCABD, 0xCAD7, prH3, gcLo}, // [27] HANGUL SYLLABLE JJOG..HANGUL SYLLABLE JJOH
+ {0xCAD8, 0xCAD8, prH2, gcLo}, // HANGUL SYLLABLE JJWA
+ {0xCAD9, 0xCAF3, prH3, gcLo}, // [27] HANGUL SYLLABLE JJWAG..HANGUL SYLLABLE JJWAH
+ {0xCAF4, 0xCAF4, prH2, gcLo}, // HANGUL SYLLABLE JJWAE
+ {0xCAF5, 0xCB0F, prH3, gcLo}, // [27] HANGUL SYLLABLE JJWAEG..HANGUL SYLLABLE JJWAEH
+ {0xCB10, 0xCB10, prH2, gcLo}, // HANGUL SYLLABLE JJOE
+ {0xCB11, 0xCB2B, prH3, gcLo}, // [27] HANGUL SYLLABLE JJOEG..HANGUL SYLLABLE JJOEH
+ {0xCB2C, 0xCB2C, prH2, gcLo}, // HANGUL SYLLABLE JJYO
+ {0xCB2D, 0xCB47, prH3, gcLo}, // [27] HANGUL SYLLABLE JJYOG..HANGUL SYLLABLE JJYOH
+ {0xCB48, 0xCB48, prH2, gcLo}, // HANGUL SYLLABLE JJU
+ {0xCB49, 0xCB63, prH3, gcLo}, // [27] HANGUL SYLLABLE JJUG..HANGUL SYLLABLE JJUH
+ {0xCB64, 0xCB64, prH2, gcLo}, // HANGUL SYLLABLE JJWEO
+ {0xCB65, 0xCB7F, prH3, gcLo}, // [27] HANGUL SYLLABLE JJWEOG..HANGUL SYLLABLE JJWEOH
+ {0xCB80, 0xCB80, prH2, gcLo}, // HANGUL SYLLABLE JJWE
+ {0xCB81, 0xCB9B, prH3, gcLo}, // [27] HANGUL SYLLABLE JJWEG..HANGUL SYLLABLE JJWEH
+ {0xCB9C, 0xCB9C, prH2, gcLo}, // HANGUL SYLLABLE JJWI
+ {0xCB9D, 0xCBB7, prH3, gcLo}, // [27] HANGUL SYLLABLE JJWIG..HANGUL SYLLABLE JJWIH
+ {0xCBB8, 0xCBB8, prH2, gcLo}, // HANGUL SYLLABLE JJYU
+ {0xCBB9, 0xCBD3, prH3, gcLo}, // [27] HANGUL SYLLABLE JJYUG..HANGUL SYLLABLE JJYUH
+ {0xCBD4, 0xCBD4, prH2, gcLo}, // HANGUL SYLLABLE JJEU
+ {0xCBD5, 0xCBEF, prH3, gcLo}, // [27] HANGUL SYLLABLE JJEUG..HANGUL SYLLABLE JJEUH
+ {0xCBF0, 0xCBF0, prH2, gcLo}, // HANGUL SYLLABLE JJYI
+ {0xCBF1, 0xCC0B, prH3, gcLo}, // [27] HANGUL SYLLABLE JJYIG..HANGUL SYLLABLE JJYIH
+ {0xCC0C, 0xCC0C, prH2, gcLo}, // HANGUL SYLLABLE JJI
+ {0xCC0D, 0xCC27, prH3, gcLo}, // [27] HANGUL SYLLABLE JJIG..HANGUL SYLLABLE JJIH
+ {0xCC28, 0xCC28, prH2, gcLo}, // HANGUL SYLLABLE CA
+ {0xCC29, 0xCC43, prH3, gcLo}, // [27] HANGUL SYLLABLE CAG..HANGUL SYLLABLE CAH
+ {0xCC44, 0xCC44, prH2, gcLo}, // HANGUL SYLLABLE CAE
+ {0xCC45, 0xCC5F, prH3, gcLo}, // [27] HANGUL SYLLABLE CAEG..HANGUL SYLLABLE CAEH
+ {0xCC60, 0xCC60, prH2, gcLo}, // HANGUL SYLLABLE CYA
+ {0xCC61, 0xCC7B, prH3, gcLo}, // [27] HANGUL SYLLABLE CYAG..HANGUL SYLLABLE CYAH
+ {0xCC7C, 0xCC7C, prH2, gcLo}, // HANGUL SYLLABLE CYAE
+ {0xCC7D, 0xCC97, prH3, gcLo}, // [27] HANGUL SYLLABLE CYAEG..HANGUL SYLLABLE CYAEH
+ {0xCC98, 0xCC98, prH2, gcLo}, // HANGUL SYLLABLE CEO
+ {0xCC99, 0xCCB3, prH3, gcLo}, // [27] HANGUL SYLLABLE CEOG..HANGUL SYLLABLE CEOH
+ {0xCCB4, 0xCCB4, prH2, gcLo}, // HANGUL SYLLABLE CE
+ {0xCCB5, 0xCCCF, prH3, gcLo}, // [27] HANGUL SYLLABLE CEG..HANGUL SYLLABLE CEH
+ {0xCCD0, 0xCCD0, prH2, gcLo}, // HANGUL SYLLABLE CYEO
+ {0xCCD1, 0xCCEB, prH3, gcLo}, // [27] HANGUL SYLLABLE CYEOG..HANGUL SYLLABLE CYEOH
+ {0xCCEC, 0xCCEC, prH2, gcLo}, // HANGUL SYLLABLE CYE
+ {0xCCED, 0xCD07, prH3, gcLo}, // [27] HANGUL SYLLABLE CYEG..HANGUL SYLLABLE CYEH
+ {0xCD08, 0xCD08, prH2, gcLo}, // HANGUL SYLLABLE CO
+ {0xCD09, 0xCD23, prH3, gcLo}, // [27] HANGUL SYLLABLE COG..HANGUL SYLLABLE COH
+ {0xCD24, 0xCD24, prH2, gcLo}, // HANGUL SYLLABLE CWA
+ {0xCD25, 0xCD3F, prH3, gcLo}, // [27] HANGUL SYLLABLE CWAG..HANGUL SYLLABLE CWAH
+ {0xCD40, 0xCD40, prH2, gcLo}, // HANGUL SYLLABLE CWAE
+ {0xCD41, 0xCD5B, prH3, gcLo}, // [27] HANGUL SYLLABLE CWAEG..HANGUL SYLLABLE CWAEH
+ {0xCD5C, 0xCD5C, prH2, gcLo}, // HANGUL SYLLABLE COE
+ {0xCD5D, 0xCD77, prH3, gcLo}, // [27] HANGUL SYLLABLE COEG..HANGUL SYLLABLE COEH
+ {0xCD78, 0xCD78, prH2, gcLo}, // HANGUL SYLLABLE CYO
+ {0xCD79, 0xCD93, prH3, gcLo}, // [27] HANGUL SYLLABLE CYOG..HANGUL SYLLABLE CYOH
+ {0xCD94, 0xCD94, prH2, gcLo}, // HANGUL SYLLABLE CU
+ {0xCD95, 0xCDAF, prH3, gcLo}, // [27] HANGUL SYLLABLE CUG..HANGUL SYLLABLE CUH
+ {0xCDB0, 0xCDB0, prH2, gcLo}, // HANGUL SYLLABLE CWEO
+ {0xCDB1, 0xCDCB, prH3, gcLo}, // [27] HANGUL SYLLABLE CWEOG..HANGUL SYLLABLE CWEOH
+ {0xCDCC, 0xCDCC, prH2, gcLo}, // HANGUL SYLLABLE CWE
+ {0xCDCD, 0xCDE7, prH3, gcLo}, // [27] HANGUL SYLLABLE CWEG..HANGUL SYLLABLE CWEH
+ {0xCDE8, 0xCDE8, prH2, gcLo}, // HANGUL SYLLABLE CWI
+ {0xCDE9, 0xCE03, prH3, gcLo}, // [27] HANGUL SYLLABLE CWIG..HANGUL SYLLABLE CWIH
+ {0xCE04, 0xCE04, prH2, gcLo}, // HANGUL SYLLABLE CYU
+ {0xCE05, 0xCE1F, prH3, gcLo}, // [27] HANGUL SYLLABLE CYUG..HANGUL SYLLABLE CYUH
+ {0xCE20, 0xCE20, prH2, gcLo}, // HANGUL SYLLABLE CEU
+ {0xCE21, 0xCE3B, prH3, gcLo}, // [27] HANGUL SYLLABLE CEUG..HANGUL SYLLABLE CEUH
+ {0xCE3C, 0xCE3C, prH2, gcLo}, // HANGUL SYLLABLE CYI
+ {0xCE3D, 0xCE57, prH3, gcLo}, // [27] HANGUL SYLLABLE CYIG..HANGUL SYLLABLE CYIH
+ {0xCE58, 0xCE58, prH2, gcLo}, // HANGUL SYLLABLE CI
+ {0xCE59, 0xCE73, prH3, gcLo}, // [27] HANGUL SYLLABLE CIG..HANGUL SYLLABLE CIH
+ {0xCE74, 0xCE74, prH2, gcLo}, // HANGUL SYLLABLE KA
+ {0xCE75, 0xCE8F, prH3, gcLo}, // [27] HANGUL SYLLABLE KAG..HANGUL SYLLABLE KAH
+ {0xCE90, 0xCE90, prH2, gcLo}, // HANGUL SYLLABLE KAE
+ {0xCE91, 0xCEAB, prH3, gcLo}, // [27] HANGUL SYLLABLE KAEG..HANGUL SYLLABLE KAEH
+ {0xCEAC, 0xCEAC, prH2, gcLo}, // HANGUL SYLLABLE KYA
+ {0xCEAD, 0xCEC7, prH3, gcLo}, // [27] HANGUL SYLLABLE KYAG..HANGUL SYLLABLE KYAH
+ {0xCEC8, 0xCEC8, prH2, gcLo}, // HANGUL SYLLABLE KYAE
+ {0xCEC9, 0xCEE3, prH3, gcLo}, // [27] HANGUL SYLLABLE KYAEG..HANGUL SYLLABLE KYAEH
+ {0xCEE4, 0xCEE4, prH2, gcLo}, // HANGUL SYLLABLE KEO
+ {0xCEE5, 0xCEFF, prH3, gcLo}, // [27] HANGUL SYLLABLE KEOG..HANGUL SYLLABLE KEOH
+ {0xCF00, 0xCF00, prH2, gcLo}, // HANGUL SYLLABLE KE
+ {0xCF01, 0xCF1B, prH3, gcLo}, // [27] HANGUL SYLLABLE KEG..HANGUL SYLLABLE KEH
+ {0xCF1C, 0xCF1C, prH2, gcLo}, // HANGUL SYLLABLE KYEO
+ {0xCF1D, 0xCF37, prH3, gcLo}, // [27] HANGUL SYLLABLE KYEOG..HANGUL SYLLABLE KYEOH
+ {0xCF38, 0xCF38, prH2, gcLo}, // HANGUL SYLLABLE KYE
+ {0xCF39, 0xCF53, prH3, gcLo}, // [27] HANGUL SYLLABLE KYEG..HANGUL SYLLABLE KYEH
+ {0xCF54, 0xCF54, prH2, gcLo}, // HANGUL SYLLABLE KO
+ {0xCF55, 0xCF6F, prH3, gcLo}, // [27] HANGUL SYLLABLE KOG..HANGUL SYLLABLE KOH
+ {0xCF70, 0xCF70, prH2, gcLo}, // HANGUL SYLLABLE KWA
+ {0xCF71, 0xCF8B, prH3, gcLo}, // [27] HANGUL SYLLABLE KWAG..HANGUL SYLLABLE KWAH
+ {0xCF8C, 0xCF8C, prH2, gcLo}, // HANGUL SYLLABLE KWAE
+ {0xCF8D, 0xCFA7, prH3, gcLo}, // [27] HANGUL SYLLABLE KWAEG..HANGUL SYLLABLE KWAEH
+ {0xCFA8, 0xCFA8, prH2, gcLo}, // HANGUL SYLLABLE KOE
+ {0xCFA9, 0xCFC3, prH3, gcLo}, // [27] HANGUL SYLLABLE KOEG..HANGUL SYLLABLE KOEH
+ {0xCFC4, 0xCFC4, prH2, gcLo}, // HANGUL SYLLABLE KYO
+ {0xCFC5, 0xCFDF, prH3, gcLo}, // [27] HANGUL SYLLABLE KYOG..HANGUL SYLLABLE KYOH
+ {0xCFE0, 0xCFE0, prH2, gcLo}, // HANGUL SYLLABLE KU
+ {0xCFE1, 0xCFFB, prH3, gcLo}, // [27] HANGUL SYLLABLE KUG..HANGUL SYLLABLE KUH
+ {0xCFFC, 0xCFFC, prH2, gcLo}, // HANGUL SYLLABLE KWEO
+ {0xCFFD, 0xD017, prH3, gcLo}, // [27] HANGUL SYLLABLE KWEOG..HANGUL SYLLABLE KWEOH
+ {0xD018, 0xD018, prH2, gcLo}, // HANGUL SYLLABLE KWE
+ {0xD019, 0xD033, prH3, gcLo}, // [27] HANGUL SYLLABLE KWEG..HANGUL SYLLABLE KWEH
+ {0xD034, 0xD034, prH2, gcLo}, // HANGUL SYLLABLE KWI
+ {0xD035, 0xD04F, prH3, gcLo}, // [27] HANGUL SYLLABLE KWIG..HANGUL SYLLABLE KWIH
+ {0xD050, 0xD050, prH2, gcLo}, // HANGUL SYLLABLE KYU
+ {0xD051, 0xD06B, prH3, gcLo}, // [27] HANGUL SYLLABLE KYUG..HANGUL SYLLABLE KYUH
+ {0xD06C, 0xD06C, prH2, gcLo}, // HANGUL SYLLABLE KEU
+ {0xD06D, 0xD087, prH3, gcLo}, // [27] HANGUL SYLLABLE KEUG..HANGUL SYLLABLE KEUH
+ {0xD088, 0xD088, prH2, gcLo}, // HANGUL SYLLABLE KYI
+ {0xD089, 0xD0A3, prH3, gcLo}, // [27] HANGUL SYLLABLE KYIG..HANGUL SYLLABLE KYIH
+ {0xD0A4, 0xD0A4, prH2, gcLo}, // HANGUL SYLLABLE KI
+ {0xD0A5, 0xD0BF, prH3, gcLo}, // [27] HANGUL SYLLABLE KIG..HANGUL SYLLABLE KIH
+ {0xD0C0, 0xD0C0, prH2, gcLo}, // HANGUL SYLLABLE TA
+ {0xD0C1, 0xD0DB, prH3, gcLo}, // [27] HANGUL SYLLABLE TAG..HANGUL SYLLABLE TAH
+ {0xD0DC, 0xD0DC, prH2, gcLo}, // HANGUL SYLLABLE TAE
+ {0xD0DD, 0xD0F7, prH3, gcLo}, // [27] HANGUL SYLLABLE TAEG..HANGUL SYLLABLE TAEH
+ {0xD0F8, 0xD0F8, prH2, gcLo}, // HANGUL SYLLABLE TYA
+ {0xD0F9, 0xD113, prH3, gcLo}, // [27] HANGUL SYLLABLE TYAG..HANGUL SYLLABLE TYAH
+ {0xD114, 0xD114, prH2, gcLo}, // HANGUL SYLLABLE TYAE
+ {0xD115, 0xD12F, prH3, gcLo}, // [27] HANGUL SYLLABLE TYAEG..HANGUL SYLLABLE TYAEH
+ {0xD130, 0xD130, prH2, gcLo}, // HANGUL SYLLABLE TEO
+ {0xD131, 0xD14B, prH3, gcLo}, // [27] HANGUL SYLLABLE TEOG..HANGUL SYLLABLE TEOH
+ {0xD14C, 0xD14C, prH2, gcLo}, // HANGUL SYLLABLE TE
+ {0xD14D, 0xD167, prH3, gcLo}, // [27] HANGUL SYLLABLE TEG..HANGUL SYLLABLE TEH
+ {0xD168, 0xD168, prH2, gcLo}, // HANGUL SYLLABLE TYEO
+ {0xD169, 0xD183, prH3, gcLo}, // [27] HANGUL SYLLABLE TYEOG..HANGUL SYLLABLE TYEOH
+ {0xD184, 0xD184, prH2, gcLo}, // HANGUL SYLLABLE TYE
+ {0xD185, 0xD19F, prH3, gcLo}, // [27] HANGUL SYLLABLE TYEG..HANGUL SYLLABLE TYEH
+ {0xD1A0, 0xD1A0, prH2, gcLo}, // HANGUL SYLLABLE TO
+ {0xD1A1, 0xD1BB, prH3, gcLo}, // [27] HANGUL SYLLABLE TOG..HANGUL SYLLABLE TOH
+ {0xD1BC, 0xD1BC, prH2, gcLo}, // HANGUL SYLLABLE TWA
+ {0xD1BD, 0xD1D7, prH3, gcLo}, // [27] HANGUL SYLLABLE TWAG..HANGUL SYLLABLE TWAH
+ {0xD1D8, 0xD1D8, prH2, gcLo}, // HANGUL SYLLABLE TWAE
+ {0xD1D9, 0xD1F3, prH3, gcLo}, // [27] HANGUL SYLLABLE TWAEG..HANGUL SYLLABLE TWAEH
+ {0xD1F4, 0xD1F4, prH2, gcLo}, // HANGUL SYLLABLE TOE
+ {0xD1F5, 0xD20F, prH3, gcLo}, // [27] HANGUL SYLLABLE TOEG..HANGUL SYLLABLE TOEH
+ {0xD210, 0xD210, prH2, gcLo}, // HANGUL SYLLABLE TYO
+ {0xD211, 0xD22B, prH3, gcLo}, // [27] HANGUL SYLLABLE TYOG..HANGUL SYLLABLE TYOH
+ {0xD22C, 0xD22C, prH2, gcLo}, // HANGUL SYLLABLE TU
+ {0xD22D, 0xD247, prH3, gcLo}, // [27] HANGUL SYLLABLE TUG..HANGUL SYLLABLE TUH
+ {0xD248, 0xD248, prH2, gcLo}, // HANGUL SYLLABLE TWEO
+ {0xD249, 0xD263, prH3, gcLo}, // [27] HANGUL SYLLABLE TWEOG..HANGUL SYLLABLE TWEOH
+ {0xD264, 0xD264, prH2, gcLo}, // HANGUL SYLLABLE TWE
+ {0xD265, 0xD27F, prH3, gcLo}, // [27] HANGUL SYLLABLE TWEG..HANGUL SYLLABLE TWEH
+ {0xD280, 0xD280, prH2, gcLo}, // HANGUL SYLLABLE TWI
+ {0xD281, 0xD29B, prH3, gcLo}, // [27] HANGUL SYLLABLE TWIG..HANGUL SYLLABLE TWIH
+ {0xD29C, 0xD29C, prH2, gcLo}, // HANGUL SYLLABLE TYU
+ {0xD29D, 0xD2B7, prH3, gcLo}, // [27] HANGUL SYLLABLE TYUG..HANGUL SYLLABLE TYUH
+ {0xD2B8, 0xD2B8, prH2, gcLo}, // HANGUL SYLLABLE TEU
+ {0xD2B9, 0xD2D3, prH3, gcLo}, // [27] HANGUL SYLLABLE TEUG..HANGUL SYLLABLE TEUH
+ {0xD2D4, 0xD2D4, prH2, gcLo}, // HANGUL SYLLABLE TYI
+ {0xD2D5, 0xD2EF, prH3, gcLo}, // [27] HANGUL SYLLABLE TYIG..HANGUL SYLLABLE TYIH
+ {0xD2F0, 0xD2F0, prH2, gcLo}, // HANGUL SYLLABLE TI
+ {0xD2F1, 0xD30B, prH3, gcLo}, // [27] HANGUL SYLLABLE TIG..HANGUL SYLLABLE TIH
+ {0xD30C, 0xD30C, prH2, gcLo}, // HANGUL SYLLABLE PA
+ {0xD30D, 0xD327, prH3, gcLo}, // [27] HANGUL SYLLABLE PAG..HANGUL SYLLABLE PAH
+ {0xD328, 0xD328, prH2, gcLo}, // HANGUL SYLLABLE PAE
+ {0xD329, 0xD343, prH3, gcLo}, // [27] HANGUL SYLLABLE PAEG..HANGUL SYLLABLE PAEH
+ {0xD344, 0xD344, prH2, gcLo}, // HANGUL SYLLABLE PYA
+ {0xD345, 0xD35F, prH3, gcLo}, // [27] HANGUL SYLLABLE PYAG..HANGUL SYLLABLE PYAH
+ {0xD360, 0xD360, prH2, gcLo}, // HANGUL SYLLABLE PYAE
+ {0xD361, 0xD37B, prH3, gcLo}, // [27] HANGUL SYLLABLE PYAEG..HANGUL SYLLABLE PYAEH
+ {0xD37C, 0xD37C, prH2, gcLo}, // HANGUL SYLLABLE PEO
+ {0xD37D, 0xD397, prH3, gcLo}, // [27] HANGUL SYLLABLE PEOG..HANGUL SYLLABLE PEOH
+ {0xD398, 0xD398, prH2, gcLo}, // HANGUL SYLLABLE PE
+ {0xD399, 0xD3B3, prH3, gcLo}, // [27] HANGUL SYLLABLE PEG..HANGUL SYLLABLE PEH
+ {0xD3B4, 0xD3B4, prH2, gcLo}, // HANGUL SYLLABLE PYEO
+ {0xD3B5, 0xD3CF, prH3, gcLo}, // [27] HANGUL SYLLABLE PYEOG..HANGUL SYLLABLE PYEOH
+ {0xD3D0, 0xD3D0, prH2, gcLo}, // HANGUL SYLLABLE PYE
+ {0xD3D1, 0xD3EB, prH3, gcLo}, // [27] HANGUL SYLLABLE PYEG..HANGUL SYLLABLE PYEH
+ {0xD3EC, 0xD3EC, prH2, gcLo}, // HANGUL SYLLABLE PO
+ {0xD3ED, 0xD407, prH3, gcLo}, // [27] HANGUL SYLLABLE POG..HANGUL SYLLABLE POH
+ {0xD408, 0xD408, prH2, gcLo}, // HANGUL SYLLABLE PWA
+ {0xD409, 0xD423, prH3, gcLo}, // [27] HANGUL SYLLABLE PWAG..HANGUL SYLLABLE PWAH
+ {0xD424, 0xD424, prH2, gcLo}, // HANGUL SYLLABLE PWAE
+ {0xD425, 0xD43F, prH3, gcLo}, // [27] HANGUL SYLLABLE PWAEG..HANGUL SYLLABLE PWAEH
+ {0xD440, 0xD440, prH2, gcLo}, // HANGUL SYLLABLE POE
+ {0xD441, 0xD45B, prH3, gcLo}, // [27] HANGUL SYLLABLE POEG..HANGUL SYLLABLE POEH
+ {0xD45C, 0xD45C, prH2, gcLo}, // HANGUL SYLLABLE PYO
+ {0xD45D, 0xD477, prH3, gcLo}, // [27] HANGUL SYLLABLE PYOG..HANGUL SYLLABLE PYOH
+ {0xD478, 0xD478, prH2, gcLo}, // HANGUL SYLLABLE PU
+ {0xD479, 0xD493, prH3, gcLo}, // [27] HANGUL SYLLABLE PUG..HANGUL SYLLABLE PUH
+ {0xD494, 0xD494, prH2, gcLo}, // HANGUL SYLLABLE PWEO
+ {0xD495, 0xD4AF, prH3, gcLo}, // [27] HANGUL SYLLABLE PWEOG..HANGUL SYLLABLE PWEOH
+ {0xD4B0, 0xD4B0, prH2, gcLo}, // HANGUL SYLLABLE PWE
+ {0xD4B1, 0xD4CB, prH3, gcLo}, // [27] HANGUL SYLLABLE PWEG..HANGUL SYLLABLE PWEH
+ {0xD4CC, 0xD4CC, prH2, gcLo}, // HANGUL SYLLABLE PWI
+ {0xD4CD, 0xD4E7, prH3, gcLo}, // [27] HANGUL SYLLABLE PWIG..HANGUL SYLLABLE PWIH
+ {0xD4E8, 0xD4E8, prH2, gcLo}, // HANGUL SYLLABLE PYU
+ {0xD4E9, 0xD503, prH3, gcLo}, // [27] HANGUL SYLLABLE PYUG..HANGUL SYLLABLE PYUH
+ {0xD504, 0xD504, prH2, gcLo}, // HANGUL SYLLABLE PEU
+ {0xD505, 0xD51F, prH3, gcLo}, // [27] HANGUL SYLLABLE PEUG..HANGUL SYLLABLE PEUH
+ {0xD520, 0xD520, prH2, gcLo}, // HANGUL SYLLABLE PYI
+ {0xD521, 0xD53B, prH3, gcLo}, // [27] HANGUL SYLLABLE PYIG..HANGUL SYLLABLE PYIH
+ {0xD53C, 0xD53C, prH2, gcLo}, // HANGUL SYLLABLE PI
+ {0xD53D, 0xD557, prH3, gcLo}, // [27] HANGUL SYLLABLE PIG..HANGUL SYLLABLE PIH
+ {0xD558, 0xD558, prH2, gcLo}, // HANGUL SYLLABLE HA
+ {0xD559, 0xD573, prH3, gcLo}, // [27] HANGUL SYLLABLE HAG..HANGUL SYLLABLE HAH
+ {0xD574, 0xD574, prH2, gcLo}, // HANGUL SYLLABLE HAE
+ {0xD575, 0xD58F, prH3, gcLo}, // [27] HANGUL SYLLABLE HAEG..HANGUL SYLLABLE HAEH
+ {0xD590, 0xD590, prH2, gcLo}, // HANGUL SYLLABLE HYA
+ {0xD591, 0xD5AB, prH3, gcLo}, // [27] HANGUL SYLLABLE HYAG..HANGUL SYLLABLE HYAH
+ {0xD5AC, 0xD5AC, prH2, gcLo}, // HANGUL SYLLABLE HYAE
+ {0xD5AD, 0xD5C7, prH3, gcLo}, // [27] HANGUL SYLLABLE HYAEG..HANGUL SYLLABLE HYAEH
+ {0xD5C8, 0xD5C8, prH2, gcLo}, // HANGUL SYLLABLE HEO
+ {0xD5C9, 0xD5E3, prH3, gcLo}, // [27] HANGUL SYLLABLE HEOG..HANGUL SYLLABLE HEOH
+ {0xD5E4, 0xD5E4, prH2, gcLo}, // HANGUL SYLLABLE HE
+ {0xD5E5, 0xD5FF, prH3, gcLo}, // [27] HANGUL SYLLABLE HEG..HANGUL SYLLABLE HEH
+ {0xD600, 0xD600, prH2, gcLo}, // HANGUL SYLLABLE HYEO
+ {0xD601, 0xD61B, prH3, gcLo}, // [27] HANGUL SYLLABLE HYEOG..HANGUL SYLLABLE HYEOH
+ {0xD61C, 0xD61C, prH2, gcLo}, // HANGUL SYLLABLE HYE
+ {0xD61D, 0xD637, prH3, gcLo}, // [27] HANGUL SYLLABLE HYEG..HANGUL SYLLABLE HYEH
+ {0xD638, 0xD638, prH2, gcLo}, // HANGUL SYLLABLE HO
+ {0xD639, 0xD653, prH3, gcLo}, // [27] HANGUL SYLLABLE HOG..HANGUL SYLLABLE HOH
+ {0xD654, 0xD654, prH2, gcLo}, // HANGUL SYLLABLE HWA
+ {0xD655, 0xD66F, prH3, gcLo}, // [27] HANGUL SYLLABLE HWAG..HANGUL SYLLABLE HWAH
+ {0xD670, 0xD670, prH2, gcLo}, // HANGUL SYLLABLE HWAE
+ {0xD671, 0xD68B, prH3, gcLo}, // [27] HANGUL SYLLABLE HWAEG..HANGUL SYLLABLE HWAEH
+ {0xD68C, 0xD68C, prH2, gcLo}, // HANGUL SYLLABLE HOE
+ {0xD68D, 0xD6A7, prH3, gcLo}, // [27] HANGUL SYLLABLE HOEG..HANGUL SYLLABLE HOEH
+ {0xD6A8, 0xD6A8, prH2, gcLo}, // HANGUL SYLLABLE HYO
+ {0xD6A9, 0xD6C3, prH3, gcLo}, // [27] HANGUL SYLLABLE HYOG..HANGUL SYLLABLE HYOH
+ {0xD6C4, 0xD6C4, prH2, gcLo}, // HANGUL SYLLABLE HU
+ {0xD6C5, 0xD6DF, prH3, gcLo}, // [27] HANGUL SYLLABLE HUG..HANGUL SYLLABLE HUH
+ {0xD6E0, 0xD6E0, prH2, gcLo}, // HANGUL SYLLABLE HWEO
+ {0xD6E1, 0xD6FB, prH3, gcLo}, // [27] HANGUL SYLLABLE HWEOG..HANGUL SYLLABLE HWEOH
+ {0xD6FC, 0xD6FC, prH2, gcLo}, // HANGUL SYLLABLE HWE
+ {0xD6FD, 0xD717, prH3, gcLo}, // [27] HANGUL SYLLABLE HWEG..HANGUL SYLLABLE HWEH
+ {0xD718, 0xD718, prH2, gcLo}, // HANGUL SYLLABLE HWI
+ {0xD719, 0xD733, prH3, gcLo}, // [27] HANGUL SYLLABLE HWIG..HANGUL SYLLABLE HWIH
+ {0xD734, 0xD734, prH2, gcLo}, // HANGUL SYLLABLE HYU
+ {0xD735, 0xD74F, prH3, gcLo}, // [27] HANGUL SYLLABLE HYUG..HANGUL SYLLABLE HYUH
+ {0xD750, 0xD750, prH2, gcLo}, // HANGUL SYLLABLE HEU
+ {0xD751, 0xD76B, prH3, gcLo}, // [27] HANGUL SYLLABLE HEUG..HANGUL SYLLABLE HEUH
+ {0xD76C, 0xD76C, prH2, gcLo}, // HANGUL SYLLABLE HYI
+ {0xD76D, 0xD787, prH3, gcLo}, // [27] HANGUL SYLLABLE HYIG..HANGUL SYLLABLE HYIH
+ {0xD788, 0xD788, prH2, gcLo}, // HANGUL SYLLABLE HI
+ {0xD789, 0xD7A3, prH3, gcLo}, // [27] HANGUL SYLLABLE HIG..HANGUL SYLLABLE HIH
+ {0xD7B0, 0xD7C6, prJV, gcLo}, // [23] HANGUL JUNGSEONG O-YEO..HANGUL JUNGSEONG ARAEA-E
+ {0xD7CB, 0xD7FB, prJT, gcLo}, // [49] HANGUL JONGSEONG NIEUN-RIEUL..HANGUL JONGSEONG PHIEUPH-THIEUTH
+ {0xD800, 0xDB7F, prSG, gcCs}, // [896] ..
+ {0xDB80, 0xDBFF, prSG, gcCs}, // [128] ..
+ {0xDC00, 0xDFFF, prSG, gcCs}, // [1024] ..
+ {0xE000, 0xF8FF, prXX, gcCo}, // [6400] ..
+ {0xF900, 0xFA6D, prID, gcLo}, // [366] CJK COMPATIBILITY IDEOGRAPH-F900..CJK COMPATIBILITY IDEOGRAPH-FA6D
+ {0xFA6E, 0xFA6F, prID, gcCn}, // [2] ..
+ {0xFA70, 0xFAD9, prID, gcLo}, // [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COMPATIBILITY IDEOGRAPH-FAD9
+ {0xFADA, 0xFAFF, prID, gcCn}, // [38] ..
+ {0xFB00, 0xFB06, prAL, gcLl}, // [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST
+ {0xFB13, 0xFB17, prAL, gcLl}, // [5] ARMENIAN SMALL LIGATURE MEN NOW..ARMENIAN SMALL LIGATURE MEN XEH
+ {0xFB1D, 0xFB1D, prHL, gcLo}, // HEBREW LETTER YOD WITH HIRIQ
+ {0xFB1E, 0xFB1E, prCM, gcMn}, // HEBREW POINT JUDEO-SPANISH VARIKA
+ {0xFB1F, 0xFB28, prHL, gcLo}, // [10] HEBREW LIGATURE YIDDISH YOD YOD PATAH..HEBREW LETTER WIDE TAV
+ {0xFB29, 0xFB29, prAL, gcSm}, // HEBREW LETTER ALTERNATIVE PLUS SIGN
+ {0xFB2A, 0xFB36, prHL, gcLo}, // [13] HEBREW LETTER SHIN WITH SHIN DOT..HEBREW LETTER ZAYIN WITH DAGESH
+ {0xFB38, 0xFB3C, prHL, gcLo}, // [5] HEBREW LETTER TET WITH DAGESH..HEBREW LETTER LAMED WITH DAGESH
+ {0xFB3E, 0xFB3E, prHL, gcLo}, // HEBREW LETTER MEM WITH DAGESH
+ {0xFB40, 0xFB41, prHL, gcLo}, // [2] HEBREW LETTER NUN WITH DAGESH..HEBREW LETTER SAMEKH WITH DAGESH
+ {0xFB43, 0xFB44, prHL, gcLo}, // [2] HEBREW LETTER FINAL PE WITH DAGESH..HEBREW LETTER PE WITH DAGESH
+ {0xFB46, 0xFB4F, prHL, gcLo}, // [10] HEBREW LETTER TSADI WITH DAGESH..HEBREW LIGATURE ALEF LAMED
+ {0xFB50, 0xFBB1, prAL, gcLo}, // [98] ARABIC LETTER ALEF WASLA ISOLATED FORM..ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM
+ {0xFBB2, 0xFBC2, prAL, gcSk}, // [17] ARABIC SYMBOL DOT ABOVE..ARABIC SYMBOL WASLA ABOVE
+ {0xFBD3, 0xFD3D, prAL, gcLo}, // [363] ARABIC LETTER NG ISOLATED FORM..ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM
+ {0xFD3E, 0xFD3E, prCL, gcPe}, // ORNATE LEFT PARENTHESIS
+ {0xFD3F, 0xFD3F, prOP, gcPs}, // ORNATE RIGHT PARENTHESIS
+ {0xFD40, 0xFD4F, prAL, gcSo}, // [16] ARABIC LIGATURE RAHIMAHU ALLAAH..ARABIC LIGATURE RAHIMAHUM ALLAAH
+ {0xFD50, 0xFD8F, prAL, gcLo}, // [64] ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM..ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM
+ {0xFD92, 0xFDC7, prAL, gcLo}, // [54] ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM..ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM
+ {0xFDCF, 0xFDCF, prAL, gcSo}, // ARABIC LIGATURE SALAAMUHU ALAYNAA
+ {0xFDF0, 0xFDFB, prAL, gcLo}, // [12] ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM..ARABIC LIGATURE JALLAJALALOUHOU
+ {0xFDFC, 0xFDFC, prPO, gcSc}, // RIAL SIGN
+ {0xFDFD, 0xFDFF, prAL, gcSo}, // [3] ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM..ARABIC LIGATURE AZZA WA JALL
+ {0xFE00, 0xFE0F, prCM, gcMn}, // [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16
+ {0xFE10, 0xFE10, prIS, gcPo}, // PRESENTATION FORM FOR VERTICAL COMMA
+ {0xFE11, 0xFE12, prCL, gcPo}, // [2] PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC COMMA..PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC FULL STOP
+ {0xFE13, 0xFE14, prIS, gcPo}, // [2] PRESENTATION FORM FOR VERTICAL COLON..PRESENTATION FORM FOR VERTICAL SEMICOLON
+ {0xFE15, 0xFE16, prEX, gcPo}, // [2] PRESENTATION FORM FOR VERTICAL EXCLAMATION MARK..PRESENTATION FORM FOR VERTICAL QUESTION MARK
+ {0xFE17, 0xFE17, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET
+ {0xFE18, 0xFE18, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET
+ {0xFE19, 0xFE19, prIN, gcPo}, // PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS
+ {0xFE20, 0xFE2F, prCM, gcMn}, // [16] COMBINING LIGATURE LEFT HALF..COMBINING CYRILLIC TITLO RIGHT HALF
+ {0xFE30, 0xFE30, prID, gcPo}, // PRESENTATION FORM FOR VERTICAL TWO DOT LEADER
+ {0xFE31, 0xFE32, prID, gcPd}, // [2] PRESENTATION FORM FOR VERTICAL EM DASH..PRESENTATION FORM FOR VERTICAL EN DASH
+ {0xFE33, 0xFE34, prID, gcPc}, // [2] PRESENTATION FORM FOR VERTICAL LOW LINE..PRESENTATION FORM FOR VERTICAL WAVY LOW LINE
+ {0xFE35, 0xFE35, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS
+ {0xFE36, 0xFE36, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS
+ {0xFE37, 0xFE37, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET
+ {0xFE38, 0xFE38, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET
+ {0xFE39, 0xFE39, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET
+ {0xFE3A, 0xFE3A, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET
+ {0xFE3B, 0xFE3B, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET
+ {0xFE3C, 0xFE3C, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET
+ {0xFE3D, 0xFE3D, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET
+ {0xFE3E, 0xFE3E, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET
+ {0xFE3F, 0xFE3F, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET
+ {0xFE40, 0xFE40, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET
+ {0xFE41, 0xFE41, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET
+ {0xFE42, 0xFE42, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET
+ {0xFE43, 0xFE43, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET
+ {0xFE44, 0xFE44, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET
+ {0xFE45, 0xFE46, prID, gcPo}, // [2] SESAME DOT..WHITE SESAME DOT
+ {0xFE47, 0xFE47, prOP, gcPs}, // PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET
+ {0xFE48, 0xFE48, prCL, gcPe}, // PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET
+ {0xFE49, 0xFE4C, prID, gcPo}, // [4] DASHED OVERLINE..DOUBLE WAVY OVERLINE
+ {0xFE4D, 0xFE4F, prID, gcPc}, // [3] DASHED LOW LINE..WAVY LOW LINE
+ {0xFE50, 0xFE50, prCL, gcPo}, // SMALL COMMA
+ {0xFE51, 0xFE51, prID, gcPo}, // SMALL IDEOGRAPHIC COMMA
+ {0xFE52, 0xFE52, prCL, gcPo}, // SMALL FULL STOP
+ {0xFE54, 0xFE55, prNS, gcPo}, // [2] SMALL SEMICOLON..SMALL COLON
+ {0xFE56, 0xFE57, prEX, gcPo}, // [2] SMALL QUESTION MARK..SMALL EXCLAMATION MARK
+ {0xFE58, 0xFE58, prID, gcPd}, // SMALL EM DASH
+ {0xFE59, 0xFE59, prOP, gcPs}, // SMALL LEFT PARENTHESIS
+ {0xFE5A, 0xFE5A, prCL, gcPe}, // SMALL RIGHT PARENTHESIS
+ {0xFE5B, 0xFE5B, prOP, gcPs}, // SMALL LEFT CURLY BRACKET
+ {0xFE5C, 0xFE5C, prCL, gcPe}, // SMALL RIGHT CURLY BRACKET
+ {0xFE5D, 0xFE5D, prOP, gcPs}, // SMALL LEFT TORTOISE SHELL BRACKET
+ {0xFE5E, 0xFE5E, prCL, gcPe}, // SMALL RIGHT TORTOISE SHELL BRACKET
+ {0xFE5F, 0xFE61, prID, gcPo}, // [3] SMALL NUMBER SIGN..SMALL ASTERISK
+ {0xFE62, 0xFE62, prID, gcSm}, // SMALL PLUS SIGN
+ {0xFE63, 0xFE63, prID, gcPd}, // SMALL HYPHEN-MINUS
+ {0xFE64, 0xFE66, prID, gcSm}, // [3] SMALL LESS-THAN SIGN..SMALL EQUALS SIGN
+ {0xFE68, 0xFE68, prID, gcPo}, // SMALL REVERSE SOLIDUS
+ {0xFE69, 0xFE69, prPR, gcSc}, // SMALL DOLLAR SIGN
+ {0xFE6A, 0xFE6A, prPO, gcPo}, // SMALL PERCENT SIGN
+ {0xFE6B, 0xFE6B, prID, gcPo}, // SMALL COMMERCIAL AT
+ {0xFE70, 0xFE74, prAL, gcLo}, // [5] ARABIC FATHATAN ISOLATED FORM..ARABIC KASRATAN ISOLATED FORM
+ {0xFE76, 0xFEFC, prAL, gcLo}, // [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LAM WITH ALEF FINAL FORM
+ {0xFEFF, 0xFEFF, prWJ, gcCf}, // ZERO WIDTH NO-BREAK SPACE
+ {0xFF01, 0xFF01, prEX, gcPo}, // FULLWIDTH EXCLAMATION MARK
+ {0xFF02, 0xFF03, prID, gcPo}, // [2] FULLWIDTH QUOTATION MARK..FULLWIDTH NUMBER SIGN
+ {0xFF04, 0xFF04, prPR, gcSc}, // FULLWIDTH DOLLAR SIGN
+ {0xFF05, 0xFF05, prPO, gcPo}, // FULLWIDTH PERCENT SIGN
+ {0xFF06, 0xFF07, prID, gcPo}, // [2] FULLWIDTH AMPERSAND..FULLWIDTH APOSTROPHE
+ {0xFF08, 0xFF08, prOP, gcPs}, // FULLWIDTH LEFT PARENTHESIS
+ {0xFF09, 0xFF09, prCL, gcPe}, // FULLWIDTH RIGHT PARENTHESIS
+ {0xFF0A, 0xFF0A, prID, gcPo}, // FULLWIDTH ASTERISK
+ {0xFF0B, 0xFF0B, prID, gcSm}, // FULLWIDTH PLUS SIGN
+ {0xFF0C, 0xFF0C, prCL, gcPo}, // FULLWIDTH COMMA
+ {0xFF0D, 0xFF0D, prID, gcPd}, // FULLWIDTH HYPHEN-MINUS
+ {0xFF0E, 0xFF0E, prCL, gcPo}, // FULLWIDTH FULL STOP
+ {0xFF0F, 0xFF0F, prID, gcPo}, // FULLWIDTH SOLIDUS
+ {0xFF10, 0xFF19, prID, gcNd}, // [10] FULLWIDTH DIGIT ZERO..FULLWIDTH DIGIT NINE
+ {0xFF1A, 0xFF1B, prNS, gcPo}, // [2] FULLWIDTH COLON..FULLWIDTH SEMICOLON
+ {0xFF1C, 0xFF1E, prID, gcSm}, // [3] FULLWIDTH LESS-THAN SIGN..FULLWIDTH GREATER-THAN SIGN
+ {0xFF1F, 0xFF1F, prEX, gcPo}, // FULLWIDTH QUESTION MARK
+ {0xFF20, 0xFF20, prID, gcPo}, // FULLWIDTH COMMERCIAL AT
+ {0xFF21, 0xFF3A, prID, gcLu}, // [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z
+ {0xFF3B, 0xFF3B, prOP, gcPs}, // FULLWIDTH LEFT SQUARE BRACKET
+ {0xFF3C, 0xFF3C, prID, gcPo}, // FULLWIDTH REVERSE SOLIDUS
+ {0xFF3D, 0xFF3D, prCL, gcPe}, // FULLWIDTH RIGHT SQUARE BRACKET
+ {0xFF3E, 0xFF3E, prID, gcSk}, // FULLWIDTH CIRCUMFLEX ACCENT
+ {0xFF3F, 0xFF3F, prID, gcPc}, // FULLWIDTH LOW LINE
+ {0xFF40, 0xFF40, prID, gcSk}, // FULLWIDTH GRAVE ACCENT
+ {0xFF41, 0xFF5A, prID, gcLl}, // [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN SMALL LETTER Z
+ {0xFF5B, 0xFF5B, prOP, gcPs}, // FULLWIDTH LEFT CURLY BRACKET
+ {0xFF5C, 0xFF5C, prID, gcSm}, // FULLWIDTH VERTICAL LINE
+ {0xFF5D, 0xFF5D, prCL, gcPe}, // FULLWIDTH RIGHT CURLY BRACKET
+ {0xFF5E, 0xFF5E, prID, gcSm}, // FULLWIDTH TILDE
+ {0xFF5F, 0xFF5F, prOP, gcPs}, // FULLWIDTH LEFT WHITE PARENTHESIS
+ {0xFF60, 0xFF60, prCL, gcPe}, // FULLWIDTH RIGHT WHITE PARENTHESIS
+ {0xFF61, 0xFF61, prCL, gcPo}, // HALFWIDTH IDEOGRAPHIC FULL STOP
+ {0xFF62, 0xFF62, prOP, gcPs}, // HALFWIDTH LEFT CORNER BRACKET
+ {0xFF63, 0xFF63, prCL, gcPe}, // HALFWIDTH RIGHT CORNER BRACKET
+ {0xFF64, 0xFF64, prCL, gcPo}, // HALFWIDTH IDEOGRAPHIC COMMA
+ {0xFF65, 0xFF65, prNS, gcPo}, // HALFWIDTH KATAKANA MIDDLE DOT
+ {0xFF66, 0xFF66, prID, gcLo}, // HALFWIDTH KATAKANA LETTER WO
+ {0xFF67, 0xFF6F, prCJ, gcLo}, // [9] HALFWIDTH KATAKANA LETTER SMALL A..HALFWIDTH KATAKANA LETTER SMALL TU
+ {0xFF70, 0xFF70, prCJ, gcLm}, // HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
+ {0xFF71, 0xFF9D, prID, gcLo}, // [45] HALFWIDTH KATAKANA LETTER A..HALFWIDTH KATAKANA LETTER N
+ {0xFF9E, 0xFF9F, prNS, gcLm}, // [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
+ {0xFFA0, 0xFFBE, prID, gcLo}, // [31] HALFWIDTH HANGUL FILLER..HALFWIDTH HANGUL LETTER HIEUH
+ {0xFFC2, 0xFFC7, prID, gcLo}, // [6] HALFWIDTH HANGUL LETTER A..HALFWIDTH HANGUL LETTER E
+ {0xFFCA, 0xFFCF, prID, gcLo}, // [6] HALFWIDTH HANGUL LETTER YEO..HALFWIDTH HANGUL LETTER OE
+ {0xFFD2, 0xFFD7, prID, gcLo}, // [6] HALFWIDTH HANGUL LETTER YO..HALFWIDTH HANGUL LETTER YU
+ {0xFFDA, 0xFFDC, prID, gcLo}, // [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL LETTER I
+ {0xFFE0, 0xFFE0, prPO, gcSc}, // FULLWIDTH CENT SIGN
+ {0xFFE1, 0xFFE1, prPR, gcSc}, // FULLWIDTH POUND SIGN
+ {0xFFE2, 0xFFE2, prID, gcSm}, // FULLWIDTH NOT SIGN
+ {0xFFE3, 0xFFE3, prID, gcSk}, // FULLWIDTH MACRON
+ {0xFFE4, 0xFFE4, prID, gcSo}, // FULLWIDTH BROKEN BAR
+ {0xFFE5, 0xFFE6, prPR, gcSc}, // [2] FULLWIDTH YEN SIGN..FULLWIDTH WON SIGN
+ {0xFFE8, 0xFFE8, prAL, gcSo}, // HALFWIDTH FORMS LIGHT VERTICAL
+ {0xFFE9, 0xFFEC, prAL, gcSm}, // [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS ARROW
+ {0xFFED, 0xFFEE, prAL, gcSo}, // [2] HALFWIDTH BLACK SQUARE..HALFWIDTH WHITE CIRCLE
+ {0xFFF9, 0xFFFB, prCM, gcCf}, // [3] INTERLINEAR ANNOTATION ANCHOR..INTERLINEAR ANNOTATION TERMINATOR
+ {0xFFFC, 0xFFFC, prCB, gcSo}, // OBJECT REPLACEMENT CHARACTER
+ {0xFFFD, 0xFFFD, prAI, gcSo}, // REPLACEMENT CHARACTER
+ {0x10000, 0x1000B, prAL, gcLo}, // [12] LINEAR B SYLLABLE B008 A..LINEAR B SYLLABLE B046 JE
+ {0x1000D, 0x10026, prAL, gcLo}, // [26] LINEAR B SYLLABLE B036 JO..LINEAR B SYLLABLE B032 QO
+ {0x10028, 0x1003A, prAL, gcLo}, // [19] LINEAR B SYLLABLE B060 RA..LINEAR B SYLLABLE B042 WO
+ {0x1003C, 0x1003D, prAL, gcLo}, // [2] LINEAR B SYLLABLE B017 ZA..LINEAR B SYLLABLE B074 ZE
+ {0x1003F, 0x1004D, prAL, gcLo}, // [15] LINEAR B SYLLABLE B020 ZO..LINEAR B SYLLABLE B091 TWO
+ {0x10050, 0x1005D, prAL, gcLo}, // [14] LINEAR B SYMBOL B018..LINEAR B SYMBOL B089
+ {0x10080, 0x100FA, prAL, gcLo}, // [123] LINEAR B IDEOGRAM B100 MAN..LINEAR B IDEOGRAM VESSEL B305
+ {0x10100, 0x10102, prBA, gcPo}, // [3] AEGEAN WORD SEPARATOR LINE..AEGEAN CHECK MARK
+ {0x10107, 0x10133, prAL, gcNo}, // [45] AEGEAN NUMBER ONE..AEGEAN NUMBER NINETY THOUSAND
+ {0x10137, 0x1013F, prAL, gcSo}, // [9] AEGEAN WEIGHT BASE UNIT..AEGEAN MEASURE THIRD SUBUNIT
+ {0x10140, 0x10174, prAL, gcNl}, // [53] GREEK ACROPHONIC ATTIC ONE QUARTER..GREEK ACROPHONIC STRATIAN FIFTY MNAS
+ {0x10175, 0x10178, prAL, gcNo}, // [4] GREEK ONE HALF SIGN..GREEK THREE QUARTERS SIGN
+ {0x10179, 0x10189, prAL, gcSo}, // [17] GREEK YEAR SIGN..GREEK TRYBLION BASE SIGN
+ {0x1018A, 0x1018B, prAL, gcNo}, // [2] GREEK ZERO SIGN..GREEK ONE QUARTER SIGN
+ {0x1018C, 0x1018E, prAL, gcSo}, // [3] GREEK SINUSOID SIGN..NOMISMA SIGN
+ {0x10190, 0x1019C, prAL, gcSo}, // [13] ROMAN SEXTANS SIGN..ASCIA SYMBOL
+ {0x101A0, 0x101A0, prAL, gcSo}, // GREEK SYMBOL TAU RHO
+ {0x101D0, 0x101FC, prAL, gcSo}, // [45] PHAISTOS DISC SIGN PEDESTRIAN..PHAISTOS DISC SIGN WAVY BAND
+ {0x101FD, 0x101FD, prCM, gcMn}, // PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE
+ {0x10280, 0x1029C, prAL, gcLo}, // [29] LYCIAN LETTER A..LYCIAN LETTER X
+ {0x102A0, 0x102D0, prAL, gcLo}, // [49] CARIAN LETTER A..CARIAN LETTER UUU3
+ {0x102E0, 0x102E0, prCM, gcMn}, // COPTIC EPACT THOUSANDS MARK
+ {0x102E1, 0x102FB, prAL, gcNo}, // [27] COPTIC EPACT DIGIT ONE..COPTIC EPACT NUMBER NINE HUNDRED
+ {0x10300, 0x1031F, prAL, gcLo}, // [32] OLD ITALIC LETTER A..OLD ITALIC LETTER ESS
+ {0x10320, 0x10323, prAL, gcNo}, // [4] OLD ITALIC NUMERAL ONE..OLD ITALIC NUMERAL FIFTY
+ {0x1032D, 0x1032F, prAL, gcLo}, // [3] OLD ITALIC LETTER YE..OLD ITALIC LETTER SOUTHERN TSE
+ {0x10330, 0x10340, prAL, gcLo}, // [17] GOTHIC LETTER AHSA..GOTHIC LETTER PAIRTHRA
+ {0x10341, 0x10341, prAL, gcNl}, // GOTHIC LETTER NINETY
+ {0x10342, 0x10349, prAL, gcLo}, // [8] GOTHIC LETTER RAIDA..GOTHIC LETTER OTHAL
+ {0x1034A, 0x1034A, prAL, gcNl}, // GOTHIC LETTER NINE HUNDRED
+ {0x10350, 0x10375, prAL, gcLo}, // [38] OLD PERMIC LETTER AN..OLD PERMIC LETTER IA
+ {0x10376, 0x1037A, prCM, gcMn}, // [5] COMBINING OLD PERMIC LETTER AN..COMBINING OLD PERMIC LETTER SII
+ {0x10380, 0x1039D, prAL, gcLo}, // [30] UGARITIC LETTER ALPA..UGARITIC LETTER SSU
+ {0x1039F, 0x1039F, prBA, gcPo}, // UGARITIC WORD DIVIDER
+ {0x103A0, 0x103C3, prAL, gcLo}, // [36] OLD PERSIAN SIGN A..OLD PERSIAN SIGN HA
+ {0x103C8, 0x103CF, prAL, gcLo}, // [8] OLD PERSIAN SIGN AURAMAZDAA..OLD PERSIAN SIGN BUUMISH
+ {0x103D0, 0x103D0, prBA, gcPo}, // OLD PERSIAN WORD DIVIDER
+ {0x103D1, 0x103D5, prAL, gcNl}, // [5] OLD PERSIAN NUMBER ONE..OLD PERSIAN NUMBER HUNDRED
+ {0x10400, 0x1044F, prAL, gcLC}, // [80] DESERET CAPITAL LETTER LONG I..DESERET SMALL LETTER EW
+ {0x10450, 0x1047F, prAL, gcLo}, // [48] SHAVIAN LETTER PEEP..SHAVIAN LETTER YEW
+ {0x10480, 0x1049D, prAL, gcLo}, // [30] OSMANYA LETTER ALEF..OSMANYA LETTER OO
+ {0x104A0, 0x104A9, prNU, gcNd}, // [10] OSMANYA DIGIT ZERO..OSMANYA DIGIT NINE
+ {0x104B0, 0x104D3, prAL, gcLu}, // [36] OSAGE CAPITAL LETTER A..OSAGE CAPITAL LETTER ZHA
+ {0x104D8, 0x104FB, prAL, gcLl}, // [36] OSAGE SMALL LETTER A..OSAGE SMALL LETTER ZHA
+ {0x10500, 0x10527, prAL, gcLo}, // [40] ELBASAN LETTER A..ELBASAN LETTER KHE
+ {0x10530, 0x10563, prAL, gcLo}, // [52] CAUCASIAN ALBANIAN LETTER ALT..CAUCASIAN ALBANIAN LETTER KIW
+ {0x1056F, 0x1056F, prAL, gcPo}, // CAUCASIAN ALBANIAN CITATION MARK
+ {0x10570, 0x1057A, prAL, gcLu}, // [11] VITHKUQI CAPITAL LETTER A..VITHKUQI CAPITAL LETTER GA
+ {0x1057C, 0x1058A, prAL, gcLu}, // [15] VITHKUQI CAPITAL LETTER HA..VITHKUQI CAPITAL LETTER RE
+ {0x1058C, 0x10592, prAL, gcLu}, // [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE
+ {0x10594, 0x10595, prAL, gcLu}, // [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE
+ {0x10597, 0x105A1, prAL, gcLl}, // [11] VITHKUQI SMALL LETTER A..VITHKUQI SMALL LETTER GA
+ {0x105A3, 0x105B1, prAL, gcLl}, // [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE
+ {0x105B3, 0x105B9, prAL, gcLl}, // [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE
+ {0x105BB, 0x105BC, prAL, gcLl}, // [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE
+ {0x10600, 0x10736, prAL, gcLo}, // [311] LINEAR A SIGN AB001..LINEAR A SIGN A664
+ {0x10740, 0x10755, prAL, gcLo}, // [22] LINEAR A SIGN A701 A..LINEAR A SIGN A732 JE
+ {0x10760, 0x10767, prAL, gcLo}, // [8] LINEAR A SIGN A800..LINEAR A SIGN A807
+ {0x10780, 0x10785, prAL, gcLm}, // [6] MODIFIER LETTER SMALL CAPITAL AA..MODIFIER LETTER SMALL B WITH HOOK
+ {0x10787, 0x107B0, prAL, gcLm}, // [42] MODIFIER LETTER SMALL DZ DIGRAPH..MODIFIER LETTER SMALL V WITH RIGHT HOOK
+ {0x107B2, 0x107BA, prAL, gcLm}, // [9] MODIFIER LETTER SMALL CAPITAL Y..MODIFIER LETTER SMALL S WITH CURL
+ {0x10800, 0x10805, prAL, gcLo}, // [6] CYPRIOT SYLLABLE A..CYPRIOT SYLLABLE JA
+ {0x10808, 0x10808, prAL, gcLo}, // CYPRIOT SYLLABLE JO
+ {0x1080A, 0x10835, prAL, gcLo}, // [44] CYPRIOT SYLLABLE KA..CYPRIOT SYLLABLE WO
+ {0x10837, 0x10838, prAL, gcLo}, // [2] CYPRIOT SYLLABLE XA..CYPRIOT SYLLABLE XE
+ {0x1083C, 0x1083C, prAL, gcLo}, // CYPRIOT SYLLABLE ZA
+ {0x1083F, 0x1083F, prAL, gcLo}, // CYPRIOT SYLLABLE ZO
+ {0x10840, 0x10855, prAL, gcLo}, // [22] IMPERIAL ARAMAIC LETTER ALEPH..IMPERIAL ARAMAIC LETTER TAW
+ {0x10857, 0x10857, prBA, gcPo}, // IMPERIAL ARAMAIC SECTION SIGN
+ {0x10858, 0x1085F, prAL, gcNo}, // [8] IMPERIAL ARAMAIC NUMBER ONE..IMPERIAL ARAMAIC NUMBER TEN THOUSAND
+ {0x10860, 0x10876, prAL, gcLo}, // [23] PALMYRENE LETTER ALEPH..PALMYRENE LETTER TAW
+ {0x10877, 0x10878, prAL, gcSo}, // [2] PALMYRENE LEFT-POINTING FLEURON..PALMYRENE RIGHT-POINTING FLEURON
+ {0x10879, 0x1087F, prAL, gcNo}, // [7] PALMYRENE NUMBER ONE..PALMYRENE NUMBER TWENTY
+ {0x10880, 0x1089E, prAL, gcLo}, // [31] NABATAEAN LETTER FINAL ALEPH..NABATAEAN LETTER TAW
+ {0x108A7, 0x108AF, prAL, gcNo}, // [9] NABATAEAN NUMBER ONE..NABATAEAN NUMBER ONE HUNDRED
+ {0x108E0, 0x108F2, prAL, gcLo}, // [19] HATRAN LETTER ALEPH..HATRAN LETTER QOPH
+ {0x108F4, 0x108F5, prAL, gcLo}, // [2] HATRAN LETTER SHIN..HATRAN LETTER TAW
+ {0x108FB, 0x108FF, prAL, gcNo}, // [5] HATRAN NUMBER ONE..HATRAN NUMBER ONE HUNDRED
+ {0x10900, 0x10915, prAL, gcLo}, // [22] PHOENICIAN LETTER ALF..PHOENICIAN LETTER TAU
+ {0x10916, 0x1091B, prAL, gcNo}, // [6] PHOENICIAN NUMBER ONE..PHOENICIAN NUMBER THREE
+ {0x1091F, 0x1091F, prBA, gcPo}, // PHOENICIAN WORD SEPARATOR
+ {0x10920, 0x10939, prAL, gcLo}, // [26] LYDIAN LETTER A..LYDIAN LETTER C
+ {0x1093F, 0x1093F, prAL, gcPo}, // LYDIAN TRIANGULAR MARK
+ {0x10980, 0x1099F, prAL, gcLo}, // [32] MEROITIC HIEROGLYPHIC LETTER A..MEROITIC HIEROGLYPHIC SYMBOL VIDJ-2
+ {0x109A0, 0x109B7, prAL, gcLo}, // [24] MEROITIC CURSIVE LETTER A..MEROITIC CURSIVE LETTER DA
+ {0x109BC, 0x109BD, prAL, gcNo}, // [2] MEROITIC CURSIVE FRACTION ELEVEN TWELFTHS..MEROITIC CURSIVE FRACTION ONE HALF
+ {0x109BE, 0x109BF, prAL, gcLo}, // [2] MEROITIC CURSIVE LOGOGRAM RMT..MEROITIC CURSIVE LOGOGRAM IMN
+ {0x109C0, 0x109CF, prAL, gcNo}, // [16] MEROITIC CURSIVE NUMBER ONE..MEROITIC CURSIVE NUMBER SEVENTY
+ {0x109D2, 0x109FF, prAL, gcNo}, // [46] MEROITIC CURSIVE NUMBER ONE HUNDRED..MEROITIC CURSIVE FRACTION TEN TWELFTHS
+ {0x10A00, 0x10A00, prAL, gcLo}, // KHAROSHTHI LETTER A
+ {0x10A01, 0x10A03, prCM, gcMn}, // [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R
+ {0x10A05, 0x10A06, prCM, gcMn}, // [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O
+ {0x10A0C, 0x10A0F, prCM, gcMn}, // [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA
+ {0x10A10, 0x10A13, prAL, gcLo}, // [4] KHAROSHTHI LETTER KA..KHAROSHTHI LETTER GHA
+ {0x10A15, 0x10A17, prAL, gcLo}, // [3] KHAROSHTHI LETTER CA..KHAROSHTHI LETTER JA
+ {0x10A19, 0x10A35, prAL, gcLo}, // [29] KHAROSHTHI LETTER NYA..KHAROSHTHI LETTER VHA
+ {0x10A38, 0x10A3A, prCM, gcMn}, // [3] KHAROSHTHI SIGN BAR ABOVE..KHAROSHTHI SIGN DOT BELOW
+ {0x10A3F, 0x10A3F, prCM, gcMn}, // KHAROSHTHI VIRAMA
+ {0x10A40, 0x10A48, prAL, gcNo}, // [9] KHAROSHTHI DIGIT ONE..KHAROSHTHI FRACTION ONE HALF
+ {0x10A50, 0x10A57, prBA, gcPo}, // [8] KHAROSHTHI PUNCTUATION DOT..KHAROSHTHI PUNCTUATION DOUBLE DANDA
+ {0x10A58, 0x10A58, prAL, gcPo}, // KHAROSHTHI PUNCTUATION LINES
+ {0x10A60, 0x10A7C, prAL, gcLo}, // [29] OLD SOUTH ARABIAN LETTER HE..OLD SOUTH ARABIAN LETTER THETH
+ {0x10A7D, 0x10A7E, prAL, gcNo}, // [2] OLD SOUTH ARABIAN NUMBER ONE..OLD SOUTH ARABIAN NUMBER FIFTY
+ {0x10A7F, 0x10A7F, prAL, gcPo}, // OLD SOUTH ARABIAN NUMERIC INDICATOR
+ {0x10A80, 0x10A9C, prAL, gcLo}, // [29] OLD NORTH ARABIAN LETTER HEH..OLD NORTH ARABIAN LETTER ZAH
+ {0x10A9D, 0x10A9F, prAL, gcNo}, // [3] OLD NORTH ARABIAN NUMBER ONE..OLD NORTH ARABIAN NUMBER TWENTY
+ {0x10AC0, 0x10AC7, prAL, gcLo}, // [8] MANICHAEAN LETTER ALEPH..MANICHAEAN LETTER WAW
+ {0x10AC8, 0x10AC8, prAL, gcSo}, // MANICHAEAN SIGN UD
+ {0x10AC9, 0x10AE4, prAL, gcLo}, // [28] MANICHAEAN LETTER ZAYIN..MANICHAEAN LETTER TAW
+ {0x10AE5, 0x10AE6, prCM, gcMn}, // [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW
+ {0x10AEB, 0x10AEF, prAL, gcNo}, // [5] MANICHAEAN NUMBER ONE..MANICHAEAN NUMBER ONE HUNDRED
+ {0x10AF0, 0x10AF5, prBA, gcPo}, // [6] MANICHAEAN PUNCTUATION STAR..MANICHAEAN PUNCTUATION TWO DOTS
+ {0x10AF6, 0x10AF6, prIN, gcPo}, // MANICHAEAN PUNCTUATION LINE FILLER
+ {0x10B00, 0x10B35, prAL, gcLo}, // [54] AVESTAN LETTER A..AVESTAN LETTER HE
+ {0x10B39, 0x10B3F, prBA, gcPo}, // [7] AVESTAN ABBREVIATION MARK..LARGE ONE RING OVER TWO RINGS PUNCTUATION
+ {0x10B40, 0x10B55, prAL, gcLo}, // [22] INSCRIPTIONAL PARTHIAN LETTER ALEPH..INSCRIPTIONAL PARTHIAN LETTER TAW
+ {0x10B58, 0x10B5F, prAL, gcNo}, // [8] INSCRIPTIONAL PARTHIAN NUMBER ONE..INSCRIPTIONAL PARTHIAN NUMBER ONE THOUSAND
+ {0x10B60, 0x10B72, prAL, gcLo}, // [19] INSCRIPTIONAL PAHLAVI LETTER ALEPH..INSCRIPTIONAL PAHLAVI LETTER TAW
+ {0x10B78, 0x10B7F, prAL, gcNo}, // [8] INSCRIPTIONAL PAHLAVI NUMBER ONE..INSCRIPTIONAL PAHLAVI NUMBER ONE THOUSAND
+ {0x10B80, 0x10B91, prAL, gcLo}, // [18] PSALTER PAHLAVI LETTER ALEPH..PSALTER PAHLAVI LETTER TAW
+ {0x10B99, 0x10B9C, prAL, gcPo}, // [4] PSALTER PAHLAVI SECTION MARK..PSALTER PAHLAVI FOUR DOTS WITH DOT
+ {0x10BA9, 0x10BAF, prAL, gcNo}, // [7] PSALTER PAHLAVI NUMBER ONE..PSALTER PAHLAVI NUMBER ONE HUNDRED
+ {0x10C00, 0x10C48, prAL, gcLo}, // [73] OLD TURKIC LETTER ORKHON A..OLD TURKIC LETTER ORKHON BASH
+ {0x10C80, 0x10CB2, prAL, gcLu}, // [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US
+ {0x10CC0, 0x10CF2, prAL, gcLl}, // [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US
+ {0x10CFA, 0x10CFF, prAL, gcNo}, // [6] OLD HUNGARIAN NUMBER ONE..OLD HUNGARIAN NUMBER ONE THOUSAND
+ {0x10D00, 0x10D23, prAL, gcLo}, // [36] HANIFI ROHINGYA LETTER A..HANIFI ROHINGYA MARK NA KHONNA
+ {0x10D24, 0x10D27, prCM, gcMn}, // [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI
+ {0x10D30, 0x10D39, prNU, gcNd}, // [10] HANIFI ROHINGYA DIGIT ZERO..HANIFI ROHINGYA DIGIT NINE
+ {0x10E60, 0x10E7E, prAL, gcNo}, // [31] RUMI DIGIT ONE..RUMI FRACTION TWO THIRDS
+ {0x10E80, 0x10EA9, prAL, gcLo}, // [42] YEZIDI LETTER ELIF..YEZIDI LETTER ET
+ {0x10EAB, 0x10EAC, prCM, gcMn}, // [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK
+ {0x10EAD, 0x10EAD, prBA, gcPd}, // YEZIDI HYPHENATION MARK
+ {0x10EB0, 0x10EB1, prAL, gcLo}, // [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE
+ {0x10EFD, 0x10EFF, prCM, gcMn}, // [3] ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA
+ {0x10F00, 0x10F1C, prAL, gcLo}, // [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL
+ {0x10F1D, 0x10F26, prAL, gcNo}, // [10] OLD SOGDIAN NUMBER ONE..OLD SOGDIAN FRACTION ONE HALF
+ {0x10F27, 0x10F27, prAL, gcLo}, // OLD SOGDIAN LIGATURE AYIN-DALETH
+ {0x10F30, 0x10F45, prAL, gcLo}, // [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN
+ {0x10F46, 0x10F50, prCM, gcMn}, // [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW
+ {0x10F51, 0x10F54, prAL, gcNo}, // [4] SOGDIAN NUMBER ONE..SOGDIAN NUMBER ONE HUNDRED
+ {0x10F55, 0x10F59, prAL, gcPo}, // [5] SOGDIAN PUNCTUATION TWO VERTICAL BARS..SOGDIAN PUNCTUATION HALF CIRCLE WITH DOT
+ {0x10F70, 0x10F81, prAL, gcLo}, // [18] OLD UYGHUR LETTER ALEPH..OLD UYGHUR LETTER LESH
+ {0x10F82, 0x10F85, prCM, gcMn}, // [4] OLD UYGHUR COMBINING DOT ABOVE..OLD UYGHUR COMBINING TWO DOTS BELOW
+ {0x10F86, 0x10F89, prAL, gcPo}, // [4] OLD UYGHUR PUNCTUATION BAR..OLD UYGHUR PUNCTUATION FOUR DOTS
+ {0x10FB0, 0x10FC4, prAL, gcLo}, // [21] CHORASMIAN LETTER ALEPH..CHORASMIAN LETTER TAW
+ {0x10FC5, 0x10FCB, prAL, gcNo}, // [7] CHORASMIAN NUMBER ONE..CHORASMIAN NUMBER ONE HUNDRED
+ {0x10FE0, 0x10FF6, prAL, gcLo}, // [23] ELYMAIC LETTER ALEPH..ELYMAIC LIGATURE ZAYIN-YODH
+ {0x11000, 0x11000, prCM, gcMc}, // BRAHMI SIGN CANDRABINDU
+ {0x11001, 0x11001, prCM, gcMn}, // BRAHMI SIGN ANUSVARA
+ {0x11002, 0x11002, prCM, gcMc}, // BRAHMI SIGN VISARGA
+ {0x11003, 0x11037, prAL, gcLo}, // [53] BRAHMI SIGN JIHVAMULIYA..BRAHMI LETTER OLD TAMIL NNNA
+ {0x11038, 0x11046, prCM, gcMn}, // [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA
+ {0x11047, 0x11048, prBA, gcPo}, // [2] BRAHMI DANDA..BRAHMI DOUBLE DANDA
+ {0x11049, 0x1104D, prAL, gcPo}, // [5] BRAHMI PUNCTUATION DOT..BRAHMI PUNCTUATION LOTUS
+ {0x11052, 0x11065, prAL, gcNo}, // [20] BRAHMI NUMBER ONE..BRAHMI NUMBER ONE THOUSAND
+ {0x11066, 0x1106F, prNU, gcNd}, // [10] BRAHMI DIGIT ZERO..BRAHMI DIGIT NINE
+ {0x11070, 0x11070, prCM, gcMn}, // BRAHMI SIGN OLD TAMIL VIRAMA
+ {0x11071, 0x11072, prAL, gcLo}, // [2] BRAHMI LETTER OLD TAMIL SHORT E..BRAHMI LETTER OLD TAMIL SHORT O
+ {0x11073, 0x11074, prCM, gcMn}, // [2] BRAHMI VOWEL SIGN OLD TAMIL SHORT E..BRAHMI VOWEL SIGN OLD TAMIL SHORT O
+ {0x11075, 0x11075, prAL, gcLo}, // BRAHMI LETTER OLD TAMIL LLA
+ {0x1107F, 0x1107F, prCM, gcMn}, // BRAHMI NUMBER JOINER
+ {0x11080, 0x11081, prCM, gcMn}, // [2] KAITHI SIGN CANDRABINDU..KAITHI SIGN ANUSVARA
+ {0x11082, 0x11082, prCM, gcMc}, // KAITHI SIGN VISARGA
+ {0x11083, 0x110AF, prAL, gcLo}, // [45] KAITHI LETTER A..KAITHI LETTER HA
+ {0x110B0, 0x110B2, prCM, gcMc}, // [3] KAITHI VOWEL SIGN AA..KAITHI VOWEL SIGN II
+ {0x110B3, 0x110B6, prCM, gcMn}, // [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI
+ {0x110B7, 0x110B8, prCM, gcMc}, // [2] KAITHI VOWEL SIGN O..KAITHI VOWEL SIGN AU
+ {0x110B9, 0x110BA, prCM, gcMn}, // [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA
+ {0x110BB, 0x110BC, prAL, gcPo}, // [2] KAITHI ABBREVIATION SIGN..KAITHI ENUMERATION SIGN
+ {0x110BD, 0x110BD, prAL, gcCf}, // KAITHI NUMBER SIGN
+ {0x110BE, 0x110C1, prBA, gcPo}, // [4] KAITHI SECTION MARK..KAITHI DOUBLE DANDA
+ {0x110C2, 0x110C2, prCM, gcMn}, // KAITHI VOWEL SIGN VOCALIC R
+ {0x110CD, 0x110CD, prAL, gcCf}, // KAITHI NUMBER SIGN ABOVE
+ {0x110D0, 0x110E8, prAL, gcLo}, // [25] SORA SOMPENG LETTER SAH..SORA SOMPENG LETTER MAE
+ {0x110F0, 0x110F9, prNU, gcNd}, // [10] SORA SOMPENG DIGIT ZERO..SORA SOMPENG DIGIT NINE
+ {0x11100, 0x11102, prCM, gcMn}, // [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA
+ {0x11103, 0x11126, prAL, gcLo}, // [36] CHAKMA LETTER AA..CHAKMA LETTER HAA
+ {0x11127, 0x1112B, prCM, gcMn}, // [5] CHAKMA VOWEL SIGN A..CHAKMA VOWEL SIGN UU
+ {0x1112C, 0x1112C, prCM, gcMc}, // CHAKMA VOWEL SIGN E
+ {0x1112D, 0x11134, prCM, gcMn}, // [8] CHAKMA VOWEL SIGN AI..CHAKMA MAAYYAA
+ {0x11136, 0x1113F, prNU, gcNd}, // [10] CHAKMA DIGIT ZERO..CHAKMA DIGIT NINE
+ {0x11140, 0x11143, prBA, gcPo}, // [4] CHAKMA SECTION MARK..CHAKMA QUESTION MARK
+ {0x11144, 0x11144, prAL, gcLo}, // CHAKMA LETTER LHAA
+ {0x11145, 0x11146, prCM, gcMc}, // [2] CHAKMA VOWEL SIGN AA..CHAKMA VOWEL SIGN EI
+ {0x11147, 0x11147, prAL, gcLo}, // CHAKMA LETTER VAA
+ {0x11150, 0x11172, prAL, gcLo}, // [35] MAHAJANI LETTER A..MAHAJANI LETTER RRA
+ {0x11173, 0x11173, prCM, gcMn}, // MAHAJANI SIGN NUKTA
+ {0x11174, 0x11174, prAL, gcPo}, // MAHAJANI ABBREVIATION SIGN
+ {0x11175, 0x11175, prBB, gcPo}, // MAHAJANI SECTION MARK
+ {0x11176, 0x11176, prAL, gcLo}, // MAHAJANI LIGATURE SHRI
+ {0x11180, 0x11181, prCM, gcMn}, // [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA
+ {0x11182, 0x11182, prCM, gcMc}, // SHARADA SIGN VISARGA
+ {0x11183, 0x111B2, prAL, gcLo}, // [48] SHARADA LETTER A..SHARADA LETTER HA
+ {0x111B3, 0x111B5, prCM, gcMc}, // [3] SHARADA VOWEL SIGN AA..SHARADA VOWEL SIGN II
+ {0x111B6, 0x111BE, prCM, gcMn}, // [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O
+ {0x111BF, 0x111C0, prCM, gcMc}, // [2] SHARADA VOWEL SIGN AU..SHARADA SIGN VIRAMA
+ {0x111C1, 0x111C4, prAL, gcLo}, // [4] SHARADA SIGN AVAGRAHA..SHARADA OM
+ {0x111C5, 0x111C6, prBA, gcPo}, // [2] SHARADA DANDA..SHARADA DOUBLE DANDA
+ {0x111C7, 0x111C7, prAL, gcPo}, // SHARADA ABBREVIATION SIGN
+ {0x111C8, 0x111C8, prBA, gcPo}, // SHARADA SEPARATOR
+ {0x111C9, 0x111CC, prCM, gcMn}, // [4] SHARADA SANDHI MARK..SHARADA EXTRA SHORT VOWEL MARK
+ {0x111CD, 0x111CD, prAL, gcPo}, // SHARADA SUTRA MARK
+ {0x111CE, 0x111CE, prCM, gcMc}, // SHARADA VOWEL SIGN PRISHTHAMATRA E
+ {0x111CF, 0x111CF, prCM, gcMn}, // SHARADA SIGN INVERTED CANDRABINDU
+ {0x111D0, 0x111D9, prNU, gcNd}, // [10] SHARADA DIGIT ZERO..SHARADA DIGIT NINE
+ {0x111DA, 0x111DA, prAL, gcLo}, // SHARADA EKAM
+ {0x111DB, 0x111DB, prBB, gcPo}, // SHARADA SIGN SIDDHAM
+ {0x111DC, 0x111DC, prAL, gcLo}, // SHARADA HEADSTROKE
+ {0x111DD, 0x111DF, prBA, gcPo}, // [3] SHARADA CONTINUATION SIGN..SHARADA SECTION MARK-2
+ {0x111E1, 0x111F4, prAL, gcNo}, // [20] SINHALA ARCHAIC DIGIT ONE..SINHALA ARCHAIC NUMBER ONE THOUSAND
+ {0x11200, 0x11211, prAL, gcLo}, // [18] KHOJKI LETTER A..KHOJKI LETTER JJA
+ {0x11213, 0x1122B, prAL, gcLo}, // [25] KHOJKI LETTER NYA..KHOJKI LETTER LLA
+ {0x1122C, 0x1122E, prCM, gcMc}, // [3] KHOJKI VOWEL SIGN AA..KHOJKI VOWEL SIGN II
+ {0x1122F, 0x11231, prCM, gcMn}, // [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI
+ {0x11232, 0x11233, prCM, gcMc}, // [2] KHOJKI VOWEL SIGN O..KHOJKI VOWEL SIGN AU
+ {0x11234, 0x11234, prCM, gcMn}, // KHOJKI SIGN ANUSVARA
+ {0x11235, 0x11235, prCM, gcMc}, // KHOJKI SIGN VIRAMA
+ {0x11236, 0x11237, prCM, gcMn}, // [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA
+ {0x11238, 0x11239, prBA, gcPo}, // [2] KHOJKI DANDA..KHOJKI DOUBLE DANDA
+ {0x1123A, 0x1123A, prAL, gcPo}, // KHOJKI WORD SEPARATOR
+ {0x1123B, 0x1123C, prBA, gcPo}, // [2] KHOJKI SECTION MARK..KHOJKI DOUBLE SECTION MARK
+ {0x1123D, 0x1123D, prAL, gcPo}, // KHOJKI ABBREVIATION SIGN
+ {0x1123E, 0x1123E, prCM, gcMn}, // KHOJKI SIGN SUKUN
+ {0x1123F, 0x11240, prAL, gcLo}, // [2] KHOJKI LETTER QA..KHOJKI LETTER SHORT I
+ {0x11241, 0x11241, prCM, gcMn}, // KHOJKI VOWEL SIGN VOCALIC R
+ {0x11280, 0x11286, prAL, gcLo}, // [7] MULTANI LETTER A..MULTANI LETTER GA
+ {0x11288, 0x11288, prAL, gcLo}, // MULTANI LETTER GHA
+ {0x1128A, 0x1128D, prAL, gcLo}, // [4] MULTANI LETTER CA..MULTANI LETTER JJA
+ {0x1128F, 0x1129D, prAL, gcLo}, // [15] MULTANI LETTER NYA..MULTANI LETTER BA
+ {0x1129F, 0x112A8, prAL, gcLo}, // [10] MULTANI LETTER BHA..MULTANI LETTER RHA
+ {0x112A9, 0x112A9, prBA, gcPo}, // MULTANI SECTION MARK
+ {0x112B0, 0x112DE, prAL, gcLo}, // [47] KHUDAWADI LETTER A..KHUDAWADI LETTER HA
+ {0x112DF, 0x112DF, prCM, gcMn}, // KHUDAWADI SIGN ANUSVARA
+ {0x112E0, 0x112E2, prCM, gcMc}, // [3] KHUDAWADI VOWEL SIGN AA..KHUDAWADI VOWEL SIGN II
+ {0x112E3, 0x112EA, prCM, gcMn}, // [8] KHUDAWADI VOWEL SIGN U..KHUDAWADI SIGN VIRAMA
+ {0x112F0, 0x112F9, prNU, gcNd}, // [10] KHUDAWADI DIGIT ZERO..KHUDAWADI DIGIT NINE
+ {0x11300, 0x11301, prCM, gcMn}, // [2] GRANTHA SIGN COMBINING ANUSVARA ABOVE..GRANTHA SIGN CANDRABINDU
+ {0x11302, 0x11303, prCM, gcMc}, // [2] GRANTHA SIGN ANUSVARA..GRANTHA SIGN VISARGA
+ {0x11305, 0x1130C, prAL, gcLo}, // [8] GRANTHA LETTER A..GRANTHA LETTER VOCALIC L
+ {0x1130F, 0x11310, prAL, gcLo}, // [2] GRANTHA LETTER EE..GRANTHA LETTER AI
+ {0x11313, 0x11328, prAL, gcLo}, // [22] GRANTHA LETTER OO..GRANTHA LETTER NA
+ {0x1132A, 0x11330, prAL, gcLo}, // [7] GRANTHA LETTER PA..GRANTHA LETTER RA
+ {0x11332, 0x11333, prAL, gcLo}, // [2] GRANTHA LETTER LA..GRANTHA LETTER LLA
+ {0x11335, 0x11339, prAL, gcLo}, // [5] GRANTHA LETTER VA..GRANTHA LETTER HA
+ {0x1133B, 0x1133C, prCM, gcMn}, // [2] COMBINING BINDU BELOW..GRANTHA SIGN NUKTA
+ {0x1133D, 0x1133D, prAL, gcLo}, // GRANTHA SIGN AVAGRAHA
+ {0x1133E, 0x1133F, prCM, gcMc}, // [2] GRANTHA VOWEL SIGN AA..GRANTHA VOWEL SIGN I
+ {0x11340, 0x11340, prCM, gcMn}, // GRANTHA VOWEL SIGN II
+ {0x11341, 0x11344, prCM, gcMc}, // [4] GRANTHA VOWEL SIGN U..GRANTHA VOWEL SIGN VOCALIC RR
+ {0x11347, 0x11348, prCM, gcMc}, // [2] GRANTHA VOWEL SIGN EE..GRANTHA VOWEL SIGN AI
+ {0x1134B, 0x1134D, prCM, gcMc}, // [3] GRANTHA VOWEL SIGN OO..GRANTHA SIGN VIRAMA
+ {0x11350, 0x11350, prAL, gcLo}, // GRANTHA OM
+ {0x11357, 0x11357, prCM, gcMc}, // GRANTHA AU LENGTH MARK
+ {0x1135D, 0x11361, prAL, gcLo}, // [5] GRANTHA SIGN PLUTA..GRANTHA LETTER VOCALIC LL
+ {0x11362, 0x11363, prCM, gcMc}, // [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL
+ {0x11366, 0x1136C, prCM, gcMn}, // [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX
+ {0x11370, 0x11374, prCM, gcMn}, // [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA
+ {0x11400, 0x11434, prAL, gcLo}, // [53] NEWA LETTER A..NEWA LETTER HA
+ {0x11435, 0x11437, prCM, gcMc}, // [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II
+ {0x11438, 0x1143F, prCM, gcMn}, // [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI
+ {0x11440, 0x11441, prCM, gcMc}, // [2] NEWA VOWEL SIGN O..NEWA VOWEL SIGN AU
+ {0x11442, 0x11444, prCM, gcMn}, // [3] NEWA SIGN VIRAMA..NEWA SIGN ANUSVARA
+ {0x11445, 0x11445, prCM, gcMc}, // NEWA SIGN VISARGA
+ {0x11446, 0x11446, prCM, gcMn}, // NEWA SIGN NUKTA
+ {0x11447, 0x1144A, prAL, gcLo}, // [4] NEWA SIGN AVAGRAHA..NEWA SIDDHI
+ {0x1144B, 0x1144E, prBA, gcPo}, // [4] NEWA DANDA..NEWA GAP FILLER
+ {0x1144F, 0x1144F, prAL, gcPo}, // NEWA ABBREVIATION SIGN
+ {0x11450, 0x11459, prNU, gcNd}, // [10] NEWA DIGIT ZERO..NEWA DIGIT NINE
+ {0x1145A, 0x1145B, prBA, gcPo}, // [2] NEWA DOUBLE COMMA..NEWA PLACEHOLDER MARK
+ {0x1145D, 0x1145D, prAL, gcPo}, // NEWA INSERTION SIGN
+ {0x1145E, 0x1145E, prCM, gcMn}, // NEWA SANDHI MARK
+ {0x1145F, 0x11461, prAL, gcLo}, // [3] NEWA LETTER VEDIC ANUSVARA..NEWA SIGN UPADHMANIYA
+ {0x11480, 0x114AF, prAL, gcLo}, // [48] TIRHUTA ANJI..TIRHUTA LETTER HA
+ {0x114B0, 0x114B2, prCM, gcMc}, // [3] TIRHUTA VOWEL SIGN AA..TIRHUTA VOWEL SIGN II
+ {0x114B3, 0x114B8, prCM, gcMn}, // [6] TIRHUTA VOWEL SIGN U..TIRHUTA VOWEL SIGN VOCALIC LL
+ {0x114B9, 0x114B9, prCM, gcMc}, // TIRHUTA VOWEL SIGN E
+ {0x114BA, 0x114BA, prCM, gcMn}, // TIRHUTA VOWEL SIGN SHORT E
+ {0x114BB, 0x114BE, prCM, gcMc}, // [4] TIRHUTA VOWEL SIGN AI..TIRHUTA VOWEL SIGN AU
+ {0x114BF, 0x114C0, prCM, gcMn}, // [2] TIRHUTA SIGN CANDRABINDU..TIRHUTA SIGN ANUSVARA
+ {0x114C1, 0x114C1, prCM, gcMc}, // TIRHUTA SIGN VISARGA
+ {0x114C2, 0x114C3, prCM, gcMn}, // [2] TIRHUTA SIGN VIRAMA..TIRHUTA SIGN NUKTA
+ {0x114C4, 0x114C5, prAL, gcLo}, // [2] TIRHUTA SIGN AVAGRAHA..TIRHUTA GVANG
+ {0x114C6, 0x114C6, prAL, gcPo}, // TIRHUTA ABBREVIATION SIGN
+ {0x114C7, 0x114C7, prAL, gcLo}, // TIRHUTA OM
+ {0x114D0, 0x114D9, prNU, gcNd}, // [10] TIRHUTA DIGIT ZERO..TIRHUTA DIGIT NINE
+ {0x11580, 0x115AE, prAL, gcLo}, // [47] SIDDHAM LETTER A..SIDDHAM LETTER HA
+ {0x115AF, 0x115B1, prCM, gcMc}, // [3] SIDDHAM VOWEL SIGN AA..SIDDHAM VOWEL SIGN II
+ {0x115B2, 0x115B5, prCM, gcMn}, // [4] SIDDHAM VOWEL SIGN U..SIDDHAM VOWEL SIGN VOCALIC RR
+ {0x115B8, 0x115BB, prCM, gcMc}, // [4] SIDDHAM VOWEL SIGN E..SIDDHAM VOWEL SIGN AU
+ {0x115BC, 0x115BD, prCM, gcMn}, // [2] SIDDHAM SIGN CANDRABINDU..SIDDHAM SIGN ANUSVARA
+ {0x115BE, 0x115BE, prCM, gcMc}, // SIDDHAM SIGN VISARGA
+ {0x115BF, 0x115C0, prCM, gcMn}, // [2] SIDDHAM SIGN VIRAMA..SIDDHAM SIGN NUKTA
+ {0x115C1, 0x115C1, prBB, gcPo}, // SIDDHAM SIGN SIDDHAM
+ {0x115C2, 0x115C3, prBA, gcPo}, // [2] SIDDHAM DANDA..SIDDHAM DOUBLE DANDA
+ {0x115C4, 0x115C5, prEX, gcPo}, // [2] SIDDHAM SEPARATOR DOT..SIDDHAM SEPARATOR BAR
+ {0x115C6, 0x115C8, prAL, gcPo}, // [3] SIDDHAM REPETITION MARK-1..SIDDHAM REPETITION MARK-3
+ {0x115C9, 0x115D7, prBA, gcPo}, // [15] SIDDHAM END OF TEXT MARK..SIDDHAM SECTION MARK WITH CIRCLES AND FOUR ENCLOSURES
+ {0x115D8, 0x115DB, prAL, gcLo}, // [4] SIDDHAM LETTER THREE-CIRCLE ALTERNATE I..SIDDHAM LETTER ALTERNATE U
+ {0x115DC, 0x115DD, prCM, gcMn}, // [2] SIDDHAM VOWEL SIGN ALTERNATE U..SIDDHAM VOWEL SIGN ALTERNATE UU
+ {0x11600, 0x1162F, prAL, gcLo}, // [48] MODI LETTER A..MODI LETTER LLA
+ {0x11630, 0x11632, prCM, gcMc}, // [3] MODI VOWEL SIGN AA..MODI VOWEL SIGN II
+ {0x11633, 0x1163A, prCM, gcMn}, // [8] MODI VOWEL SIGN U..MODI VOWEL SIGN AI
+ {0x1163B, 0x1163C, prCM, gcMc}, // [2] MODI VOWEL SIGN O..MODI VOWEL SIGN AU
+ {0x1163D, 0x1163D, prCM, gcMn}, // MODI SIGN ANUSVARA
+ {0x1163E, 0x1163E, prCM, gcMc}, // MODI SIGN VISARGA
+ {0x1163F, 0x11640, prCM, gcMn}, // [2] MODI SIGN VIRAMA..MODI SIGN ARDHACANDRA
+ {0x11641, 0x11642, prBA, gcPo}, // [2] MODI DANDA..MODI DOUBLE DANDA
+ {0x11643, 0x11643, prAL, gcPo}, // MODI ABBREVIATION SIGN
+ {0x11644, 0x11644, prAL, gcLo}, // MODI SIGN HUVA
+ {0x11650, 0x11659, prNU, gcNd}, // [10] MODI DIGIT ZERO..MODI DIGIT NINE
+ {0x11660, 0x1166C, prBB, gcPo}, // [13] MONGOLIAN BIRGA WITH ORNAMENT..MONGOLIAN TURNED SWIRL BIRGA WITH DOUBLE ORNAMENT
+ {0x11680, 0x116AA, prAL, gcLo}, // [43] TAKRI LETTER A..TAKRI LETTER RRA
+ {0x116AB, 0x116AB, prCM, gcMn}, // TAKRI SIGN ANUSVARA
+ {0x116AC, 0x116AC, prCM, gcMc}, // TAKRI SIGN VISARGA
+ {0x116AD, 0x116AD, prCM, gcMn}, // TAKRI VOWEL SIGN AA
+ {0x116AE, 0x116AF, prCM, gcMc}, // [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II
+ {0x116B0, 0x116B5, prCM, gcMn}, // [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU
+ {0x116B6, 0x116B6, prCM, gcMc}, // TAKRI SIGN VIRAMA
+ {0x116B7, 0x116B7, prCM, gcMn}, // TAKRI SIGN NUKTA
+ {0x116B8, 0x116B8, prAL, gcLo}, // TAKRI LETTER ARCHAIC KHA
+ {0x116B9, 0x116B9, prAL, gcPo}, // TAKRI ABBREVIATION SIGN
+ {0x116C0, 0x116C9, prNU, gcNd}, // [10] TAKRI DIGIT ZERO..TAKRI DIGIT NINE
+ {0x11700, 0x1171A, prSA, gcLo}, // [27] AHOM LETTER KA..AHOM LETTER ALTERNATE BA
+ {0x1171D, 0x1171F, prSA, gcMn}, // [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA
+ {0x11720, 0x11721, prSA, gcMc}, // [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA
+ {0x11722, 0x11725, prSA, gcMn}, // [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU
+ {0x11726, 0x11726, prSA, gcMc}, // AHOM VOWEL SIGN E
+ {0x11727, 0x1172B, prSA, gcMn}, // [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER
+ {0x11730, 0x11739, prNU, gcNd}, // [10] AHOM DIGIT ZERO..AHOM DIGIT NINE
+ {0x1173A, 0x1173B, prSA, gcNo}, // [2] AHOM NUMBER TEN..AHOM NUMBER TWENTY
+ {0x1173C, 0x1173E, prBA, gcPo}, // [3] AHOM SIGN SMALL SECTION..AHOM SIGN RULAI
+ {0x1173F, 0x1173F, prSA, gcSo}, // AHOM SYMBOL VI
+ {0x11740, 0x11746, prSA, gcLo}, // [7] AHOM LETTER CA..AHOM LETTER LLA
+ {0x11800, 0x1182B, prAL, gcLo}, // [44] DOGRA LETTER A..DOGRA LETTER RRA
+ {0x1182C, 0x1182E, prCM, gcMc}, // [3] DOGRA VOWEL SIGN AA..DOGRA VOWEL SIGN II
+ {0x1182F, 0x11837, prCM, gcMn}, // [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA
+ {0x11838, 0x11838, prCM, gcMc}, // DOGRA SIGN VISARGA
+ {0x11839, 0x1183A, prCM, gcMn}, // [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA
+ {0x1183B, 0x1183B, prAL, gcPo}, // DOGRA ABBREVIATION SIGN
+ {0x118A0, 0x118DF, prAL, gcLC}, // [64] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI SMALL LETTER VIYO
+ {0x118E0, 0x118E9, prNU, gcNd}, // [10] WARANG CITI DIGIT ZERO..WARANG CITI DIGIT NINE
+ {0x118EA, 0x118F2, prAL, gcNo}, // [9] WARANG CITI NUMBER TEN..WARANG CITI NUMBER NINETY
+ {0x118FF, 0x118FF, prAL, gcLo}, // WARANG CITI OM
+ {0x11900, 0x11906, prAL, gcLo}, // [7] DIVES AKURU LETTER A..DIVES AKURU LETTER E
+ {0x11909, 0x11909, prAL, gcLo}, // DIVES AKURU LETTER O
+ {0x1190C, 0x11913, prAL, gcLo}, // [8] DIVES AKURU LETTER KA..DIVES AKURU LETTER JA
+ {0x11915, 0x11916, prAL, gcLo}, // [2] DIVES AKURU LETTER NYA..DIVES AKURU LETTER TTA
+ {0x11918, 0x1192F, prAL, gcLo}, // [24] DIVES AKURU LETTER DDA..DIVES AKURU LETTER ZA
+ {0x11930, 0x11935, prCM, gcMc}, // [6] DIVES AKURU VOWEL SIGN AA..DIVES AKURU VOWEL SIGN E
+ {0x11937, 0x11938, prCM, gcMc}, // [2] DIVES AKURU VOWEL SIGN AI..DIVES AKURU VOWEL SIGN O
+ {0x1193B, 0x1193C, prCM, gcMn}, // [2] DIVES AKURU SIGN ANUSVARA..DIVES AKURU SIGN CANDRABINDU
+ {0x1193D, 0x1193D, prCM, gcMc}, // DIVES AKURU SIGN HALANTA
+ {0x1193E, 0x1193E, prCM, gcMn}, // DIVES AKURU VIRAMA
+ {0x1193F, 0x1193F, prAL, gcLo}, // DIVES AKURU PREFIXED NASAL SIGN
+ {0x11940, 0x11940, prCM, gcMc}, // DIVES AKURU MEDIAL YA
+ {0x11941, 0x11941, prAL, gcLo}, // DIVES AKURU INITIAL RA
+ {0x11942, 0x11942, prCM, gcMc}, // DIVES AKURU MEDIAL RA
+ {0x11943, 0x11943, prCM, gcMn}, // DIVES AKURU SIGN NUKTA
+ {0x11944, 0x11946, prBA, gcPo}, // [3] DIVES AKURU DOUBLE DANDA..DIVES AKURU END OF TEXT MARK
+ {0x11950, 0x11959, prNU, gcNd}, // [10] DIVES AKURU DIGIT ZERO..DIVES AKURU DIGIT NINE
+ {0x119A0, 0x119A7, prAL, gcLo}, // [8] NANDINAGARI LETTER A..NANDINAGARI LETTER VOCALIC RR
+ {0x119AA, 0x119D0, prAL, gcLo}, // [39] NANDINAGARI LETTER E..NANDINAGARI LETTER RRA
+ {0x119D1, 0x119D3, prCM, gcMc}, // [3] NANDINAGARI VOWEL SIGN AA..NANDINAGARI VOWEL SIGN II
+ {0x119D4, 0x119D7, prCM, gcMn}, // [4] NANDINAGARI VOWEL SIGN U..NANDINAGARI VOWEL SIGN VOCALIC RR
+ {0x119DA, 0x119DB, prCM, gcMn}, // [2] NANDINAGARI VOWEL SIGN E..NANDINAGARI VOWEL SIGN AI
+ {0x119DC, 0x119DF, prCM, gcMc}, // [4] NANDINAGARI VOWEL SIGN O..NANDINAGARI SIGN VISARGA
+ {0x119E0, 0x119E0, prCM, gcMn}, // NANDINAGARI SIGN VIRAMA
+ {0x119E1, 0x119E1, prAL, gcLo}, // NANDINAGARI SIGN AVAGRAHA
+ {0x119E2, 0x119E2, prBB, gcPo}, // NANDINAGARI SIGN SIDDHAM
+ {0x119E3, 0x119E3, prAL, gcLo}, // NANDINAGARI HEADSTROKE
+ {0x119E4, 0x119E4, prCM, gcMc}, // NANDINAGARI VOWEL SIGN PRISHTHAMATRA E
+ {0x11A00, 0x11A00, prAL, gcLo}, // ZANABAZAR SQUARE LETTER A
+ {0x11A01, 0x11A0A, prCM, gcMn}, // [10] ZANABAZAR SQUARE VOWEL SIGN I..ZANABAZAR SQUARE VOWEL LENGTH MARK
+ {0x11A0B, 0x11A32, prAL, gcLo}, // [40] ZANABAZAR SQUARE LETTER KA..ZANABAZAR SQUARE LETTER KSSA
+ {0x11A33, 0x11A38, prCM, gcMn}, // [6] ZANABAZAR SQUARE FINAL CONSONANT MARK..ZANABAZAR SQUARE SIGN ANUSVARA
+ {0x11A39, 0x11A39, prCM, gcMc}, // ZANABAZAR SQUARE SIGN VISARGA
+ {0x11A3A, 0x11A3A, prAL, gcLo}, // ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA
+ {0x11A3B, 0x11A3E, prCM, gcMn}, // [4] ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA..ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA
+ {0x11A3F, 0x11A3F, prBB, gcPo}, // ZANABAZAR SQUARE INITIAL HEAD MARK
+ {0x11A40, 0x11A40, prAL, gcPo}, // ZANABAZAR SQUARE CLOSING HEAD MARK
+ {0x11A41, 0x11A44, prBA, gcPo}, // [4] ZANABAZAR SQUARE MARK TSHEG..ZANABAZAR SQUARE MARK LONG TSHEG
+ {0x11A45, 0x11A45, prBB, gcPo}, // ZANABAZAR SQUARE INITIAL DOUBLE-LINED HEAD MARK
+ {0x11A46, 0x11A46, prAL, gcPo}, // ZANABAZAR SQUARE CLOSING DOUBLE-LINED HEAD MARK
+ {0x11A47, 0x11A47, prCM, gcMn}, // ZANABAZAR SQUARE SUBJOINER
+ {0x11A50, 0x11A50, prAL, gcLo}, // SOYOMBO LETTER A
+ {0x11A51, 0x11A56, prCM, gcMn}, // [6] SOYOMBO VOWEL SIGN I..SOYOMBO VOWEL SIGN OE
+ {0x11A57, 0x11A58, prCM, gcMc}, // [2] SOYOMBO VOWEL SIGN AI..SOYOMBO VOWEL SIGN AU
+ {0x11A59, 0x11A5B, prCM, gcMn}, // [3] SOYOMBO VOWEL SIGN VOCALIC R..SOYOMBO VOWEL LENGTH MARK
+ {0x11A5C, 0x11A89, prAL, gcLo}, // [46] SOYOMBO LETTER KA..SOYOMBO CLUSTER-INITIAL LETTER SA
+ {0x11A8A, 0x11A96, prCM, gcMn}, // [13] SOYOMBO FINAL CONSONANT SIGN G..SOYOMBO SIGN ANUSVARA
+ {0x11A97, 0x11A97, prCM, gcMc}, // SOYOMBO SIGN VISARGA
+ {0x11A98, 0x11A99, prCM, gcMn}, // [2] SOYOMBO GEMINATION MARK..SOYOMBO SUBJOINER
+ {0x11A9A, 0x11A9C, prBA, gcPo}, // [3] SOYOMBO MARK TSHEG..SOYOMBO MARK DOUBLE SHAD
+ {0x11A9D, 0x11A9D, prAL, gcLo}, // SOYOMBO MARK PLUTA
+ {0x11A9E, 0x11AA0, prBB, gcPo}, // [3] SOYOMBO HEAD MARK WITH MOON AND SUN AND TRIPLE FLAME..SOYOMBO HEAD MARK WITH MOON AND SUN
+ {0x11AA1, 0x11AA2, prBA, gcPo}, // [2] SOYOMBO TERMINAL MARK-1..SOYOMBO TERMINAL MARK-2
+ {0x11AB0, 0x11ABF, prAL, gcLo}, // [16] CANADIAN SYLLABICS NATTILIK HI..CANADIAN SYLLABICS SPA
+ {0x11AC0, 0x11AF8, prAL, gcLo}, // [57] PAU CIN HAU LETTER PA..PAU CIN HAU GLOTTAL STOP FINAL
+ {0x11B00, 0x11B09, prBB, gcPo}, // [10] DEVANAGARI HEAD MARK..DEVANAGARI SIGN MINDU
+ {0x11C00, 0x11C08, prAL, gcLo}, // [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L
+ {0x11C0A, 0x11C2E, prAL, gcLo}, // [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA
+ {0x11C2F, 0x11C2F, prCM, gcMc}, // BHAIKSUKI VOWEL SIGN AA
+ {0x11C30, 0x11C36, prCM, gcMn}, // [7] BHAIKSUKI VOWEL SIGN I..BHAIKSUKI VOWEL SIGN VOCALIC L
+ {0x11C38, 0x11C3D, prCM, gcMn}, // [6] BHAIKSUKI VOWEL SIGN E..BHAIKSUKI SIGN ANUSVARA
+ {0x11C3E, 0x11C3E, prCM, gcMc}, // BHAIKSUKI SIGN VISARGA
+ {0x11C3F, 0x11C3F, prCM, gcMn}, // BHAIKSUKI SIGN VIRAMA
+ {0x11C40, 0x11C40, prAL, gcLo}, // BHAIKSUKI SIGN AVAGRAHA
+ {0x11C41, 0x11C45, prBA, gcPo}, // [5] BHAIKSUKI DANDA..BHAIKSUKI GAP FILLER-2
+ {0x11C50, 0x11C59, prNU, gcNd}, // [10] BHAIKSUKI DIGIT ZERO..BHAIKSUKI DIGIT NINE
+ {0x11C5A, 0x11C6C, prAL, gcNo}, // [19] BHAIKSUKI NUMBER ONE..BHAIKSUKI HUNDREDS UNIT MARK
+ {0x11C70, 0x11C70, prBB, gcPo}, // MARCHEN HEAD MARK
+ {0x11C71, 0x11C71, prEX, gcPo}, // MARCHEN MARK SHAD
+ {0x11C72, 0x11C8F, prAL, gcLo}, // [30] MARCHEN LETTER KA..MARCHEN LETTER A
+ {0x11C92, 0x11CA7, prCM, gcMn}, // [22] MARCHEN SUBJOINED LETTER KA..MARCHEN SUBJOINED LETTER ZA
+ {0x11CA9, 0x11CA9, prCM, gcMc}, // MARCHEN SUBJOINED LETTER YA
+ {0x11CAA, 0x11CB0, prCM, gcMn}, // [7] MARCHEN SUBJOINED LETTER RA..MARCHEN VOWEL SIGN AA
+ {0x11CB1, 0x11CB1, prCM, gcMc}, // MARCHEN VOWEL SIGN I
+ {0x11CB2, 0x11CB3, prCM, gcMn}, // [2] MARCHEN VOWEL SIGN U..MARCHEN VOWEL SIGN E
+ {0x11CB4, 0x11CB4, prCM, gcMc}, // MARCHEN VOWEL SIGN O
+ {0x11CB5, 0x11CB6, prCM, gcMn}, // [2] MARCHEN SIGN ANUSVARA..MARCHEN SIGN CANDRABINDU
+ {0x11D00, 0x11D06, prAL, gcLo}, // [7] MASARAM GONDI LETTER A..MASARAM GONDI LETTER E
+ {0x11D08, 0x11D09, prAL, gcLo}, // [2] MASARAM GONDI LETTER AI..MASARAM GONDI LETTER O
+ {0x11D0B, 0x11D30, prAL, gcLo}, // [38] MASARAM GONDI LETTER AU..MASARAM GONDI LETTER TRA
+ {0x11D31, 0x11D36, prCM, gcMn}, // [6] MASARAM GONDI VOWEL SIGN AA..MASARAM GONDI VOWEL SIGN VOCALIC R
+ {0x11D3A, 0x11D3A, prCM, gcMn}, // MASARAM GONDI VOWEL SIGN E
+ {0x11D3C, 0x11D3D, prCM, gcMn}, // [2] MASARAM GONDI VOWEL SIGN AI..MASARAM GONDI VOWEL SIGN O
+ {0x11D3F, 0x11D45, prCM, gcMn}, // [7] MASARAM GONDI VOWEL SIGN AU..MASARAM GONDI VIRAMA
+ {0x11D46, 0x11D46, prAL, gcLo}, // MASARAM GONDI REPHA
+ {0x11D47, 0x11D47, prCM, gcMn}, // MASARAM GONDI RA-KARA
+ {0x11D50, 0x11D59, prNU, gcNd}, // [10] MASARAM GONDI DIGIT ZERO..MASARAM GONDI DIGIT NINE
+ {0x11D60, 0x11D65, prAL, gcLo}, // [6] GUNJALA GONDI LETTER A..GUNJALA GONDI LETTER UU
+ {0x11D67, 0x11D68, prAL, gcLo}, // [2] GUNJALA GONDI LETTER EE..GUNJALA GONDI LETTER AI
+ {0x11D6A, 0x11D89, prAL, gcLo}, // [32] GUNJALA GONDI LETTER OO..GUNJALA GONDI LETTER SA
+ {0x11D8A, 0x11D8E, prCM, gcMc}, // [5] GUNJALA GONDI VOWEL SIGN AA..GUNJALA GONDI VOWEL SIGN UU
+ {0x11D90, 0x11D91, prCM, gcMn}, // [2] GUNJALA GONDI VOWEL SIGN EE..GUNJALA GONDI VOWEL SIGN AI
+ {0x11D93, 0x11D94, prCM, gcMc}, // [2] GUNJALA GONDI VOWEL SIGN OO..GUNJALA GONDI VOWEL SIGN AU
+ {0x11D95, 0x11D95, prCM, gcMn}, // GUNJALA GONDI SIGN ANUSVARA
+ {0x11D96, 0x11D96, prCM, gcMc}, // GUNJALA GONDI SIGN VISARGA
+ {0x11D97, 0x11D97, prCM, gcMn}, // GUNJALA GONDI VIRAMA
+ {0x11D98, 0x11D98, prAL, gcLo}, // GUNJALA GONDI OM
+ {0x11DA0, 0x11DA9, prNU, gcNd}, // [10] GUNJALA GONDI DIGIT ZERO..GUNJALA GONDI DIGIT NINE
+ {0x11EE0, 0x11EF2, prAL, gcLo}, // [19] MAKASAR LETTER KA..MAKASAR ANGKA
+ {0x11EF3, 0x11EF4, prCM, gcMn}, // [2] MAKASAR VOWEL SIGN I..MAKASAR VOWEL SIGN U
+ {0x11EF5, 0x11EF6, prCM, gcMc}, // [2] MAKASAR VOWEL SIGN E..MAKASAR VOWEL SIGN O
+ {0x11EF7, 0x11EF8, prAL, gcPo}, // [2] MAKASAR PASSIMBANG..MAKASAR END OF SECTION
+ {0x11F00, 0x11F01, prCM, gcMn}, // [2] KAWI SIGN CANDRABINDU..KAWI SIGN ANUSVARA
+ {0x11F02, 0x11F02, prAL, gcLo}, // KAWI SIGN REPHA
+ {0x11F03, 0x11F03, prCM, gcMc}, // KAWI SIGN VISARGA
+ {0x11F04, 0x11F10, prAL, gcLo}, // [13] KAWI LETTER A..KAWI LETTER O
+ {0x11F12, 0x11F33, prAL, gcLo}, // [34] KAWI LETTER KA..KAWI LETTER JNYA
+ {0x11F34, 0x11F35, prCM, gcMc}, // [2] KAWI VOWEL SIGN AA..KAWI VOWEL SIGN ALTERNATE AA
+ {0x11F36, 0x11F3A, prCM, gcMn}, // [5] KAWI VOWEL SIGN I..KAWI VOWEL SIGN VOCALIC R
+ {0x11F3E, 0x11F3F, prCM, gcMc}, // [2] KAWI VOWEL SIGN E..KAWI VOWEL SIGN AI
+ {0x11F40, 0x11F40, prCM, gcMn}, // KAWI VOWEL SIGN EU
+ {0x11F41, 0x11F41, prCM, gcMc}, // KAWI SIGN KILLER
+ {0x11F42, 0x11F42, prCM, gcMn}, // KAWI CONJOINER
+ {0x11F43, 0x11F44, prBA, gcPo}, // [2] KAWI DANDA..KAWI DOUBLE DANDA
+ {0x11F45, 0x11F4F, prID, gcPo}, // [11] KAWI PUNCTUATION SECTION MARKER..KAWI PUNCTUATION CLOSING SPIRAL
+ {0x11F50, 0x11F59, prNU, gcNd}, // [10] KAWI DIGIT ZERO..KAWI DIGIT NINE
+ {0x11FB0, 0x11FB0, prAL, gcLo}, // LISU LETTER YHA
+ {0x11FC0, 0x11FD4, prAL, gcNo}, // [21] TAMIL FRACTION ONE THREE-HUNDRED-AND-TWENTIETH..TAMIL FRACTION DOWNSCALING FACTOR KIIZH
+ {0x11FD5, 0x11FDC, prAL, gcSo}, // [8] TAMIL SIGN NEL..TAMIL SIGN MUKKURUNI
+ {0x11FDD, 0x11FE0, prPO, gcSc}, // [4] TAMIL SIGN KAACU..TAMIL SIGN VARAAKAN
+ {0x11FE1, 0x11FF1, prAL, gcSo}, // [17] TAMIL SIGN PAARAM..TAMIL SIGN VAKAIYARAA
+ {0x11FFF, 0x11FFF, prBA, gcPo}, // TAMIL PUNCTUATION END OF TEXT
+ {0x12000, 0x12399, prAL, gcLo}, // [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U
+ {0x12400, 0x1246E, prAL, gcNl}, // [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM
+ {0x12470, 0x12474, prBA, gcPo}, // [5] CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER..CUNEIFORM PUNCTUATION SIGN DIAGONAL QUADCOLON
+ {0x12480, 0x12543, prAL, gcLo}, // [196] CUNEIFORM SIGN AB TIMES NUN TENU..CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU
+ {0x12F90, 0x12FF0, prAL, gcLo}, // [97] CYPRO-MINOAN SIGN CM001..CYPRO-MINOAN SIGN CM114
+ {0x12FF1, 0x12FF2, prAL, gcPo}, // [2] CYPRO-MINOAN SIGN CM301..CYPRO-MINOAN SIGN CM302
+ {0x13000, 0x13257, prAL, gcLo}, // [600] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH O006
+ {0x13258, 0x1325A, prOP, gcLo}, // [3] EGYPTIAN HIEROGLYPH O006A..EGYPTIAN HIEROGLYPH O006C
+ {0x1325B, 0x1325D, prCL, gcLo}, // [3] EGYPTIAN HIEROGLYPH O006D..EGYPTIAN HIEROGLYPH O006F
+ {0x1325E, 0x13281, prAL, gcLo}, // [36] EGYPTIAN HIEROGLYPH O007..EGYPTIAN HIEROGLYPH O033
+ {0x13282, 0x13282, prCL, gcLo}, // EGYPTIAN HIEROGLYPH O033A
+ {0x13283, 0x13285, prAL, gcLo}, // [3] EGYPTIAN HIEROGLYPH O034..EGYPTIAN HIEROGLYPH O036
+ {0x13286, 0x13286, prOP, gcLo}, // EGYPTIAN HIEROGLYPH O036A
+ {0x13287, 0x13287, prCL, gcLo}, // EGYPTIAN HIEROGLYPH O036B
+ {0x13288, 0x13288, prOP, gcLo}, // EGYPTIAN HIEROGLYPH O036C
+ {0x13289, 0x13289, prCL, gcLo}, // EGYPTIAN HIEROGLYPH O036D
+ {0x1328A, 0x13378, prAL, gcLo}, // [239] EGYPTIAN HIEROGLYPH O037..EGYPTIAN HIEROGLYPH V011
+ {0x13379, 0x13379, prOP, gcLo}, // EGYPTIAN HIEROGLYPH V011A
+ {0x1337A, 0x1337B, prCL, gcLo}, // [2] EGYPTIAN HIEROGLYPH V011B..EGYPTIAN HIEROGLYPH V011C
+ {0x1337C, 0x1342F, prAL, gcLo}, // [180] EGYPTIAN HIEROGLYPH V012..EGYPTIAN HIEROGLYPH V011D
+ {0x13430, 0x13436, prGL, gcCf}, // [7] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH OVERLAY MIDDLE
+ {0x13437, 0x13437, prOP, gcCf}, // EGYPTIAN HIEROGLYPH BEGIN SEGMENT
+ {0x13438, 0x13438, prCL, gcCf}, // EGYPTIAN HIEROGLYPH END SEGMENT
+ {0x13439, 0x1343B, prGL, gcCf}, // [3] EGYPTIAN HIEROGLYPH INSERT AT MIDDLE..EGYPTIAN HIEROGLYPH INSERT AT BOTTOM
+ {0x1343C, 0x1343C, prOP, gcCf}, // EGYPTIAN HIEROGLYPH BEGIN ENCLOSURE
+ {0x1343D, 0x1343D, prCL, gcCf}, // EGYPTIAN HIEROGLYPH END ENCLOSURE
+ {0x1343E, 0x1343E, prOP, gcCf}, // EGYPTIAN HIEROGLYPH BEGIN WALLED ENCLOSURE
+ {0x1343F, 0x1343F, prCL, gcCf}, // EGYPTIAN HIEROGLYPH END WALLED ENCLOSURE
+ {0x13440, 0x13440, prCM, gcMn}, // EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY
+ {0x13441, 0x13446, prAL, gcLo}, // [6] EGYPTIAN HIEROGLYPH FULL BLANK..EGYPTIAN HIEROGLYPH WIDE LOST SIGN
+ {0x13447, 0x13455, prCM, gcMn}, // [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED
+ {0x14400, 0x145CD, prAL, gcLo}, // [462] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A409
+ {0x145CE, 0x145CE, prOP, gcLo}, // ANATOLIAN HIEROGLYPH A410 BEGIN LOGOGRAM MARK
+ {0x145CF, 0x145CF, prCL, gcLo}, // ANATOLIAN HIEROGLYPH A410A END LOGOGRAM MARK
+ {0x145D0, 0x14646, prAL, gcLo}, // [119] ANATOLIAN HIEROGLYPH A411..ANATOLIAN HIEROGLYPH A530
+ {0x16800, 0x16A38, prAL, gcLo}, // [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ
+ {0x16A40, 0x16A5E, prAL, gcLo}, // [31] MRO LETTER TA..MRO LETTER TEK
+ {0x16A60, 0x16A69, prNU, gcNd}, // [10] MRO DIGIT ZERO..MRO DIGIT NINE
+ {0x16A6E, 0x16A6F, prBA, gcPo}, // [2] MRO DANDA..MRO DOUBLE DANDA
+ {0x16A70, 0x16ABE, prAL, gcLo}, // [79] TANGSA LETTER OZ..TANGSA LETTER ZA
+ {0x16AC0, 0x16AC9, prNU, gcNd}, // [10] TANGSA DIGIT ZERO..TANGSA DIGIT NINE
+ {0x16AD0, 0x16AED, prAL, gcLo}, // [30] BASSA VAH LETTER ENNI..BASSA VAH LETTER I
+ {0x16AF0, 0x16AF4, prCM, gcMn}, // [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE
+ {0x16AF5, 0x16AF5, prBA, gcPo}, // BASSA VAH FULL STOP
+ {0x16B00, 0x16B2F, prAL, gcLo}, // [48] PAHAWH HMONG VOWEL KEEB..PAHAWH HMONG CONSONANT CAU
+ {0x16B30, 0x16B36, prCM, gcMn}, // [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM
+ {0x16B37, 0x16B39, prBA, gcPo}, // [3] PAHAWH HMONG SIGN VOS THOM..PAHAWH HMONG SIGN CIM CHEEM
+ {0x16B3A, 0x16B3B, prAL, gcPo}, // [2] PAHAWH HMONG SIGN VOS THIAB..PAHAWH HMONG SIGN VOS FEEM
+ {0x16B3C, 0x16B3F, prAL, gcSo}, // [4] PAHAWH HMONG SIGN XYEEM NTXIV..PAHAWH HMONG SIGN XYEEM FAIB
+ {0x16B40, 0x16B43, prAL, gcLm}, // [4] PAHAWH HMONG SIGN VOS SEEV..PAHAWH HMONG SIGN IB YAM
+ {0x16B44, 0x16B44, prBA, gcPo}, // PAHAWH HMONG SIGN XAUS
+ {0x16B45, 0x16B45, prAL, gcSo}, // PAHAWH HMONG SIGN CIM TSOV ROG
+ {0x16B50, 0x16B59, prNU, gcNd}, // [10] PAHAWH HMONG DIGIT ZERO..PAHAWH HMONG DIGIT NINE
+ {0x16B5B, 0x16B61, prAL, gcNo}, // [7] PAHAWH HMONG NUMBER TENS..PAHAWH HMONG NUMBER TRILLIONS
+ {0x16B63, 0x16B77, prAL, gcLo}, // [21] PAHAWH HMONG SIGN VOS LUB..PAHAWH HMONG SIGN CIM NRES TOS
+ {0x16B7D, 0x16B8F, prAL, gcLo}, // [19] PAHAWH HMONG CLAN SIGN TSHEEJ..PAHAWH HMONG CLAN SIGN VWJ
+ {0x16E40, 0x16E7F, prAL, gcLC}, // [64] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN SMALL LETTER Y
+ {0x16E80, 0x16E96, prAL, gcNo}, // [23] MEDEFAIDRIN DIGIT ZERO..MEDEFAIDRIN DIGIT THREE ALTERNATE FORM
+ {0x16E97, 0x16E98, prBA, gcPo}, // [2] MEDEFAIDRIN COMMA..MEDEFAIDRIN FULL STOP
+ {0x16E99, 0x16E9A, prAL, gcPo}, // [2] MEDEFAIDRIN SYMBOL AIVA..MEDEFAIDRIN EXCLAMATION OH
+ {0x16F00, 0x16F4A, prAL, gcLo}, // [75] MIAO LETTER PA..MIAO LETTER RTE
+ {0x16F4F, 0x16F4F, prCM, gcMn}, // MIAO SIGN CONSONANT MODIFIER BAR
+ {0x16F50, 0x16F50, prAL, gcLo}, // MIAO LETTER NASALIZATION
+ {0x16F51, 0x16F87, prCM, gcMc}, // [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI
+ {0x16F8F, 0x16F92, prCM, gcMn}, // [4] MIAO TONE RIGHT..MIAO TONE BELOW
+ {0x16F93, 0x16F9F, prAL, gcLm}, // [13] MIAO LETTER TONE-2..MIAO LETTER REFORMED TONE-8
+ {0x16FE0, 0x16FE1, prNS, gcLm}, // [2] TANGUT ITERATION MARK..NUSHU ITERATION MARK
+ {0x16FE2, 0x16FE2, prNS, gcPo}, // OLD CHINESE HOOK MARK
+ {0x16FE3, 0x16FE3, prNS, gcLm}, // OLD CHINESE ITERATION MARK
+ {0x16FE4, 0x16FE4, prGL, gcMn}, // KHITAN SMALL SCRIPT FILLER
+ {0x16FF0, 0x16FF1, prCM, gcMc}, // [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY
+ {0x17000, 0x187F7, prID, gcLo}, // [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7
+ {0x18800, 0x18AFF, prID, gcLo}, // [768] TANGUT COMPONENT-001..TANGUT COMPONENT-768
+ {0x18B00, 0x18CD5, prAL, gcLo}, // [470] KHITAN SMALL SCRIPT CHARACTER-18B00..KHITAN SMALL SCRIPT CHARACTER-18CD5
+ {0x18D00, 0x18D08, prID, gcLo}, // [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08
+ {0x1AFF0, 0x1AFF3, prAL, gcLm}, // [4] KATAKANA LETTER MINNAN TONE-2..KATAKANA LETTER MINNAN TONE-5
+ {0x1AFF5, 0x1AFFB, prAL, gcLm}, // [7] KATAKANA LETTER MINNAN TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-5
+ {0x1AFFD, 0x1AFFE, prAL, gcLm}, // [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8
+ {0x1B000, 0x1B0FF, prID, gcLo}, // [256] KATAKANA LETTER ARCHAIC E..HENTAIGANA LETTER RE-2
+ {0x1B100, 0x1B122, prID, gcLo}, // [35] HENTAIGANA LETTER RE-3..KATAKANA LETTER ARCHAIC WU
+ {0x1B132, 0x1B132, prCJ, gcLo}, // HIRAGANA LETTER SMALL KO
+ {0x1B150, 0x1B152, prCJ, gcLo}, // [3] HIRAGANA LETTER SMALL WI..HIRAGANA LETTER SMALL WO
+ {0x1B155, 0x1B155, prCJ, gcLo}, // KATAKANA LETTER SMALL KO
+ {0x1B164, 0x1B167, prCJ, gcLo}, // [4] KATAKANA LETTER SMALL WI..KATAKANA LETTER SMALL N
+ {0x1B170, 0x1B2FB, prID, gcLo}, // [396] NUSHU CHARACTER-1B170..NUSHU CHARACTER-1B2FB
+ {0x1BC00, 0x1BC6A, prAL, gcLo}, // [107] DUPLOYAN LETTER H..DUPLOYAN LETTER VOCALIC M
+ {0x1BC70, 0x1BC7C, prAL, gcLo}, // [13] DUPLOYAN AFFIX LEFT HORIZONTAL SECANT..DUPLOYAN AFFIX ATTACHED TANGENT HOOK
+ {0x1BC80, 0x1BC88, prAL, gcLo}, // [9] DUPLOYAN AFFIX HIGH ACUTE..DUPLOYAN AFFIX HIGH VERTICAL
+ {0x1BC90, 0x1BC99, prAL, gcLo}, // [10] DUPLOYAN AFFIX LOW ACUTE..DUPLOYAN AFFIX LOW ARROW
+ {0x1BC9C, 0x1BC9C, prAL, gcSo}, // DUPLOYAN SIGN O WITH CROSS
+ {0x1BC9D, 0x1BC9E, prCM, gcMn}, // [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK
+ {0x1BC9F, 0x1BC9F, prBA, gcPo}, // DUPLOYAN PUNCTUATION CHINOOK FULL STOP
+ {0x1BCA0, 0x1BCA3, prCM, gcCf}, // [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP
+ {0x1CF00, 0x1CF2D, prCM, gcMn}, // [46] ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT..ZNAMENNY COMBINING MARK KRYZH ON LEFT
+ {0x1CF30, 0x1CF46, prCM, gcMn}, // [23] ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO..ZNAMENNY PRIZNAK MODIFIER ROG
+ {0x1CF50, 0x1CFC3, prAL, gcSo}, // [116] ZNAMENNY NEUME KRYUK..ZNAMENNY NEUME PAUK
+ {0x1D000, 0x1D0F5, prAL, gcSo}, // [246] BYZANTINE MUSICAL SYMBOL PSILI..BYZANTINE MUSICAL SYMBOL GORGON NEO KATO
+ {0x1D100, 0x1D126, prAL, gcSo}, // [39] MUSICAL SYMBOL SINGLE BARLINE..MUSICAL SYMBOL DRUM CLEF-2
+ {0x1D129, 0x1D164, prAL, gcSo}, // [60] MUSICAL SYMBOL MULTIPLE MEASURE REST..MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE
+ {0x1D165, 0x1D166, prCM, gcMc}, // [2] MUSICAL SYMBOL COMBINING STEM..MUSICAL SYMBOL COMBINING SPRECHGESANG STEM
+ {0x1D167, 0x1D169, prCM, gcMn}, // [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3
+ {0x1D16A, 0x1D16C, prAL, gcSo}, // [3] MUSICAL SYMBOL FINGERED TREMOLO-1..MUSICAL SYMBOL FINGERED TREMOLO-3
+ {0x1D16D, 0x1D172, prCM, gcMc}, // [6] MUSICAL SYMBOL COMBINING AUGMENTATION DOT..MUSICAL SYMBOL COMBINING FLAG-5
+ {0x1D173, 0x1D17A, prCM, gcCf}, // [8] MUSICAL SYMBOL BEGIN BEAM..MUSICAL SYMBOL END PHRASE
+ {0x1D17B, 0x1D182, prCM, gcMn}, // [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE
+ {0x1D183, 0x1D184, prAL, gcSo}, // [2] MUSICAL SYMBOL ARPEGGIATO UP..MUSICAL SYMBOL ARPEGGIATO DOWN
+ {0x1D185, 0x1D18B, prCM, gcMn}, // [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE
+ {0x1D18C, 0x1D1A9, prAL, gcSo}, // [30] MUSICAL SYMBOL RINFORZANDO..MUSICAL SYMBOL DEGREE SLASH
+ {0x1D1AA, 0x1D1AD, prCM, gcMn}, // [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO
+ {0x1D1AE, 0x1D1EA, prAL, gcSo}, // [61] MUSICAL SYMBOL PEDAL MARK..MUSICAL SYMBOL KORON
+ {0x1D200, 0x1D241, prAL, gcSo}, // [66] GREEK VOCAL NOTATION SYMBOL-1..GREEK INSTRUMENTAL NOTATION SYMBOL-54
+ {0x1D242, 0x1D244, prCM, gcMn}, // [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME
+ {0x1D245, 0x1D245, prAL, gcSo}, // GREEK MUSICAL LEIMMA
+ {0x1D2C0, 0x1D2D3, prAL, gcNo}, // [20] KAKTOVIK NUMERAL ZERO..KAKTOVIK NUMERAL NINETEEN
+ {0x1D2E0, 0x1D2F3, prAL, gcNo}, // [20] MAYAN NUMERAL ZERO..MAYAN NUMERAL NINETEEN
+ {0x1D300, 0x1D356, prAL, gcSo}, // [87] MONOGRAM FOR EARTH..TETRAGRAM FOR FOSTERING
+ {0x1D360, 0x1D378, prAL, gcNo}, // [25] COUNTING ROD UNIT DIGIT ONE..TALLY MARK FIVE
+ {0x1D400, 0x1D454, prAL, gcLC}, // [85] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL ITALIC SMALL G
+ {0x1D456, 0x1D49C, prAL, gcLC}, // [71] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL SCRIPT CAPITAL A
+ {0x1D49E, 0x1D49F, prAL, gcLu}, // [2] MATHEMATICAL SCRIPT CAPITAL C..MATHEMATICAL SCRIPT CAPITAL D
+ {0x1D4A2, 0x1D4A2, prAL, gcLu}, // MATHEMATICAL SCRIPT CAPITAL G
+ {0x1D4A5, 0x1D4A6, prAL, gcLu}, // [2] MATHEMATICAL SCRIPT CAPITAL J..MATHEMATICAL SCRIPT CAPITAL K
+ {0x1D4A9, 0x1D4AC, prAL, gcLu}, // [4] MATHEMATICAL SCRIPT CAPITAL N..MATHEMATICAL SCRIPT CAPITAL Q
+ {0x1D4AE, 0x1D4B9, prAL, gcLC}, // [12] MATHEMATICAL SCRIPT CAPITAL S..MATHEMATICAL SCRIPT SMALL D
+ {0x1D4BB, 0x1D4BB, prAL, gcLl}, // MATHEMATICAL SCRIPT SMALL F
+ {0x1D4BD, 0x1D4C3, prAL, gcLl}, // [7] MATHEMATICAL SCRIPT SMALL H..MATHEMATICAL SCRIPT SMALL N
+ {0x1D4C5, 0x1D505, prAL, gcLC}, // [65] MATHEMATICAL SCRIPT SMALL P..MATHEMATICAL FRAKTUR CAPITAL B
+ {0x1D507, 0x1D50A, prAL, gcLu}, // [4] MATHEMATICAL FRAKTUR CAPITAL D..MATHEMATICAL FRAKTUR CAPITAL G
+ {0x1D50D, 0x1D514, prAL, gcLu}, // [8] MATHEMATICAL FRAKTUR CAPITAL J..MATHEMATICAL FRAKTUR CAPITAL Q
+ {0x1D516, 0x1D51C, prAL, gcLu}, // [7] MATHEMATICAL FRAKTUR CAPITAL S..MATHEMATICAL FRAKTUR CAPITAL Y
+ {0x1D51E, 0x1D539, prAL, gcLC}, // [28] MATHEMATICAL FRAKTUR SMALL A..MATHEMATICAL DOUBLE-STRUCK CAPITAL B
+ {0x1D53B, 0x1D53E, prAL, gcLu}, // [4] MATHEMATICAL DOUBLE-STRUCK CAPITAL D..MATHEMATICAL DOUBLE-STRUCK CAPITAL G
+ {0x1D540, 0x1D544, prAL, gcLu}, // [5] MATHEMATICAL DOUBLE-STRUCK CAPITAL I..MATHEMATICAL DOUBLE-STRUCK CAPITAL M
+ {0x1D546, 0x1D546, prAL, gcLu}, // MATHEMATICAL DOUBLE-STRUCK CAPITAL O
+ {0x1D54A, 0x1D550, prAL, gcLu}, // [7] MATHEMATICAL DOUBLE-STRUCK CAPITAL S..MATHEMATICAL DOUBLE-STRUCK CAPITAL Y
+ {0x1D552, 0x1D6A5, prAL, gcLC}, // [340] MATHEMATICAL DOUBLE-STRUCK SMALL A..MATHEMATICAL ITALIC SMALL DOTLESS J
+ {0x1D6A8, 0x1D6C0, prAL, gcLu}, // [25] MATHEMATICAL BOLD CAPITAL ALPHA..MATHEMATICAL BOLD CAPITAL OMEGA
+ {0x1D6C1, 0x1D6C1, prAL, gcSm}, // MATHEMATICAL BOLD NABLA
+ {0x1D6C2, 0x1D6DA, prAL, gcLl}, // [25] MATHEMATICAL BOLD SMALL ALPHA..MATHEMATICAL BOLD SMALL OMEGA
+ {0x1D6DB, 0x1D6DB, prAL, gcSm}, // MATHEMATICAL BOLD PARTIAL DIFFERENTIAL
+ {0x1D6DC, 0x1D6FA, prAL, gcLC}, // [31] MATHEMATICAL BOLD EPSILON SYMBOL..MATHEMATICAL ITALIC CAPITAL OMEGA
+ {0x1D6FB, 0x1D6FB, prAL, gcSm}, // MATHEMATICAL ITALIC NABLA
+ {0x1D6FC, 0x1D714, prAL, gcLl}, // [25] MATHEMATICAL ITALIC SMALL ALPHA..MATHEMATICAL ITALIC SMALL OMEGA
+ {0x1D715, 0x1D715, prAL, gcSm}, // MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL
+ {0x1D716, 0x1D734, prAL, gcLC}, // [31] MATHEMATICAL ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD ITALIC CAPITAL OMEGA
+ {0x1D735, 0x1D735, prAL, gcSm}, // MATHEMATICAL BOLD ITALIC NABLA
+ {0x1D736, 0x1D74E, prAL, gcLl}, // [25] MATHEMATICAL BOLD ITALIC SMALL ALPHA..MATHEMATICAL BOLD ITALIC SMALL OMEGA
+ {0x1D74F, 0x1D74F, prAL, gcSm}, // MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL
+ {0x1D750, 0x1D76E, prAL, gcLC}, // [31] MATHEMATICAL BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA
+ {0x1D76F, 0x1D76F, prAL, gcSm}, // MATHEMATICAL SANS-SERIF BOLD NABLA
+ {0x1D770, 0x1D788, prAL, gcLl}, // [25] MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA
+ {0x1D789, 0x1D789, prAL, gcSm}, // MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL
+ {0x1D78A, 0x1D7A8, prAL, gcLC}, // [31] MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL..MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA
+ {0x1D7A9, 0x1D7A9, prAL, gcSm}, // MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA
+ {0x1D7AA, 0x1D7C2, prAL, gcLl}, // [25] MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA..MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA
+ {0x1D7C3, 0x1D7C3, prAL, gcSm}, // MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL
+ {0x1D7C4, 0x1D7CB, prAL, gcLC}, // [8] MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL..MATHEMATICAL BOLD SMALL DIGAMMA
+ {0x1D7CE, 0x1D7FF, prNU, gcNd}, // [50] MATHEMATICAL BOLD DIGIT ZERO..MATHEMATICAL MONOSPACE DIGIT NINE
+ {0x1D800, 0x1D9FF, prAL, gcSo}, // [512] SIGNWRITING HAND-FIST INDEX..SIGNWRITING HEAD
+ {0x1DA00, 0x1DA36, prCM, gcMn}, // [55] SIGNWRITING HEAD RIM..SIGNWRITING AIR SUCKING IN
+ {0x1DA37, 0x1DA3A, prAL, gcSo}, // [4] SIGNWRITING AIR BLOW SMALL ROTATIONS..SIGNWRITING BREATH EXHALE
+ {0x1DA3B, 0x1DA6C, prCM, gcMn}, // [50] SIGNWRITING MOUTH CLOSED NEUTRAL..SIGNWRITING EXCITEMENT
+ {0x1DA6D, 0x1DA74, prAL, gcSo}, // [8] SIGNWRITING SHOULDER HIP SPINE..SIGNWRITING TORSO-FLOORPLANE TWISTING
+ {0x1DA75, 0x1DA75, prCM, gcMn}, // SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS
+ {0x1DA76, 0x1DA83, prAL, gcSo}, // [14] SIGNWRITING LIMB COMBINATION..SIGNWRITING LOCATION DEPTH
+ {0x1DA84, 0x1DA84, prCM, gcMn}, // SIGNWRITING LOCATION HEAD NECK
+ {0x1DA85, 0x1DA86, prAL, gcSo}, // [2] SIGNWRITING LOCATION TORSO..SIGNWRITING LOCATION LIMBS DIGITS
+ {0x1DA87, 0x1DA8A, prBA, gcPo}, // [4] SIGNWRITING COMMA..SIGNWRITING COLON
+ {0x1DA8B, 0x1DA8B, prAL, gcPo}, // SIGNWRITING PARENTHESIS
+ {0x1DA9B, 0x1DA9F, prCM, gcMn}, // [5] SIGNWRITING FILL MODIFIER-2..SIGNWRITING FILL MODIFIER-6
+ {0x1DAA1, 0x1DAAF, prCM, gcMn}, // [15] SIGNWRITING ROTATION MODIFIER-2..SIGNWRITING ROTATION MODIFIER-16
+ {0x1DF00, 0x1DF09, prAL, gcLl}, // [10] LATIN SMALL LETTER FENG DIGRAPH WITH TRILL..LATIN SMALL LETTER T WITH HOOK AND RETROFLEX HOOK
+ {0x1DF0A, 0x1DF0A, prAL, gcLo}, // LATIN LETTER RETROFLEX CLICK WITH RETROFLEX HOOK
+ {0x1DF0B, 0x1DF1E, prAL, gcLl}, // [20] LATIN SMALL LETTER ESH WITH DOUBLE BAR..LATIN SMALL LETTER S WITH CURL
+ {0x1DF25, 0x1DF2A, prAL, gcLl}, // [6] LATIN SMALL LETTER D WITH MID-HEIGHT LEFT HOOK..LATIN SMALL LETTER T WITH MID-HEIGHT LEFT HOOK
+ {0x1E000, 0x1E006, prCM, gcMn}, // [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE
+ {0x1E008, 0x1E018, prCM, gcMn}, // [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU
+ {0x1E01B, 0x1E021, prCM, gcMn}, // [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI
+ {0x1E023, 0x1E024, prCM, gcMn}, // [2] COMBINING GLAGOLITIC LETTER YU..COMBINING GLAGOLITIC LETTER SMALL YUS
+ {0x1E026, 0x1E02A, prCM, gcMn}, // [5] COMBINING GLAGOLITIC LETTER YO..COMBINING GLAGOLITIC LETTER FITA
+ {0x1E030, 0x1E06D, prAL, gcLm}, // [62] MODIFIER LETTER CYRILLIC SMALL A..MODIFIER LETTER CYRILLIC SMALL STRAIGHT U WITH STROKE
+ {0x1E08F, 0x1E08F, prCM, gcMn}, // COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+ {0x1E100, 0x1E12C, prAL, gcLo}, // [45] NYIAKENG PUACHUE HMONG LETTER MA..NYIAKENG PUACHUE HMONG LETTER W
+ {0x1E130, 0x1E136, prCM, gcMn}, // [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D
+ {0x1E137, 0x1E13D, prAL, gcLm}, // [7] NYIAKENG PUACHUE HMONG SIGN FOR PERSON..NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER
+ {0x1E140, 0x1E149, prNU, gcNd}, // [10] NYIAKENG PUACHUE HMONG DIGIT ZERO..NYIAKENG PUACHUE HMONG DIGIT NINE
+ {0x1E14E, 0x1E14E, prAL, gcLo}, // NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ
+ {0x1E14F, 0x1E14F, prAL, gcSo}, // NYIAKENG PUACHUE HMONG CIRCLED CA
+ {0x1E290, 0x1E2AD, prAL, gcLo}, // [30] TOTO LETTER PA..TOTO LETTER A
+ {0x1E2AE, 0x1E2AE, prCM, gcMn}, // TOTO SIGN RISING TONE
+ {0x1E2C0, 0x1E2EB, prAL, gcLo}, // [44] WANCHO LETTER AA..WANCHO LETTER YIH
+ {0x1E2EC, 0x1E2EF, prCM, gcMn}, // [4] WANCHO TONE TUP..WANCHO TONE KOINI
+ {0x1E2F0, 0x1E2F9, prNU, gcNd}, // [10] WANCHO DIGIT ZERO..WANCHO DIGIT NINE
+ {0x1E2FF, 0x1E2FF, prPR, gcSc}, // WANCHO NGUN SIGN
+ {0x1E4D0, 0x1E4EA, prAL, gcLo}, // [27] NAG MUNDARI LETTER O..NAG MUNDARI LETTER ELL
+ {0x1E4EB, 0x1E4EB, prAL, gcLm}, // NAG MUNDARI SIGN OJOD
+ {0x1E4EC, 0x1E4EF, prCM, gcMn}, // [4] NAG MUNDARI SIGN MUHOR..NAG MUNDARI SIGN SUTUH
+ {0x1E4F0, 0x1E4F9, prNU, gcNd}, // [10] NAG MUNDARI DIGIT ZERO..NAG MUNDARI DIGIT NINE
+ {0x1E7E0, 0x1E7E6, prAL, gcLo}, // [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO
+ {0x1E7E8, 0x1E7EB, prAL, gcLo}, // [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE
+ {0x1E7ED, 0x1E7EE, prAL, gcLo}, // [2] ETHIOPIC SYLLABLE GURAGE MWI..ETHIOPIC SYLLABLE GURAGE MWEE
+ {0x1E7F0, 0x1E7FE, prAL, gcLo}, // [15] ETHIOPIC SYLLABLE GURAGE QWI..ETHIOPIC SYLLABLE GURAGE PWEE
+ {0x1E800, 0x1E8C4, prAL, gcLo}, // [197] MENDE KIKAKUI SYLLABLE M001 KI..MENDE KIKAKUI SYLLABLE M060 NYON
+ {0x1E8C7, 0x1E8CF, prAL, gcNo}, // [9] MENDE KIKAKUI DIGIT ONE..MENDE KIKAKUI DIGIT NINE
+ {0x1E8D0, 0x1E8D6, prCM, gcMn}, // [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS
+ {0x1E900, 0x1E943, prAL, gcLC}, // [68] ADLAM CAPITAL LETTER ALIF..ADLAM SMALL LETTER SHA
+ {0x1E944, 0x1E94A, prCM, gcMn}, // [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA
+ {0x1E94B, 0x1E94B, prAL, gcLm}, // ADLAM NASALIZATION MARK
+ {0x1E950, 0x1E959, prNU, gcNd}, // [10] ADLAM DIGIT ZERO..ADLAM DIGIT NINE
+ {0x1E95E, 0x1E95F, prOP, gcPo}, // [2] ADLAM INITIAL EXCLAMATION MARK..ADLAM INITIAL QUESTION MARK
+ {0x1EC71, 0x1ECAB, prAL, gcNo}, // [59] INDIC SIYAQ NUMBER ONE..INDIC SIYAQ NUMBER PREFIXED NINE
+ {0x1ECAC, 0x1ECAC, prPO, gcSo}, // INDIC SIYAQ PLACEHOLDER
+ {0x1ECAD, 0x1ECAF, prAL, gcNo}, // [3] INDIC SIYAQ FRACTION ONE QUARTER..INDIC SIYAQ FRACTION THREE QUARTERS
+ {0x1ECB0, 0x1ECB0, prPO, gcSc}, // INDIC SIYAQ RUPEE MARK
+ {0x1ECB1, 0x1ECB4, prAL, gcNo}, // [4] INDIC SIYAQ NUMBER ALTERNATE ONE..INDIC SIYAQ ALTERNATE LAKH MARK
+ {0x1ED01, 0x1ED2D, prAL, gcNo}, // [45] OTTOMAN SIYAQ NUMBER ONE..OTTOMAN SIYAQ NUMBER NINETY THOUSAND
+ {0x1ED2E, 0x1ED2E, prAL, gcSo}, // OTTOMAN SIYAQ MARRATAN
+ {0x1ED2F, 0x1ED3D, prAL, gcNo}, // [15] OTTOMAN SIYAQ ALTERNATE NUMBER TWO..OTTOMAN SIYAQ FRACTION ONE SIXTH
+ {0x1EE00, 0x1EE03, prAL, gcLo}, // [4] ARABIC MATHEMATICAL ALEF..ARABIC MATHEMATICAL DAL
+ {0x1EE05, 0x1EE1F, prAL, gcLo}, // [27] ARABIC MATHEMATICAL WAW..ARABIC MATHEMATICAL DOTLESS QAF
+ {0x1EE21, 0x1EE22, prAL, gcLo}, // [2] ARABIC MATHEMATICAL INITIAL BEH..ARABIC MATHEMATICAL INITIAL JEEM
+ {0x1EE24, 0x1EE24, prAL, gcLo}, // ARABIC MATHEMATICAL INITIAL HEH
+ {0x1EE27, 0x1EE27, prAL, gcLo}, // ARABIC MATHEMATICAL INITIAL HAH
+ {0x1EE29, 0x1EE32, prAL, gcLo}, // [10] ARABIC MATHEMATICAL INITIAL YEH..ARABIC MATHEMATICAL INITIAL QAF
+ {0x1EE34, 0x1EE37, prAL, gcLo}, // [4] ARABIC MATHEMATICAL INITIAL SHEEN..ARABIC MATHEMATICAL INITIAL KHAH
+ {0x1EE39, 0x1EE39, prAL, gcLo}, // ARABIC MATHEMATICAL INITIAL DAD
+ {0x1EE3B, 0x1EE3B, prAL, gcLo}, // ARABIC MATHEMATICAL INITIAL GHAIN
+ {0x1EE42, 0x1EE42, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED JEEM
+ {0x1EE47, 0x1EE47, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED HAH
+ {0x1EE49, 0x1EE49, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED YEH
+ {0x1EE4B, 0x1EE4B, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED LAM
+ {0x1EE4D, 0x1EE4F, prAL, gcLo}, // [3] ARABIC MATHEMATICAL TAILED NOON..ARABIC MATHEMATICAL TAILED AIN
+ {0x1EE51, 0x1EE52, prAL, gcLo}, // [2] ARABIC MATHEMATICAL TAILED SAD..ARABIC MATHEMATICAL TAILED QAF
+ {0x1EE54, 0x1EE54, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED SHEEN
+ {0x1EE57, 0x1EE57, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED KHAH
+ {0x1EE59, 0x1EE59, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED DAD
+ {0x1EE5B, 0x1EE5B, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED GHAIN
+ {0x1EE5D, 0x1EE5D, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED DOTLESS NOON
+ {0x1EE5F, 0x1EE5F, prAL, gcLo}, // ARABIC MATHEMATICAL TAILED DOTLESS QAF
+ {0x1EE61, 0x1EE62, prAL, gcLo}, // [2] ARABIC MATHEMATICAL STRETCHED BEH..ARABIC MATHEMATICAL STRETCHED JEEM
+ {0x1EE64, 0x1EE64, prAL, gcLo}, // ARABIC MATHEMATICAL STRETCHED HEH
+ {0x1EE67, 0x1EE6A, prAL, gcLo}, // [4] ARABIC MATHEMATICAL STRETCHED HAH..ARABIC MATHEMATICAL STRETCHED KAF
+ {0x1EE6C, 0x1EE72, prAL, gcLo}, // [7] ARABIC MATHEMATICAL STRETCHED MEEM..ARABIC MATHEMATICAL STRETCHED QAF
+ {0x1EE74, 0x1EE77, prAL, gcLo}, // [4] ARABIC MATHEMATICAL STRETCHED SHEEN..ARABIC MATHEMATICAL STRETCHED KHAH
+ {0x1EE79, 0x1EE7C, prAL, gcLo}, // [4] ARABIC MATHEMATICAL STRETCHED DAD..ARABIC MATHEMATICAL STRETCHED DOTLESS BEH
+ {0x1EE7E, 0x1EE7E, prAL, gcLo}, // ARABIC MATHEMATICAL STRETCHED DOTLESS FEH
+ {0x1EE80, 0x1EE89, prAL, gcLo}, // [10] ARABIC MATHEMATICAL LOOPED ALEF..ARABIC MATHEMATICAL LOOPED YEH
+ {0x1EE8B, 0x1EE9B, prAL, gcLo}, // [17] ARABIC MATHEMATICAL LOOPED LAM..ARABIC MATHEMATICAL LOOPED GHAIN
+ {0x1EEA1, 0x1EEA3, prAL, gcLo}, // [3] ARABIC MATHEMATICAL DOUBLE-STRUCK BEH..ARABIC MATHEMATICAL DOUBLE-STRUCK DAL
+ {0x1EEA5, 0x1EEA9, prAL, gcLo}, // [5] ARABIC MATHEMATICAL DOUBLE-STRUCK WAW..ARABIC MATHEMATICAL DOUBLE-STRUCK YEH
+ {0x1EEAB, 0x1EEBB, prAL, gcLo}, // [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN
+ {0x1EEF0, 0x1EEF1, prAL, gcSm}, // [2] ARABIC MATHEMATICAL OPERATOR MEEM WITH HAH WITH TATWEEL..ARABIC MATHEMATICAL OPERATOR HAH WITH DAL
+ {0x1F000, 0x1F02B, prID, gcSo}, // [44] MAHJONG TILE EAST WIND..MAHJONG TILE BACK
+ {0x1F02C, 0x1F02F, prID, gcCn}, // [4] ..
+ {0x1F030, 0x1F093, prID, gcSo}, // [100] DOMINO TILE HORIZONTAL BACK..DOMINO TILE VERTICAL-06-06
+ {0x1F094, 0x1F09F, prID, gcCn}, // [12] ..
+ {0x1F0A0, 0x1F0AE, prID, gcSo}, // [15] PLAYING CARD BACK..PLAYING CARD KING OF SPADES
+ {0x1F0AF, 0x1F0B0, prID, gcCn}, // [2] ..
+ {0x1F0B1, 0x1F0BF, prID, gcSo}, // [15] PLAYING CARD ACE OF HEARTS..PLAYING CARD RED JOKER
+ {0x1F0C0, 0x1F0C0, prID, gcCn}, //
+ {0x1F0C1, 0x1F0CF, prID, gcSo}, // [15] PLAYING CARD ACE OF DIAMONDS..PLAYING CARD BLACK JOKER
+ {0x1F0D0, 0x1F0D0, prID, gcCn}, //
+ {0x1F0D1, 0x1F0F5, prID, gcSo}, // [37] PLAYING CARD ACE OF CLUBS..PLAYING CARD TRUMP-21
+ {0x1F0F6, 0x1F0FF, prID, gcCn}, // [10] ..
+ {0x1F100, 0x1F10C, prAI, gcNo}, // [13] DIGIT ZERO FULL STOP..DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ZERO
+ {0x1F10D, 0x1F10F, prID, gcSo}, // [3] CIRCLED ZERO WITH SLASH..CIRCLED DOLLAR SIGN WITH OVERLAID BACKSLASH
+ {0x1F110, 0x1F12D, prAI, gcSo}, // [30] PARENTHESIZED LATIN CAPITAL LETTER A..CIRCLED CD
+ {0x1F12E, 0x1F12F, prAL, gcSo}, // [2] CIRCLED WZ..COPYLEFT SYMBOL
+ {0x1F130, 0x1F169, prAI, gcSo}, // [58] SQUARED LATIN CAPITAL LETTER A..NEGATIVE CIRCLED LATIN CAPITAL LETTER Z
+ {0x1F16A, 0x1F16C, prAL, gcSo}, // [3] RAISED MC SIGN..RAISED MR SIGN
+ {0x1F16D, 0x1F16F, prID, gcSo}, // [3] CIRCLED CC..CIRCLED HUMAN FIGURE
+ {0x1F170, 0x1F1AC, prAI, gcSo}, // [61] NEGATIVE SQUARED LATIN CAPITAL LETTER A..SQUARED VOD
+ {0x1F1AD, 0x1F1AD, prID, gcSo}, // MASK WORK SYMBOL
+ {0x1F1AE, 0x1F1E5, prID, gcCn}, // [56] ..
+ {0x1F1E6, 0x1F1FF, prRI, gcSo}, // [26] REGIONAL INDICATOR SYMBOL LETTER A..REGIONAL INDICATOR SYMBOL LETTER Z
+ {0x1F200, 0x1F202, prID, gcSo}, // [3] SQUARE HIRAGANA HOKA..SQUARED KATAKANA SA
+ {0x1F203, 0x1F20F, prID, gcCn}, // [13] ..
+ {0x1F210, 0x1F23B, prID, gcSo}, // [44] SQUARED CJK UNIFIED IDEOGRAPH-624B..SQUARED CJK UNIFIED IDEOGRAPH-914D
+ {0x1F23C, 0x1F23F, prID, gcCn}, // [4] ..
+ {0x1F240, 0x1F248, prID, gcSo}, // [9] TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-672C..TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557
+ {0x1F249, 0x1F24F, prID, gcCn}, // [7] ..
+ {0x1F250, 0x1F251, prID, gcSo}, // [2] CIRCLED IDEOGRAPH ADVANTAGE..CIRCLED IDEOGRAPH ACCEPT
+ {0x1F252, 0x1F25F, prID, gcCn}, // [14] ..
+ {0x1F260, 0x1F265, prID, gcSo}, // [6] ROUNDED SYMBOL FOR FU..ROUNDED SYMBOL FOR CAI
+ {0x1F266, 0x1F2FF, prID, gcCn}, // [154] ..
+ {0x1F300, 0x1F384, prID, gcSo}, // [133] CYCLONE..CHRISTMAS TREE
+ {0x1F385, 0x1F385, prEB, gcSo}, // FATHER CHRISTMAS
+ {0x1F386, 0x1F39B, prID, gcSo}, // [22] FIREWORKS..CONTROL KNOBS
+ {0x1F39C, 0x1F39D, prAL, gcSo}, // [2] BEAMED ASCENDING MUSICAL NOTES..BEAMED DESCENDING MUSICAL NOTES
+ {0x1F39E, 0x1F3B4, prID, gcSo}, // [23] FILM FRAMES..FLOWER PLAYING CARDS
+ {0x1F3B5, 0x1F3B6, prAL, gcSo}, // [2] MUSICAL NOTE..MULTIPLE MUSICAL NOTES
+ {0x1F3B7, 0x1F3BB, prID, gcSo}, // [5] SAXOPHONE..VIOLIN
+ {0x1F3BC, 0x1F3BC, prAL, gcSo}, // MUSICAL SCORE
+ {0x1F3BD, 0x1F3C1, prID, gcSo}, // [5] RUNNING SHIRT WITH SASH..CHEQUERED FLAG
+ {0x1F3C2, 0x1F3C4, prEB, gcSo}, // [3] SNOWBOARDER..SURFER
+ {0x1F3C5, 0x1F3C6, prID, gcSo}, // [2] SPORTS MEDAL..TROPHY
+ {0x1F3C7, 0x1F3C7, prEB, gcSo}, // HORSE RACING
+ {0x1F3C8, 0x1F3C9, prID, gcSo}, // [2] AMERICAN FOOTBALL..RUGBY FOOTBALL
+ {0x1F3CA, 0x1F3CC, prEB, gcSo}, // [3] SWIMMER..GOLFER
+ {0x1F3CD, 0x1F3FA, prID, gcSo}, // [46] RACING MOTORCYCLE..AMPHORA
+ {0x1F3FB, 0x1F3FF, prEM, gcSk}, // [5] EMOJI MODIFIER FITZPATRICK TYPE-1-2..EMOJI MODIFIER FITZPATRICK TYPE-6
+ {0x1F400, 0x1F441, prID, gcSo}, // [66] RAT..EYE
+ {0x1F442, 0x1F443, prEB, gcSo}, // [2] EAR..NOSE
+ {0x1F444, 0x1F445, prID, gcSo}, // [2] MOUTH..TONGUE
+ {0x1F446, 0x1F450, prEB, gcSo}, // [11] WHITE UP POINTING BACKHAND INDEX..OPEN HANDS SIGN
+ {0x1F451, 0x1F465, prID, gcSo}, // [21] CROWN..BUSTS IN SILHOUETTE
+ {0x1F466, 0x1F478, prEB, gcSo}, // [19] BOY..PRINCESS
+ {0x1F479, 0x1F47B, prID, gcSo}, // [3] JAPANESE OGRE..GHOST
+ {0x1F47C, 0x1F47C, prEB, gcSo}, // BABY ANGEL
+ {0x1F47D, 0x1F480, prID, gcSo}, // [4] EXTRATERRESTRIAL ALIEN..SKULL
+ {0x1F481, 0x1F483, prEB, gcSo}, // [3] INFORMATION DESK PERSON..DANCER
+ {0x1F484, 0x1F484, prID, gcSo}, // LIPSTICK
+ {0x1F485, 0x1F487, prEB, gcSo}, // [3] NAIL POLISH..HAIRCUT
+ {0x1F488, 0x1F48E, prID, gcSo}, // [7] BARBER POLE..GEM STONE
+ {0x1F48F, 0x1F48F, prEB, gcSo}, // KISS
+ {0x1F490, 0x1F490, prID, gcSo}, // BOUQUET
+ {0x1F491, 0x1F491, prEB, gcSo}, // COUPLE WITH HEART
+ {0x1F492, 0x1F49F, prID, gcSo}, // [14] WEDDING..HEART DECORATION
+ {0x1F4A0, 0x1F4A0, prAL, gcSo}, // DIAMOND SHAPE WITH A DOT INSIDE
+ {0x1F4A1, 0x1F4A1, prID, gcSo}, // ELECTRIC LIGHT BULB
+ {0x1F4A2, 0x1F4A2, prAL, gcSo}, // ANGER SYMBOL
+ {0x1F4A3, 0x1F4A3, prID, gcSo}, // BOMB
+ {0x1F4A4, 0x1F4A4, prAL, gcSo}, // SLEEPING SYMBOL
+ {0x1F4A5, 0x1F4A9, prID, gcSo}, // [5] COLLISION SYMBOL..PILE OF POO
+ {0x1F4AA, 0x1F4AA, prEB, gcSo}, // FLEXED BICEPS
+ {0x1F4AB, 0x1F4AE, prID, gcSo}, // [4] DIZZY SYMBOL..WHITE FLOWER
+ {0x1F4AF, 0x1F4AF, prAL, gcSo}, // HUNDRED POINTS SYMBOL
+ {0x1F4B0, 0x1F4B0, prID, gcSo}, // MONEY BAG
+ {0x1F4B1, 0x1F4B2, prAL, gcSo}, // [2] CURRENCY EXCHANGE..HEAVY DOLLAR SIGN
+ {0x1F4B3, 0x1F4FF, prID, gcSo}, // [77] CREDIT CARD..PRAYER BEADS
+ {0x1F500, 0x1F506, prAL, gcSo}, // [7] TWISTED RIGHTWARDS ARROWS..HIGH BRIGHTNESS SYMBOL
+ {0x1F507, 0x1F516, prID, gcSo}, // [16] SPEAKER WITH CANCELLATION STROKE..BOOKMARK
+ {0x1F517, 0x1F524, prAL, gcSo}, // [14] LINK SYMBOL..INPUT SYMBOL FOR LATIN LETTERS
+ {0x1F525, 0x1F531, prID, gcSo}, // [13] FIRE..TRIDENT EMBLEM
+ {0x1F532, 0x1F549, prAL, gcSo}, // [24] BLACK SQUARE BUTTON..OM SYMBOL
+ {0x1F54A, 0x1F573, prID, gcSo}, // [42] DOVE OF PEACE..HOLE
+ {0x1F574, 0x1F575, prEB, gcSo}, // [2] MAN IN BUSINESS SUIT LEVITATING..SLEUTH OR SPY
+ {0x1F576, 0x1F579, prID, gcSo}, // [4] DARK SUNGLASSES..JOYSTICK
+ {0x1F57A, 0x1F57A, prEB, gcSo}, // MAN DANCING
+ {0x1F57B, 0x1F58F, prID, gcSo}, // [21] LEFT HAND TELEPHONE RECEIVER..TURNED OK HAND SIGN
+ {0x1F590, 0x1F590, prEB, gcSo}, // RAISED HAND WITH FINGERS SPLAYED
+ {0x1F591, 0x1F594, prID, gcSo}, // [4] REVERSED RAISED HAND WITH FINGERS SPLAYED..REVERSED VICTORY HAND
+ {0x1F595, 0x1F596, prEB, gcSo}, // [2] REVERSED HAND WITH MIDDLE FINGER EXTENDED..RAISED HAND WITH PART BETWEEN MIDDLE AND RING FINGERS
+ {0x1F597, 0x1F5D3, prID, gcSo}, // [61] WHITE DOWN POINTING LEFT HAND INDEX..SPIRAL CALENDAR PAD
+ {0x1F5D4, 0x1F5DB, prAL, gcSo}, // [8] DESKTOP WINDOW..DECREASE FONT SIZE SYMBOL
+ {0x1F5DC, 0x1F5F3, prID, gcSo}, // [24] COMPRESSION..BALLOT BOX WITH BALLOT
+ {0x1F5F4, 0x1F5F9, prAL, gcSo}, // [6] BALLOT SCRIPT X..BALLOT BOX WITH BOLD CHECK
+ {0x1F5FA, 0x1F5FF, prID, gcSo}, // [6] WORLD MAP..MOYAI
+ {0x1F600, 0x1F644, prID, gcSo}, // [69] GRINNING FACE..FACE WITH ROLLING EYES
+ {0x1F645, 0x1F647, prEB, gcSo}, // [3] FACE WITH NO GOOD GESTURE..PERSON BOWING DEEPLY
+ {0x1F648, 0x1F64A, prID, gcSo}, // [3] SEE-NO-EVIL MONKEY..SPEAK-NO-EVIL MONKEY
+ {0x1F64B, 0x1F64F, prEB, gcSo}, // [5] HAPPY PERSON RAISING ONE HAND..PERSON WITH FOLDED HANDS
+ {0x1F650, 0x1F675, prAL, gcSo}, // [38] NORTH WEST POINTING LEAF..SWASH AMPERSAND ORNAMENT
+ {0x1F676, 0x1F678, prQU, gcSo}, // [3] SANS-SERIF HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT..SANS-SERIF HEAVY LOW DOUBLE COMMA QUOTATION MARK ORNAMENT
+ {0x1F679, 0x1F67B, prNS, gcSo}, // [3] HEAVY INTERROBANG ORNAMENT..HEAVY SANS-SERIF INTERROBANG ORNAMENT
+ {0x1F67C, 0x1F67F, prAL, gcSo}, // [4] VERY HEAVY SOLIDUS..REVERSE CHECKER BOARD
+ {0x1F680, 0x1F6A2, prID, gcSo}, // [35] ROCKET..SHIP
+ {0x1F6A3, 0x1F6A3, prEB, gcSo}, // ROWBOAT
+ {0x1F6A4, 0x1F6B3, prID, gcSo}, // [16] SPEEDBOAT..NO BICYCLES
+ {0x1F6B4, 0x1F6B6, prEB, gcSo}, // [3] BICYCLIST..PEDESTRIAN
+ {0x1F6B7, 0x1F6BF, prID, gcSo}, // [9] NO PEDESTRIANS..SHOWER
+ {0x1F6C0, 0x1F6C0, prEB, gcSo}, // BATH
+ {0x1F6C1, 0x1F6CB, prID, gcSo}, // [11] BATHTUB..COUCH AND LAMP
+ {0x1F6CC, 0x1F6CC, prEB, gcSo}, // SLEEPING ACCOMMODATION
+ {0x1F6CD, 0x1F6D7, prID, gcSo}, // [11] SHOPPING BAGS..ELEVATOR
+ {0x1F6D8, 0x1F6DB, prID, gcCn}, // [4] ..
+ {0x1F6DC, 0x1F6EC, prID, gcSo}, // [17] WIRELESS..AIRPLANE ARRIVING
+ {0x1F6ED, 0x1F6EF, prID, gcCn}, // [3] ..
+ {0x1F6F0, 0x1F6FC, prID, gcSo}, // [13] SATELLITE..ROLLER SKATE
+ {0x1F6FD, 0x1F6FF, prID, gcCn}, // [3] ..
+ {0x1F700, 0x1F773, prAL, gcSo}, // [116] ALCHEMICAL SYMBOL FOR QUINTESSENCE..ALCHEMICAL SYMBOL FOR HALF OUNCE
+ {0x1F774, 0x1F776, prID, gcSo}, // [3] LOT OF FORTUNE..LUNAR ECLIPSE
+ {0x1F777, 0x1F77A, prID, gcCn}, // [4] ..
+ {0x1F77B, 0x1F77F, prID, gcSo}, // [5] HAUMEA..ORCUS
+ {0x1F780, 0x1F7D4, prAL, gcSo}, // [85] BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE..HEAVY TWELVE POINTED PINWHEEL STAR
+ {0x1F7D5, 0x1F7D9, prID, gcSo}, // [5] CIRCLED TRIANGLE..NINE POINTED WHITE STAR
+ {0x1F7DA, 0x1F7DF, prID, gcCn}, // [6] ..
+ {0x1F7E0, 0x1F7EB, prID, gcSo}, // [12] LARGE ORANGE CIRCLE..LARGE BROWN SQUARE
+ {0x1F7EC, 0x1F7EF, prID, gcCn}, // [4] ..
+ {0x1F7F0, 0x1F7F0, prID, gcSo}, // HEAVY EQUALS SIGN
+ {0x1F7F1, 0x1F7FF, prID, gcCn}, // [15] ..