diff --git a/go.mod b/go.mod
index 54a696df..780b1f3b 100644
--- a/go.mod
+++ b/go.mod
@@ -5,6 +5,7 @@ go 1.24.0
require (
github.com/NVIDIA/go-nvlib v0.7.4
github.com/NVIDIA/go-nvml v0.12.9-0
+ github.com/go-playground/validator/v10 v10.27.0
github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.10.0
github.com/urfave/cli/v2 v2.27.7
@@ -20,16 +21,20 @@ require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
+ github.com/gabriel-vasile/mimetype v1.4.8 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
+ github.com/go-playground/locales v0.14.1 // indirect
+ github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/gnostic-models v0.6.9 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
+ github.com/leodido/go-urn v1.4.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
@@ -40,6 +45,7 @@ require (
github.com/spf13/pflag v1.0.5 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
+ golang.org/x/crypto v0.36.0 // indirect
golang.org/x/net v0.38.0 // indirect
golang.org/x/oauth2 v0.27.0 // indirect
golang.org/x/sys v0.31.0 // indirect
diff --git a/go.sum b/go.sum
index bddc3689..2d4783ae 100644
--- a/go.sum
+++ b/go.sum
@@ -13,6 +13,8 @@ github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxER
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
+github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
+github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
@@ -23,6 +25,14 @@ github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
+github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
+github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
+github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
+github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
+github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
+github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
+github.com/go-playground/validator/v10 v10.27.0 h1:w8+XrWVMhGkxOaaowyKH35gFydVHOvC0/uWoy2Fzwn4=
+github.com/go-playground/validator/v10 v10.27.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
@@ -50,6 +60,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
+github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -101,6 +113,8 @@ go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
+golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
diff --git a/pkg/mig/reconfigure/api.go b/pkg/mig/reconfigure/api.go
new file mode 100644
index 00000000..86b34245
--- /dev/null
+++ b/pkg/mig/reconfigure/api.go
@@ -0,0 +1,40 @@
+package reconfigure
+
+import "os/exec"
+
+const (
+ MIGConfigStateLabel = "nvidia.com/mig.config.state"
+ VGPUConfigStateLabel = "nvidia.com/vgpu.config.state"
+)
+
+// A Reconfigurer applies a specified MIG configuration.
+type Reconfigurer interface {
+ Reconfigure() error
+}
+
+// A commandRunner is used to run a constructed command.
+// This interface allows us to inject a runner for testing.
+//
+//go:generate moq -rm -fmt=goimports -out command-runner_mock.go . commandRunner
+type commandRunner interface {
+ Run(*exec.Cmd) error
+}
+
+// migParted defines an interface for interacting with mig-parted.
+//
+//go:generate moq -rm -fmt=goimports -out mig-parted_mock.go . migParted
+type migParted interface {
+ assertValidMIGConfig() error
+ assertMIGConfig() error
+ assertMIGModeOnly() error
+ applyMIGModeOnly() error
+ applyMIGConfig() error
+}
+
+// nodeLabeller defines an interface for interacting with node labels.
+//
+//go:generate moq -rm -fmt=goimports -out node-labeller_mock.go . nodeLabeller
+type nodeLabeller interface {
+ getNodeLabelValue(string) (string, error)
+ setNodeLabelValue(string, string) error
+}
diff --git a/pkg/mig/reconfigure/command-runner_mock.go b/pkg/mig/reconfigure/command-runner_mock.go
new file mode 100644
index 00000000..53e61859
--- /dev/null
+++ b/pkg/mig/reconfigure/command-runner_mock.go
@@ -0,0 +1,75 @@
+// Code generated by moq; DO NOT EDIT.
+// github.com/matryer/moq
+
+package reconfigure
+
+import (
+ "os/exec"
+ "sync"
+)
+
+// Ensure, that commandRunnerMock does implement commandRunner.
+// If this is not the case, regenerate this file with moq.
+var _ commandRunner = &commandRunnerMock{}
+
+// commandRunnerMock is a mock implementation of commandRunner.
+//
+// func TestSomethingThatUsescommandRunner(t *testing.T) {
+//
+// // make and configure a mocked commandRunner
+// mockedcommandRunner := &commandRunnerMock{
+// RunFunc: func(cmd *exec.Cmd) error {
+// panic("mock out the Run method")
+// },
+// }
+//
+// // use mockedcommandRunner in code that requires commandRunner
+// // and then make assertions.
+//
+// }
+type commandRunnerMock struct {
+ // RunFunc mocks the Run method.
+ RunFunc func(cmd *exec.Cmd) error
+
+ // calls tracks calls to the methods.
+ calls struct {
+ // Run holds details about calls to the Run method.
+ Run []struct {
+ // Cmd is the cmd argument value.
+ Cmd *exec.Cmd
+ }
+ }
+ lockRun sync.RWMutex
+}
+
+// Run calls RunFunc.
+func (mock *commandRunnerMock) Run(cmd *exec.Cmd) error {
+ if mock.RunFunc == nil {
+ panic("commandRunnerMock.RunFunc: method is nil but commandRunner.Run was just called")
+ }
+ callInfo := struct {
+ Cmd *exec.Cmd
+ }{
+ Cmd: cmd,
+ }
+ mock.lockRun.Lock()
+ mock.calls.Run = append(mock.calls.Run, callInfo)
+ mock.lockRun.Unlock()
+ return mock.RunFunc(cmd)
+}
+
+// RunCalls gets all the calls that were made to Run.
+// Check the length with:
+//
+// len(mockedcommandRunner.RunCalls())
+func (mock *commandRunnerMock) RunCalls() []struct {
+ Cmd *exec.Cmd
+} {
+ var calls []struct {
+ Cmd *exec.Cmd
+ }
+ mock.lockRun.RLock()
+ calls = mock.calls.Run
+ mock.lockRun.RUnlock()
+ return calls
+}
diff --git a/pkg/mig/reconfigure/mig-parted_mock.go b/pkg/mig/reconfigure/mig-parted_mock.go
new file mode 100644
index 00000000..b3996137
--- /dev/null
+++ b/pkg/mig/reconfigure/mig-parted_mock.go
@@ -0,0 +1,215 @@
+// Code generated by moq; DO NOT EDIT.
+// github.com/matryer/moq
+
+package reconfigure
+
+import (
+ "sync"
+)
+
+// Ensure, that migPartedMock does implement migParted.
+// If this is not the case, regenerate this file with moq.
+var _ migParted = &migPartedMock{}
+
+// migPartedMock is a mock implementation of migParted.
+//
+// func TestSomethingThatUsesmigParted(t *testing.T) {
+//
+// // make and configure a mocked migParted
+// mockedmigParted := &migPartedMock{
+// applyMIGConfigFunc: func() error {
+// panic("mock out the applyMIGConfig method")
+// },
+// applyMIGModeOnlyFunc: func() error {
+// panic("mock out the applyMIGModeOnly method")
+// },
+// assertMIGConfigFunc: func() error {
+// panic("mock out the assertMIGConfig method")
+// },
+// assertMIGModeOnlyFunc: func() error {
+// panic("mock out the assertMIGModeOnly method")
+// },
+// assertValidMIGConfigFunc: func() error {
+// panic("mock out the assertValidMIGConfig method")
+// },
+// }
+//
+// // use mockedmigParted in code that requires migParted
+// // and then make assertions.
+//
+// }
+type migPartedMock struct {
+ // applyMIGConfigFunc mocks the applyMIGConfig method.
+ applyMIGConfigFunc func() error
+
+ // applyMIGModeOnlyFunc mocks the applyMIGModeOnly method.
+ applyMIGModeOnlyFunc func() error
+
+ // assertMIGConfigFunc mocks the assertMIGConfig method.
+ assertMIGConfigFunc func() error
+
+ // assertMIGModeOnlyFunc mocks the assertMIGModeOnly method.
+ assertMIGModeOnlyFunc func() error
+
+ // assertValidMIGConfigFunc mocks the assertValidMIGConfig method.
+ assertValidMIGConfigFunc func() error
+
+ // calls tracks calls to the methods.
+ calls struct {
+ // applyMIGConfig holds details about calls to the applyMIGConfig method.
+ applyMIGConfig []struct {
+ }
+ // applyMIGModeOnly holds details about calls to the applyMIGModeOnly method.
+ applyMIGModeOnly []struct {
+ }
+ // assertMIGConfig holds details about calls to the assertMIGConfig method.
+ assertMIGConfig []struct {
+ }
+ // assertMIGModeOnly holds details about calls to the assertMIGModeOnly method.
+ assertMIGModeOnly []struct {
+ }
+ // assertValidMIGConfig holds details about calls to the assertValidMIGConfig method.
+ assertValidMIGConfig []struct {
+ }
+ }
+ lockapplyMIGConfig sync.RWMutex
+ lockapplyMIGModeOnly sync.RWMutex
+ lockassertMIGConfig sync.RWMutex
+ lockassertMIGModeOnly sync.RWMutex
+ lockassertValidMIGConfig sync.RWMutex
+}
+
+// applyMIGConfig calls applyMIGConfigFunc.
+func (mock *migPartedMock) applyMIGConfig() error {
+ if mock.applyMIGConfigFunc == nil {
+ panic("migPartedMock.applyMIGConfigFunc: method is nil but migParted.applyMIGConfig was just called")
+ }
+ callInfo := struct {
+ }{}
+ mock.lockapplyMIGConfig.Lock()
+ mock.calls.applyMIGConfig = append(mock.calls.applyMIGConfig, callInfo)
+ mock.lockapplyMIGConfig.Unlock()
+ return mock.applyMIGConfigFunc()
+}
+
+// applyMIGConfigCalls gets all the calls that were made to applyMIGConfig.
+// Check the length with:
+//
+// len(mockedmigParted.applyMIGConfigCalls())
+func (mock *migPartedMock) applyMIGConfigCalls() []struct {
+} {
+ var calls []struct {
+ }
+ mock.lockapplyMIGConfig.RLock()
+ calls = mock.calls.applyMIGConfig
+ mock.lockapplyMIGConfig.RUnlock()
+ return calls
+}
+
+// applyMIGModeOnly calls applyMIGModeOnlyFunc.
+func (mock *migPartedMock) applyMIGModeOnly() error {
+ if mock.applyMIGModeOnlyFunc == nil {
+ panic("migPartedMock.applyMIGModeOnlyFunc: method is nil but migParted.applyMIGModeOnly was just called")
+ }
+ callInfo := struct {
+ }{}
+ mock.lockapplyMIGModeOnly.Lock()
+ mock.calls.applyMIGModeOnly = append(mock.calls.applyMIGModeOnly, callInfo)
+ mock.lockapplyMIGModeOnly.Unlock()
+ return mock.applyMIGModeOnlyFunc()
+}
+
+// applyMIGModeOnlyCalls gets all the calls that were made to applyMIGModeOnly.
+// Check the length with:
+//
+// len(mockedmigParted.applyMIGModeOnlyCalls())
+func (mock *migPartedMock) applyMIGModeOnlyCalls() []struct {
+} {
+ var calls []struct {
+ }
+ mock.lockapplyMIGModeOnly.RLock()
+ calls = mock.calls.applyMIGModeOnly
+ mock.lockapplyMIGModeOnly.RUnlock()
+ return calls
+}
+
+// assertMIGConfig calls assertMIGConfigFunc.
+func (mock *migPartedMock) assertMIGConfig() error {
+ if mock.assertMIGConfigFunc == nil {
+ panic("migPartedMock.assertMIGConfigFunc: method is nil but migParted.assertMIGConfig was just called")
+ }
+ callInfo := struct {
+ }{}
+ mock.lockassertMIGConfig.Lock()
+ mock.calls.assertMIGConfig = append(mock.calls.assertMIGConfig, callInfo)
+ mock.lockassertMIGConfig.Unlock()
+ return mock.assertMIGConfigFunc()
+}
+
+// assertMIGConfigCalls gets all the calls that were made to assertMIGConfig.
+// Check the length with:
+//
+// len(mockedmigParted.assertMIGConfigCalls())
+func (mock *migPartedMock) assertMIGConfigCalls() []struct {
+} {
+ var calls []struct {
+ }
+ mock.lockassertMIGConfig.RLock()
+ calls = mock.calls.assertMIGConfig
+ mock.lockassertMIGConfig.RUnlock()
+ return calls
+}
+
+// assertMIGModeOnly calls assertMIGModeOnlyFunc.
+func (mock *migPartedMock) assertMIGModeOnly() error {
+ if mock.assertMIGModeOnlyFunc == nil {
+ panic("migPartedMock.assertMIGModeOnlyFunc: method is nil but migParted.assertMIGModeOnly was just called")
+ }
+ callInfo := struct {
+ }{}
+ mock.lockassertMIGModeOnly.Lock()
+ mock.calls.assertMIGModeOnly = append(mock.calls.assertMIGModeOnly, callInfo)
+ mock.lockassertMIGModeOnly.Unlock()
+ return mock.assertMIGModeOnlyFunc()
+}
+
+// assertMIGModeOnlyCalls gets all the calls that were made to assertMIGModeOnly.
+// Check the length with:
+//
+// len(mockedmigParted.assertMIGModeOnlyCalls())
+func (mock *migPartedMock) assertMIGModeOnlyCalls() []struct {
+} {
+ var calls []struct {
+ }
+ mock.lockassertMIGModeOnly.RLock()
+ calls = mock.calls.assertMIGModeOnly
+ mock.lockassertMIGModeOnly.RUnlock()
+ return calls
+}
+
+// assertValidMIGConfig calls assertValidMIGConfigFunc.
+func (mock *migPartedMock) assertValidMIGConfig() error {
+ if mock.assertValidMIGConfigFunc == nil {
+ panic("migPartedMock.assertValidMIGConfigFunc: method is nil but migParted.assertValidMIGConfig was just called")
+ }
+ callInfo := struct {
+ }{}
+ mock.lockassertValidMIGConfig.Lock()
+ mock.calls.assertValidMIGConfig = append(mock.calls.assertValidMIGConfig, callInfo)
+ mock.lockassertValidMIGConfig.Unlock()
+ return mock.assertValidMIGConfigFunc()
+}
+
+// assertValidMIGConfigCalls gets all the calls that were made to assertValidMIGConfig.
+// Check the length with:
+//
+// len(mockedmigParted.assertValidMIGConfigCalls())
+func (mock *migPartedMock) assertValidMIGConfigCalls() []struct {
+} {
+ var calls []struct {
+ }
+ mock.lockassertValidMIGConfig.RLock()
+ calls = mock.calls.assertValidMIGConfig
+ mock.lockassertValidMIGConfig.RUnlock()
+ return calls
+}
diff --git a/pkg/mig/reconfigure/node-labeller_mock.go b/pkg/mig/reconfigure/node-labeller_mock.go
new file mode 100644
index 00000000..24c88036
--- /dev/null
+++ b/pkg/mig/reconfigure/node-labeller_mock.go
@@ -0,0 +1,124 @@
+// Code generated by moq; DO NOT EDIT.
+// github.com/matryer/moq
+
+package reconfigure
+
+import (
+ "sync"
+)
+
+// Ensure, that nodeLabellerMock does implement nodeLabeller.
+// If this is not the case, regenerate this file with moq.
+var _ nodeLabeller = &nodeLabellerMock{}
+
+// nodeLabellerMock is a mock implementation of nodeLabeller.
+//
+// func TestSomethingThatUsesnodeLabeller(t *testing.T) {
+//
+// // make and configure a mocked nodeLabeller
+// mockednodeLabeller := &nodeLabellerMock{
+// getNodeLabelValueFunc: func(s string) (string, error) {
+// panic("mock out the getNodeLabelValue method")
+// },
+// setNodeLabelValueFunc: func(s1 string, s2 string) error {
+// panic("mock out the setNodeLabelValue method")
+// },
+// }
+//
+// // use mockednodeLabeller in code that requires nodeLabeller
+// // and then make assertions.
+//
+// }
+type nodeLabellerMock struct {
+ // getNodeLabelValueFunc mocks the getNodeLabelValue method.
+ getNodeLabelValueFunc func(s string) (string, error)
+
+ // setNodeLabelValueFunc mocks the setNodeLabelValue method.
+ setNodeLabelValueFunc func(s1 string, s2 string) error
+
+ // calls tracks calls to the methods.
+ calls struct {
+ // getNodeLabelValue holds details about calls to the getNodeLabelValue method.
+ getNodeLabelValue []struct {
+ // S is the s argument value.
+ S string
+ }
+ // setNodeLabelValue holds details about calls to the setNodeLabelValue method.
+ setNodeLabelValue []struct {
+ // S1 is the s1 argument value.
+ S1 string
+ // S2 is the s2 argument value.
+ S2 string
+ }
+ }
+ lockgetNodeLabelValue sync.RWMutex
+ locksetNodeLabelValue sync.RWMutex
+}
+
+// getNodeLabelValue calls getNodeLabelValueFunc.
+func (mock *nodeLabellerMock) getNodeLabelValue(s string) (string, error) {
+ if mock.getNodeLabelValueFunc == nil {
+ panic("nodeLabellerMock.getNodeLabelValueFunc: method is nil but nodeLabeller.getNodeLabelValue was just called")
+ }
+ callInfo := struct {
+ S string
+ }{
+ S: s,
+ }
+ mock.lockgetNodeLabelValue.Lock()
+ mock.calls.getNodeLabelValue = append(mock.calls.getNodeLabelValue, callInfo)
+ mock.lockgetNodeLabelValue.Unlock()
+ return mock.getNodeLabelValueFunc(s)
+}
+
+// getNodeLabelValueCalls gets all the calls that were made to getNodeLabelValue.
+// Check the length with:
+//
+// len(mockednodeLabeller.getNodeLabelValueCalls())
+func (mock *nodeLabellerMock) getNodeLabelValueCalls() []struct {
+ S string
+} {
+ var calls []struct {
+ S string
+ }
+ mock.lockgetNodeLabelValue.RLock()
+ calls = mock.calls.getNodeLabelValue
+ mock.lockgetNodeLabelValue.RUnlock()
+ return calls
+}
+
+// setNodeLabelValue calls setNodeLabelValueFunc.
+func (mock *nodeLabellerMock) setNodeLabelValue(s1 string, s2 string) error {
+ if mock.setNodeLabelValueFunc == nil {
+ panic("nodeLabellerMock.setNodeLabelValueFunc: method is nil but nodeLabeller.setNodeLabelValue was just called")
+ }
+ callInfo := struct {
+ S1 string
+ S2 string
+ }{
+ S1: s1,
+ S2: s2,
+ }
+ mock.locksetNodeLabelValue.Lock()
+ mock.calls.setNodeLabelValue = append(mock.calls.setNodeLabelValue, callInfo)
+ mock.locksetNodeLabelValue.Unlock()
+ return mock.setNodeLabelValueFunc(s1, s2)
+}
+
+// setNodeLabelValueCalls gets all the calls that were made to setNodeLabelValue.
+// Check the length with:
+//
+// len(mockednodeLabeller.setNodeLabelValueCalls())
+func (mock *nodeLabellerMock) setNodeLabelValueCalls() []struct {
+ S1 string
+ S2 string
+} {
+ var calls []struct {
+ S1 string
+ S2 string
+ }
+ mock.locksetNodeLabelValue.RLock()
+ calls = mock.calls.setNodeLabelValue
+ mock.locksetNodeLabelValue.RUnlock()
+ return calls
+}
diff --git a/pkg/mig/reconfigure/options.go b/pkg/mig/reconfigure/options.go
new file mode 100644
index 00000000..b27337d3
--- /dev/null
+++ b/pkg/mig/reconfigure/options.go
@@ -0,0 +1,149 @@
+/**
+# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+# SPDX-License-Identifier: Apache-2.0
+#
+# 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 reconfigure
+
+import (
+ "k8s.io/client-go/kubernetes"
+)
+
+// An Option represents a functional option passed to the constructor.
+type Option func(*reconfigureMIGOptions)
+
+// reconfigureMIGOptions contains configuration options for reconfiguring MIG
+// settings on a Kubernetes node. This struct is used to manage the various
+// parameters required for applying MIG configurations through mig-parted, including node identification, configuration files, reboot behavior, and host
+// system service management.
+type reconfigureMIGOptions struct {
+ clientset *kubernetes.Clientset `validate:"required"`
+
+ // NodeName is the kubernetes node to change the MIG configuration on.
+ // Its validation follows the RFC 1123 standard for DNS subdomain names.
+ // Source: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names
+ NodeName string `validate:"required,hostname_rfc1123"`
+
+ // MIGPartedConfigFile is the mig-parted configuration file path.
+ MIGPartedConfigFile string `validate:"required,filepath"`
+
+ // SelectedMIGConfig is the selected mig-parted configuration to apply to the
+ // node.
+ // TODO: Define the validation schema.
+ SelectedMIGConfig string `validate:"required"`
+
+ // DriverLibraryPath is the path to libnvidia-ml.so.1 in the container.
+ DriverLibraryPath string `validate:"required,filepath"`
+
+ // WithReboot reboots the node if changing the MIG mode fails for any reason.
+ WithReboot bool
+
+ // WithShutdownHostGPUClients shutdowns/restarts any required host GPU clients
+ // across a MIG configuration.
+ WithShutdownHostGPUClients bool
+
+ // HostRootMount is the container path where host root directory is mounted.
+ HostRootMount string `validate:"dirpath"`
+
+ // HostMIGManagerStateFile is the path where the systemd mig-manager state
+ // file is located.
+ HostMIGManagerStateFile string `validate:"omitempty,filepath"`
+
+ // HostGPUClientServices is a comma separated list of host systemd services to
+ // shutdown/restart across a MIG reconfiguration.
+ HostGPUClientServices []string `validate:"dive,systemd_service_name"`
+
+ // HostKubeletService is the name of the host's 'kubelet' systemd service
+ // which may need to be shutdown/restarted across a MIG mode reconfiguration.
+ HostKubeletService string `validate:"omitempty,systemd_service_name"`
+
+ // TODO: Define the validation schema.
+ ConfigStateLabel string `validate:"required"`
+
+ // TODO: The following is not an option, but is tracked during the reconfiguration.
+ hostGPUClientServicesStopped []string
+}
+
+func WithAllowReboot(allowReboot bool) Option {
+ return func(o *reconfigureMIGOptions) {
+ o.WithReboot = allowReboot
+ }
+}
+
+func WithClientset(clientset *kubernetes.Clientset) Option {
+ return func(o *reconfigureMIGOptions) {
+ o.clientset = clientset
+ }
+}
+
+func WithConfigStateLabel(configStateLabel string) Option {
+ return func(o *reconfigureMIGOptions) {
+ o.ConfigStateLabel = configStateLabel
+ }
+}
+
+func WithDriverLibraryPath(driverLibraryPath string) Option {
+ return func(o *reconfigureMIGOptions) {
+ o.DriverLibraryPath = driverLibraryPath
+ }
+}
+
+func WithHostGPUClientServices(hostGPUClientServices ...string) Option {
+ return func(o *reconfigureMIGOptions) {
+ o.HostGPUClientServices = append([]string{}, hostGPUClientServices...)
+ }
+}
+
+func WithHostKubeletService(hostKubeletService string) Option {
+ return func(o *reconfigureMIGOptions) {
+ o.HostKubeletService = hostKubeletService
+ }
+}
+
+func WithHostMIGManagerStateFile(hostMIGManagerStateFile string) Option {
+ return func(o *reconfigureMIGOptions) {
+ o.HostMIGManagerStateFile = hostMIGManagerStateFile
+ }
+}
+
+func WithHostRootMount(hostRootMount string) Option {
+ return func(o *reconfigureMIGOptions) {
+ o.HostRootMount = hostRootMount
+ }
+}
+
+func WithMIGPartedConfigFile(migPartedConfigFile string) Option {
+ return func(o *reconfigureMIGOptions) {
+ o.MIGPartedConfigFile = migPartedConfigFile
+ }
+}
+
+func WithNodeName(nodeName string) Option {
+ return func(o *reconfigureMIGOptions) {
+ o.NodeName = nodeName
+ }
+}
+
+func WithSelectedMIGConfig(selectedMIGConfig string) Option {
+ return func(o *reconfigureMIGOptions) {
+ o.SelectedMIGConfig = selectedMIGConfig
+ }
+}
+
+func WithShutdownHostGPUClients(shutdownHostGPUClients bool) Option {
+ return func(o *reconfigureMIGOptions) {
+ o.WithShutdownHostGPUClients = shutdownHostGPUClients
+ }
+}
diff --git a/pkg/mig/reconfigure/reconfigure.go b/pkg/mig/reconfigure/reconfigure.go
new file mode 100644
index 00000000..8c0b50bc
--- /dev/null
+++ b/pkg/mig/reconfigure/reconfigure.go
@@ -0,0 +1,436 @@
+/**
+# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+# SPDX-License-Identifier: Apache-2.0
+#
+# 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 reconfigure
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strings"
+ "time"
+
+ log "github.com/sirupsen/logrus"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/client-go/kubernetes"
+)
+
+const (
+ migPartedCliName = "nvidia-mig-parted"
+
+ configStateRebooting = "rebooting"
+
+ ldPreloadEnvVar = "LD_PRELOAD"
+)
+
+type reconfigurer struct {
+ *reconfigureMIGOptions
+ commandRunner
+ migParted migParted
+ node nodeLabeller
+}
+
+// A commandWithOutput runs a command and ensures that STDERR and STDOUT are
+// set.
+type commandWithOutput struct{}
+
+var _ commandRunner = (*commandWithOutput)(nil)
+
+// New creates a MIG Reconfigurer with the supplied options.
+func New(opts ...Option) (Reconfigurer, error) {
+ o := &reconfigureMIGOptions{}
+
+ for _, opt := range opts {
+ opt(o)
+ }
+
+ if err := o.Validate(); err != nil {
+ return nil, err
+ }
+
+ c := &commandWithOutput{}
+
+ r := &reconfigurer{
+ reconfigureMIGOptions: o,
+ commandRunner: c,
+ migParted: &migPartedCLI{
+ MIGPartedConfigFile: o.MIGPartedConfigFile,
+ SelectedMIGConfig: o.SelectedMIGConfig,
+ DriverLibraryPath: o.DriverLibraryPath,
+ commandRunner: c,
+ },
+ node: &node{
+ clientset: o.clientset,
+ name: o.NodeName,
+ },
+ }
+
+ return r, nil
+}
+
+// Reconfigure configures MIG (Multi-Instance GPU) settings on a Kubernetes
+// node. It validates the requested configuration, checks the current state,
+// applies MIG mode changes, manages host GPU client services, and handles
+// reboots when necessary. The function ensures that MIG configurations are
+// applied safely with proper service lifecycle management.
+func (opts *reconfigurer) Reconfigure() error {
+ log.Info("Asserting that the requested configuration is present in the configuration file")
+ if err := opts.migParted.assertValidMIGConfig(); err != nil {
+ return fmt.Errorf("error validating the selected MIG configuration: %w", err)
+ }
+
+ log.Infof("Getting current value of the '%s' node label", opts.ConfigStateLabel)
+ state, err := opts.node.getNodeLabelValue(opts.ConfigStateLabel)
+ if err != nil {
+ return fmt.Errorf("unable to get the value of the %q label: %w", opts.ConfigStateLabel, err)
+ }
+ log.Infof("Current value of '%s=%s'", opts.ConfigStateLabel, state)
+
+ log.Info("Checking if the selected MIG config is currently applied or not")
+ if err := opts.migParted.assertMIGConfig(); err == nil {
+ log.Info("MIG configuration already applied")
+ return nil
+ }
+
+ if opts.HostRootMount != "" && opts.HostMIGManagerStateFile != "" {
+ stateFilePath := filepath.Join(opts.HostRootMount, opts.HostMIGManagerStateFile)
+ if _, err := os.Stat(stateFilePath); err == nil {
+ log.Infof("Persisting %s to %s", opts.SelectedMIGConfig, opts.HostMIGManagerStateFile)
+ if err := opts.hostPersistConfig(); err != nil {
+ return fmt.Errorf("unable to persist %s to %s: %w", opts.SelectedMIGConfig, opts.HostMIGManagerStateFile, err)
+ }
+ }
+ }
+
+ log.Info("Checking if the MIG mode setting in the selected config is currently applied or not")
+ log.Infof("If the state is '%s', we expect this to always return true", configStateRebooting)
+ migModeChangeRequired := false
+ if err := opts.migParted.assertMIGModeOnly(); err != nil {
+ if state == configStateRebooting {
+ return fmt.Errorf("MIG mode change failed after reboot: %w", err)
+ }
+ if opts.WithShutdownHostGPUClients {
+ opts.HostGPUClientServices = append(opts.HostGPUClientServices, opts.HostKubeletService)
+ }
+ migModeChangeRequired = true
+ }
+
+ if opts.WithShutdownHostGPUClients {
+ log.Info("Shutting down all GPU clients on the host by stopping their systemd services")
+ if err := opts.hostStopSystemdServices(); err != nil {
+ return fmt.Errorf("unable to shutdown host GPU clients: %w", err)
+ }
+ if migModeChangeRequired {
+ log.Info("Waiting 30 seconds for services to settle")
+ time.Sleep(30 * time.Second)
+ }
+ }
+
+ log.Info("Applying the MIG mode change from the selected config to the node (and double checking it took effect)")
+ log.Info("If the -r option was passed, the node will be automatically rebooted if this is not successful")
+ if err := opts.migParted.applyMIGModeOnly(); err != nil || opts.migParted.assertMIGModeOnly() != nil {
+ if opts.WithReboot {
+ log.Infof("Changing the '%s' node label to '%s'", opts.ConfigStateLabel, configStateRebooting)
+ if err := opts.node.setNodeLabelValue(opts.ConfigStateLabel, configStateRebooting); err != nil {
+ log.Errorf("Unable to set the value of '%s' to '%s'", opts.ConfigStateLabel, configStateRebooting)
+ log.Error("Exiting so as not to reboot multiple times unexpectedly")
+ return fmt.Errorf("unable to set the value of %q to %q: %w", opts.ConfigStateLabel, configStateRebooting, err)
+ }
+ return rebootHost(opts.HostRootMount)
+ }
+ }
+
+ log.Info("Applying the selected MIG config to the node")
+ if err := opts.migParted.applyMIGConfig(); err != nil {
+ return err
+ }
+
+ if opts.WithShutdownHostGPUClients {
+ log.Info("Restarting all GPU clients previously shutdown on the host by restarting their systemd services")
+ if err := opts.hostStartSystemdServices(); err != nil {
+ return fmt.Errorf("unable to restart host GPU clients: %w", err)
+ }
+ }
+
+ return nil
+}
+
+type migPartedCLI struct {
+ MIGPartedConfigFile string
+ SelectedMIGConfig string
+ DriverLibraryPath string
+ commandRunner
+}
+
+var _ migParted = (*migPartedCLI)(nil)
+
+func (opts *migPartedCLI) assertValidMIGConfig() error {
+ args := []string{
+ "--debug",
+ "assert",
+ "--valid-config",
+ "--config-file", opts.MIGPartedConfigFile,
+ "--selected-config", opts.SelectedMIGConfig,
+ }
+ return opts.runMigParted(args...)
+}
+
+func (opts *migPartedCLI) assertMIGConfig() error {
+ args := []string{
+ "--debug",
+ "assert",
+ "--config-file", opts.MIGPartedConfigFile,
+ "--selected-config", opts.SelectedMIGConfig,
+ }
+ return opts.runMigParted(args...)
+}
+
+func (opts *migPartedCLI) assertMIGModeOnly() error {
+ args := []string{
+ "--debug",
+ "assert",
+ "--mode-only",
+ "--config-file", opts.MIGPartedConfigFile,
+ "--selected-config", opts.SelectedMIGConfig,
+ }
+ return opts.runMigParted(args...)
+}
+
+func (opts *migPartedCLI) applyMIGModeOnly() error {
+ args := []string{
+ "--debug",
+ "apply",
+ "--mode-only",
+ "--config-file", opts.MIGPartedConfigFile,
+ "--selected-config", opts.SelectedMIGConfig,
+ }
+ return opts.runMigParted(args...)
+}
+
+func (opts *migPartedCLI) applyMIGConfig() error {
+ args := []string{
+ "--debug",
+ "apply",
+ "--config-file", opts.MIGPartedConfigFile,
+ "--selected-config", opts.SelectedMIGConfig,
+ }
+ return opts.runMigParted(args...)
+}
+
+func (opts *reconfigurer) hostPersistConfig() error {
+ config := fmt.Sprintf(`[Service]
+Environment="MIG_PARTED_SELECTED_CONFIG=%s"
+`, opts.SelectedMIGConfig)
+
+ stateFilePath := filepath.Join(opts.HostRootMount, opts.HostMIGManagerStateFile)
+ // #nosec G306 -- We cannot use 0600 here as the file is read by systemd.
+ if err := os.WriteFile(stateFilePath, []byte(config), 0644); err != nil {
+ return err
+ }
+
+ cmd := exec.Command("chroot", opts.HostRootMount, "systemctl", "daemon-reload") // #nosec G204 -- HostRootMount is validated via dirpath validator.
+ return opts.Run(cmd)
+}
+
+func (opts *reconfigureMIGOptions) hostStopSystemdServices() error {
+ opts.hostGPUClientServicesStopped = []string{}
+
+ for _, service := range opts.HostGPUClientServices {
+ if err := processSystemdService(opts, service, "stop"); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (opts *reconfigureMIGOptions) hostStartSystemdServices() error {
+ if len(opts.hostGPUClientServicesStopped) == 0 {
+ for _, service := range opts.HostGPUClientServices {
+ if shouldRestartService(opts, service) {
+ opts.hostGPUClientServicesStopped = append(opts.hostGPUClientServicesStopped, service)
+ }
+ }
+ }
+
+ var errs error
+ for _, service := range opts.hostGPUClientServicesStopped {
+ log.Infof("Starting %s", service)
+ cmd := exec.Command("chroot", opts.HostRootMount, "systemctl", "start", service) // #nosec G204 -- HostRootMount validated via dirpath, service validated via systemd_service_name.
+ if err := cmd.Run(); err != nil {
+ serviceError := fmt.Errorf("error starting %q: %w", service, err)
+ log.Errorf("%v; skipping, but continuing...", serviceError)
+
+ errs = errors.Join(errs, serviceError)
+ }
+ }
+
+ if errs != nil {
+ return fmt.Errorf("some services failed to start: %w", errs)
+ }
+ return nil
+}
+
+func processSystemdService(opts *reconfigureMIGOptions, service, action string) error {
+ cmd := exec.Command("chroot", opts.HostRootMount, "systemctl", "-q", "is-active", service) // #nosec G204 -- HostRootMount validated via dirpath, service validated via systemd_service_name.
+ if err := cmd.Run(); err == nil {
+ log.Infof("%s %s (active, will-restart)", action, service)
+ cmd = exec.Command("chroot", opts.HostRootMount, "systemctl", action, service) // #nosec G204 -- HostRootMount validated via dirpath, service validated via systemd_service_name, action is controlled parameter.
+ if err := cmd.Run(); err != nil {
+ return err
+ }
+ if action == "stop" {
+ opts.hostGPUClientServicesStopped = append([]string{service}, opts.hostGPUClientServicesStopped...)
+ }
+ return nil
+ }
+
+ cmd = exec.Command("chroot", opts.HostRootMount, "systemctl", "-q", "is-enabled", service) // #nosec G204 -- HostRootMount validated via dirpath, service validated via systemd_service_name.
+ if err := cmd.Run(); err != nil {
+ log.Infof("Skipping %s (no-exist)", service)
+ return nil
+ }
+
+ cmd = exec.Command("chroot", opts.HostRootMount, "systemctl", "-q", "is-failed", service) // #nosec G204 -- HostRootMount validated via dirpath, service validated via systemd_service_name.
+ if err := cmd.Run(); err == nil {
+ log.Infof("Skipping %s (is-failed, will-restart)", service)
+ if action == "stop" {
+ opts.hostGPUClientServicesStopped = append([]string{service}, opts.hostGPUClientServicesStopped...)
+ }
+ return nil
+ }
+
+ cmd = exec.Command("chroot", opts.HostRootMount, "systemctl", "-q", "is-enabled", service) // #nosec G204 -- HostRootMount validated via dirpath, service validated via systemd_service_name.
+ if err := cmd.Run(); err != nil {
+ log.Infof("Skipping %s (disabled)", service)
+ return nil
+ }
+
+ cmd = exec.Command("chroot", opts.HostRootMount, "systemctl", "show", "--property=Type", service) // #nosec G204 -- HostRootMount validated via dirpath, service validated via systemd_service_name.
+ output, err := cmd.Output()
+ if err != nil {
+ return err
+ }
+ if strings.TrimSpace(string(output)) == "Type=oneshot" {
+ log.Infof("Skipping %s (inactive, oneshot, no-restart)", service)
+ return nil
+ }
+
+ log.Infof("Skipping %s (inactive, will-restart)", service)
+ if action == "stop" {
+ opts.hostGPUClientServicesStopped = append([]string{service}, opts.hostGPUClientServicesStopped...)
+ }
+ return nil
+}
+
+func shouldRestartService(opts *reconfigureMIGOptions, service string) bool {
+ cmd := exec.Command("chroot", opts.HostRootMount, "systemctl", "-q", "is-active", service) // #nosec G204 -- HostRootMount validated via dirpath, service validated via systemd_service_name.
+ if err := cmd.Run(); err == nil {
+ return false
+ }
+
+ cmd = exec.Command("chroot", opts.HostRootMount, "systemctl", "-q", "is-enabled", service) // #nosec G204 -- HostRootMount validated via dirpath, service validated via systemd_service_name.
+ if err := cmd.Run(); err != nil {
+ return false
+ }
+
+ cmd = exec.Command("chroot", opts.HostRootMount, "systemctl", "-q", "is-failed", service) // #nosec G204 -- HostRootMount validated via dirpath, service validated via systemd_service_name.
+ if err := cmd.Run(); err == nil {
+ return true
+ }
+
+ cmd = exec.Command("chroot", opts.HostRootMount, "systemctl", "-q", "is-enabled", service) // #nosec G204 -- HostRootMount validated via dirpath, service validated via systemd_service_name.
+ if err := cmd.Run(); err != nil {
+ return false
+ }
+
+ cmd = exec.Command("chroot", opts.HostRootMount, "systemctl", "show", "--property=Type", service) // #nosec G204 -- HostRootMount validated via dirpath, service validated via systemd_service_name.
+ output, err := cmd.Output()
+ if err != nil {
+ return false
+ }
+ if strings.TrimSpace(string(output)) == "Type=oneshot" {
+ return false
+ }
+
+ return true
+}
+
+func (c *commandWithOutput) Run(cmd *exec.Cmd) error {
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ return cmd.Run()
+}
+
+func (opts *migPartedCLI) runMigParted(args ...string) error {
+ cmd := opts.migPartedCmd(args...)
+ return opts.Run(cmd)
+}
+
+func (opts *migPartedCLI) migPartedCmd(args ...string) *exec.Cmd {
+ cmd := exec.Command(migPartedCliName, args...)
+ cmd.Env = append(os.Environ(), fmt.Sprintf("%s=%s", ldPreloadEnvVar, opts.DriverLibraryPath))
+ return cmd
+}
+
+func rebootHost(hostRootMount string) error {
+ cmd := exec.Command("chroot", hostRootMount, "reboot")
+ if err := cmd.Start(); err != nil {
+ return err
+ }
+
+ os.Exit(0)
+ return nil
+}
+
+type node struct {
+ clientset *kubernetes.Clientset
+ name string
+}
+
+func (n *node) getNodeLabelValue(label string) (string, error) {
+ node, err := n.clientset.CoreV1().Nodes().Get(context.TODO(), n.name, metav1.GetOptions{})
+ if err != nil {
+ return "", fmt.Errorf("unable to get node object: %w", err)
+ }
+
+ value, ok := node.Labels[label]
+ if !ok {
+ return "", nil
+ }
+
+ return value, nil
+}
+
+func (n *node) setNodeLabelValue(label, value string) error {
+ node, err := n.clientset.CoreV1().Nodes().Get(context.TODO(), n.name, metav1.GetOptions{})
+ if err != nil {
+ return fmt.Errorf("unable to get node object: %w", err)
+ }
+
+ labels := node.GetLabels()
+ labels[label] = value
+ node.SetLabels(labels)
+ _, err = n.clientset.CoreV1().Nodes().Update(context.TODO(), node, metav1.UpdateOptions{})
+ if err != nil {
+ return fmt.Errorf("unable to update node object: %w", err)
+ }
+
+ return nil
+}
diff --git a/pkg/mig/reconfigure/reconfigure_test.go b/pkg/mig/reconfigure/reconfigure_test.go
new file mode 100644
index 00000000..83754d84
--- /dev/null
+++ b/pkg/mig/reconfigure/reconfigure_test.go
@@ -0,0 +1,352 @@
+/**
+# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+# SPDX-License-Identifier: Apache-2.0
+#
+# 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 reconfigure
+
+import (
+ "fmt"
+ "os/exec"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+type commandRunnerWithCLI struct {
+ mock *commandRunnerMock
+ calls [][]string
+}
+
+func (c *commandRunnerWithCLI) Run(cmd *exec.Cmd) error {
+ c.calls = append(c.calls, append([]string{cmd.Path}, cmd.Args...))
+ return c.mock.Run(cmd)
+}
+
+type nodeWithLabels struct {
+ mock *nodeLabellerMock
+ setLabels map[string]string
+}
+
+func (n *nodeWithLabels) getNodeLabelValue(label string) (string, error) {
+ return n.mock.getNodeLabelValue(label)
+}
+
+func (n *nodeWithLabels) setNodeLabelValue(label string, value string) error {
+ if err := n.mock.setNodeLabelValue(label, value); err != nil {
+ return err
+ }
+ if n.setLabels == nil {
+ n.setLabels = make(map[string]string)
+ }
+ n.setLabels[label] = value
+ return nil
+}
+
+func TestReconfigure(t *testing.T) {
+ testCases := []struct {
+ description string
+ options reconfigureMIGOptions
+ migParted *migPartedMock
+ checkMigParted func(*migPartedMock)
+ nodeLabeller *nodeWithLabels
+ checkNodeLabeller func(*nodeWithLabels)
+ expectedError error
+ expectedCalls [][]string
+ }{
+ {
+ description: "mig assert valid config failure does not call commands",
+ options: reconfigureMIGOptions{
+ NodeName: "NodeName",
+ MIGPartedConfigFile: "/path/to/config/file.yaml",
+ SelectedMIGConfig: "selected-mig-config",
+ DriverLibraryPath: "/path/to/libnvidia-ml.so.1",
+ HostRootMount: "/host/",
+ ConfigStateLabel: "example.com/config.state",
+ },
+ migParted: &migPartedMock{
+ assertValidMIGConfigFunc: func() error {
+ return fmt.Errorf("invalid mig config")
+ },
+ },
+ checkMigParted: func(mpm *migPartedMock) {
+ require.Len(t, mpm.calls.assertValidMIGConfig, 1)
+ require.Len(t, mpm.calls.applyMIGConfig, 0)
+ require.Len(t, mpm.calls.assertMIGModeOnly, 0)
+ require.Len(t, mpm.calls.applyMIGModeOnly, 0)
+ require.Len(t, mpm.calls.applyMIGConfig, 0)
+ },
+ expectedError: fmt.Errorf("error validating the selected MIG configuration: invalid mig config"),
+ expectedCalls: nil,
+ },
+ {
+ description: "node label error is causes exit",
+ options: reconfigureMIGOptions{
+ NodeName: "NodeName",
+ MIGPartedConfigFile: "/path/to/config/file.yaml",
+ SelectedMIGConfig: "selected-mig-config",
+ DriverLibraryPath: "/path/to/libnvidia-ml.so.1",
+ HostRootMount: "/host/",
+ ConfigStateLabel: "example.com/config.state",
+ },
+ migParted: &migPartedMock{
+ assertValidMIGConfigFunc: func() error {
+ return nil
+ },
+ },
+ checkMigParted: func(mpm *migPartedMock) {
+ require.Len(t, mpm.calls.assertValidMIGConfig, 1)
+ require.Len(t, mpm.calls.applyMIGConfig, 0)
+ require.Len(t, mpm.calls.assertMIGModeOnly, 0)
+ require.Len(t, mpm.calls.applyMIGModeOnly, 0)
+ require.Len(t, mpm.calls.applyMIGConfig, 0)
+ },
+ nodeLabeller: &nodeWithLabels{
+ mock: &nodeLabellerMock{
+ getNodeLabelValueFunc: func(s string) (string, error) {
+ return "", fmt.Errorf("error getting label")
+ },
+ },
+ },
+ checkNodeLabeller: func(nwl *nodeWithLabels) {
+ calls := nwl.mock.getNodeLabelValueCalls()
+ require.Len(t, calls, 1)
+ require.EqualValues(t, []struct{ S string }{{"example.com/config.state"}}, calls)
+ },
+ expectedError: fmt.Errorf(`unable to get the value of the "example.com/config.state" label: error getting label`),
+ },
+ {
+ description: "reconfigure exits if config is applied",
+ options: reconfigureMIGOptions{
+ NodeName: "NodeName",
+ MIGPartedConfigFile: "/path/to/config/file.yaml",
+ SelectedMIGConfig: "selected-mig-config",
+ DriverLibraryPath: "/path/to/libnvidia-ml.so.1",
+ HostRootMount: "/host/",
+ ConfigStateLabel: "example.com/config.state",
+ },
+ migParted: &migPartedMock{
+ assertValidMIGConfigFunc: func() error {
+ return nil
+ },
+ assertMIGConfigFunc: func() error {
+ return nil
+ },
+ },
+ checkMigParted: func(mpm *migPartedMock) {
+ require.Len(t, mpm.calls.assertValidMIGConfig, 1)
+ require.Len(t, mpm.calls.assertMIGConfig, 1)
+ require.Len(t, mpm.calls.applyMIGConfig, 0)
+ require.Len(t, mpm.calls.assertMIGModeOnly, 0)
+ require.Len(t, mpm.calls.applyMIGModeOnly, 0)
+ },
+ nodeLabeller: &nodeWithLabels{
+ mock: &nodeLabellerMock{
+ getNodeLabelValueFunc: func(s string) (string, error) {
+ return "current-state", nil
+ },
+ },
+ },
+ checkNodeLabeller: func(nwl *nodeWithLabels) {
+ calls := nwl.mock.getNodeLabelValueCalls()
+ require.Len(t, calls, 1)
+ require.EqualValues(t, []struct{ S string }{{"example.com/config.state"}}, calls)
+ },
+ expectedError: nil,
+ },
+ {
+ description: "mode change required after reboot is error",
+ options: reconfigureMIGOptions{
+ NodeName: "NodeName",
+ MIGPartedConfigFile: "/path/to/config/file.yaml",
+ SelectedMIGConfig: "selected-mig-config",
+ DriverLibraryPath: "/path/to/libnvidia-ml.so.1",
+ HostRootMount: "/host/",
+ ConfigStateLabel: "example.com/config.state",
+ },
+ migParted: &migPartedMock{
+ assertValidMIGConfigFunc: func() error {
+ return nil
+ },
+ assertMIGConfigFunc: func() error {
+ return fmt.Errorf("config needs updating")
+ },
+ assertMIGModeOnlyFunc: func() error {
+ return fmt.Errorf("mode needs updating")
+ },
+ },
+ checkMigParted: func(mpm *migPartedMock) {
+ require.Len(t, mpm.calls.assertValidMIGConfig, 1)
+ require.Len(t, mpm.calls.assertMIGConfig, 1)
+ require.Len(t, mpm.calls.assertMIGModeOnly, 1)
+ require.Len(t, mpm.calls.applyMIGConfig, 0)
+ require.Len(t, mpm.calls.applyMIGModeOnly, 0)
+ },
+ nodeLabeller: &nodeWithLabels{
+ mock: &nodeLabellerMock{
+ getNodeLabelValueFunc: func(s string) (string, error) {
+ return "rebooting", nil
+ },
+ },
+ },
+ checkNodeLabeller: func(nwl *nodeWithLabels) {
+ calls := nwl.mock.getNodeLabelValueCalls()
+ require.Len(t, calls, 1)
+ require.EqualValues(t, []struct{ S string }{{"example.com/config.state"}}, calls)
+ },
+ expectedError: fmt.Errorf("MIG mode change failed after reboot: mode needs updating"),
+ },
+ {
+ description: "mode does not need updating; apply config error is returned",
+ options: reconfigureMIGOptions{
+ NodeName: "NodeName",
+ MIGPartedConfigFile: "/path/to/config/file.yaml",
+ SelectedMIGConfig: "selected-mig-config",
+ DriverLibraryPath: "/path/to/libnvidia-ml.so.1",
+ HostRootMount: "/host/",
+ ConfigStateLabel: "example.com/config.state",
+ },
+ migParted: &migPartedMock{
+ assertValidMIGConfigFunc: func() error {
+ return nil
+ },
+ assertMIGConfigFunc: func() error {
+ return fmt.Errorf("config needs updating")
+ },
+ assertMIGModeOnlyFunc: func() error {
+ return nil
+ },
+ applyMIGModeOnlyFunc: func() error {
+ return nil
+ },
+ applyMIGConfigFunc: func() error {
+ return fmt.Errorf("failed to apply config")
+ },
+ },
+ checkMigParted: func(mpm *migPartedMock) {
+ require.Len(t, mpm.calls.assertValidMIGConfig, 1)
+ require.Len(t, mpm.calls.assertMIGConfig, 1)
+ require.Len(t, mpm.calls.assertMIGModeOnly, 2)
+ require.Len(t, mpm.calls.applyMIGModeOnly, 1)
+ require.Len(t, mpm.calls.applyMIGConfig, 1)
+ },
+ nodeLabeller: &nodeWithLabels{
+ mock: &nodeLabellerMock{
+ getNodeLabelValueFunc: func(s string) (string, error) {
+ return "current-state", nil
+ },
+ },
+ },
+ checkNodeLabeller: func(nwl *nodeWithLabels) {
+ calls := nwl.mock.getNodeLabelValueCalls()
+ require.Len(t, calls, 1)
+ require.EqualValues(t, []struct{ S string }{{"example.com/config.state"}}, calls)
+ },
+ expectedError: fmt.Errorf("failed to apply config"),
+ },
+ {
+ description: "mode does not need updating; apply config succeeds",
+ options: reconfigureMIGOptions{
+ NodeName: "NodeName",
+ MIGPartedConfigFile: "/path/to/config/file.yaml",
+ SelectedMIGConfig: "selected-mig-config",
+ DriverLibraryPath: "/path/to/libnvidia-ml.so.1",
+ HostRootMount: "/host/",
+ ConfigStateLabel: "example.com/config.state",
+ },
+ migParted: &migPartedMock{
+ assertValidMIGConfigFunc: func() error {
+ return nil
+ },
+ assertMIGConfigFunc: func() error {
+ return fmt.Errorf("config needs updating")
+ },
+ assertMIGModeOnlyFunc: func() error {
+ return nil
+ },
+ applyMIGModeOnlyFunc: func() error {
+ return nil
+ },
+ applyMIGConfigFunc: func() error {
+ return nil
+ },
+ },
+ checkMigParted: func(mpm *migPartedMock) {
+ require.Len(t, mpm.calls.assertValidMIGConfig, 1)
+ require.Len(t, mpm.calls.assertMIGConfig, 1)
+ require.Len(t, mpm.calls.assertMIGModeOnly, 2)
+ require.Len(t, mpm.calls.applyMIGModeOnly, 1)
+ require.Len(t, mpm.calls.applyMIGConfig, 1)
+ },
+ nodeLabeller: &nodeWithLabels{
+ mock: &nodeLabellerMock{
+ getNodeLabelValueFunc: func(s string) (string, error) {
+ return "current-state", nil
+ },
+ },
+ },
+ checkNodeLabeller: func(nwl *nodeWithLabels) {
+ calls := nwl.mock.getNodeLabelValueCalls()
+ require.Len(t, calls, 1)
+ require.EqualValues(t, []struct{ S string }{{"example.com/config.state"}}, calls)
+ },
+ expectedError: nil,
+ },
+ }
+
+ for _, tc := range testCases {
+ commandRunner := &commandRunnerWithCLI{
+ mock: &commandRunnerMock{
+ RunFunc: func(cmd *exec.Cmd) error {
+ return fmt.Errorf("error running command %v", cmd.Path)
+ },
+ },
+ }
+
+ t.Run(tc.description, func(t *testing.T) {
+ // TODO: Once we have better mocks in place for the following
+ // functionality, we can update this.
+ require.False(t, tc.options.WithReboot)
+ require.False(t, tc.options.WithShutdownHostGPUClients)
+
+ // We test explicit validation in a separate test.
+ // For now we only ensure that the options are valid.
+ require.NoError(t, tc.options.Validate())
+
+ r := &reconfigurer{
+ reconfigureMIGOptions: &tc.options,
+ commandRunner: commandRunner,
+ migParted: tc.migParted,
+ node: tc.nodeLabeller,
+ }
+
+ err := r.Reconfigure()
+ if tc.expectedError == nil {
+ require.NoError(t, err)
+ } else {
+ require.EqualError(t, err, tc.expectedError.Error())
+ }
+
+ if tc.checkMigParted != nil {
+ tc.checkMigParted(tc.migParted)
+ }
+ if tc.checkNodeLabeller != nil {
+ tc.checkNodeLabeller(tc.nodeLabeller)
+ }
+
+ require.EqualValues(t, tc.expectedCalls, commandRunner.calls)
+ })
+ }
+}
diff --git a/pkg/mig/reconfigure/validate.go b/pkg/mig/reconfigure/validate.go
new file mode 100644
index 00000000..a25ad0b7
--- /dev/null
+++ b/pkg/mig/reconfigure/validate.go
@@ -0,0 +1,82 @@
+/**
+# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+# SPDX-License-Identifier: Apache-2.0
+#
+# 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 reconfigure
+
+import (
+ "fmt"
+ "regexp"
+ "strings"
+
+ "github.com/go-playground/validator/v10"
+)
+
+var (
+ systemdServicePrefixPattern = regexp.MustCompile(`^[a-zA-Z0-9:._\\-]+\.(service|socket|device|mount|automount|swap|target|path|timer|slice|scope)$`)
+)
+
+// Validate the MIG reconfiguration options.
+func (o *reconfigureMIGOptions) Validate() error {
+ validate := validator.New(validator.WithRequiredStructEnabled())
+
+ err := validate.RegisterValidation("systemd_service_name", validateSystemdServiceName)
+ if err != nil {
+ return fmt.Errorf("unable to register systemd service name validator: %w", err)
+ }
+ return validate.Struct(o)
+}
+
+// validateSystemdServiceName validates a systemd service name according to systemd naming rules.
+// The unit name prefix must consist of one or more valid characters (ASCII letters, digits, ":", "-", "_", ".", and "\").
+// The total length of the unit name including the suffix must not exceed 255 characters.
+// The unit type suffix must be one of ".service", ".socket", ".device", ".mount", ".automount", ".swap", ".target", ".path", ".timer", ".slice", or ".scope".
+// Source: https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html
+func validateSystemdServiceName(fl validator.FieldLevel) bool {
+ serviceName := fl.Field().String()
+
+ if len(serviceName) == 0 || len(serviceName) > 255 {
+ return false
+ }
+
+ validSuffixes := []string{
+ ".service",
+ ".socket",
+ ".device",
+ ".mount",
+ ".automount",
+ ".swap",
+ ".target",
+ ".path",
+ ".timer",
+ ".slice",
+ ".scope",
+ }
+
+ hasSuffix := false
+ for _, suffix := range validSuffixes {
+ if strings.HasSuffix(serviceName, suffix) {
+ hasSuffix = true
+ break
+ }
+ }
+
+ if !hasSuffix {
+ return false
+ }
+
+ return systemdServicePrefixPattern.MatchString(serviceName)
+}
diff --git a/vendor/github.com/gabriel-vasile/mimetype/.gitattributes b/vendor/github.com/gabriel-vasile/mimetype/.gitattributes
new file mode 100644
index 00000000..0cc26ec0
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/.gitattributes
@@ -0,0 +1 @@
+testdata/* linguist-vendored
diff --git a/vendor/github.com/gabriel-vasile/mimetype/CODE_OF_CONDUCT.md b/vendor/github.com/gabriel-vasile/mimetype/CODE_OF_CONDUCT.md
new file mode 100644
index 00000000..8479cd87
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/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 vasile.gabriel@email.com. 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/gabriel-vasile/mimetype/CONTRIBUTING.md b/vendor/github.com/gabriel-vasile/mimetype/CONTRIBUTING.md
new file mode 100644
index 00000000..56ae4e57
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/CONTRIBUTING.md
@@ -0,0 +1,12 @@
+## Contribute
+Contributions to **mimetype** are welcome. If you find an issue and you consider
+contributing, you can use the [Github issues tracker](https://github.com/gabriel-vasile/mimetype/issues)
+in order to report it, or better yet, open a pull request.
+
+Code contributions must respect these rules:
+ - code must be test covered
+ - code must be formatted using gofmt tool
+ - exported names must be documented
+
+**Important**: By submitting a pull request, you agree to allow the project
+owner to license your work under the same license as that used by the project.
diff --git a/vendor/github.com/gabriel-vasile/mimetype/LICENSE b/vendor/github.com/gabriel-vasile/mimetype/LICENSE
new file mode 100644
index 00000000..13b61daa
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 Gabriel Vasile
+
+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/gabriel-vasile/mimetype/README.md b/vendor/github.com/gabriel-vasile/mimetype/README.md
new file mode 100644
index 00000000..aa88b4bd
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/README.md
@@ -0,0 +1,102 @@
+
+ mimetype
+
+
+
+ A package for detecting MIME types and extensions based on magic numbers
+
+
+ Goroutine safe, extensible, no C bindings
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+## Features
+- fast and precise MIME type and file extension detection
+- long list of [supported MIME types](supported_mimes.md)
+- possibility to [extend](https://pkg.go.dev/github.com/gabriel-vasile/mimetype#example-package-Extend) with other file formats
+- common file formats are prioritized
+- [text vs. binary files differentiation](https://pkg.go.dev/github.com/gabriel-vasile/mimetype#example-package-TextVsBinary)
+- safe for concurrent usage
+
+## Install
+```bash
+go get github.com/gabriel-vasile/mimetype
+```
+
+## Usage
+```go
+mtype := mimetype.Detect([]byte)
+// OR
+mtype, err := mimetype.DetectReader(io.Reader)
+// OR
+mtype, err := mimetype.DetectFile("/path/to/file")
+fmt.Println(mtype.String(), mtype.Extension())
+```
+See the [runnable Go Playground examples](https://pkg.go.dev/github.com/gabriel-vasile/mimetype#pkg-overview).
+
+## Usage'
+Only use libraries like **mimetype** as a last resort. Content type detection
+using magic numbers is slow, inaccurate, and non-standard. Most of the times
+protocols have methods for specifying such metadata; e.g., `Content-Type` header
+in HTTP and SMTP.
+
+## FAQ
+Q: My file is in the list of [supported MIME types](supported_mimes.md) but
+it is not correctly detected. What should I do?
+
+A: Some file formats (often Microsoft Office documents) keep their signatures
+towards the end of the file. Try increasing the number of bytes used for detection
+with:
+```go
+mimetype.SetLimit(1024*1024) // Set limit to 1MB.
+// or
+mimetype.SetLimit(0) // No limit, whole file content used.
+mimetype.DetectFile("file.doc")
+```
+If increasing the limit does not help, please
+[open an issue](https://github.com/gabriel-vasile/mimetype/issues/new?assignees=&labels=&template=mismatched-mime-type-detected.md&title=).
+
+## Structure
+**mimetype** uses a hierarchical structure to keep the MIME type detection logic.
+This reduces the number of calls needed for detecting the file type. The reason
+behind this choice is that there are file formats used as containers for other
+file formats. For example, Microsoft Office files are just zip archives,
+containing specific metadata files. Once a file has been identified as a
+zip, there is no need to check if it is a text file, but it is worth checking if
+it is an Microsoft Office file.
+
+To prevent loading entire files into memory, when detecting from a
+[reader](https://pkg.go.dev/github.com/gabriel-vasile/mimetype#DetectReader)
+or from a [file](https://pkg.go.dev/github.com/gabriel-vasile/mimetype#DetectFile)
+**mimetype** limits itself to reading only the header of the input.
+
+
+
+
+## Performance
+Thanks to the hierarchical structure, searching for common formats first,
+and limiting itself to file headers, **mimetype** matches the performance of
+stdlib `http.DetectContentType` while outperforming the alternative package.
+
+```bash
+ mimetype http.DetectContentType filetype
+BenchmarkMatchTar-24 250 ns/op 400 ns/op 3778 ns/op
+BenchmarkMatchZip-24 524 ns/op 351 ns/op 4884 ns/op
+BenchmarkMatchJpeg-24 103 ns/op 228 ns/op 839 ns/op
+BenchmarkMatchGif-24 139 ns/op 202 ns/op 751 ns/op
+BenchmarkMatchPng-24 165 ns/op 221 ns/op 1176 ns/op
+```
+
+## Contributing
+See [CONTRIBUTING.md](CONTRIBUTING.md).
diff --git a/vendor/github.com/gabriel-vasile/mimetype/internal/charset/charset.go b/vendor/github.com/gabriel-vasile/mimetype/internal/charset/charset.go
new file mode 100644
index 00000000..0647f730
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/internal/charset/charset.go
@@ -0,0 +1,309 @@
+package charset
+
+import (
+ "bytes"
+ "encoding/xml"
+ "strings"
+ "unicode/utf8"
+
+ "golang.org/x/net/html"
+)
+
+const (
+ F = 0 /* character never appears in text */
+ T = 1 /* character appears in plain ASCII text */
+ I = 2 /* character appears in ISO-8859 text */
+ X = 3 /* character appears in non-ISO extended ASCII (Mac, IBM PC) */
+)
+
+var (
+ boms = []struct {
+ bom []byte
+ enc string
+ }{
+ {[]byte{0xEF, 0xBB, 0xBF}, "utf-8"},
+ {[]byte{0x00, 0x00, 0xFE, 0xFF}, "utf-32be"},
+ {[]byte{0xFF, 0xFE, 0x00, 0x00}, "utf-32le"},
+ {[]byte{0xFE, 0xFF}, "utf-16be"},
+ {[]byte{0xFF, 0xFE}, "utf-16le"},
+ }
+
+ // https://github.com/file/file/blob/fa93fb9f7d21935f1c7644c47d2975d31f12b812/src/encoding.c#L241
+ textChars = [256]byte{
+ /* BEL BS HT LF VT FF CR */
+ F, F, F, F, F, F, F, T, T, T, T, T, T, T, F, F, /* 0x0X */
+ /* ESC */
+ F, F, F, F, F, F, F, F, F, F, F, T, F, F, F, F, /* 0x1X */
+ T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x2X */
+ T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x3X */
+ T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x4X */
+ T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x5X */
+ T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x6X */
+ T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, F, /* 0x7X */
+ /* NEL */
+ X, X, X, X, X, T, X, X, X, X, X, X, X, X, X, X, /* 0x8X */
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, /* 0x9X */
+ I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xaX */
+ I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xbX */
+ I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xcX */
+ I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xdX */
+ I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xeX */
+ I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xfX */
+ }
+)
+
+// FromBOM returns the charset declared in the BOM of content.
+func FromBOM(content []byte) string {
+ for _, b := range boms {
+ if bytes.HasPrefix(content, b.bom) {
+ return b.enc
+ }
+ }
+ return ""
+}
+
+// FromPlain returns the charset of a plain text. It relies on BOM presence
+// and it falls back on checking each byte in content.
+func FromPlain(content []byte) string {
+ if len(content) == 0 {
+ return ""
+ }
+ if cset := FromBOM(content); cset != "" {
+ return cset
+ }
+ origContent := content
+ // Try to detect UTF-8.
+ // First eliminate any partial rune at the end.
+ for i := len(content) - 1; i >= 0 && i > len(content)-4; i-- {
+ b := content[i]
+ if b < 0x80 {
+ break
+ }
+ if utf8.RuneStart(b) {
+ content = content[:i]
+ break
+ }
+ }
+ hasHighBit := false
+ for _, c := range content {
+ if c >= 0x80 {
+ hasHighBit = true
+ break
+ }
+ }
+ if hasHighBit && utf8.Valid(content) {
+ return "utf-8"
+ }
+
+ // ASCII is a subset of UTF8. Follow W3C recommendation and replace with UTF8.
+ if ascii(origContent) {
+ return "utf-8"
+ }
+
+ return latin(origContent)
+}
+
+func latin(content []byte) string {
+ hasControlBytes := false
+ for _, b := range content {
+ t := textChars[b]
+ if t != T && t != I {
+ return ""
+ }
+ if b >= 0x80 && b <= 0x9F {
+ hasControlBytes = true
+ }
+ }
+ // Code range 0x80 to 0x9F is reserved for control characters in ISO-8859-1
+ // (so-called C1 Controls). Windows 1252, however, has printable punctuation
+ // characters in this range.
+ if hasControlBytes {
+ return "windows-1252"
+ }
+ return "iso-8859-1"
+}
+
+func ascii(content []byte) bool {
+ for _, b := range content {
+ if textChars[b] != T {
+ return false
+ }
+ }
+ return true
+}
+
+// FromXML returns the charset of an XML document. It relies on the XML
+// header and falls back on the plain
+// text content.
+func FromXML(content []byte) string {
+ if cset := fromXML(content); cset != "" {
+ return cset
+ }
+ return FromPlain(content)
+}
+func fromXML(content []byte) string {
+ content = trimLWS(content)
+ dec := xml.NewDecoder(bytes.NewReader(content))
+ rawT, err := dec.RawToken()
+ if err != nil {
+ return ""
+ }
+
+ t, ok := rawT.(xml.ProcInst)
+ if !ok {
+ return ""
+ }
+
+ return strings.ToLower(xmlEncoding(string(t.Inst)))
+}
+
+// FromHTML returns the charset of an HTML document. It first looks if a BOM is
+// present and if so uses it to determine the charset. If no BOM is present,
+// it relies on the meta tag and falls back on the
+// plain text content.
+func FromHTML(content []byte) string {
+ if cset := FromBOM(content); cset != "" {
+ return cset
+ }
+ if cset := fromHTML(content); cset != "" {
+ return cset
+ }
+ return FromPlain(content)
+}
+
+func fromHTML(content []byte) string {
+ z := html.NewTokenizer(bytes.NewReader(content))
+ for {
+ switch z.Next() {
+ case html.ErrorToken:
+ return ""
+
+ case html.StartTagToken, html.SelfClosingTagToken:
+ tagName, hasAttr := z.TagName()
+ if !bytes.Equal(tagName, []byte("meta")) {
+ continue
+ }
+ attrList := make(map[string]bool)
+ gotPragma := false
+
+ const (
+ dontKnow = iota
+ doNeedPragma
+ doNotNeedPragma
+ )
+ needPragma := dontKnow
+
+ name := ""
+ for hasAttr {
+ var key, val []byte
+ key, val, hasAttr = z.TagAttr()
+ ks := string(key)
+ if attrList[ks] {
+ continue
+ }
+ attrList[ks] = true
+ for i, c := range val {
+ if 'A' <= c && c <= 'Z' {
+ val[i] = c + 0x20
+ }
+ }
+
+ switch ks {
+ case "http-equiv":
+ if bytes.Equal(val, []byte("content-type")) {
+ gotPragma = true
+ }
+
+ case "content":
+ name = fromMetaElement(string(val))
+ if name != "" {
+ needPragma = doNeedPragma
+ }
+
+ case "charset":
+ name = string(val)
+ needPragma = doNotNeedPragma
+ }
+ }
+
+ if needPragma == dontKnow || needPragma == doNeedPragma && !gotPragma {
+ continue
+ }
+
+ if strings.HasPrefix(name, "utf-16") {
+ name = "utf-8"
+ }
+
+ return name
+ }
+ }
+}
+
+func fromMetaElement(s string) string {
+ for s != "" {
+ csLoc := strings.Index(s, "charset")
+ if csLoc == -1 {
+ return ""
+ }
+ s = s[csLoc+len("charset"):]
+ s = strings.TrimLeft(s, " \t\n\f\r")
+ if !strings.HasPrefix(s, "=") {
+ continue
+ }
+ s = s[1:]
+ s = strings.TrimLeft(s, " \t\n\f\r")
+ if s == "" {
+ return ""
+ }
+ if q := s[0]; q == '"' || q == '\'' {
+ s = s[1:]
+ closeQuote := strings.IndexRune(s, rune(q))
+ if closeQuote == -1 {
+ return ""
+ }
+ return s[:closeQuote]
+ }
+
+ end := strings.IndexAny(s, "; \t\n\f\r")
+ if end == -1 {
+ end = len(s)
+ }
+ return s[:end]
+ }
+ return ""
+}
+
+func xmlEncoding(s string) string {
+ param := "encoding="
+ idx := strings.Index(s, param)
+ if idx == -1 {
+ return ""
+ }
+ v := s[idx+len(param):]
+ if v == "" {
+ return ""
+ }
+ if v[0] != '\'' && v[0] != '"' {
+ return ""
+ }
+ idx = strings.IndexRune(v[1:], rune(v[0]))
+ if idx == -1 {
+ return ""
+ }
+ return v[1 : idx+1]
+}
+
+// trimLWS trims whitespace from beginning of the input.
+// TODO: find a way to call trimLWS once per detection instead of once in each
+// detector which needs the trimmed input.
+func trimLWS(in []byte) []byte {
+ firstNonWS := 0
+ for ; firstNonWS < len(in) && isWS(in[firstNonWS]); firstNonWS++ {
+ }
+
+ return in[firstNonWS:]
+}
+
+func isWS(b byte) bool {
+ return b == '\t' || b == '\n' || b == '\x0c' || b == '\r' || b == ' '
+}
diff --git a/vendor/github.com/gabriel-vasile/mimetype/internal/json/json.go b/vendor/github.com/gabriel-vasile/mimetype/internal/json/json.go
new file mode 100644
index 00000000..5b2ecee4
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/internal/json/json.go
@@ -0,0 +1,567 @@
+// 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 json provides a JSON value parser state machine.
+// This package is almost entirely copied from the Go stdlib.
+// Changes made to it permit users of the package to tell
+// if some slice of bytes is a valid beginning of a json string.
+package json
+
+import (
+ "fmt"
+ "sync"
+)
+
+type (
+ scanStatus int
+)
+
+const (
+ parseObjectKey = iota // parsing object key (before colon)
+ parseObjectValue // parsing object value (after colon)
+ parseArrayValue // parsing array value
+
+ scanContinue scanStatus = iota // uninteresting byte
+ scanBeginLiteral // end implied by next result != scanContinue
+ scanBeginObject // begin object
+ scanObjectKey // just finished object key (string)
+ scanObjectValue // just finished non-last object value
+ scanEndObject // end object (implies scanObjectValue if possible)
+ scanBeginArray // begin array
+ scanArrayValue // just finished array value
+ scanEndArray // end array (implies scanArrayValue if possible)
+ scanSkipSpace // space byte; can skip; known to be last "continue" result
+ scanEnd // top-level value ended *before* this byte; known to be first "stop" result
+ scanError // hit an error, scanner.err.
+
+ // This limits the max nesting depth to prevent stack overflow.
+ // This is permitted by https://tools.ietf.org/html/rfc7159#section-9
+ maxNestingDepth = 10000
+)
+
+type (
+ scanner struct {
+ step func(*scanner, byte) scanStatus
+ parseState []int
+ endTop bool
+ err error
+ index int
+ }
+)
+
+var scannerPool = sync.Pool{
+ New: func() any {
+ return &scanner{}
+ },
+}
+
+func newScanner() *scanner {
+ s := scannerPool.Get().(*scanner)
+ s.reset()
+ return s
+}
+
+func freeScanner(s *scanner) {
+ // Avoid hanging on to too much memory in extreme cases.
+ if len(s.parseState) > 1024 {
+ s.parseState = nil
+ }
+ scannerPool.Put(s)
+}
+
+// Scan returns the number of bytes scanned and if there was any error
+// in trying to reach the end of data.
+func Scan(data []byte) (int, error) {
+ s := newScanner()
+ defer freeScanner(s)
+ _ = checkValid(data, s)
+ return s.index, s.err
+}
+
+// checkValid verifies that data is valid JSON-encoded data.
+// scan is passed in for use by checkValid to avoid an allocation.
+func checkValid(data []byte, scan *scanner) error {
+ for _, c := range data {
+ scan.index++
+ if scan.step(scan, c) == scanError {
+ return scan.err
+ }
+ }
+ if scan.eof() == scanError {
+ return scan.err
+ }
+ return nil
+}
+
+func isSpace(c byte) bool {
+ return c == ' ' || c == '\t' || c == '\r' || c == '\n'
+}
+
+func (s *scanner) reset() {
+ s.step = stateBeginValue
+ s.parseState = s.parseState[0:0]
+ s.err = nil
+ s.endTop = false
+ s.index = 0
+}
+
+// eof tells the scanner that the end of input has been reached.
+// It returns a scan status just as s.step does.
+func (s *scanner) eof() scanStatus {
+ if s.err != nil {
+ return scanError
+ }
+ if s.endTop {
+ return scanEnd
+ }
+ s.step(s, ' ')
+ if s.endTop {
+ return scanEnd
+ }
+ if s.err == nil {
+ s.err = fmt.Errorf("unexpected end of JSON input")
+ }
+ return scanError
+}
+
+// pushParseState pushes a new parse state p onto the parse stack.
+// an error state is returned if maxNestingDepth was exceeded, otherwise successState is returned.
+func (s *scanner) pushParseState(c byte, newParseState int, successState scanStatus) scanStatus {
+ s.parseState = append(s.parseState, newParseState)
+ if len(s.parseState) <= maxNestingDepth {
+ return successState
+ }
+ return s.error(c, "exceeded max depth")
+}
+
+// popParseState pops a parse state (already obtained) off the stack
+// and updates s.step accordingly.
+func (s *scanner) popParseState() {
+ n := len(s.parseState) - 1
+ s.parseState = s.parseState[0:n]
+ if n == 0 {
+ s.step = stateEndTop
+ s.endTop = true
+ } else {
+ s.step = stateEndValue
+ }
+}
+
+// stateBeginValueOrEmpty is the state after reading `[`.
+func stateBeginValueOrEmpty(s *scanner, c byte) scanStatus {
+ if c <= ' ' && isSpace(c) {
+ return scanSkipSpace
+ }
+ if c == ']' {
+ return stateEndValue(s, c)
+ }
+ return stateBeginValue(s, c)
+}
+
+// stateBeginValue is the state at the beginning of the input.
+func stateBeginValue(s *scanner, c byte) scanStatus {
+ if c <= ' ' && isSpace(c) {
+ return scanSkipSpace
+ }
+ switch c {
+ case '{':
+ s.step = stateBeginStringOrEmpty
+ return s.pushParseState(c, parseObjectKey, scanBeginObject)
+ case '[':
+ s.step = stateBeginValueOrEmpty
+ return s.pushParseState(c, parseArrayValue, scanBeginArray)
+ case '"':
+ s.step = stateInString
+ return scanBeginLiteral
+ case '-':
+ s.step = stateNeg
+ return scanBeginLiteral
+ case '0': // beginning of 0.123
+ s.step = state0
+ return scanBeginLiteral
+ case 't': // beginning of true
+ s.step = stateT
+ return scanBeginLiteral
+ case 'f': // beginning of false
+ s.step = stateF
+ return scanBeginLiteral
+ case 'n': // beginning of null
+ s.step = stateN
+ return scanBeginLiteral
+ }
+ if '1' <= c && c <= '9' { // beginning of 1234.5
+ s.step = state1
+ return scanBeginLiteral
+ }
+ return s.error(c, "looking for beginning of value")
+}
+
+// stateBeginStringOrEmpty is the state after reading `{`.
+func stateBeginStringOrEmpty(s *scanner, c byte) scanStatus {
+ if c <= ' ' && isSpace(c) {
+ return scanSkipSpace
+ }
+ if c == '}' {
+ n := len(s.parseState)
+ s.parseState[n-1] = parseObjectValue
+ return stateEndValue(s, c)
+ }
+ return stateBeginString(s, c)
+}
+
+// stateBeginString is the state after reading `{"key": value,`.
+func stateBeginString(s *scanner, c byte) scanStatus {
+ if c <= ' ' && isSpace(c) {
+ return scanSkipSpace
+ }
+ if c == '"' {
+ s.step = stateInString
+ return scanBeginLiteral
+ }
+ return s.error(c, "looking for beginning of object key string")
+}
+
+// stateEndValue is the state after completing a value,
+// such as after reading `{}` or `true` or `["x"`.
+func stateEndValue(s *scanner, c byte) scanStatus {
+ n := len(s.parseState)
+ if n == 0 {
+ // Completed top-level before the current byte.
+ s.step = stateEndTop
+ s.endTop = true
+ return stateEndTop(s, c)
+ }
+ if c <= ' ' && isSpace(c) {
+ s.step = stateEndValue
+ return scanSkipSpace
+ }
+ ps := s.parseState[n-1]
+ switch ps {
+ case parseObjectKey:
+ if c == ':' {
+ s.parseState[n-1] = parseObjectValue
+ s.step = stateBeginValue
+ return scanObjectKey
+ }
+ return s.error(c, "after object key")
+ case parseObjectValue:
+ if c == ',' {
+ s.parseState[n-1] = parseObjectKey
+ s.step = stateBeginString
+ return scanObjectValue
+ }
+ if c == '}' {
+ s.popParseState()
+ return scanEndObject
+ }
+ return s.error(c, "after object key:value pair")
+ case parseArrayValue:
+ if c == ',' {
+ s.step = stateBeginValue
+ return scanArrayValue
+ }
+ if c == ']' {
+ s.popParseState()
+ return scanEndArray
+ }
+ return s.error(c, "after array element")
+ }
+ return s.error(c, "")
+}
+
+// stateEndTop is the state after finishing the top-level value,
+// such as after reading `{}` or `[1,2,3]`.
+// Only space characters should be seen now.
+func stateEndTop(s *scanner, c byte) scanStatus {
+ if c != ' ' && c != '\t' && c != '\r' && c != '\n' {
+ // Complain about non-space byte on next call.
+ s.error(c, "after top-level value")
+ }
+ return scanEnd
+}
+
+// stateInString is the state after reading `"`.
+func stateInString(s *scanner, c byte) scanStatus {
+ if c == '"' {
+ s.step = stateEndValue
+ return scanContinue
+ }
+ if c == '\\' {
+ s.step = stateInStringEsc
+ return scanContinue
+ }
+ if c < 0x20 {
+ return s.error(c, "in string literal")
+ }
+ return scanContinue
+}
+
+// stateInStringEsc is the state after reading `"\` during a quoted string.
+func stateInStringEsc(s *scanner, c byte) scanStatus {
+ switch c {
+ case 'b', 'f', 'n', 'r', 't', '\\', '/', '"':
+ s.step = stateInString
+ return scanContinue
+ case 'u':
+ s.step = stateInStringEscU
+ return scanContinue
+ }
+ return s.error(c, "in string escape code")
+}
+
+// stateInStringEscU is the state after reading `"\u` during a quoted string.
+func stateInStringEscU(s *scanner, c byte) scanStatus {
+ if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
+ s.step = stateInStringEscU1
+ return scanContinue
+ }
+ // numbers
+ return s.error(c, "in \\u hexadecimal character escape")
+}
+
+// stateInStringEscU1 is the state after reading `"\u1` during a quoted string.
+func stateInStringEscU1(s *scanner, c byte) scanStatus {
+ if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
+ s.step = stateInStringEscU12
+ return scanContinue
+ }
+ // numbers
+ return s.error(c, "in \\u hexadecimal character escape")
+}
+
+// stateInStringEscU12 is the state after reading `"\u12` during a quoted string.
+func stateInStringEscU12(s *scanner, c byte) scanStatus {
+ if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
+ s.step = stateInStringEscU123
+ return scanContinue
+ }
+ // numbers
+ return s.error(c, "in \\u hexadecimal character escape")
+}
+
+// stateInStringEscU123 is the state after reading `"\u123` during a quoted string.
+func stateInStringEscU123(s *scanner, c byte) scanStatus {
+ if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
+ s.step = stateInString
+ return scanContinue
+ }
+ // numbers
+ return s.error(c, "in \\u hexadecimal character escape")
+}
+
+// stateNeg is the state after reading `-` during a number.
+func stateNeg(s *scanner, c byte) scanStatus {
+ if c == '0' {
+ s.step = state0
+ return scanContinue
+ }
+ if '1' <= c && c <= '9' {
+ s.step = state1
+ return scanContinue
+ }
+ return s.error(c, "in numeric literal")
+}
+
+// state1 is the state after reading a non-zero integer during a number,
+// such as after reading `1` or `100` but not `0`.
+func state1(s *scanner, c byte) scanStatus {
+ if '0' <= c && c <= '9' {
+ s.step = state1
+ return scanContinue
+ }
+ return state0(s, c)
+}
+
+// state0 is the state after reading `0` during a number.
+func state0(s *scanner, c byte) scanStatus {
+ if c == '.' {
+ s.step = stateDot
+ return scanContinue
+ }
+ if c == 'e' || c == 'E' {
+ s.step = stateE
+ return scanContinue
+ }
+ return stateEndValue(s, c)
+}
+
+// stateDot is the state after reading the integer and decimal point in a number,
+// such as after reading `1.`.
+func stateDot(s *scanner, c byte) scanStatus {
+ if '0' <= c && c <= '9' {
+ s.step = stateDot0
+ return scanContinue
+ }
+ return s.error(c, "after decimal point in numeric literal")
+}
+
+// stateDot0 is the state after reading the integer, decimal point, and subsequent
+// digits of a number, such as after reading `3.14`.
+func stateDot0(s *scanner, c byte) scanStatus {
+ if '0' <= c && c <= '9' {
+ return scanContinue
+ }
+ if c == 'e' || c == 'E' {
+ s.step = stateE
+ return scanContinue
+ }
+ return stateEndValue(s, c)
+}
+
+// stateE is the state after reading the mantissa and e in a number,
+// such as after reading `314e` or `0.314e`.
+func stateE(s *scanner, c byte) scanStatus {
+ if c == '+' || c == '-' {
+ s.step = stateESign
+ return scanContinue
+ }
+ return stateESign(s, c)
+}
+
+// stateESign is the state after reading the mantissa, e, and sign in a number,
+// such as after reading `314e-` or `0.314e+`.
+func stateESign(s *scanner, c byte) scanStatus {
+ if '0' <= c && c <= '9' {
+ s.step = stateE0
+ return scanContinue
+ }
+ return s.error(c, "in exponent of numeric literal")
+}
+
+// stateE0 is the state after reading the mantissa, e, optional sign,
+// and at least one digit of the exponent in a number,
+// such as after reading `314e-2` or `0.314e+1` or `3.14e0`.
+func stateE0(s *scanner, c byte) scanStatus {
+ if '0' <= c && c <= '9' {
+ return scanContinue
+ }
+ return stateEndValue(s, c)
+}
+
+// stateT is the state after reading `t`.
+func stateT(s *scanner, c byte) scanStatus {
+ if c == 'r' {
+ s.step = stateTr
+ return scanContinue
+ }
+ return s.error(c, "in literal true (expecting 'r')")
+}
+
+// stateTr is the state after reading `tr`.
+func stateTr(s *scanner, c byte) scanStatus {
+ if c == 'u' {
+ s.step = stateTru
+ return scanContinue
+ }
+ return s.error(c, "in literal true (expecting 'u')")
+}
+
+// stateTru is the state after reading `tru`.
+func stateTru(s *scanner, c byte) scanStatus {
+ if c == 'e' {
+ s.step = stateEndValue
+ return scanContinue
+ }
+ return s.error(c, "in literal true (expecting 'e')")
+}
+
+// stateF is the state after reading `f`.
+func stateF(s *scanner, c byte) scanStatus {
+ if c == 'a' {
+ s.step = stateFa
+ return scanContinue
+ }
+ return s.error(c, "in literal false (expecting 'a')")
+}
+
+// stateFa is the state after reading `fa`.
+func stateFa(s *scanner, c byte) scanStatus {
+ if c == 'l' {
+ s.step = stateFal
+ return scanContinue
+ }
+ return s.error(c, "in literal false (expecting 'l')")
+}
+
+// stateFal is the state after reading `fal`.
+func stateFal(s *scanner, c byte) scanStatus {
+ if c == 's' {
+ s.step = stateFals
+ return scanContinue
+ }
+ return s.error(c, "in literal false (expecting 's')")
+}
+
+// stateFals is the state after reading `fals`.
+func stateFals(s *scanner, c byte) scanStatus {
+ if c == 'e' {
+ s.step = stateEndValue
+ return scanContinue
+ }
+ return s.error(c, "in literal false (expecting 'e')")
+}
+
+// stateN is the state after reading `n`.
+func stateN(s *scanner, c byte) scanStatus {
+ if c == 'u' {
+ s.step = stateNu
+ return scanContinue
+ }
+ return s.error(c, "in literal null (expecting 'u')")
+}
+
+// stateNu is the state after reading `nu`.
+func stateNu(s *scanner, c byte) scanStatus {
+ if c == 'l' {
+ s.step = stateNul
+ return scanContinue
+ }
+ return s.error(c, "in literal null (expecting 'l')")
+}
+
+// stateNul is the state after reading `nul`.
+func stateNul(s *scanner, c byte) scanStatus {
+ if c == 'l' {
+ s.step = stateEndValue
+ return scanContinue
+ }
+ return s.error(c, "in literal null (expecting 'l')")
+}
+
+// stateError is the state after reaching a syntax error,
+// such as after reading `[1}` or `5.1.2`.
+func stateError(s *scanner, c byte) scanStatus {
+ return scanError
+}
+
+// error records an error and switches to the error state.
+func (s *scanner) error(c byte, context string) scanStatus {
+ s.step = stateError
+ s.err = fmt.Errorf("invalid character <<%c>> %s", c, context)
+ return scanError
+}
diff --git a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/archive.go b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/archive.go
new file mode 100644
index 00000000..068d00f7
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/archive.go
@@ -0,0 +1,163 @@
+package magic
+
+import (
+ "bytes"
+ "encoding/binary"
+)
+
+var (
+ // SevenZ matches a 7z archive.
+ SevenZ = prefix([]byte{0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C})
+ // Gzip matches gzip files based on http://www.zlib.org/rfc-gzip.html#header-trailer.
+ Gzip = prefix([]byte{0x1f, 0x8b})
+ // Fits matches an Flexible Image Transport System file.
+ Fits = prefix([]byte{
+ 0x53, 0x49, 0x4D, 0x50, 0x4C, 0x45, 0x20, 0x20, 0x3D, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x54,
+ })
+ // Xar matches an eXtensible ARchive format file.
+ Xar = prefix([]byte{0x78, 0x61, 0x72, 0x21})
+ // Bz2 matches a bzip2 file.
+ Bz2 = prefix([]byte{0x42, 0x5A, 0x68})
+ // Ar matches an ar (Unix) archive file.
+ Ar = prefix([]byte{0x21, 0x3C, 0x61, 0x72, 0x63, 0x68, 0x3E})
+ // Deb matches a Debian package file.
+ Deb = offset([]byte{
+ 0x64, 0x65, 0x62, 0x69, 0x61, 0x6E, 0x2D,
+ 0x62, 0x69, 0x6E, 0x61, 0x72, 0x79,
+ }, 8)
+ // Warc matches a Web ARChive file.
+ Warc = prefix([]byte("WARC/1.0"), []byte("WARC/1.1"))
+ // Cab matches a Microsoft Cabinet archive file.
+ Cab = prefix([]byte("MSCF\x00\x00\x00\x00"))
+ // Xz matches an xz compressed stream based on https://tukaani.org/xz/xz-file-format.txt.
+ Xz = prefix([]byte{0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00})
+ // Lzip matches an Lzip compressed file.
+ Lzip = prefix([]byte{0x4c, 0x5a, 0x49, 0x50})
+ // RPM matches an RPM or Delta RPM package file.
+ RPM = prefix([]byte{0xed, 0xab, 0xee, 0xdb}, []byte("drpm"))
+ // Cpio matches a cpio archive file.
+ Cpio = prefix([]byte("070707"), []byte("070701"), []byte("070702"))
+ // RAR matches a RAR archive file.
+ RAR = prefix([]byte("Rar!\x1A\x07\x00"), []byte("Rar!\x1A\x07\x01\x00"))
+)
+
+// InstallShieldCab matches an InstallShield Cabinet archive file.
+func InstallShieldCab(raw []byte, _ uint32) bool {
+ return len(raw) > 7 &&
+ bytes.Equal(raw[0:4], []byte("ISc(")) &&
+ raw[6] == 0 &&
+ (raw[7] == 1 || raw[7] == 2 || raw[7] == 4)
+}
+
+// Zstd matches a Zstandard archive file.
+// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md
+func Zstd(raw []byte, limit uint32) bool {
+ if len(raw) < 4 {
+ return false
+ }
+ sig := binary.LittleEndian.Uint32(raw)
+ // Check for Zstandard frames and skippable frames.
+ return (sig >= 0xFD2FB522 && sig <= 0xFD2FB528) ||
+ (sig >= 0x184D2A50 && sig <= 0x184D2A5F)
+}
+
+// CRX matches a Chrome extension file: a zip archive prepended by a package header.
+func CRX(raw []byte, limit uint32) bool {
+ const minHeaderLen = 16
+ if len(raw) < minHeaderLen || !bytes.HasPrefix(raw, []byte("Cr24")) {
+ return false
+ }
+ pubkeyLen := binary.LittleEndian.Uint32(raw[8:12])
+ sigLen := binary.LittleEndian.Uint32(raw[12:16])
+ zipOffset := minHeaderLen + pubkeyLen + sigLen
+ if uint32(len(raw)) < zipOffset {
+ return false
+ }
+ return Zip(raw[zipOffset:], limit)
+}
+
+// Tar matches a (t)ape (ar)chive file.
+// Tar files are divided into 512 bytes records. First record contains a 257
+// bytes header padded with NUL.
+func Tar(raw []byte, _ uint32) bool {
+ const sizeRecord = 512
+
+ // The structure of a tar header:
+ // type TarHeader struct {
+ // Name [100]byte
+ // Mode [8]byte
+ // Uid [8]byte
+ // Gid [8]byte
+ // Size [12]byte
+ // Mtime [12]byte
+ // Chksum [8]byte
+ // Linkflag byte
+ // Linkname [100]byte
+ // Magic [8]byte
+ // Uname [32]byte
+ // Gname [32]byte
+ // Devmajor [8]byte
+ // Devminor [8]byte
+ // }
+
+ if len(raw) < sizeRecord {
+ return false
+ }
+ raw = raw[:sizeRecord]
+
+ // First 100 bytes of the header represent the file name.
+ // Check if file looks like Gentoo GLEP binary package.
+ if bytes.Contains(raw[:100], []byte("/gpkg-1\x00")) {
+ return false
+ }
+
+ // Get the checksum recorded into the file.
+ recsum := tarParseOctal(raw[148:156])
+ if recsum == -1 {
+ return false
+ }
+ sum1, sum2 := tarChksum(raw)
+ return recsum == sum1 || recsum == sum2
+}
+
+// tarParseOctal converts octal string to decimal int.
+func tarParseOctal(b []byte) int64 {
+ // Because unused fields are filled with NULs, we need to skip leading NULs.
+ // Fields may also be padded with spaces or NULs.
+ // So we remove leading and trailing NULs and spaces to be sure.
+ b = bytes.Trim(b, " \x00")
+
+ if len(b) == 0 {
+ return -1
+ }
+ ret := int64(0)
+ for _, b := range b {
+ if b == 0 {
+ break
+ }
+ if !(b >= '0' && b <= '7') {
+ return -1
+ }
+ ret = (ret << 3) | int64(b-'0')
+ }
+ return ret
+}
+
+// tarChksum computes the checksum for the header block b.
+// The actual checksum is written to same b block after it has been calculated.
+// Before calculation the bytes from b reserved for checksum have placeholder
+// value of ASCII space 0x20.
+// POSIX specifies a sum of the unsigned byte values, but the Sun tar used
+// signed byte values. We compute and return both.
+func tarChksum(b []byte) (unsigned, signed int64) {
+ for i, c := range b {
+ if 148 <= i && i < 156 {
+ c = ' ' // Treat the checksum field itself as all spaces.
+ }
+ unsigned += int64(c)
+ signed += int64(int8(c))
+ }
+ return unsigned, signed
+}
diff --git a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/audio.go b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/audio.go
new file mode 100644
index 00000000..d17e3248
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/audio.go
@@ -0,0 +1,76 @@
+package magic
+
+import (
+ "bytes"
+ "encoding/binary"
+)
+
+var (
+ // Flac matches a Free Lossless Audio Codec file.
+ Flac = prefix([]byte("\x66\x4C\x61\x43\x00\x00\x00\x22"))
+ // Midi matches a Musical Instrument Digital Interface file.
+ Midi = prefix([]byte("\x4D\x54\x68\x64"))
+ // Ape matches a Monkey's Audio file.
+ Ape = prefix([]byte("\x4D\x41\x43\x20\x96\x0F\x00\x00\x34\x00\x00\x00\x18\x00\x00\x00\x90\xE3"))
+ // MusePack matches a Musepack file.
+ MusePack = prefix([]byte("MPCK"))
+ // Au matches a Sun Microsystems au file.
+ Au = prefix([]byte("\x2E\x73\x6E\x64"))
+ // Amr matches an Adaptive Multi-Rate file.
+ Amr = prefix([]byte("\x23\x21\x41\x4D\x52"))
+ // Voc matches a Creative Voice file.
+ Voc = prefix([]byte("Creative Voice File"))
+ // M3u matches a Playlist file.
+ M3u = prefix([]byte("#EXTM3U"))
+ // AAC matches an Advanced Audio Coding file.
+ AAC = prefix([]byte{0xFF, 0xF1}, []byte{0xFF, 0xF9})
+)
+
+// Mp3 matches an mp3 file.
+func Mp3(raw []byte, limit uint32) bool {
+ if len(raw) < 3 {
+ return false
+ }
+
+ if bytes.HasPrefix(raw, []byte("ID3")) {
+ // MP3s with an ID3v2 tag will start with "ID3"
+ // ID3v1 tags, however appear at the end of the file.
+ return true
+ }
+
+ // Match MP3 files without tags
+ switch binary.BigEndian.Uint16(raw[:2]) & 0xFFFE {
+ case 0xFFFA:
+ // MPEG ADTS, layer III, v1
+ return true
+ case 0xFFF2:
+ // MPEG ADTS, layer III, v2
+ return true
+ case 0xFFE2:
+ // MPEG ADTS, layer III, v2.5
+ return true
+ }
+
+ return false
+}
+
+// Wav matches a Waveform Audio File Format file.
+func Wav(raw []byte, limit uint32) bool {
+ return len(raw) > 12 &&
+ bytes.Equal(raw[:4], []byte("RIFF")) &&
+ bytes.Equal(raw[8:12], []byte{0x57, 0x41, 0x56, 0x45})
+}
+
+// Aiff matches Audio Interchange File Format file.
+func Aiff(raw []byte, limit uint32) bool {
+ return len(raw) > 12 &&
+ bytes.Equal(raw[:4], []byte{0x46, 0x4F, 0x52, 0x4D}) &&
+ bytes.Equal(raw[8:12], []byte{0x41, 0x49, 0x46, 0x46})
+}
+
+// Qcp matches a Qualcomm Pure Voice file.
+func Qcp(raw []byte, limit uint32) bool {
+ return len(raw) > 12 &&
+ bytes.Equal(raw[:4], []byte("RIFF")) &&
+ bytes.Equal(raw[8:12], []byte("QLCM"))
+}
diff --git a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/binary.go b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/binary.go
new file mode 100644
index 00000000..76973201
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/binary.go
@@ -0,0 +1,203 @@
+package magic
+
+import (
+ "bytes"
+ "debug/macho"
+ "encoding/binary"
+)
+
+var (
+ // Lnk matches Microsoft lnk binary format.
+ Lnk = prefix([]byte{0x4C, 0x00, 0x00, 0x00, 0x01, 0x14, 0x02, 0x00})
+ // Wasm matches a web assembly File Format file.
+ Wasm = prefix([]byte{0x00, 0x61, 0x73, 0x6D})
+ // Exe matches a Windows/DOS executable file.
+ Exe = prefix([]byte{0x4D, 0x5A})
+ // Elf matches an Executable and Linkable Format file.
+ Elf = prefix([]byte{0x7F, 0x45, 0x4C, 0x46})
+ // Nes matches a Nintendo Entertainment system ROM file.
+ Nes = prefix([]byte{0x4E, 0x45, 0x53, 0x1A})
+ // SWF matches an Adobe Flash swf file.
+ SWF = prefix([]byte("CWS"), []byte("FWS"), []byte("ZWS"))
+ // Torrent has bencoded text in the beginning.
+ Torrent = prefix([]byte("d8:announce"))
+ // PAR1 matches a parquet file.
+ Par1 = prefix([]byte{0x50, 0x41, 0x52, 0x31})
+ // CBOR matches a Concise Binary Object Representation https://cbor.io/
+ CBOR = prefix([]byte{0xD9, 0xD9, 0xF7})
+)
+
+// Java bytecode and Mach-O binaries share the same magic number.
+// More info here https://github.com/threatstack/libmagic/blob/master/magic/Magdir/cafebabe
+func classOrMachOFat(in []byte) bool {
+ // There should be at least 8 bytes for both of them because the only way to
+ // quickly distinguish them is by comparing byte at position 7
+ if len(in) < 8 {
+ return false
+ }
+
+ return binary.BigEndian.Uint32(in) == macho.MagicFat
+}
+
+// Class matches a java class file.
+func Class(raw []byte, limit uint32) bool {
+ return classOrMachOFat(raw) && raw[7] > 30
+}
+
+// MachO matches Mach-O binaries format.
+func MachO(raw []byte, limit uint32) bool {
+ if classOrMachOFat(raw) && raw[7] < 0x14 {
+ return true
+ }
+
+ if len(raw) < 4 {
+ return false
+ }
+
+ be := binary.BigEndian.Uint32(raw)
+ le := binary.LittleEndian.Uint32(raw)
+
+ return be == macho.Magic32 ||
+ le == macho.Magic32 ||
+ be == macho.Magic64 ||
+ le == macho.Magic64
+}
+
+// Dbf matches a dBase file.
+// https://www.dbase.com/Knowledgebase/INT/db7_file_fmt.htm
+func Dbf(raw []byte, limit uint32) bool {
+ if len(raw) < 68 {
+ return false
+ }
+
+ // 3rd and 4th bytes contain the last update month and day of month.
+ if !(0 < raw[2] && raw[2] < 13 && 0 < raw[3] && raw[3] < 32) {
+ return false
+ }
+
+ // 12, 13, 30, 31 are reserved bytes and always filled with 0x00.
+ if raw[12] != 0x00 || raw[13] != 0x00 || raw[30] != 0x00 || raw[31] != 0x00 {
+ return false
+ }
+ // Production MDX flag;
+ // 0x01 if a production .MDX file exists for this table;
+ // 0x00 if no .MDX file exists.
+ if raw[28] > 0x01 {
+ return false
+ }
+
+ // dbf type is dictated by the first byte.
+ dbfTypes := []byte{
+ 0x02, 0x03, 0x04, 0x05, 0x30, 0x31, 0x32, 0x42, 0x62, 0x7B, 0x82,
+ 0x83, 0x87, 0x8A, 0x8B, 0x8E, 0xB3, 0xCB, 0xE5, 0xF5, 0xF4, 0xFB,
+ }
+ for _, b := range dbfTypes {
+ if raw[0] == b {
+ return true
+ }
+ }
+
+ return false
+}
+
+// ElfObj matches an object file.
+func ElfObj(raw []byte, limit uint32) bool {
+ return len(raw) > 17 && ((raw[16] == 0x01 && raw[17] == 0x00) ||
+ (raw[16] == 0x00 && raw[17] == 0x01))
+}
+
+// ElfExe matches an executable file.
+func ElfExe(raw []byte, limit uint32) bool {
+ return len(raw) > 17 && ((raw[16] == 0x02 && raw[17] == 0x00) ||
+ (raw[16] == 0x00 && raw[17] == 0x02))
+}
+
+// ElfLib matches a shared library file.
+func ElfLib(raw []byte, limit uint32) bool {
+ return len(raw) > 17 && ((raw[16] == 0x03 && raw[17] == 0x00) ||
+ (raw[16] == 0x00 && raw[17] == 0x03))
+}
+
+// ElfDump matches a core dump file.
+func ElfDump(raw []byte, limit uint32) bool {
+ return len(raw) > 17 && ((raw[16] == 0x04 && raw[17] == 0x00) ||
+ (raw[16] == 0x00 && raw[17] == 0x04))
+}
+
+// Dcm matches a DICOM medical format file.
+func Dcm(raw []byte, limit uint32) bool {
+ return len(raw) > 131 &&
+ bytes.Equal(raw[128:132], []byte{0x44, 0x49, 0x43, 0x4D})
+}
+
+// Marc matches a MARC21 (MAchine-Readable Cataloging) file.
+func Marc(raw []byte, limit uint32) bool {
+ // File is at least 24 bytes ("leader" field size).
+ if len(raw) < 24 {
+ return false
+ }
+
+ // Fixed bytes at offset 20.
+ if !bytes.Equal(raw[20:24], []byte("4500")) {
+ return false
+ }
+
+ // First 5 bytes are ASCII digits.
+ for i := 0; i < 5; i++ {
+ if raw[i] < '0' || raw[i] > '9' {
+ return false
+ }
+ }
+
+ // Field terminator is present in first 2048 bytes.
+ return bytes.Contains(raw[:min(2048, len(raw))], []byte{0x1E})
+}
+
+// Glb matches a glTF model format file.
+// GLB is the binary file format representation of 3D models saved in
+// the GL transmission Format (glTF).
+// GLB uses little endian and its header structure is as follows:
+//
+// <-- 12-byte header -->
+// | magic | version | length |
+// | (uint32) | (uint32) | (uint32) |
+// | \x67\x6C\x54\x46 | \x01\x00\x00\x00 | ... |
+// | g l T F | 1 | ... |
+//
+// Visit [glTF specification] and [IANA glTF entry] for more details.
+//
+// [glTF specification]: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html
+// [IANA glTF entry]: https://www.iana.org/assignments/media-types/model/gltf-binary
+var Glb = prefix([]byte("\x67\x6C\x54\x46\x02\x00\x00\x00"),
+ []byte("\x67\x6C\x54\x46\x01\x00\x00\x00"))
+
+// TzIf matches a Time Zone Information Format (TZif) file.
+// See more: https://tools.ietf.org/id/draft-murchison-tzdist-tzif-00.html#rfc.section.3
+// Its header structure is shown below:
+//
+// +---------------+---+
+// | magic (4) | <-+-- version (1)
+// +---------------+---+---------------------------------------+
+// | [unused - reserved for future use] (15) |
+// +---------------+---------------+---------------+-----------+
+// | isutccnt (4) | isstdcnt (4) | leapcnt (4) |
+// +---------------+---------------+---------------+
+// | timecnt (4) | typecnt (4) | charcnt (4) |
+func TzIf(raw []byte, limit uint32) bool {
+ // File is at least 44 bytes (header size).
+ if len(raw) < 44 {
+ return false
+ }
+
+ if !bytes.HasPrefix(raw, []byte("TZif")) {
+ return false
+ }
+
+ // Field "typecnt" MUST not be zero.
+ if binary.BigEndian.Uint32(raw[36:40]) == 0 {
+ return false
+ }
+
+ // Version has to be NUL (0x00), '2' (0x32) or '3' (0x33).
+ return raw[4] == 0x00 || raw[4] == 0x32 || raw[4] == 0x33
+}
diff --git a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/database.go b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/database.go
new file mode 100644
index 00000000..cb1fed12
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/database.go
@@ -0,0 +1,13 @@
+package magic
+
+var (
+ // Sqlite matches an SQLite database file.
+ Sqlite = prefix([]byte{
+ 0x53, 0x51, 0x4c, 0x69, 0x74, 0x65, 0x20, 0x66,
+ 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x33, 0x00,
+ })
+ // MsAccessAce matches Microsoft Access dababase file.
+ MsAccessAce = offset([]byte("Standard ACE DB"), 4)
+ // MsAccessMdb matches legacy Microsoft Access database file (JET, 2003 and earlier).
+ MsAccessMdb = offset([]byte("Standard Jet DB"), 4)
+)
diff --git a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/document.go b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/document.go
new file mode 100644
index 00000000..b3b26d5a
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/document.go
@@ -0,0 +1,62 @@
+package magic
+
+import "bytes"
+
+var (
+ // Pdf matches a Portable Document Format file.
+ // https://github.com/file/file/blob/11010cc805546a3e35597e67e1129a481aed40e8/magic/Magdir/pdf
+ Pdf = prefix(
+ // usual pdf signature
+ []byte("%PDF-"),
+ // new-line prefixed signature
+ []byte("\012%PDF-"),
+ // UTF-8 BOM prefixed signature
+ []byte("\xef\xbb\xbf%PDF-"),
+ )
+ // Fdf matches a Forms Data Format file.
+ Fdf = prefix([]byte("%FDF"))
+ // Mobi matches a Mobi file.
+ Mobi = offset([]byte("BOOKMOBI"), 60)
+ // Lit matches a Microsoft Lit file.
+ Lit = prefix([]byte("ITOLITLS"))
+)
+
+// DjVu matches a DjVu file.
+func DjVu(raw []byte, limit uint32) bool {
+ if len(raw) < 12 {
+ return false
+ }
+ if !bytes.HasPrefix(raw, []byte{0x41, 0x54, 0x26, 0x54, 0x46, 0x4F, 0x52, 0x4D}) {
+ return false
+ }
+ return bytes.HasPrefix(raw[12:], []byte("DJVM")) ||
+ bytes.HasPrefix(raw[12:], []byte("DJVU")) ||
+ bytes.HasPrefix(raw[12:], []byte("DJVI")) ||
+ bytes.HasPrefix(raw[12:], []byte("THUM"))
+}
+
+// P7s matches an .p7s signature File (PEM, Base64).
+func P7s(raw []byte, limit uint32) bool {
+ // Check for PEM Encoding.
+ if bytes.HasPrefix(raw, []byte("-----BEGIN PKCS7")) {
+ return true
+ }
+ // Check if DER Encoding is long enough.
+ if len(raw) < 20 {
+ return false
+ }
+ // Magic Bytes for the signedData ASN.1 encoding.
+ startHeader := [][]byte{{0x30, 0x80}, {0x30, 0x81}, {0x30, 0x82}, {0x30, 0x83}, {0x30, 0x84}}
+ signedDataMatch := []byte{0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07}
+ // Check if Header is correct. There are multiple valid headers.
+ for i, match := range startHeader {
+ // If first bytes match, then check for ASN.1 Object Type.
+ if bytes.HasPrefix(raw, match) {
+ if bytes.HasPrefix(raw[i+2:], signedDataMatch) {
+ return true
+ }
+ }
+ }
+
+ return false
+}
diff --git a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/font.go b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/font.go
new file mode 100644
index 00000000..43af2821
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/font.go
@@ -0,0 +1,39 @@
+package magic
+
+import (
+ "bytes"
+)
+
+var (
+ // Woff matches a Web Open Font Format file.
+ Woff = prefix([]byte("wOFF"))
+ // Woff2 matches a Web Open Font Format version 2 file.
+ Woff2 = prefix([]byte("wOF2"))
+ // Otf matches an OpenType font file.
+ Otf = prefix([]byte{0x4F, 0x54, 0x54, 0x4F, 0x00})
+)
+
+// Ttf matches a TrueType font file.
+func Ttf(raw []byte, limit uint32) bool {
+ if !bytes.HasPrefix(raw, []byte{0x00, 0x01, 0x00, 0x00}) {
+ return false
+ }
+ return !MsAccessAce(raw, limit) && !MsAccessMdb(raw, limit)
+}
+
+// Eot matches an Embedded OpenType font file.
+func Eot(raw []byte, limit uint32) bool {
+ return len(raw) > 35 &&
+ bytes.Equal(raw[34:36], []byte{0x4C, 0x50}) &&
+ (bytes.Equal(raw[8:11], []byte{0x02, 0x00, 0x01}) ||
+ bytes.Equal(raw[8:11], []byte{0x01, 0x00, 0x00}) ||
+ bytes.Equal(raw[8:11], []byte{0x02, 0x00, 0x02}))
+}
+
+// Ttc matches a TrueType Collection font file.
+func Ttc(raw []byte, limit uint32) bool {
+ return len(raw) > 7 &&
+ bytes.HasPrefix(raw, []byte("ttcf")) &&
+ (bytes.Equal(raw[4:8], []byte{0x00, 0x01, 0x00, 0x00}) ||
+ bytes.Equal(raw[4:8], []byte{0x00, 0x02, 0x00, 0x00}))
+}
diff --git a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/ftyp.go b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/ftyp.go
new file mode 100644
index 00000000..ac727139
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/ftyp.go
@@ -0,0 +1,109 @@
+package magic
+
+import (
+ "bytes"
+)
+
+var (
+ // AVIF matches an AV1 Image File Format still or animated.
+ // Wikipedia page seems outdated listing image/avif-sequence for animations.
+ // https://github.com/AOMediaCodec/av1-avif/issues/59
+ AVIF = ftyp([]byte("avif"), []byte("avis"))
+ // ThreeGP matches a 3GPP file.
+ ThreeGP = ftyp(
+ []byte("3gp1"), []byte("3gp2"), []byte("3gp3"), []byte("3gp4"),
+ []byte("3gp5"), []byte("3gp6"), []byte("3gp7"), []byte("3gs7"),
+ []byte("3ge6"), []byte("3ge7"), []byte("3gg6"),
+ )
+ // ThreeG2 matches a 3GPP2 file.
+ ThreeG2 = ftyp(
+ []byte("3g24"), []byte("3g25"), []byte("3g26"), []byte("3g2a"),
+ []byte("3g2b"), []byte("3g2c"), []byte("KDDI"),
+ )
+ // AMp4 matches an audio MP4 file.
+ AMp4 = ftyp(
+ // audio for Adobe Flash Player 9+
+ []byte("F4A "), []byte("F4B "),
+ // Apple iTunes AAC-LC (.M4A) Audio
+ []byte("M4B "), []byte("M4P "),
+ // MPEG-4 (.MP4) for SonyPSP
+ []byte("MSNV"),
+ // Nero Digital AAC Audio
+ []byte("NDAS"),
+ )
+ // Mqv matches a Sony / Mobile QuickTime file.
+ Mqv = ftyp([]byte("mqt "))
+ // M4a matches an audio M4A file.
+ M4a = ftyp([]byte("M4A "))
+ // M4v matches an Appl4 M4V video file.
+ M4v = ftyp([]byte("M4V "), []byte("M4VH"), []byte("M4VP"))
+ // Heic matches a High Efficiency Image Coding (HEIC) file.
+ Heic = ftyp([]byte("heic"), []byte("heix"))
+ // HeicSequence matches a High Efficiency Image Coding (HEIC) file sequence.
+ HeicSequence = ftyp([]byte("hevc"), []byte("hevx"))
+ // Heif matches a High Efficiency Image File Format (HEIF) file.
+ Heif = ftyp([]byte("mif1"), []byte("heim"), []byte("heis"), []byte("avic"))
+ // HeifSequence matches a High Efficiency Image File Format (HEIF) file sequence.
+ HeifSequence = ftyp([]byte("msf1"), []byte("hevm"), []byte("hevs"), []byte("avcs"))
+ // Mj2 matches a Motion JPEG 2000 file: https://en.wikipedia.org/wiki/Motion_JPEG_2000.
+ Mj2 = ftyp([]byte("mj2s"), []byte("mjp2"), []byte("MFSM"), []byte("MGSV"))
+ // Dvb matches a Digital Video Broadcasting file: https://dvb.org.
+ // https://cconcolato.github.io/mp4ra/filetype.html
+ // https://github.com/file/file/blob/512840337ead1076519332d24fefcaa8fac36e06/magic/Magdir/animation#L135-L154
+ Dvb = ftyp(
+ []byte("dby1"), []byte("dsms"), []byte("dts1"), []byte("dts2"),
+ []byte("dts3"), []byte("dxo "), []byte("dmb1"), []byte("dmpf"),
+ []byte("drc1"), []byte("dv1a"), []byte("dv1b"), []byte("dv2a"),
+ []byte("dv2b"), []byte("dv3a"), []byte("dv3b"), []byte("dvr1"),
+ []byte("dvt1"), []byte("emsg"))
+ // TODO: add support for remaining video formats at ftyps.com.
+)
+
+// QuickTime matches a QuickTime File Format file.
+// https://www.loc.gov/preservation/digital/formats/fdd/fdd000052.shtml
+// https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap1/qtff1.html#//apple_ref/doc/uid/TP40000939-CH203-38190
+// https://github.com/apache/tika/blob/0f5570691133c75ac4472c3340354a6c4080b104/tika-core/src/main/resources/org/apache/tika/mime/tika-mimetypes.xml#L7758-L7777
+func QuickTime(raw []byte, _ uint32) bool {
+ if len(raw) < 12 {
+ return false
+ }
+ // First 4 bytes represent the size of the atom as unsigned int.
+ // Next 4 bytes are the type of the atom.
+ // For `ftyp` atoms check if first byte in size is 0, otherwise, a text file
+ // which happens to contain 'ftypqt ' at index 4 will trigger a false positive.
+ if bytes.Equal(raw[4:12], []byte("ftypqt ")) ||
+ bytes.Equal(raw[4:12], []byte("ftypmoov")) {
+ return raw[0] == 0x00
+ }
+ basicAtomTypes := [][]byte{
+ []byte("moov\x00"),
+ []byte("mdat\x00"),
+ []byte("free\x00"),
+ []byte("skip\x00"),
+ []byte("pnot\x00"),
+ }
+ for _, a := range basicAtomTypes {
+ if bytes.Equal(raw[4:9], a) {
+ return true
+ }
+ }
+ return bytes.Equal(raw[:8], []byte("\x00\x00\x00\x08wide"))
+}
+
+// Mp4 detects an .mp4 file. Mp4 detections only does a basic ftyp check.
+// Mp4 has many registered and unregistered code points so it's hard to keep track
+// of all. Detection will default on video/mp4 for all ftyp files.
+// ISO_IEC_14496-12 is the specification for the iso container.
+func Mp4(raw []byte, _ uint32) bool {
+ if len(raw) < 12 {
+ return false
+ }
+ // ftyps are made out of boxes. The first 4 bytes of the box represent
+ // its size in big-endian uint32. First box is the ftyp box and it is small
+ // in size. Check most significant byte is 0 to filter out false positive
+ // text files that happen to contain the string "ftyp" at index 4.
+ if raw[0] != 0 {
+ return false
+ }
+ return bytes.Equal(raw[4:8], []byte("ftyp"))
+}
diff --git a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/geo.go b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/geo.go
new file mode 100644
index 00000000..f077e167
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/geo.go
@@ -0,0 +1,55 @@
+package magic
+
+import (
+ "bytes"
+ "encoding/binary"
+)
+
+// Shp matches a shape format file.
+// https://www.esri.com/library/whitepapers/pdfs/shapefile.pdf
+func Shp(raw []byte, limit uint32) bool {
+ if len(raw) < 112 {
+ return false
+ }
+
+ if !(binary.BigEndian.Uint32(raw[0:4]) == 9994 &&
+ binary.BigEndian.Uint32(raw[4:8]) == 0 &&
+ binary.BigEndian.Uint32(raw[8:12]) == 0 &&
+ binary.BigEndian.Uint32(raw[12:16]) == 0 &&
+ binary.BigEndian.Uint32(raw[16:20]) == 0 &&
+ binary.BigEndian.Uint32(raw[20:24]) == 0 &&
+ binary.LittleEndian.Uint32(raw[28:32]) == 1000) {
+ return false
+ }
+
+ shapeTypes := []int{
+ 0, // Null shape
+ 1, // Point
+ 3, // Polyline
+ 5, // Polygon
+ 8, // MultiPoint
+ 11, // PointZ
+ 13, // PolylineZ
+ 15, // PolygonZ
+ 18, // MultiPointZ
+ 21, // PointM
+ 23, // PolylineM
+ 25, // PolygonM
+ 28, // MultiPointM
+ 31, // MultiPatch
+ }
+
+ for _, st := range shapeTypes {
+ if st == int(binary.LittleEndian.Uint32(raw[108:112])) {
+ return true
+ }
+ }
+
+ return false
+}
+
+// Shx matches a shape index format file.
+// https://www.esri.com/library/whitepapers/pdfs/shapefile.pdf
+func Shx(raw []byte, limit uint32) bool {
+ return bytes.HasPrefix(raw, []byte{0x00, 0x00, 0x27, 0x0A})
+}
diff --git a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/image.go b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/image.go
new file mode 100644
index 00000000..0eb7e95f
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/image.go
@@ -0,0 +1,110 @@
+package magic
+
+import "bytes"
+
+var (
+ // Png matches a Portable Network Graphics file.
+ // https://www.w3.org/TR/PNG/
+ Png = prefix([]byte{0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A})
+ // Apng matches an Animated Portable Network Graphics file.
+ // https://wiki.mozilla.org/APNG_Specification
+ Apng = offset([]byte("acTL"), 37)
+ // Jpg matches a Joint Photographic Experts Group file.
+ Jpg = prefix([]byte{0xFF, 0xD8, 0xFF})
+ // Jp2 matches a JPEG 2000 Image file (ISO 15444-1).
+ Jp2 = jpeg2k([]byte{0x6a, 0x70, 0x32, 0x20})
+ // Jpx matches a JPEG 2000 Image file (ISO 15444-2).
+ Jpx = jpeg2k([]byte{0x6a, 0x70, 0x78, 0x20})
+ // Jpm matches a JPEG 2000 Image file (ISO 15444-6).
+ Jpm = jpeg2k([]byte{0x6a, 0x70, 0x6D, 0x20})
+ // Gif matches a Graphics Interchange Format file.
+ Gif = prefix([]byte("GIF87a"), []byte("GIF89a"))
+ // Bmp matches a bitmap image file.
+ Bmp = prefix([]byte{0x42, 0x4D})
+ // Ps matches a PostScript file.
+ Ps = prefix([]byte("%!PS-Adobe-"))
+ // Psd matches a Photoshop Document file.
+ Psd = prefix([]byte("8BPS"))
+ // Ico matches an ICO file.
+ Ico = prefix([]byte{0x00, 0x00, 0x01, 0x00}, []byte{0x00, 0x00, 0x02, 0x00})
+ // Icns matches an ICNS (Apple Icon Image format) file.
+ Icns = prefix([]byte("icns"))
+ // Tiff matches a Tagged Image File Format file.
+ Tiff = prefix([]byte{0x49, 0x49, 0x2A, 0x00}, []byte{0x4D, 0x4D, 0x00, 0x2A})
+ // Bpg matches a Better Portable Graphics file.
+ Bpg = prefix([]byte{0x42, 0x50, 0x47, 0xFB})
+ // Xcf matches GIMP image data.
+ Xcf = prefix([]byte("gimp xcf"))
+ // Pat matches GIMP pattern data.
+ Pat = offset([]byte("GPAT"), 20)
+ // Gbr matches GIMP brush data.
+ Gbr = offset([]byte("GIMP"), 20)
+ // Hdr matches Radiance HDR image.
+ // https://web.archive.org/web/20060913152809/http://local.wasp.uwa.edu.au/~pbourke/dataformats/pic/
+ Hdr = prefix([]byte("#?RADIANCE\n"))
+ // Xpm matches X PixMap image data.
+ Xpm = prefix([]byte{0x2F, 0x2A, 0x20, 0x58, 0x50, 0x4D, 0x20, 0x2A, 0x2F})
+ // Jxs matches a JPEG XS coded image file (ISO/IEC 21122-3).
+ Jxs = prefix([]byte{0x00, 0x00, 0x00, 0x0C, 0x4A, 0x58, 0x53, 0x20, 0x0D, 0x0A, 0x87, 0x0A})
+ // Jxr matches Microsoft HD JXR photo file.
+ Jxr = prefix([]byte{0x49, 0x49, 0xBC, 0x01})
+)
+
+func jpeg2k(sig []byte) Detector {
+ return func(raw []byte, _ uint32) bool {
+ if len(raw) < 24 {
+ return false
+ }
+
+ if !bytes.Equal(raw[4:8], []byte{0x6A, 0x50, 0x20, 0x20}) &&
+ !bytes.Equal(raw[4:8], []byte{0x6A, 0x50, 0x32, 0x20}) {
+ return false
+ }
+ return bytes.Equal(raw[20:24], sig)
+ }
+}
+
+// Webp matches a WebP file.
+func Webp(raw []byte, _ uint32) bool {
+ return len(raw) > 12 &&
+ bytes.Equal(raw[0:4], []byte("RIFF")) &&
+ bytes.Equal(raw[8:12], []byte{0x57, 0x45, 0x42, 0x50})
+}
+
+// Dwg matches a CAD drawing file.
+func Dwg(raw []byte, _ uint32) bool {
+ if len(raw) < 6 || raw[0] != 0x41 || raw[1] != 0x43 {
+ return false
+ }
+ dwgVersions := [][]byte{
+ {0x31, 0x2E, 0x34, 0x30},
+ {0x31, 0x2E, 0x35, 0x30},
+ {0x32, 0x2E, 0x31, 0x30},
+ {0x31, 0x30, 0x30, 0x32},
+ {0x31, 0x30, 0x30, 0x33},
+ {0x31, 0x30, 0x30, 0x34},
+ {0x31, 0x30, 0x30, 0x36},
+ {0x31, 0x30, 0x30, 0x39},
+ {0x31, 0x30, 0x31, 0x32},
+ {0x31, 0x30, 0x31, 0x34},
+ {0x31, 0x30, 0x31, 0x35},
+ {0x31, 0x30, 0x31, 0x38},
+ {0x31, 0x30, 0x32, 0x31},
+ {0x31, 0x30, 0x32, 0x34},
+ {0x31, 0x30, 0x33, 0x32},
+ }
+
+ for _, d := range dwgVersions {
+ if bytes.Equal(raw[2:6], d) {
+ return true
+ }
+ }
+
+ return false
+}
+
+// Jxl matches JPEG XL image file.
+func Jxl(raw []byte, _ uint32) bool {
+ return bytes.HasPrefix(raw, []byte{0xFF, 0x0A}) ||
+ bytes.HasPrefix(raw, []byte("\x00\x00\x00\x0cJXL\x20\x0d\x0a\x87\x0a"))
+}
diff --git a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/magic.go b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/magic.go
new file mode 100644
index 00000000..a34c6098
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/magic.go
@@ -0,0 +1,251 @@
+// Package magic holds the matching functions used to find MIME types.
+package magic
+
+import (
+ "bytes"
+ "fmt"
+)
+
+type (
+ // Detector receiveѕ the raw data of a file and returns whether the data
+ // meets any conditions. The limit parameter is an upper limit to the number
+ // of bytes received and is used to tell if the byte slice represents the
+ // whole file or is just the header of a file: len(raw) < limit or len(raw)>limit.
+ Detector func(raw []byte, limit uint32) bool
+ xmlSig struct {
+ // the local name of the root tag
+ localName []byte
+ // the namespace of the XML document
+ xmlns []byte
+ }
+)
+
+// prefix creates a Detector which returns true if any of the provided signatures
+// is the prefix of the raw input.
+func prefix(sigs ...[]byte) Detector {
+ return func(raw []byte, limit uint32) bool {
+ for _, s := range sigs {
+ if bytes.HasPrefix(raw, s) {
+ return true
+ }
+ }
+ return false
+ }
+}
+
+// offset creates a Detector which returns true if the provided signature can be
+// found at offset in the raw input.
+func offset(sig []byte, offset int) Detector {
+ return func(raw []byte, limit uint32) bool {
+ return len(raw) > offset && bytes.HasPrefix(raw[offset:], sig)
+ }
+}
+
+// ciPrefix is like prefix but the check is case insensitive.
+func ciPrefix(sigs ...[]byte) Detector {
+ return func(raw []byte, limit uint32) bool {
+ for _, s := range sigs {
+ if ciCheck(s, raw) {
+ return true
+ }
+ }
+ return false
+ }
+}
+func ciCheck(sig, raw []byte) bool {
+ if len(raw) < len(sig)+1 {
+ return false
+ }
+ // perform case insensitive check
+ for i, b := range sig {
+ db := raw[i]
+ if 'A' <= b && b <= 'Z' {
+ db &= 0xDF
+ }
+ if b != db {
+ return false
+ }
+ }
+
+ return true
+}
+
+// xml creates a Detector which returns true if any of the provided XML signatures
+// matches the raw input.
+func xml(sigs ...xmlSig) Detector {
+ return func(raw []byte, limit uint32) bool {
+ raw = trimLWS(raw)
+ if len(raw) == 0 {
+ return false
+ }
+ for _, s := range sigs {
+ if xmlCheck(s, raw) {
+ return true
+ }
+ }
+ return false
+ }
+}
+func xmlCheck(sig xmlSig, raw []byte) bool {
+ raw = raw[:min(len(raw), 512)]
+
+ if len(sig.localName) == 0 {
+ return bytes.Index(raw, sig.xmlns) > 0
+ }
+ if len(sig.xmlns) == 0 {
+ return bytes.Index(raw, sig.localName) > 0
+ }
+
+ localNameIndex := bytes.Index(raw, sig.localName)
+ return localNameIndex != -1 && localNameIndex < bytes.Index(raw, sig.xmlns)
+}
+
+// markup creates a Detector which returns true is any of the HTML signatures
+// matches the raw input.
+func markup(sigs ...[]byte) Detector {
+ return func(raw []byte, limit uint32) bool {
+ if bytes.HasPrefix(raw, []byte{0xEF, 0xBB, 0xBF}) {
+ // We skip the UTF-8 BOM if present to ensure we correctly
+ // process any leading whitespace. The presence of the BOM
+ // is taken into account during charset detection in charset.go.
+ raw = trimLWS(raw[3:])
+ } else {
+ raw = trimLWS(raw)
+ }
+ if len(raw) == 0 {
+ return false
+ }
+ for _, s := range sigs {
+ if markupCheck(s, raw) {
+ return true
+ }
+ }
+ return false
+ }
+}
+func markupCheck(sig, raw []byte) bool {
+ if len(raw) < len(sig)+1 {
+ return false
+ }
+
+ // perform case insensitive check
+ for i, b := range sig {
+ db := raw[i]
+ if 'A' <= b && b <= 'Z' {
+ db &= 0xDF
+ }
+ if b != db {
+ return false
+ }
+ }
+ // Next byte must be space or right angle bracket.
+ if db := raw[len(sig)]; db != ' ' && db != '>' {
+ return false
+ }
+
+ return true
+}
+
+// ftyp creates a Detector which returns true if any of the FTYP signatures
+// matches the raw input.
+func ftyp(sigs ...[]byte) Detector {
+ return func(raw []byte, limit uint32) bool {
+ if len(raw) < 12 {
+ return false
+ }
+ for _, s := range sigs {
+ if bytes.Equal(raw[8:12], s) {
+ return true
+ }
+ }
+ return false
+ }
+}
+
+func newXMLSig(localName, xmlns string) xmlSig {
+ ret := xmlSig{xmlns: []byte(xmlns)}
+ if localName != "" {
+ ret.localName = []byte(fmt.Sprintf("<%s", localName))
+ }
+
+ return ret
+}
+
+// A valid shebang starts with the "#!" characters,
+// followed by any number of spaces,
+// followed by the path to the interpreter,
+// and, optionally, followed by the arguments for the interpreter.
+//
+// Ex:
+//
+// #! /usr/bin/env php
+//
+// /usr/bin/env is the interpreter, php is the first and only argument.
+func shebang(sigs ...[]byte) Detector {
+ return func(raw []byte, limit uint32) bool {
+ for _, s := range sigs {
+ if shebangCheck(s, firstLine(raw)) {
+ return true
+ }
+ }
+ return false
+ }
+}
+
+func shebangCheck(sig, raw []byte) bool {
+ if len(raw) < len(sig)+2 {
+ return false
+ }
+ if raw[0] != '#' || raw[1] != '!' {
+ return false
+ }
+
+ return bytes.Equal(trimLWS(trimRWS(raw[2:])), sig)
+}
+
+// trimLWS trims whitespace from beginning of the input.
+func trimLWS(in []byte) []byte {
+ firstNonWS := 0
+ for ; firstNonWS < len(in) && isWS(in[firstNonWS]); firstNonWS++ {
+ }
+
+ return in[firstNonWS:]
+}
+
+// trimRWS trims whitespace from the end of the input.
+func trimRWS(in []byte) []byte {
+ lastNonWS := len(in) - 1
+ for ; lastNonWS > 0 && isWS(in[lastNonWS]); lastNonWS-- {
+ }
+
+ return in[:lastNonWS+1]
+}
+
+func firstLine(in []byte) []byte {
+ lineEnd := 0
+ for ; lineEnd < len(in) && in[lineEnd] != '\n'; lineEnd++ {
+ }
+
+ return in[:lineEnd]
+}
+
+func isWS(b byte) bool {
+ return b == '\t' || b == '\n' || b == '\x0c' || b == '\r' || b == ' '
+}
+
+func min(a, b int) int {
+ if a < b {
+ return a
+ }
+ return b
+}
+
+type readBuf []byte
+
+func (b *readBuf) advance(n int) bool {
+ if n < 0 || len(*b) < n {
+ return false
+ }
+ *b = (*b)[n:]
+ return true
+}
diff --git a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/ms_office.go b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/ms_office.go
new file mode 100644
index 00000000..7d60e22e
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/ms_office.go
@@ -0,0 +1,186 @@
+package magic
+
+import (
+ "bytes"
+ "encoding/binary"
+)
+
+// Xlsx matches a Microsoft Excel 2007 file.
+func Xlsx(raw []byte, limit uint32) bool {
+ return zipContains(raw, []byte("xl/"), true)
+}
+
+// Docx matches a Microsoft Word 2007 file.
+func Docx(raw []byte, limit uint32) bool {
+ return zipContains(raw, []byte("word/"), true)
+}
+
+// Pptx matches a Microsoft PowerPoint 2007 file.
+func Pptx(raw []byte, limit uint32) bool {
+ return zipContains(raw, []byte("ppt/"), true)
+}
+
+// Ole matches an Open Linking and Embedding file.
+//
+// https://en.wikipedia.org/wiki/Object_Linking_and_Embedding
+func Ole(raw []byte, limit uint32) bool {
+ return bytes.HasPrefix(raw, []byte{0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1})
+}
+
+// Aaf matches an Advanced Authoring Format file.
+// See: https://pyaaf.readthedocs.io/en/latest/about.html
+// See: https://en.wikipedia.org/wiki/Advanced_Authoring_Format
+func Aaf(raw []byte, limit uint32) bool {
+ if len(raw) < 31 {
+ return false
+ }
+ return bytes.HasPrefix(raw[8:], []byte{0x41, 0x41, 0x46, 0x42, 0x0D, 0x00, 0x4F, 0x4D}) &&
+ (raw[30] == 0x09 || raw[30] == 0x0C)
+}
+
+// Doc matches a Microsoft Word 97-2003 file.
+// See: https://github.com/decalage2/oletools/blob/412ee36ae45e70f42123e835871bac956d958461/oletools/common/clsid.py
+func Doc(raw []byte, _ uint32) bool {
+ clsids := [][]byte{
+ // Microsoft Word 97-2003 Document (Word.Document.8)
+ {0x06, 0x09, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46},
+ // Microsoft Word 6.0-7.0 Document (Word.Document.6)
+ {0x00, 0x09, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46},
+ // Microsoft Word Picture (Word.Picture.8)
+ {0x07, 0x09, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46},
+ }
+
+ for _, clsid := range clsids {
+ if matchOleClsid(raw, clsid) {
+ return true
+ }
+ }
+
+ return false
+}
+
+// Ppt matches a Microsoft PowerPoint 97-2003 file or a PowerPoint 95 presentation.
+func Ppt(raw []byte, limit uint32) bool {
+ // Root CLSID test is the safest way to detect identify OLE, however, the format
+ // often places the root CLSID at the end of the file.
+ if matchOleClsid(raw, []byte{
+ 0x10, 0x8d, 0x81, 0x64, 0x9b, 0x4f, 0xcf, 0x11,
+ 0x86, 0xea, 0x00, 0xaa, 0x00, 0xb9, 0x29, 0xe8,
+ }) || matchOleClsid(raw, []byte{
+ 0x70, 0xae, 0x7b, 0xea, 0x3b, 0xfb, 0xcd, 0x11,
+ 0xa9, 0x03, 0x00, 0xaa, 0x00, 0x51, 0x0e, 0xa3,
+ }) {
+ return true
+ }
+
+ lin := len(raw)
+ if lin < 520 {
+ return false
+ }
+ pptSubHeaders := [][]byte{
+ {0xA0, 0x46, 0x1D, 0xF0},
+ {0x00, 0x6E, 0x1E, 0xF0},
+ {0x0F, 0x00, 0xE8, 0x03},
+ }
+ for _, h := range pptSubHeaders {
+ if bytes.HasPrefix(raw[512:], h) {
+ return true
+ }
+ }
+
+ if bytes.HasPrefix(raw[512:], []byte{0xFD, 0xFF, 0xFF, 0xFF}) &&
+ raw[518] == 0x00 && raw[519] == 0x00 {
+ return true
+ }
+
+ return lin > 1152 && bytes.Contains(raw[1152:min(4096, lin)],
+ []byte("P\x00o\x00w\x00e\x00r\x00P\x00o\x00i\x00n\x00t\x00 D\x00o\x00c\x00u\x00m\x00e\x00n\x00t"))
+}
+
+// Xls matches a Microsoft Excel 97-2003 file.
+func Xls(raw []byte, limit uint32) bool {
+ // Root CLSID test is the safest way to detect identify OLE, however, the format
+ // often places the root CLSID at the end of the file.
+ if matchOleClsid(raw, []byte{
+ 0x10, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ }) || matchOleClsid(raw, []byte{
+ 0x20, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ }) {
+ return true
+ }
+
+ lin := len(raw)
+ if lin < 520 {
+ return false
+ }
+ xlsSubHeaders := [][]byte{
+ {0x09, 0x08, 0x10, 0x00, 0x00, 0x06, 0x05, 0x00},
+ {0xFD, 0xFF, 0xFF, 0xFF, 0x10},
+ {0xFD, 0xFF, 0xFF, 0xFF, 0x1F},
+ {0xFD, 0xFF, 0xFF, 0xFF, 0x22},
+ {0xFD, 0xFF, 0xFF, 0xFF, 0x23},
+ {0xFD, 0xFF, 0xFF, 0xFF, 0x28},
+ {0xFD, 0xFF, 0xFF, 0xFF, 0x29},
+ }
+ for _, h := range xlsSubHeaders {
+ if bytes.HasPrefix(raw[512:], h) {
+ return true
+ }
+ }
+
+ return lin > 1152 && bytes.Contains(raw[1152:min(4096, lin)],
+ []byte("W\x00k\x00s\x00S\x00S\x00W\x00o\x00r\x00k\x00B\x00o\x00o\x00k"))
+}
+
+// Pub matches a Microsoft Publisher file.
+func Pub(raw []byte, limit uint32) bool {
+ return matchOleClsid(raw, []byte{
+ 0x01, 0x12, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ })
+}
+
+// Msg matches a Microsoft Outlook email file.
+func Msg(raw []byte, limit uint32) bool {
+ return matchOleClsid(raw, []byte{
+ 0x0B, 0x0D, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ })
+}
+
+// Msi matches a Microsoft Windows Installer file.
+// http://fileformats.archiveteam.org/wiki/Microsoft_Compound_File
+func Msi(raw []byte, limit uint32) bool {
+ return matchOleClsid(raw, []byte{
+ 0x84, 0x10, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
+ })
+}
+
+// Helper to match by a specific CLSID of a compound file.
+//
+// http://fileformats.archiveteam.org/wiki/Microsoft_Compound_File
+func matchOleClsid(in []byte, clsid []byte) bool {
+ // Microsoft Compound files v3 have a sector length of 512, while v4 has 4096.
+ // Change sector offset depending on file version.
+ // https://www.loc.gov/preservation/digital/formats/fdd/fdd000392.shtml
+ sectorLength := 512
+ if len(in) < sectorLength {
+ return false
+ }
+ if in[26] == 0x04 && in[27] == 0x00 {
+ sectorLength = 4096
+ }
+
+ // SecID of first sector of the directory stream.
+ firstSecID := int(binary.LittleEndian.Uint32(in[48:52]))
+
+ // Expected offset of CLSID for root storage object.
+ clsidOffset := sectorLength*(1+firstSecID) + 80
+
+ if len(in) <= clsidOffset+16 {
+ return false
+ }
+
+ return bytes.HasPrefix(in[clsidOffset:], clsid)
+}
diff --git a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/ogg.go b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/ogg.go
new file mode 100644
index 00000000..bb4cd781
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/ogg.go
@@ -0,0 +1,42 @@
+package magic
+
+import (
+ "bytes"
+)
+
+/*
+ NOTE:
+
+ In May 2003, two Internet RFCs were published relating to the format.
+ The Ogg bitstream was defined in RFC 3533 (which is classified as
+ 'informative') and its Internet content type (application/ogg) in RFC
+ 3534 (which is, as of 2006, a proposed standard protocol). In
+ September 2008, RFC 3534 was obsoleted by RFC 5334, which added
+ content types video/ogg, audio/ogg and filename extensions .ogx, .ogv,
+ .oga, .spx.
+
+ See:
+ https://tools.ietf.org/html/rfc3533
+ https://developer.mozilla.org/en-US/docs/Web/HTTP/Configuring_servers_for_Ogg_media#Serve_media_with_the_correct_MIME_type
+ https://github.com/file/file/blob/master/magic/Magdir/vorbis
+*/
+
+// Ogg matches an Ogg file.
+func Ogg(raw []byte, limit uint32) bool {
+ return bytes.HasPrefix(raw, []byte("\x4F\x67\x67\x53\x00"))
+}
+
+// OggAudio matches an audio ogg file.
+func OggAudio(raw []byte, limit uint32) bool {
+ return len(raw) >= 37 && (bytes.HasPrefix(raw[28:], []byte("\x7fFLAC")) ||
+ bytes.HasPrefix(raw[28:], []byte("\x01vorbis")) ||
+ bytes.HasPrefix(raw[28:], []byte("OpusHead")) ||
+ bytes.HasPrefix(raw[28:], []byte("Speex\x20\x20\x20")))
+}
+
+// OggVideo matches a video ogg file.
+func OggVideo(raw []byte, limit uint32) bool {
+ return len(raw) >= 37 && (bytes.HasPrefix(raw[28:], []byte("\x80theora")) ||
+ bytes.HasPrefix(raw[28:], []byte("fishead\x00")) ||
+ bytes.HasPrefix(raw[28:], []byte("\x01video\x00\x00\x00"))) // OGM video
+}
diff --git a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/text.go b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/text.go
new file mode 100644
index 00000000..cf644639
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/text.go
@@ -0,0 +1,381 @@
+package magic
+
+import (
+ "bytes"
+ "strings"
+ "time"
+
+ "github.com/gabriel-vasile/mimetype/internal/charset"
+ "github.com/gabriel-vasile/mimetype/internal/json"
+)
+
+var (
+ // HTML matches a Hypertext Markup Language file.
+ HTML = markup(
+ []byte(" 0
+}
+
+// GeoJSON matches a RFC 7946 GeoJSON file.
+//
+// GeoJSON detection implies searching for key:value pairs like: `"type": "Feature"`
+// in the input.
+// BUG(gabriel-vasile): The "type" key should be searched for in the root object.
+func GeoJSON(raw []byte, limit uint32) bool {
+ raw = trimLWS(raw)
+ if len(raw) == 0 {
+ return false
+ }
+ // GeoJSON is always a JSON object, not a JSON array or any other JSON value.
+ if raw[0] != '{' {
+ return false
+ }
+
+ s := []byte(`"type"`)
+ si, sl := bytes.Index(raw, s), len(s)
+
+ if si == -1 {
+ return false
+ }
+
+ // If the "type" string is the suffix of the input,
+ // there is no need to search for the value of the key.
+ if si+sl == len(raw) {
+ return false
+ }
+ // Skip the "type" part.
+ raw = raw[si+sl:]
+ // Skip any whitespace before the colon.
+ raw = trimLWS(raw)
+ // Check for colon.
+ if len(raw) == 0 || raw[0] != ':' {
+ return false
+ }
+ // Skip any whitespace after the colon.
+ raw = trimLWS(raw[1:])
+
+ geoJSONTypes := [][]byte{
+ []byte(`"Feature"`),
+ []byte(`"FeatureCollection"`),
+ []byte(`"Point"`),
+ []byte(`"LineString"`),
+ []byte(`"Polygon"`),
+ []byte(`"MultiPoint"`),
+ []byte(`"MultiLineString"`),
+ []byte(`"MultiPolygon"`),
+ []byte(`"GeometryCollection"`),
+ }
+ for _, t := range geoJSONTypes {
+ if bytes.HasPrefix(raw, t) {
+ return true
+ }
+ }
+
+ return false
+}
+
+// NdJSON matches a Newline delimited JSON file. All complete lines from raw
+// must be valid JSON documents meaning they contain one of the valid JSON data
+// types.
+func NdJSON(raw []byte, limit uint32) bool {
+ lCount, hasObjOrArr := 0, false
+ raw = dropLastLine(raw, limit)
+ var l []byte
+ for len(raw) != 0 {
+ l, raw = scanLine(raw)
+ // Empty lines are allowed in NDJSON.
+ if l = trimRWS(trimLWS(l)); len(l) == 0 {
+ continue
+ }
+ _, err := json.Scan(l)
+ if err != nil {
+ return false
+ }
+ if l[0] == '[' || l[0] == '{' {
+ hasObjOrArr = true
+ }
+ lCount++
+ }
+
+ return lCount > 1 && hasObjOrArr
+}
+
+// HAR matches a HAR Spec file.
+// Spec: http://www.softwareishard.com/blog/har-12-spec/
+func HAR(raw []byte, limit uint32) bool {
+ s := []byte(`"log"`)
+ si, sl := bytes.Index(raw, s), len(s)
+
+ if si == -1 {
+ return false
+ }
+
+ // If the "log" string is the suffix of the input,
+ // there is no need to search for the value of the key.
+ if si+sl == len(raw) {
+ return false
+ }
+ // Skip the "log" part.
+ raw = raw[si+sl:]
+ // Skip any whitespace before the colon.
+ raw = trimLWS(raw)
+ // Check for colon.
+ if len(raw) == 0 || raw[0] != ':' {
+ return false
+ }
+ // Skip any whitespace after the colon.
+ raw = trimLWS(raw[1:])
+
+ harJSONTypes := [][]byte{
+ []byte(`"version"`),
+ []byte(`"creator"`),
+ []byte(`"entries"`),
+ }
+ for _, t := range harJSONTypes {
+ si := bytes.Index(raw, t)
+ if si > -1 {
+ return true
+ }
+ }
+
+ return false
+}
+
+// Svg matches a SVG file.
+func Svg(raw []byte, limit uint32) bool {
+ return bytes.Contains(raw, []byte(" 00:02:19,376) limits secondLine
+ // length to exactly 29 characters.
+ if len(secondLine) != 29 {
+ return false
+ }
+ // Decimal separator of fractional seconds in the timestamps must be a
+ // comma, not a period.
+ if strings.Contains(secondLine, ".") {
+ return false
+ }
+ // Second line must be a time range.
+ ts := strings.Split(secondLine, " --> ")
+ if len(ts) != 2 {
+ return false
+ }
+ const layout = "15:04:05,000"
+ t0, err := time.Parse(layout, ts[0])
+ if err != nil {
+ return false
+ }
+ t1, err := time.Parse(layout, ts[1])
+ if err != nil {
+ return false
+ }
+ if t0.After(t1) {
+ return false
+ }
+
+ line, _ = scanLine(raw)
+ // A third line must exist and not be empty. This is the actual subtitle text.
+ return len(line) != 0
+}
+
+// Vtt matches a Web Video Text Tracks (WebVTT) file. See
+// https://www.iana.org/assignments/media-types/text/vtt.
+func Vtt(raw []byte, limit uint32) bool {
+ // Prefix match.
+ prefixes := [][]byte{
+ {0xEF, 0xBB, 0xBF, 0x57, 0x45, 0x42, 0x56, 0x54, 0x54, 0x0A}, // UTF-8 BOM, "WEBVTT" and a line feed
+ {0xEF, 0xBB, 0xBF, 0x57, 0x45, 0x42, 0x56, 0x54, 0x54, 0x0D}, // UTF-8 BOM, "WEBVTT" and a carriage return
+ {0xEF, 0xBB, 0xBF, 0x57, 0x45, 0x42, 0x56, 0x54, 0x54, 0x20}, // UTF-8 BOM, "WEBVTT" and a space
+ {0xEF, 0xBB, 0xBF, 0x57, 0x45, 0x42, 0x56, 0x54, 0x54, 0x09}, // UTF-8 BOM, "WEBVTT" and a horizontal tab
+ {0x57, 0x45, 0x42, 0x56, 0x54, 0x54, 0x0A}, // "WEBVTT" and a line feed
+ {0x57, 0x45, 0x42, 0x56, 0x54, 0x54, 0x0D}, // "WEBVTT" and a carriage return
+ {0x57, 0x45, 0x42, 0x56, 0x54, 0x54, 0x20}, // "WEBVTT" and a space
+ {0x57, 0x45, 0x42, 0x56, 0x54, 0x54, 0x09}, // "WEBVTT" and a horizontal tab
+ }
+ for _, p := range prefixes {
+ if bytes.HasPrefix(raw, p) {
+ return true
+ }
+ }
+
+ // Exact match.
+ return bytes.Equal(raw, []byte{0xEF, 0xBB, 0xBF, 0x57, 0x45, 0x42, 0x56, 0x54, 0x54}) || // UTF-8 BOM and "WEBVTT"
+ bytes.Equal(raw, []byte{0x57, 0x45, 0x42, 0x56, 0x54, 0x54}) // "WEBVTT"
+}
+
+// dropCR drops a terminal \r from the data.
+func dropCR(data []byte) []byte {
+ if len(data) > 0 && data[len(data)-1] == '\r' {
+ return data[0 : len(data)-1]
+ }
+ return data
+}
+func scanLine(b []byte) (line, remainder []byte) {
+ line, remainder, _ = bytes.Cut(b, []byte("\n"))
+ return dropCR(line), remainder
+}
diff --git a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/text_csv.go b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/text_csv.go
new file mode 100644
index 00000000..6083ba8c
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/text_csv.go
@@ -0,0 +1,77 @@
+package magic
+
+import (
+ "bufio"
+ "bytes"
+ "encoding/csv"
+ "errors"
+ "io"
+ "sync"
+)
+
+// A bufio.Reader pool to alleviate problems with memory allocations.
+var readerPool = sync.Pool{
+ New: func() any {
+ // Initiate with empty source reader.
+ return bufio.NewReader(nil)
+ },
+}
+
+func newReader(r io.Reader) *bufio.Reader {
+ br := readerPool.Get().(*bufio.Reader)
+ br.Reset(r)
+ return br
+}
+
+// Csv matches a comma-separated values file.
+func Csv(raw []byte, limit uint32) bool {
+ return sv(raw, ',', limit)
+}
+
+// Tsv matches a tab-separated values file.
+func Tsv(raw []byte, limit uint32) bool {
+ return sv(raw, '\t', limit)
+}
+
+func sv(in []byte, comma rune, limit uint32) bool {
+ in = dropLastLine(in, limit)
+
+ br := newReader(bytes.NewReader(in))
+ defer readerPool.Put(br)
+ r := csv.NewReader(br)
+ r.Comma = comma
+ r.ReuseRecord = true
+ r.LazyQuotes = true
+ r.Comment = '#'
+
+ lines := 0
+ for {
+ _, err := r.Read()
+ if errors.Is(err, io.EOF) {
+ break
+ }
+ if err != nil {
+ return false
+ }
+ lines++
+ }
+
+ return r.FieldsPerRecord > 1 && lines > 1
+}
+
+// dropLastLine drops the last incomplete line from b.
+//
+// mimetype limits itself to ReadLimit bytes when performing a detection.
+// This means, for file formats like CSV for NDJSON, the last line of the input
+// can be an incomplete line.
+func dropLastLine(b []byte, readLimit uint32) []byte {
+ if readLimit == 0 || uint32(len(b)) < readLimit {
+ return b
+ }
+ for i := len(b) - 1; i > 0; i-- {
+ if b[i] == '\n' {
+ return b[:i]
+ }
+ }
+ return b
+}
diff --git a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/video.go b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/video.go
new file mode 100644
index 00000000..9caf5553
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/video.go
@@ -0,0 +1,85 @@
+package magic
+
+import (
+ "bytes"
+)
+
+var (
+ // Flv matches a Flash video file.
+ Flv = prefix([]byte("\x46\x4C\x56\x01"))
+ // Asf matches an Advanced Systems Format file.
+ Asf = prefix([]byte{
+ 0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11,
+ 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C,
+ })
+ // Rmvb matches a RealMedia Variable Bitrate file.
+ Rmvb = prefix([]byte{0x2E, 0x52, 0x4D, 0x46})
+)
+
+// WebM matches a WebM file.
+func WebM(raw []byte, limit uint32) bool {
+ return isMatroskaFileTypeMatched(raw, "webm")
+}
+
+// Mkv matches a mkv file.
+func Mkv(raw []byte, limit uint32) bool {
+ return isMatroskaFileTypeMatched(raw, "matroska")
+}
+
+// isMatroskaFileTypeMatched is used for webm and mkv file matching.
+// It checks for .Eߣ sequence. If the sequence is found,
+// then it means it is Matroska media container, including WebM.
+// Then it verifies which of the file type it is representing by matching the
+// file specific string.
+func isMatroskaFileTypeMatched(in []byte, flType string) bool {
+ if bytes.HasPrefix(in, []byte("\x1A\x45\xDF\xA3")) {
+ return isFileTypeNamePresent(in, flType)
+ }
+ return false
+}
+
+// isFileTypeNamePresent accepts the matroska input data stream and searches
+// for the given file type in the stream. Return whether a match is found.
+// The logic of search is: find first instance of \x42\x82 and then
+// search for given string after n bytes of above instance.
+func isFileTypeNamePresent(in []byte, flType string) bool {
+ ind, maxInd, lenIn := 0, 4096, len(in)
+ if lenIn < maxInd { // restricting length to 4096
+ maxInd = lenIn
+ }
+ ind = bytes.Index(in[:maxInd], []byte("\x42\x82"))
+ if ind > 0 && lenIn > ind+2 {
+ ind += 2
+
+ // filetype name will be present exactly
+ // n bytes after the match of the two bytes "\x42\x82"
+ n := vintWidth(int(in[ind]))
+ if lenIn > ind+n {
+ return bytes.HasPrefix(in[ind+n:], []byte(flType))
+ }
+ }
+ return false
+}
+
+// vintWidth parses the variable-integer width in matroska containers
+func vintWidth(v int) int {
+ mask, max, num := 128, 8, 1
+ for num < max && v&mask == 0 {
+ mask = mask >> 1
+ num++
+ }
+ return num
+}
+
+// Mpeg matches a Moving Picture Experts Group file.
+func Mpeg(raw []byte, limit uint32) bool {
+ return len(raw) > 3 && bytes.HasPrefix(raw, []byte{0x00, 0x00, 0x01}) &&
+ raw[3] >= 0xB0 && raw[3] <= 0xBF
+}
+
+// Avi matches an Audio Video Interleaved file.
+func Avi(raw []byte, limit uint32) bool {
+ return len(raw) > 16 &&
+ bytes.Equal(raw[:4], []byte("RIFF")) &&
+ bytes.Equal(raw[8:16], []byte("AVI LIST"))
+}
diff --git a/vendor/github.com/gabriel-vasile/mimetype/internal/magic/zip.go b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/zip.go
new file mode 100644
index 00000000..f6c64829
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/internal/magic/zip.go
@@ -0,0 +1,131 @@
+package magic
+
+import (
+ "bytes"
+ "encoding/binary"
+)
+
+var (
+ // Odt matches an OpenDocument Text file.
+ Odt = offset([]byte("mimetypeapplication/vnd.oasis.opendocument.text"), 30)
+ // Ott matches an OpenDocument Text Template file.
+ Ott = offset([]byte("mimetypeapplication/vnd.oasis.opendocument.text-template"), 30)
+ // Ods matches an OpenDocument Spreadsheet file.
+ Ods = offset([]byte("mimetypeapplication/vnd.oasis.opendocument.spreadsheet"), 30)
+ // Ots matches an OpenDocument Spreadsheet Template file.
+ Ots = offset([]byte("mimetypeapplication/vnd.oasis.opendocument.spreadsheet-template"), 30)
+ // Odp matches an OpenDocument Presentation file.
+ Odp = offset([]byte("mimetypeapplication/vnd.oasis.opendocument.presentation"), 30)
+ // Otp matches an OpenDocument Presentation Template file.
+ Otp = offset([]byte("mimetypeapplication/vnd.oasis.opendocument.presentation-template"), 30)
+ // Odg matches an OpenDocument Drawing file.
+ Odg = offset([]byte("mimetypeapplication/vnd.oasis.opendocument.graphics"), 30)
+ // Otg matches an OpenDocument Drawing Template file.
+ Otg = offset([]byte("mimetypeapplication/vnd.oasis.opendocument.graphics-template"), 30)
+ // Odf matches an OpenDocument Formula file.
+ Odf = offset([]byte("mimetypeapplication/vnd.oasis.opendocument.formula"), 30)
+ // Odc matches an OpenDocument Chart file.
+ Odc = offset([]byte("mimetypeapplication/vnd.oasis.opendocument.chart"), 30)
+ // Epub matches an EPUB file.
+ Epub = offset([]byte("mimetypeapplication/epub+zip"), 30)
+ // Sxc matches an OpenOffice Spreadsheet file.
+ Sxc = offset([]byte("mimetypeapplication/vnd.sun.xml.calc"), 30)
+)
+
+// Zip matches a zip archive.
+func Zip(raw []byte, limit uint32) bool {
+ return len(raw) > 3 &&
+ raw[0] == 0x50 && raw[1] == 0x4B &&
+ (raw[2] == 0x3 || raw[2] == 0x5 || raw[2] == 0x7) &&
+ (raw[3] == 0x4 || raw[3] == 0x6 || raw[3] == 0x8)
+}
+
+// Jar matches a Java archive file.
+func Jar(raw []byte, limit uint32) bool {
+ return zipContains(raw, []byte("META-INF/MANIFEST.MF"), false)
+}
+
+func zipContains(raw, sig []byte, msoCheck bool) bool {
+ b := readBuf(raw)
+ pk := []byte("PK\003\004")
+ if len(b) < 0x1E {
+ return false
+ }
+
+ if !b.advance(0x1E) {
+ return false
+ }
+ if bytes.HasPrefix(b, sig) {
+ return true
+ }
+
+ if msoCheck {
+ skipFiles := [][]byte{
+ []byte("[Content_Types].xml"),
+ []byte("_rels/.rels"),
+ []byte("docProps"),
+ []byte("customXml"),
+ []byte("[trash]"),
+ }
+
+ hasSkipFile := false
+ for _, sf := range skipFiles {
+ if bytes.HasPrefix(b, sf) {
+ hasSkipFile = true
+ break
+ }
+ }
+ if !hasSkipFile {
+ return false
+ }
+ }
+
+ searchOffset := binary.LittleEndian.Uint32(raw[18:]) + 49
+ if !b.advance(int(searchOffset)) {
+ return false
+ }
+
+ nextHeader := bytes.Index(raw[searchOffset:], pk)
+ if !b.advance(nextHeader) {
+ return false
+ }
+ if bytes.HasPrefix(b, sig) {
+ return true
+ }
+
+ for i := 0; i < 4; i++ {
+ if !b.advance(0x1A) {
+ return false
+ }
+ nextHeader = bytes.Index(b, pk)
+ if nextHeader == -1 {
+ return false
+ }
+ if !b.advance(nextHeader + 0x1E) {
+ return false
+ }
+ if bytes.HasPrefix(b, sig) {
+ return true
+ }
+ }
+ return false
+}
+
+// APK matches an Android Package Archive.
+// The source of signatures is https://github.com/file/file/blob/1778642b8ba3d947a779a36fcd81f8e807220a19/magic/Magdir/archive#L1820-L1887
+func APK(raw []byte, _ uint32) bool {
+ apkSignatures := [][]byte{
+ []byte("AndroidManifest.xml"),
+ []byte("META-INF/com/android/build/gradle/app-metadata.properties"),
+ []byte("classes.dex"),
+ []byte("resources.arsc"),
+ []byte("res/drawable"),
+ }
+ for _, sig := range apkSignatures {
+ if zipContains(raw, sig, false) {
+ return true
+ }
+ }
+
+ return false
+}
diff --git a/vendor/github.com/gabriel-vasile/mimetype/mime.go b/vendor/github.com/gabriel-vasile/mimetype/mime.go
new file mode 100644
index 00000000..62cb15f5
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/mime.go
@@ -0,0 +1,186 @@
+package mimetype
+
+import (
+ "mime"
+
+ "github.com/gabriel-vasile/mimetype/internal/charset"
+ "github.com/gabriel-vasile/mimetype/internal/magic"
+)
+
+// MIME struct holds information about a file format: the string representation
+// of the MIME type, the extension and the parent file format.
+type MIME struct {
+ mime string
+ aliases []string
+ extension string
+ // detector receives the raw input and a limit for the number of bytes it is
+ // allowed to check. It returns whether the input matches a signature or not.
+ detector magic.Detector
+ children []*MIME
+ parent *MIME
+}
+
+// String returns the string representation of the MIME type, e.g., "application/zip".
+func (m *MIME) String() string {
+ return m.mime
+}
+
+// Extension returns the file extension associated with the MIME type.
+// It includes the leading dot, as in ".html". When the file format does not
+// have an extension, the empty string is returned.
+func (m *MIME) Extension() string {
+ return m.extension
+}
+
+// Parent returns the parent MIME type from the hierarchy.
+// Each MIME type has a non-nil parent, except for the root MIME type.
+//
+// For example, the application/json and text/html MIME types have text/plain as
+// their parent because they are text files who happen to contain JSON or HTML.
+// Another example is the ZIP format, which is used as container
+// for Microsoft Office files, EPUB files, JAR files, and others.
+func (m *MIME) Parent() *MIME {
+ return m.parent
+}
+
+// Is checks whether this MIME type, or any of its aliases, is equal to the
+// expected MIME type. MIME type equality test is done on the "type/subtype"
+// section, ignores any optional MIME parameters, ignores any leading and
+// trailing whitespace, and is case insensitive.
+func (m *MIME) Is(expectedMIME string) bool {
+ // Parsing is needed because some detected MIME types contain parameters
+ // that need to be stripped for the comparison.
+ expectedMIME, _, _ = mime.ParseMediaType(expectedMIME)
+ found, _, _ := mime.ParseMediaType(m.mime)
+
+ if expectedMIME == found {
+ return true
+ }
+
+ for _, alias := range m.aliases {
+ if alias == expectedMIME {
+ return true
+ }
+ }
+
+ return false
+}
+
+func newMIME(
+ mime, extension string,
+ detector magic.Detector,
+ children ...*MIME) *MIME {
+ m := &MIME{
+ mime: mime,
+ extension: extension,
+ detector: detector,
+ children: children,
+ }
+
+ for _, c := range children {
+ c.parent = m
+ }
+
+ return m
+}
+
+func (m *MIME) alias(aliases ...string) *MIME {
+ m.aliases = aliases
+ return m
+}
+
+// match does a depth-first search on the signature tree. It returns the deepest
+// successful node for which all the children detection functions fail.
+func (m *MIME) match(in []byte, readLimit uint32) *MIME {
+ for _, c := range m.children {
+ if c.detector(in, readLimit) {
+ return c.match(in, readLimit)
+ }
+ }
+
+ needsCharset := map[string]func([]byte) string{
+ "text/plain": charset.FromPlain,
+ "text/html": charset.FromHTML,
+ "text/xml": charset.FromXML,
+ }
+ // ps holds optional MIME parameters.
+ ps := map[string]string{}
+ if f, ok := needsCharset[m.mime]; ok {
+ if cset := f(in); cset != "" {
+ ps["charset"] = cset
+ }
+ }
+
+ return m.cloneHierarchy(ps)
+}
+
+// flatten transforms an hierarchy of MIMEs into a slice of MIMEs.
+func (m *MIME) flatten() []*MIME {
+ out := []*MIME{m}
+ for _, c := range m.children {
+ out = append(out, c.flatten()...)
+ }
+
+ return out
+}
+
+// clone creates a new MIME with the provided optional MIME parameters.
+func (m *MIME) clone(ps map[string]string) *MIME {
+ clonedMIME := m.mime
+ if len(ps) > 0 {
+ clonedMIME = mime.FormatMediaType(m.mime, ps)
+ }
+
+ return &MIME{
+ mime: clonedMIME,
+ aliases: m.aliases,
+ extension: m.extension,
+ }
+}
+
+// cloneHierarchy creates a clone of m and all its ancestors. The optional MIME
+// parameters are set on the last child of the hierarchy.
+func (m *MIME) cloneHierarchy(ps map[string]string) *MIME {
+ ret := m.clone(ps)
+ lastChild := ret
+ for p := m.Parent(); p != nil; p = p.Parent() {
+ pClone := p.clone(nil)
+ lastChild.parent = pClone
+ lastChild = pClone
+ }
+
+ return ret
+}
+
+func (m *MIME) lookup(mime string) *MIME {
+ for _, n := range append(m.aliases, m.mime) {
+ if n == mime {
+ return m
+ }
+ }
+
+ for _, c := range m.children {
+ if m := c.lookup(mime); m != nil {
+ return m
+ }
+ }
+ return nil
+}
+
+// Extend adds detection for a sub-format. The detector is a function
+// returning true when the raw input file satisfies a signature.
+// The sub-format will be detected if all the detectors in the parent chain return true.
+// The extension should include the leading dot, as in ".html".
+func (m *MIME) Extend(detector func(raw []byte, limit uint32) bool, mime, extension string, aliases ...string) {
+ c := &MIME{
+ mime: mime,
+ extension: extension,
+ detector: detector,
+ parent: m,
+ aliases: aliases,
+ }
+
+ mu.Lock()
+ m.children = append([]*MIME{c}, m.children...)
+ mu.Unlock()
+}
diff --git a/vendor/github.com/gabriel-vasile/mimetype/mimetype.go b/vendor/github.com/gabriel-vasile/mimetype/mimetype.go
new file mode 100644
index 00000000..d8d512b8
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/mimetype.go
@@ -0,0 +1,126 @@
+// Package mimetype uses magic number signatures to detect the MIME type of a file.
+//
+// File formats are stored in a hierarchy with application/octet-stream at its root.
+// For example, the hierarchy for HTML format is application/octet-stream ->
+// text/plain -> text/html.
+package mimetype
+
+import (
+ "io"
+ "mime"
+ "os"
+ "sync/atomic"
+)
+
+var defaultLimit uint32 = 3072
+
+// readLimit is the maximum number of bytes from the input used when detecting.
+var readLimit uint32 = defaultLimit
+
+// Detect returns the MIME type found from the provided byte slice.
+//
+// The result is always a valid MIME type, with application/octet-stream
+// returned when identification failed.
+func Detect(in []byte) *MIME {
+ // Using atomic because readLimit can be written at the same time in other goroutine.
+ l := atomic.LoadUint32(&readLimit)
+ if l > 0 && len(in) > int(l) {
+ in = in[:l]
+ }
+ mu.RLock()
+ defer mu.RUnlock()
+ return root.match(in, l)
+}
+
+// DetectReader returns the MIME type of the provided reader.
+//
+// The result is always a valid MIME type, with application/octet-stream
+// returned when identification failed with or without an error.
+// Any error returned is related to the reading from the input reader.
+//
+// DetectReader assumes the reader offset is at the start. If the input is an
+// io.ReadSeeker you previously read from, it should be rewinded before detection:
+//
+// reader.Seek(0, io.SeekStart)
+func DetectReader(r io.Reader) (*MIME, error) {
+ var in []byte
+ var err error
+
+ // Using atomic because readLimit can be written at the same time in other goroutine.
+ l := atomic.LoadUint32(&readLimit)
+ if l == 0 {
+ in, err = io.ReadAll(r)
+ if err != nil {
+ return errMIME, err
+ }
+ } else {
+ var n int
+ in = make([]byte, l)
+ // io.UnexpectedEOF means len(r) < len(in). It is not an error in this case,
+ // it just means the input file is smaller than the allocated bytes slice.
+ n, err = io.ReadFull(r, in)
+ if err != nil && err != io.EOF && err != io.ErrUnexpectedEOF {
+ return errMIME, err
+ }
+ in = in[:n]
+ }
+
+ mu.RLock()
+ defer mu.RUnlock()
+ return root.match(in, l), nil
+}
+
+// DetectFile returns the MIME type of the provided file.
+//
+// The result is always a valid MIME type, with application/octet-stream
+// returned when identification failed with or without an error.
+// Any error returned is related to the opening and reading from the input file.
+func DetectFile(path string) (*MIME, error) {
+ f, err := os.Open(path)
+ if err != nil {
+ return errMIME, err
+ }
+ defer f.Close()
+
+ return DetectReader(f)
+}
+
+// EqualsAny reports whether s MIME type is equal to any MIME type in mimes.
+// MIME type equality test is done on the "type/subtype" section, ignores
+// any optional MIME parameters, ignores any leading and trailing whitespace,
+// and is case insensitive.
+func EqualsAny(s string, mimes ...string) bool {
+ s, _, _ = mime.ParseMediaType(s)
+ for _, m := range mimes {
+ m, _, _ = mime.ParseMediaType(m)
+ if s == m {
+ return true
+ }
+ }
+
+ return false
+}
+
+// SetLimit sets the maximum number of bytes read from input when detecting the MIME type.
+// Increasing the limit provides better detection for file formats which store
+// their magical numbers towards the end of the file: docx, pptx, xlsx, etc.
+// During detection data is read in a single block of size limit, i.e. it is not buffered.
+// A limit of 0 means the whole input file will be used.
+func SetLimit(limit uint32) {
+ // Using atomic because readLimit can be read at the same time in other goroutine.
+ atomic.StoreUint32(&readLimit, limit)
+}
+
+// Extend adds detection for other file formats.
+// It is equivalent to calling Extend() on the root mime type "application/octet-stream".
+func Extend(detector func(raw []byte, limit uint32) bool, mime, extension string, aliases ...string) {
+ root.Extend(detector, mime, extension, aliases...)
+}
+
+// Lookup finds a MIME object by its string representation.
+// The representation can be the main mime type, or any of its aliases.
+func Lookup(mime string) *MIME {
+ mu.RLock()
+ defer mu.RUnlock()
+ return root.lookup(mime)
+}
diff --git a/vendor/github.com/gabriel-vasile/mimetype/supported_mimes.md b/vendor/github.com/gabriel-vasile/mimetype/supported_mimes.md
new file mode 100644
index 00000000..f9bf03cb
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/supported_mimes.md
@@ -0,0 +1,183 @@
+## 178 Supported MIME types
+This file is automatically generated when running tests. Do not edit manually.
+
+Extension | MIME type | Aliases
+--------- | --------- | -------
+**n/a** | application/octet-stream | -
+**.xpm** | image/x-xpixmap | -
+**.7z** | application/x-7z-compressed | -
+**.zip** | application/zip | application/x-zip, application/x-zip-compressed
+**.xlsx** | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet | -
+**.docx** | application/vnd.openxmlformats-officedocument.wordprocessingml.document | -
+**.pptx** | application/vnd.openxmlformats-officedocument.presentationml.presentation | -
+**.epub** | application/epub+zip | -
+**.apk** | application/vnd.android.package-archive | -
+**.jar** | application/jar | -
+**.odt** | application/vnd.oasis.opendocument.text | application/x-vnd.oasis.opendocument.text
+**.ott** | application/vnd.oasis.opendocument.text-template | application/x-vnd.oasis.opendocument.text-template
+**.ods** | application/vnd.oasis.opendocument.spreadsheet | application/x-vnd.oasis.opendocument.spreadsheet
+**.ots** | application/vnd.oasis.opendocument.spreadsheet-template | application/x-vnd.oasis.opendocument.spreadsheet-template
+**.odp** | application/vnd.oasis.opendocument.presentation | application/x-vnd.oasis.opendocument.presentation
+**.otp** | application/vnd.oasis.opendocument.presentation-template | application/x-vnd.oasis.opendocument.presentation-template
+**.odg** | application/vnd.oasis.opendocument.graphics | application/x-vnd.oasis.opendocument.graphics
+**.otg** | application/vnd.oasis.opendocument.graphics-template | application/x-vnd.oasis.opendocument.graphics-template
+**.odf** | application/vnd.oasis.opendocument.formula | application/x-vnd.oasis.opendocument.formula
+**.odc** | application/vnd.oasis.opendocument.chart | application/x-vnd.oasis.opendocument.chart
+**.sxc** | application/vnd.sun.xml.calc | -
+**.pdf** | application/pdf | application/x-pdf
+**.fdf** | application/vnd.fdf | -
+**n/a** | application/x-ole-storage | -
+**.msi** | application/x-ms-installer | application/x-windows-installer, application/x-msi
+**.aaf** | application/octet-stream | -
+**.msg** | application/vnd.ms-outlook | -
+**.xls** | application/vnd.ms-excel | application/msexcel
+**.pub** | application/vnd.ms-publisher | -
+**.ppt** | application/vnd.ms-powerpoint | application/mspowerpoint
+**.doc** | application/msword | application/vnd.ms-word
+**.ps** | application/postscript | -
+**.psd** | image/vnd.adobe.photoshop | image/x-psd, application/photoshop
+**.p7s** | application/pkcs7-signature | -
+**.ogg** | application/ogg | application/x-ogg
+**.oga** | audio/ogg | -
+**.ogv** | video/ogg | -
+**.png** | image/png | -
+**.png** | image/vnd.mozilla.apng | -
+**.jpg** | image/jpeg | -
+**.jxl** | image/jxl | -
+**.jp2** | image/jp2 | -
+**.jpf** | image/jpx | -
+**.jpm** | image/jpm | video/jpm
+**.jxs** | image/jxs | -
+**.gif** | image/gif | -
+**.webp** | image/webp | -
+**.exe** | application/vnd.microsoft.portable-executable | -
+**n/a** | application/x-elf | -
+**n/a** | application/x-object | -
+**n/a** | application/x-executable | -
+**.so** | application/x-sharedlib | -
+**n/a** | application/x-coredump | -
+**.a** | application/x-archive | application/x-unix-archive
+**.deb** | application/vnd.debian.binary-package | -
+**.tar** | application/x-tar | -
+**.xar** | application/x-xar | -
+**.bz2** | application/x-bzip2 | -
+**.fits** | application/fits | -
+**.tiff** | image/tiff | -
+**.bmp** | image/bmp | image/x-bmp, image/x-ms-bmp
+**.ico** | image/x-icon | -
+**.mp3** | audio/mpeg | audio/x-mpeg, audio/mp3
+**.flac** | audio/flac | -
+**.midi** | audio/midi | audio/mid, audio/sp-midi, audio/x-mid, audio/x-midi
+**.ape** | audio/ape | -
+**.mpc** | audio/musepack | -
+**.amr** | audio/amr | audio/amr-nb
+**.wav** | audio/wav | audio/x-wav, audio/vnd.wave, audio/wave
+**.aiff** | audio/aiff | audio/x-aiff
+**.au** | audio/basic | -
+**.mpeg** | video/mpeg | -
+**.mov** | video/quicktime | -
+**.mp4** | video/mp4 | -
+**.avif** | image/avif | -
+**.3gp** | video/3gpp | video/3gp, audio/3gpp
+**.3g2** | video/3gpp2 | video/3g2, audio/3gpp2
+**.mp4** | audio/mp4 | audio/x-mp4a
+**.mqv** | video/quicktime | -
+**.m4a** | audio/x-m4a | -
+**.m4v** | video/x-m4v | -
+**.heic** | image/heic | -
+**.heic** | image/heic-sequence | -
+**.heif** | image/heif | -
+**.heif** | image/heif-sequence | -
+**.mj2** | video/mj2 | -
+**.dvb** | video/vnd.dvb.file | -
+**.webm** | video/webm | audio/webm
+**.avi** | video/x-msvideo | video/avi, video/msvideo
+**.flv** | video/x-flv | -
+**.mkv** | video/x-matroska | -
+**.asf** | video/x-ms-asf | video/asf, video/x-ms-wmv
+**.aac** | audio/aac | -
+**.voc** | audio/x-unknown | -
+**.m3u** | application/vnd.apple.mpegurl | audio/mpegurl
+**.rmvb** | application/vnd.rn-realmedia-vbr | -
+**.gz** | application/gzip | application/x-gzip, application/x-gunzip, application/gzipped, application/gzip-compressed, application/x-gzip-compressed, gzip/document
+**.class** | application/x-java-applet | -
+**.swf** | application/x-shockwave-flash | -
+**.crx** | application/x-chrome-extension | -
+**.ttf** | font/ttf | font/sfnt, application/x-font-ttf, application/font-sfnt
+**.woff** | font/woff | -
+**.woff2** | font/woff2 | -
+**.otf** | font/otf | -
+**.ttc** | font/collection | -
+**.eot** | application/vnd.ms-fontobject | -
+**.wasm** | application/wasm | -
+**.shx** | application/vnd.shx | -
+**.shp** | application/vnd.shp | -
+**.dbf** | application/x-dbf | -
+**.dcm** | application/dicom | -
+**.rar** | application/x-rar-compressed | application/x-rar
+**.djvu** | image/vnd.djvu | -
+**.mobi** | application/x-mobipocket-ebook | -
+**.lit** | application/x-ms-reader | -
+**.bpg** | image/bpg | -
+**.cbor** | application/cbor | -
+**.sqlite** | application/vnd.sqlite3 | application/x-sqlite3
+**.dwg** | image/vnd.dwg | image/x-dwg, application/acad, application/x-acad, application/autocad_dwg, application/dwg, application/x-dwg, application/x-autocad, drawing/dwg
+**.nes** | application/vnd.nintendo.snes.rom | -
+**.lnk** | application/x-ms-shortcut | -
+**.macho** | application/x-mach-binary | -
+**.qcp** | audio/qcelp | -
+**.icns** | image/x-icns | -
+**.hdr** | image/vnd.radiance | -
+**.mrc** | application/marc | -
+**.mdb** | application/x-msaccess | -
+**.accdb** | application/x-msaccess | -
+**.zst** | application/zstd | -
+**.cab** | application/vnd.ms-cab-compressed | -
+**.rpm** | application/x-rpm | -
+**.xz** | application/x-xz | -
+**.lz** | application/lzip | application/x-lzip
+**.torrent** | application/x-bittorrent | -
+**.cpio** | application/x-cpio | -
+**n/a** | application/tzif | -
+**.xcf** | image/x-xcf | -
+**.pat** | image/x-gimp-pat | -
+**.gbr** | image/x-gimp-gbr | -
+**.glb** | model/gltf-binary | -
+**.cab** | application/x-installshield | -
+**.jxr** | image/jxr | image/vnd.ms-photo
+**.parquet** | application/vnd.apache.parquet | application/x-parquet
+**.txt** | text/plain | -
+**.html** | text/html | -
+**.svg** | image/svg+xml | -
+**.xml** | text/xml | application/xml
+**.rss** | application/rss+xml | text/rss
+**.atom** | application/atom+xml | -
+**.x3d** | model/x3d+xml | -
+**.kml** | application/vnd.google-earth.kml+xml | -
+**.xlf** | application/x-xliff+xml | -
+**.dae** | model/vnd.collada+xml | -
+**.gml** | application/gml+xml | -
+**.gpx** | application/gpx+xml | -
+**.tcx** | application/vnd.garmin.tcx+xml | -
+**.amf** | application/x-amf | -
+**.3mf** | application/vnd.ms-package.3dmanufacturing-3dmodel+xml | -
+**.xfdf** | application/vnd.adobe.xfdf | -
+**.owl** | application/owl+xml | -
+**.php** | text/x-php | -
+**.js** | text/javascript | application/x-javascript, application/javascript
+**.lua** | text/x-lua | -
+**.pl** | text/x-perl | -
+**.py** | text/x-python | text/x-script.python, application/x-python
+**.json** | application/json | -
+**.geojson** | application/geo+json | -
+**.har** | application/json | -
+**.ndjson** | application/x-ndjson | -
+**.rtf** | text/rtf | application/rtf
+**.srt** | application/x-subrip | application/x-srt, text/x-srt
+**.tcl** | text/x-tcl | application/x-tcl
+**.csv** | text/csv | -
+**.tsv** | text/tab-separated-values | -
+**.vcf** | text/vcard | -
+**.ics** | text/calendar | -
+**.warc** | application/warc | -
+**.vtt** | text/vtt | -
diff --git a/vendor/github.com/gabriel-vasile/mimetype/tree.go b/vendor/github.com/gabriel-vasile/mimetype/tree.go
new file mode 100644
index 00000000..b5f56622
--- /dev/null
+++ b/vendor/github.com/gabriel-vasile/mimetype/tree.go
@@ -0,0 +1,270 @@
+package mimetype
+
+import (
+ "sync"
+
+ "github.com/gabriel-vasile/mimetype/internal/magic"
+)
+
+// mimetype stores the list of MIME types in a tree structure with
+// "application/octet-stream" at the root of the hierarchy. The hierarchy
+// approach minimizes the number of checks that need to be done on the input
+// and allows for more precise results once the base type of file has been
+// identified.
+//
+// root is a detector which passes for any slice of bytes.
+// When a detector passes the check, the children detectors
+// are tried in order to find a more accurate MIME type.
+var root = newMIME("application/octet-stream", "",
+ func([]byte, uint32) bool { return true },
+ xpm, sevenZ, zip, pdf, fdf, ole, ps, psd, p7s, ogg, png, jpg, jxl, jp2, jpx,
+ jpm, jxs, gif, webp, exe, elf, ar, tar, xar, bz2, fits, tiff, bmp, ico, mp3,
+ flac, midi, ape, musePack, amr, wav, aiff, au, mpeg, quickTime, mp4, webM,
+ avi, flv, mkv, asf, aac, voc, m3u, rmvb, gzip, class, swf, crx, ttf, woff,
+ woff2, otf, ttc, eot, wasm, shx, dbf, dcm, rar, djvu, mobi, lit, bpg, cbor,
+ sqlite3, dwg, nes, lnk, macho, qcp, icns, hdr, mrc, mdb, accdb, zstd, cab,
+ rpm, xz, lzip, torrent, cpio, tzif, xcf, pat, gbr, glb, cabIS, jxr, parquet,
+ // Keep text last because it is the slowest check.
+ text,
+)
+
+// errMIME is returned from Detect functions when err is not nil.
+// Detect could return root for erroneous cases, but it needs to lock mu in order to do so.
+// errMIME is same as root but it does not require locking.
+var errMIME = newMIME("application/octet-stream", "", func([]byte, uint32) bool { return false })
+
+// mu guards access to the root MIME tree. Access to root must be synchronized with this lock.
+var mu = &sync.RWMutex{}
+
+// The list of nodes appended to the root node.
+var (
+ xz = newMIME("application/x-xz", ".xz", magic.Xz)
+ gzip = newMIME("application/gzip", ".gz", magic.Gzip).alias(
+ "application/x-gzip", "application/x-gunzip", "application/gzipped",
+ "application/gzip-compressed", "application/x-gzip-compressed",
+ "gzip/document")
+ sevenZ = newMIME("application/x-7z-compressed", ".7z", magic.SevenZ)
+ // APK must be checked before JAR because APK is a subset of JAR.
+ // This means APK should be a child of JAR detector, but in practice,
+ // the decisive signature for JAR might be located at the end of the file
+ // and not reachable because of library readLimit.
+ zip = newMIME("application/zip", ".zip", magic.Zip, xlsx, docx, pptx, epub, apk, jar, odt, ods, odp, odg, odf, odc, sxc).
+ alias("application/x-zip", "application/x-zip-compressed")
+ tar = newMIME("application/x-tar", ".tar", magic.Tar)
+ xar = newMIME("application/x-xar", ".xar", magic.Xar)
+ bz2 = newMIME("application/x-bzip2", ".bz2", magic.Bz2)
+ pdf = newMIME("application/pdf", ".pdf", magic.Pdf).
+ alias("application/x-pdf")
+ fdf = newMIME("application/vnd.fdf", ".fdf", magic.Fdf)
+ xlsx = newMIME("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", ".xlsx", magic.Xlsx)
+ docx = newMIME("application/vnd.openxmlformats-officedocument.wordprocessingml.document", ".docx", magic.Docx)
+ pptx = newMIME("application/vnd.openxmlformats-officedocument.presentationml.presentation", ".pptx", magic.Pptx)
+ epub = newMIME("application/epub+zip", ".epub", magic.Epub)
+ jar = newMIME("application/jar", ".jar", magic.Jar)
+ apk = newMIME("application/vnd.android.package-archive", ".apk", magic.APK)
+ ole = newMIME("application/x-ole-storage", "", magic.Ole, msi, aaf, msg, xls, pub, ppt, doc)
+ msi = newMIME("application/x-ms-installer", ".msi", magic.Msi).
+ alias("application/x-windows-installer", "application/x-msi")
+ aaf = newMIME("application/octet-stream", ".aaf", magic.Aaf)
+ doc = newMIME("application/msword", ".doc", magic.Doc).
+ alias("application/vnd.ms-word")
+ ppt = newMIME("application/vnd.ms-powerpoint", ".ppt", magic.Ppt).
+ alias("application/mspowerpoint")
+ pub = newMIME("application/vnd.ms-publisher", ".pub", magic.Pub)
+ xls = newMIME("application/vnd.ms-excel", ".xls", magic.Xls).
+ alias("application/msexcel")
+ msg = newMIME("application/vnd.ms-outlook", ".msg", magic.Msg)
+ ps = newMIME("application/postscript", ".ps", magic.Ps)
+ fits = newMIME("application/fits", ".fits", magic.Fits)
+ ogg = newMIME("application/ogg", ".ogg", magic.Ogg, oggAudio, oggVideo).
+ alias("application/x-ogg")
+ oggAudio = newMIME("audio/ogg", ".oga", magic.OggAudio)
+ oggVideo = newMIME("video/ogg", ".ogv", magic.OggVideo)
+ text = newMIME("text/plain", ".txt", magic.Text, html, svg, xml, php, js, lua, perl, python, json, ndJSON, rtf, srt, tcl, csv, tsv, vCard, iCalendar, warc, vtt)
+ xml = newMIME("text/xml", ".xml", magic.XML, rss, atom, x3d, kml, xliff, collada, gml, gpx, tcx, amf, threemf, xfdf, owl2).
+ alias("application/xml")
+ json = newMIME("application/json", ".json", magic.JSON, geoJSON, har)
+ har = newMIME("application/json", ".har", magic.HAR)
+ csv = newMIME("text/csv", ".csv", magic.Csv)
+ tsv = newMIME("text/tab-separated-values", ".tsv", magic.Tsv)
+ geoJSON = newMIME("application/geo+json", ".geojson", magic.GeoJSON)
+ ndJSON = newMIME("application/x-ndjson", ".ndjson", magic.NdJSON)
+ html = newMIME("text/html", ".html", magic.HTML)
+ php = newMIME("text/x-php", ".php", magic.Php)
+ rtf = newMIME("text/rtf", ".rtf", magic.Rtf).alias("application/rtf")
+ js = newMIME("text/javascript", ".js", magic.Js).
+ alias("application/x-javascript", "application/javascript")
+ srt = newMIME("application/x-subrip", ".srt", magic.Srt).
+ alias("application/x-srt", "text/x-srt")
+ vtt = newMIME("text/vtt", ".vtt", magic.Vtt)
+ lua = newMIME("text/x-lua", ".lua", magic.Lua)
+ perl = newMIME("text/x-perl", ".pl", magic.Perl)
+ python = newMIME("text/x-python", ".py", magic.Python).
+ alias("text/x-script.python", "application/x-python")
+ tcl = newMIME("text/x-tcl", ".tcl", magic.Tcl).
+ alias("application/x-tcl")
+ vCard = newMIME("text/vcard", ".vcf", magic.VCard)
+ iCalendar = newMIME("text/calendar", ".ics", magic.ICalendar)
+ svg = newMIME("image/svg+xml", ".svg", magic.Svg)
+ rss = newMIME("application/rss+xml", ".rss", magic.Rss).
+ alias("text/rss")
+ owl2 = newMIME("application/owl+xml", ".owl", magic.Owl2)
+ atom = newMIME("application/atom+xml", ".atom", magic.Atom)
+ x3d = newMIME("model/x3d+xml", ".x3d", magic.X3d)
+ kml = newMIME("application/vnd.google-earth.kml+xml", ".kml", magic.Kml)
+ xliff = newMIME("application/x-xliff+xml", ".xlf", magic.Xliff)
+ collada = newMIME("model/vnd.collada+xml", ".dae", magic.Collada)
+ gml = newMIME("application/gml+xml", ".gml", magic.Gml)
+ gpx = newMIME("application/gpx+xml", ".gpx", magic.Gpx)
+ tcx = newMIME("application/vnd.garmin.tcx+xml", ".tcx", magic.Tcx)
+ amf = newMIME("application/x-amf", ".amf", magic.Amf)
+ threemf = newMIME("application/vnd.ms-package.3dmanufacturing-3dmodel+xml", ".3mf", magic.Threemf)
+ png = newMIME("image/png", ".png", magic.Png, apng)
+ apng = newMIME("image/vnd.mozilla.apng", ".png", magic.Apng)
+ jpg = newMIME("image/jpeg", ".jpg", magic.Jpg)
+ jxl = newMIME("image/jxl", ".jxl", magic.Jxl)
+ jp2 = newMIME("image/jp2", ".jp2", magic.Jp2)
+ jpx = newMIME("image/jpx", ".jpf", magic.Jpx)
+ jpm = newMIME("image/jpm", ".jpm", magic.Jpm).
+ alias("video/jpm")
+ jxs = newMIME("image/jxs", ".jxs", magic.Jxs)
+ xpm = newMIME("image/x-xpixmap", ".xpm", magic.Xpm)
+ bpg = newMIME("image/bpg", ".bpg", magic.Bpg)
+ gif = newMIME("image/gif", ".gif", magic.Gif)
+ webp = newMIME("image/webp", ".webp", magic.Webp)
+ tiff = newMIME("image/tiff", ".tiff", magic.Tiff)
+ bmp = newMIME("image/bmp", ".bmp", magic.Bmp).
+ alias("image/x-bmp", "image/x-ms-bmp")
+ ico = newMIME("image/x-icon", ".ico", magic.Ico)
+ icns = newMIME("image/x-icns", ".icns", magic.Icns)
+ psd = newMIME("image/vnd.adobe.photoshop", ".psd", magic.Psd).
+ alias("image/x-psd", "application/photoshop")
+ heic = newMIME("image/heic", ".heic", magic.Heic)
+ heicSeq = newMIME("image/heic-sequence", ".heic", magic.HeicSequence)
+ heif = newMIME("image/heif", ".heif", magic.Heif)
+ heifSeq = newMIME("image/heif-sequence", ".heif", magic.HeifSequence)
+ hdr = newMIME("image/vnd.radiance", ".hdr", magic.Hdr)
+ avif = newMIME("image/avif", ".avif", magic.AVIF)
+ mp3 = newMIME("audio/mpeg", ".mp3", magic.Mp3).
+ alias("audio/x-mpeg", "audio/mp3")
+ flac = newMIME("audio/flac", ".flac", magic.Flac)
+ midi = newMIME("audio/midi", ".midi", magic.Midi).
+ alias("audio/mid", "audio/sp-midi", "audio/x-mid", "audio/x-midi")
+ ape = newMIME("audio/ape", ".ape", magic.Ape)
+ musePack = newMIME("audio/musepack", ".mpc", magic.MusePack)
+ wav = newMIME("audio/wav", ".wav", magic.Wav).
+ alias("audio/x-wav", "audio/vnd.wave", "audio/wave")
+ aiff = newMIME("audio/aiff", ".aiff", magic.Aiff).alias("audio/x-aiff")
+ au = newMIME("audio/basic", ".au", magic.Au)
+ amr = newMIME("audio/amr", ".amr", magic.Amr).
+ alias("audio/amr-nb")
+ aac = newMIME("audio/aac", ".aac", magic.AAC)
+ voc = newMIME("audio/x-unknown", ".voc", magic.Voc)
+ aMp4 = newMIME("audio/mp4", ".mp4", magic.AMp4).
+ alias("audio/x-mp4a")
+ m4a = newMIME("audio/x-m4a", ".m4a", magic.M4a)
+ m3u = newMIME("application/vnd.apple.mpegurl", ".m3u", magic.M3u).
+ alias("audio/mpegurl")
+ m4v = newMIME("video/x-m4v", ".m4v", magic.M4v)
+ mj2 = newMIME("video/mj2", ".mj2", magic.Mj2)
+ dvb = newMIME("video/vnd.dvb.file", ".dvb", magic.Dvb)
+ mp4 = newMIME("video/mp4", ".mp4", magic.Mp4, avif, threeGP, threeG2, aMp4, mqv, m4a, m4v, heic, heicSeq, heif, heifSeq, mj2, dvb)
+ webM = newMIME("video/webm", ".webm", magic.WebM).
+ alias("audio/webm")
+ mpeg = newMIME("video/mpeg", ".mpeg", magic.Mpeg)
+ quickTime = newMIME("video/quicktime", ".mov", magic.QuickTime)
+ mqv = newMIME("video/quicktime", ".mqv", magic.Mqv)
+ threeGP = newMIME("video/3gpp", ".3gp", magic.ThreeGP).
+ alias("video/3gp", "audio/3gpp")
+ threeG2 = newMIME("video/3gpp2", ".3g2", magic.ThreeG2).
+ alias("video/3g2", "audio/3gpp2")
+ avi = newMIME("video/x-msvideo", ".avi", magic.Avi).
+ alias("video/avi", "video/msvideo")
+ flv = newMIME("video/x-flv", ".flv", magic.Flv)
+ mkv = newMIME("video/x-matroska", ".mkv", magic.Mkv)
+ asf = newMIME("video/x-ms-asf", ".asf", magic.Asf).
+ alias("video/asf", "video/x-ms-wmv")
+ rmvb = newMIME("application/vnd.rn-realmedia-vbr", ".rmvb", magic.Rmvb)
+ class = newMIME("application/x-java-applet", ".class", magic.Class)
+ swf = newMIME("application/x-shockwave-flash", ".swf", magic.SWF)
+ crx = newMIME("application/x-chrome-extension", ".crx", magic.CRX)
+ ttf = newMIME("font/ttf", ".ttf", magic.Ttf).
+ alias("font/sfnt", "application/x-font-ttf", "application/font-sfnt")
+ woff = newMIME("font/woff", ".woff", magic.Woff)
+ woff2 = newMIME("font/woff2", ".woff2", magic.Woff2)
+ otf = newMIME("font/otf", ".otf", magic.Otf)
+ ttc = newMIME("font/collection", ".ttc", magic.Ttc)
+ eot = newMIME("application/vnd.ms-fontobject", ".eot", magic.Eot)
+ wasm = newMIME("application/wasm", ".wasm", magic.Wasm)
+ shp = newMIME("application/vnd.shp", ".shp", magic.Shp)
+ shx = newMIME("application/vnd.shx", ".shx", magic.Shx, shp)
+ dbf = newMIME("application/x-dbf", ".dbf", magic.Dbf)
+ exe = newMIME("application/vnd.microsoft.portable-executable", ".exe", magic.Exe)
+ elf = newMIME("application/x-elf", "", magic.Elf, elfObj, elfExe, elfLib, elfDump)
+ elfObj = newMIME("application/x-object", "", magic.ElfObj)
+ elfExe = newMIME("application/x-executable", "", magic.ElfExe)
+ elfLib = newMIME("application/x-sharedlib", ".so", magic.ElfLib)
+ elfDump = newMIME("application/x-coredump", "", magic.ElfDump)
+ ar = newMIME("application/x-archive", ".a", magic.Ar, deb).
+ alias("application/x-unix-archive")
+ deb = newMIME("application/vnd.debian.binary-package", ".deb", magic.Deb)
+ rpm = newMIME("application/x-rpm", ".rpm", magic.RPM)
+ dcm = newMIME("application/dicom", ".dcm", magic.Dcm)
+ odt = newMIME("application/vnd.oasis.opendocument.text", ".odt", magic.Odt, ott).
+ alias("application/x-vnd.oasis.opendocument.text")
+ ott = newMIME("application/vnd.oasis.opendocument.text-template", ".ott", magic.Ott).
+ alias("application/x-vnd.oasis.opendocument.text-template")
+ ods = newMIME("application/vnd.oasis.opendocument.spreadsheet", ".ods", magic.Ods, ots).
+ alias("application/x-vnd.oasis.opendocument.spreadsheet")
+ ots = newMIME("application/vnd.oasis.opendocument.spreadsheet-template", ".ots", magic.Ots).
+ alias("application/x-vnd.oasis.opendocument.spreadsheet-template")
+ odp = newMIME("application/vnd.oasis.opendocument.presentation", ".odp", magic.Odp, otp).
+ alias("application/x-vnd.oasis.opendocument.presentation")
+ otp = newMIME("application/vnd.oasis.opendocument.presentation-template", ".otp", magic.Otp).
+ alias("application/x-vnd.oasis.opendocument.presentation-template")
+ odg = newMIME("application/vnd.oasis.opendocument.graphics", ".odg", magic.Odg, otg).
+ alias("application/x-vnd.oasis.opendocument.graphics")
+ otg = newMIME("application/vnd.oasis.opendocument.graphics-template", ".otg", magic.Otg).
+ alias("application/x-vnd.oasis.opendocument.graphics-template")
+ odf = newMIME("application/vnd.oasis.opendocument.formula", ".odf", magic.Odf).
+ alias("application/x-vnd.oasis.opendocument.formula")
+ odc = newMIME("application/vnd.oasis.opendocument.chart", ".odc", magic.Odc).
+ alias("application/x-vnd.oasis.opendocument.chart")
+ sxc = newMIME("application/vnd.sun.xml.calc", ".sxc", magic.Sxc)
+ rar = newMIME("application/x-rar-compressed", ".rar", magic.RAR).
+ alias("application/x-rar")
+ djvu = newMIME("image/vnd.djvu", ".djvu", magic.DjVu)
+ mobi = newMIME("application/x-mobipocket-ebook", ".mobi", magic.Mobi)
+ lit = newMIME("application/x-ms-reader", ".lit", magic.Lit)
+ sqlite3 = newMIME("application/vnd.sqlite3", ".sqlite", magic.Sqlite).
+ alias("application/x-sqlite3")
+ dwg = newMIME("image/vnd.dwg", ".dwg", magic.Dwg).
+ alias("image/x-dwg", "application/acad", "application/x-acad",
+ "application/autocad_dwg", "application/dwg", "application/x-dwg",
+ "application/x-autocad", "drawing/dwg")
+ warc = newMIME("application/warc", ".warc", magic.Warc)
+ nes = newMIME("application/vnd.nintendo.snes.rom", ".nes", magic.Nes)
+ lnk = newMIME("application/x-ms-shortcut", ".lnk", magic.Lnk)
+ macho = newMIME("application/x-mach-binary", ".macho", magic.MachO)
+ qcp = newMIME("audio/qcelp", ".qcp", magic.Qcp)
+ mrc = newMIME("application/marc", ".mrc", magic.Marc)
+ mdb = newMIME("application/x-msaccess", ".mdb", magic.MsAccessMdb)
+ accdb = newMIME("application/x-msaccess", ".accdb", magic.MsAccessAce)
+ zstd = newMIME("application/zstd", ".zst", magic.Zstd)
+ cab = newMIME("application/vnd.ms-cab-compressed", ".cab", magic.Cab)
+ cabIS = newMIME("application/x-installshield", ".cab", magic.InstallShieldCab)
+ lzip = newMIME("application/lzip", ".lz", magic.Lzip).alias("application/x-lzip")
+ torrent = newMIME("application/x-bittorrent", ".torrent", magic.Torrent)
+ cpio = newMIME("application/x-cpio", ".cpio", magic.Cpio)
+ tzif = newMIME("application/tzif", "", magic.TzIf)
+ p7s = newMIME("application/pkcs7-signature", ".p7s", magic.P7s)
+ xcf = newMIME("image/x-xcf", ".xcf", magic.Xcf)
+ pat = newMIME("image/x-gimp-pat", ".pat", magic.Pat)
+ gbr = newMIME("image/x-gimp-gbr", ".gbr", magic.Gbr)
+ xfdf = newMIME("application/vnd.adobe.xfdf", ".xfdf", magic.Xfdf)
+ glb = newMIME("model/gltf-binary", ".glb", magic.Glb)
+ jxr = newMIME("image/jxr", ".jxr", magic.Jxr).alias("image/vnd.ms-photo")
+ parquet = newMIME("application/vnd.apache.parquet", ".parquet", magic.Par1).
+ alias("application/x-parquet")
+ cbor = newMIME("application/cbor", ".cbor", magic.CBOR)
+)
diff --git a/vendor/github.com/go-playground/locales/.gitignore b/vendor/github.com/go-playground/locales/.gitignore
new file mode 100644
index 00000000..daf913b1
--- /dev/null
+++ b/vendor/github.com/go-playground/locales/.gitignore
@@ -0,0 +1,24 @@
+# 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
diff --git a/vendor/github.com/go-playground/locales/.travis.yml b/vendor/github.com/go-playground/locales/.travis.yml
new file mode 100644
index 00000000..d50237a6
--- /dev/null
+++ b/vendor/github.com/go-playground/locales/.travis.yml
@@ -0,0 +1,26 @@
+language: go
+go:
+ - 1.13.1
+ - tip
+matrix:
+ allow_failures:
+ - go: tip
+
+notifications:
+ email:
+ recipients: dean.karn@gmail.com
+ on_success: change
+ on_failure: always
+
+before_install:
+ - go install github.com/mattn/goveralls
+
+# Only clone the most recent commit.
+git:
+ depth: 1
+
+script:
+ - go test -v -race -covermode=atomic -coverprofile=coverage.coverprofile ./...
+
+after_success: |
+ goveralls -coverprofile=coverage.coverprofile -service travis-ci -repotoken $COVERALLS_TOKEN
\ No newline at end of file
diff --git a/vendor/github.com/go-playground/locales/LICENSE b/vendor/github.com/go-playground/locales/LICENSE
new file mode 100644
index 00000000..75854ac4
--- /dev/null
+++ b/vendor/github.com/go-playground/locales/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Go Playground
+
+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/go-playground/locales/README.md b/vendor/github.com/go-playground/locales/README.md
new file mode 100644
index 00000000..7b6be2c6
--- /dev/null
+++ b/vendor/github.com/go-playground/locales/README.md
@@ -0,0 +1,170 @@
+## locales
+ 
+[](https://travis-ci.org/go-playground/locales)
+[](https://godoc.org/github.com/go-playground/locales)
+
+
+Locales is a set of locales generated from the [Unicode CLDR Project](http://cldr.unicode.org/) which can be used independently or within
+an i18n package; these were built for use with, but not exclusive to, [Universal Translator](https://github.com/go-playground/universal-translator).
+
+Features
+--------
+- [x] Rules generated from the latest [CLDR](http://cldr.unicode.org/index/downloads) data, v36.0.1
+- [x] Contains Cardinal, Ordinal and Range Plural Rules
+- [x] Contains Month, Weekday and Timezone translations built in
+- [x] Contains Date & Time formatting functions
+- [x] Contains Number, Currency, Accounting and Percent formatting functions
+- [x] Supports the "Gregorian" calendar only ( my time isn't unlimited, had to draw the line somewhere )
+
+Full Tests
+--------------------
+I could sure use your help adding tests for every locale, it is a huge undertaking and I just don't have the free time to do it all at the moment;
+any help would be **greatly appreciated!!!!** please see [issue](https://github.com/go-playground/locales/issues/1) for details.
+
+Installation
+-----------
+
+Use go get
+
+```shell
+go get github.com/go-playground/locales
+```
+
+NOTES
+--------
+You'll notice most return types are []byte, this is because most of the time the results will be concatenated with a larger body
+of text and can avoid some allocations if already appending to a byte array, otherwise just cast as string.
+
+Usage
+-------
+```go
+package main
+
+import (
+ "fmt"
+ "time"
+
+ "github.com/go-playground/locales/currency"
+ "github.com/go-playground/locales/en_CA"
+)
+
+func main() {
+
+ loc, _ := time.LoadLocation("America/Toronto")
+ datetime := time.Date(2016, 02, 03, 9, 0, 1, 0, loc)
+
+ l := en_CA.New()
+
+ // Dates
+ fmt.Println(l.FmtDateFull(datetime))
+ fmt.Println(l.FmtDateLong(datetime))
+ fmt.Println(l.FmtDateMedium(datetime))
+ fmt.Println(l.FmtDateShort(datetime))
+
+ // Times
+ fmt.Println(l.FmtTimeFull(datetime))
+ fmt.Println(l.FmtTimeLong(datetime))
+ fmt.Println(l.FmtTimeMedium(datetime))
+ fmt.Println(l.FmtTimeShort(datetime))
+
+ // Months Wide
+ fmt.Println(l.MonthWide(time.January))
+ fmt.Println(l.MonthWide(time.February))
+ fmt.Println(l.MonthWide(time.March))
+ // ...
+
+ // Months Abbreviated
+ fmt.Println(l.MonthAbbreviated(time.January))
+ fmt.Println(l.MonthAbbreviated(time.February))
+ fmt.Println(l.MonthAbbreviated(time.March))
+ // ...
+
+ // Months Narrow
+ fmt.Println(l.MonthNarrow(time.January))
+ fmt.Println(l.MonthNarrow(time.February))
+ fmt.Println(l.MonthNarrow(time.March))
+ // ...
+
+ // Weekdays Wide
+ fmt.Println(l.WeekdayWide(time.Sunday))
+ fmt.Println(l.WeekdayWide(time.Monday))
+ fmt.Println(l.WeekdayWide(time.Tuesday))
+ // ...
+
+ // Weekdays Abbreviated
+ fmt.Println(l.WeekdayAbbreviated(time.Sunday))
+ fmt.Println(l.WeekdayAbbreviated(time.Monday))
+ fmt.Println(l.WeekdayAbbreviated(time.Tuesday))
+ // ...
+
+ // Weekdays Short
+ fmt.Println(l.WeekdayShort(time.Sunday))
+ fmt.Println(l.WeekdayShort(time.Monday))
+ fmt.Println(l.WeekdayShort(time.Tuesday))
+ // ...
+
+ // Weekdays Narrow
+ fmt.Println(l.WeekdayNarrow(time.Sunday))
+ fmt.Println(l.WeekdayNarrow(time.Monday))
+ fmt.Println(l.WeekdayNarrow(time.Tuesday))
+ // ...
+
+ var f64 float64
+
+ f64 = -10356.4523
+
+ // Number
+ fmt.Println(l.FmtNumber(f64, 2))
+
+ // Currency
+ fmt.Println(l.FmtCurrency(f64, 2, currency.CAD))
+ fmt.Println(l.FmtCurrency(f64, 2, currency.USD))
+
+ // Accounting
+ fmt.Println(l.FmtAccounting(f64, 2, currency.CAD))
+ fmt.Println(l.FmtAccounting(f64, 2, currency.USD))
+
+ f64 = 78.12
+
+ // Percent
+ fmt.Println(l.FmtPercent(f64, 0))
+
+ // Plural Rules for locale, so you know what rules you must cover
+ fmt.Println(l.PluralsCardinal())
+ fmt.Println(l.PluralsOrdinal())
+
+ // Cardinal Plural Rules
+ fmt.Println(l.CardinalPluralRule(1, 0))
+ fmt.Println(l.CardinalPluralRule(1.0, 0))
+ fmt.Println(l.CardinalPluralRule(1.0, 1))
+ fmt.Println(l.CardinalPluralRule(3, 0))
+
+ // Ordinal Plural Rules
+ fmt.Println(l.OrdinalPluralRule(21, 0)) // 21st
+ fmt.Println(l.OrdinalPluralRule(22, 0)) // 22nd
+ fmt.Println(l.OrdinalPluralRule(33, 0)) // 33rd
+ fmt.Println(l.OrdinalPluralRule(34, 0)) // 34th
+
+ // Range Plural Rules
+ fmt.Println(l.RangePluralRule(1, 0, 1, 0)) // 1-1
+ fmt.Println(l.RangePluralRule(1, 0, 2, 0)) // 1-2
+ fmt.Println(l.RangePluralRule(5, 0, 8, 0)) // 5-8
+}
+```
+
+NOTES:
+-------
+These rules were generated from the [Unicode CLDR Project](http://cldr.unicode.org/), if you encounter any issues
+I strongly encourage contributing to the CLDR project to get the locale information corrected and the next time
+these locales are regenerated the fix will come with.
+
+I do however realize that time constraints are often important and so there are two options:
+
+1. Create your own locale, copy, paste and modify, and ensure it complies with the `Translator` interface.
+2. Add an exception in the locale generation code directly and once regenerated, fix will be in place.
+
+Please to not make fixes inside the locale files, they WILL get overwritten when the locales are regenerated.
+
+License
+------
+Distributed under MIT License, please see license file in code for more details.
diff --git a/vendor/github.com/go-playground/locales/currency/currency.go b/vendor/github.com/go-playground/locales/currency/currency.go
new file mode 100644
index 00000000..b5a95fb0
--- /dev/null
+++ b/vendor/github.com/go-playground/locales/currency/currency.go
@@ -0,0 +1,311 @@
+package currency
+
+// Type is the currency type associated with the locales currency enum
+type Type int
+
+// locale currencies
+const (
+ ADP Type = iota
+ AED
+ AFA
+ AFN
+ ALK
+ ALL
+ AMD
+ ANG
+ AOA
+ AOK
+ AON
+ AOR
+ ARA
+ ARL
+ ARM
+ ARP
+ ARS
+ ATS
+ AUD
+ AWG
+ AZM
+ AZN
+ BAD
+ BAM
+ BAN
+ BBD
+ BDT
+ BEC
+ BEF
+ BEL
+ BGL
+ BGM
+ BGN
+ BGO
+ BHD
+ BIF
+ BMD
+ BND
+ BOB
+ BOL
+ BOP
+ BOV
+ BRB
+ BRC
+ BRE
+ BRL
+ BRN
+ BRR
+ BRZ
+ BSD
+ BTN
+ BUK
+ BWP
+ BYB
+ BYN
+ BYR
+ BZD
+ CAD
+ CDF
+ CHE
+ CHF
+ CHW
+ CLE
+ CLF
+ CLP
+ CNH
+ CNX
+ CNY
+ COP
+ COU
+ CRC
+ CSD
+ CSK
+ CUC
+ CUP
+ CVE
+ CYP
+ CZK
+ DDM
+ DEM
+ DJF
+ DKK
+ DOP
+ DZD
+ ECS
+ ECV
+ EEK
+ EGP
+ ERN
+ ESA
+ ESB
+ ESP
+ ETB
+ EUR
+ FIM
+ FJD
+ FKP
+ FRF
+ GBP
+ GEK
+ GEL
+ GHC
+ GHS
+ GIP
+ GMD
+ GNF
+ GNS
+ GQE
+ GRD
+ GTQ
+ GWE
+ GWP
+ GYD
+ HKD
+ HNL
+ HRD
+ HRK
+ HTG
+ HUF
+ IDR
+ IEP
+ ILP
+ ILR
+ ILS
+ INR
+ IQD
+ IRR
+ ISJ
+ ISK
+ ITL
+ JMD
+ JOD
+ JPY
+ KES
+ KGS
+ KHR
+ KMF
+ KPW
+ KRH
+ KRO
+ KRW
+ KWD
+ KYD
+ KZT
+ LAK
+ LBP
+ LKR
+ LRD
+ LSL
+ LTL
+ LTT
+ LUC
+ LUF
+ LUL
+ LVL
+ LVR
+ LYD
+ MAD
+ MAF
+ MCF
+ MDC
+ MDL
+ MGA
+ MGF
+ MKD
+ MKN
+ MLF
+ MMK
+ MNT
+ MOP
+ MRO
+ MRU
+ MTL
+ MTP
+ MUR
+ MVP
+ MVR
+ MWK
+ MXN
+ MXP
+ MXV
+ MYR
+ MZE
+ MZM
+ MZN
+ NAD
+ NGN
+ NIC
+ NIO
+ NLG
+ NOK
+ NPR
+ NZD
+ OMR
+ PAB
+ PEI
+ PEN
+ PES
+ PGK
+ PHP
+ PKR
+ PLN
+ PLZ
+ PTE
+ PYG
+ QAR
+ RHD
+ ROL
+ RON
+ RSD
+ RUB
+ RUR
+ RWF
+ SAR
+ SBD
+ SCR
+ SDD
+ SDG
+ SDP
+ SEK
+ SGD
+ SHP
+ SIT
+ SKK
+ SLL
+ SOS
+ SRD
+ SRG
+ SSP
+ STD
+ STN
+ SUR
+ SVC
+ SYP
+ SZL
+ THB
+ TJR
+ TJS
+ TMM
+ TMT
+ TND
+ TOP
+ TPE
+ TRL
+ TRY
+ TTD
+ TWD
+ TZS
+ UAH
+ UAK
+ UGS
+ UGX
+ USD
+ USN
+ USS
+ UYI
+ UYP
+ UYU
+ UYW
+ UZS
+ VEB
+ VEF
+ VES
+ VND
+ VNN
+ VUV
+ WST
+ XAF
+ XAG
+ XAU
+ XBA
+ XBB
+ XBC
+ XBD
+ XCD
+ XDR
+ XEU
+ XFO
+ XFU
+ XOF
+ XPD
+ XPF
+ XPT
+ XRE
+ XSU
+ XTS
+ XUA
+ XXX
+ YDD
+ YER
+ YUD
+ YUM
+ YUN
+ YUR
+ ZAL
+ ZAR
+ ZMK
+ ZMW
+ ZRN
+ ZRZ
+ ZWD
+ ZWL
+ ZWR
+)
diff --git a/vendor/github.com/go-playground/locales/logo.png b/vendor/github.com/go-playground/locales/logo.png
new file mode 100644
index 00000000..3038276e
Binary files /dev/null and b/vendor/github.com/go-playground/locales/logo.png differ
diff --git a/vendor/github.com/go-playground/locales/rules.go b/vendor/github.com/go-playground/locales/rules.go
new file mode 100644
index 00000000..92029001
--- /dev/null
+++ b/vendor/github.com/go-playground/locales/rules.go
@@ -0,0 +1,293 @@
+package locales
+
+import (
+ "strconv"
+ "time"
+
+ "github.com/go-playground/locales/currency"
+)
+
+// // ErrBadNumberValue is returned when the number passed for
+// // plural rule determination cannot be parsed
+// type ErrBadNumberValue struct {
+// NumberValue string
+// InnerError error
+// }
+
+// // Error returns ErrBadNumberValue error string
+// func (e *ErrBadNumberValue) Error() string {
+// return fmt.Sprintf("Invalid Number Value '%s' %s", e.NumberValue, e.InnerError)
+// }
+
+// var _ error = new(ErrBadNumberValue)
+
+// PluralRule denotes the type of plural rules
+type PluralRule int
+
+// PluralRule's
+const (
+ PluralRuleUnknown PluralRule = iota
+ PluralRuleZero // zero
+ PluralRuleOne // one - singular
+ PluralRuleTwo // two - dual
+ PluralRuleFew // few - paucal
+ PluralRuleMany // many - also used for fractions if they have a separate class
+ PluralRuleOther // other - required—general plural form—also used if the language only has a single form
+)
+
+const (
+ pluralsString = "UnknownZeroOneTwoFewManyOther"
+)
+
+// Translator encapsulates an instance of a locale
+// NOTE: some values are returned as a []byte just in case the caller
+// wishes to add more and can help avoid allocations; otherwise just cast as string
+type Translator interface {
+
+ // The following Functions are for overriding, debugging or developing
+ // with a Translator Locale
+
+ // Locale returns the string value of the translator
+ Locale() string
+
+ // returns an array of cardinal plural rules associated
+ // with this translator
+ PluralsCardinal() []PluralRule
+
+ // returns an array of ordinal plural rules associated
+ // with this translator
+ PluralsOrdinal() []PluralRule
+
+ // returns an array of range plural rules associated
+ // with this translator
+ PluralsRange() []PluralRule
+
+ // returns the cardinal PluralRule given 'num' and digits/precision of 'v' for locale
+ CardinalPluralRule(num float64, v uint64) PluralRule
+
+ // returns the ordinal PluralRule given 'num' and digits/precision of 'v' for locale
+ OrdinalPluralRule(num float64, v uint64) PluralRule
+
+ // returns the ordinal PluralRule given 'num1', 'num2' and digits/precision of 'v1' and 'v2' for locale
+ RangePluralRule(num1 float64, v1 uint64, num2 float64, v2 uint64) PluralRule
+
+ // returns the locales abbreviated month given the 'month' provided
+ MonthAbbreviated(month time.Month) string
+
+ // returns the locales abbreviated months
+ MonthsAbbreviated() []string
+
+ // returns the locales narrow month given the 'month' provided
+ MonthNarrow(month time.Month) string
+
+ // returns the locales narrow months
+ MonthsNarrow() []string
+
+ // returns the locales wide month given the 'month' provided
+ MonthWide(month time.Month) string
+
+ // returns the locales wide months
+ MonthsWide() []string
+
+ // returns the locales abbreviated weekday given the 'weekday' provided
+ WeekdayAbbreviated(weekday time.Weekday) string
+
+ // returns the locales abbreviated weekdays
+ WeekdaysAbbreviated() []string
+
+ // returns the locales narrow weekday given the 'weekday' provided
+ WeekdayNarrow(weekday time.Weekday) string
+
+ // WeekdaysNarrowreturns the locales narrow weekdays
+ WeekdaysNarrow() []string
+
+ // returns the locales short weekday given the 'weekday' provided
+ WeekdayShort(weekday time.Weekday) string
+
+ // returns the locales short weekdays
+ WeekdaysShort() []string
+
+ // returns the locales wide weekday given the 'weekday' provided
+ WeekdayWide(weekday time.Weekday) string
+
+ // returns the locales wide weekdays
+ WeekdaysWide() []string
+
+ // The following Functions are common Formatting functionsfor the Translator's Locale
+
+ // returns 'num' with digits/precision of 'v' for locale and handles both Whole and Real numbers based on 'v'
+ FmtNumber(num float64, v uint64) string
+
+ // returns 'num' with digits/precision of 'v' for locale and handles both Whole and Real numbers based on 'v'
+ // NOTE: 'num' passed into FmtPercent is assumed to be in percent already
+ FmtPercent(num float64, v uint64) string
+
+ // returns the currency representation of 'num' with digits/precision of 'v' for locale
+ FmtCurrency(num float64, v uint64, currency currency.Type) string
+
+ // returns the currency representation of 'num' with digits/precision of 'v' for locale
+ // in accounting notation.
+ FmtAccounting(num float64, v uint64, currency currency.Type) string
+
+ // returns the short date representation of 't' for locale
+ FmtDateShort(t time.Time) string
+
+ // returns the medium date representation of 't' for locale
+ FmtDateMedium(t time.Time) string
+
+ // returns the long date representation of 't' for locale
+ FmtDateLong(t time.Time) string
+
+ // returns the full date representation of 't' for locale
+ FmtDateFull(t time.Time) string
+
+ // returns the short time representation of 't' for locale
+ FmtTimeShort(t time.Time) string
+
+ // returns the medium time representation of 't' for locale
+ FmtTimeMedium(t time.Time) string
+
+ // returns the long time representation of 't' for locale
+ FmtTimeLong(t time.Time) string
+
+ // returns the full time representation of 't' for locale
+ FmtTimeFull(t time.Time) string
+}
+
+// String returns the string value of PluralRule
+func (p PluralRule) String() string {
+
+ switch p {
+ case PluralRuleZero:
+ return pluralsString[7:11]
+ case PluralRuleOne:
+ return pluralsString[11:14]
+ case PluralRuleTwo:
+ return pluralsString[14:17]
+ case PluralRuleFew:
+ return pluralsString[17:20]
+ case PluralRuleMany:
+ return pluralsString[20:24]
+ case PluralRuleOther:
+ return pluralsString[24:]
+ default:
+ return pluralsString[:7]
+ }
+}
+
+//
+// Precision Notes:
+//
+// must specify a precision >= 0, and here is why https://play.golang.org/p/LyL90U0Vyh
+//
+// v := float64(3.141)
+// i := float64(int64(v))
+//
+// fmt.Println(v - i)
+//
+// or
+//
+// s := strconv.FormatFloat(v-i, 'f', -1, 64)
+// fmt.Println(s)
+//
+// these will not print what you'd expect: 0.14100000000000001
+// and so this library requires a precision to be specified, or
+// inaccurate plural rules could be applied.
+//
+//
+//
+// n - absolute value of the source number (integer and decimals).
+// i - integer digits of n.
+// v - number of visible fraction digits in n, with trailing zeros.
+// w - number of visible fraction digits in n, without trailing zeros.
+// f - visible fractional digits in n, with trailing zeros.
+// t - visible fractional digits in n, without trailing zeros.
+//
+//
+// Func(num float64, v uint64) // v = digits/precision and prevents -1 as a special case as this can lead to very unexpected behaviour, see precision note's above.
+//
+// n := math.Abs(num)
+// i := int64(n)
+// v := v
+//
+//
+// w := strconv.FormatFloat(num-float64(i), 'f', int(v), 64) // then parse backwards on string until no more zero's....
+// f := strconv.FormatFloat(n, 'f', int(v), 64) // then turn everything after decimal into an int64
+// t := strconv.FormatFloat(n, 'f', int(v), 64) // then parse backwards on string until no more zero's....
+//
+//
+//
+// General Inclusion Rules
+// - v will always be available inherently
+// - all require n
+// - w requires i
+//
+
+// W returns the number of visible fraction digits in N, without trailing zeros.
+func W(n float64, v uint64) (w int64) {
+
+ s := strconv.FormatFloat(n-float64(int64(n)), 'f', int(v), 64)
+
+ // with either be '0' or '0.xxxx', so if 1 then w will be zero
+ // otherwise need to parse
+ if len(s) != 1 {
+
+ s = s[2:]
+ end := len(s) + 1
+
+ for i := end; i >= 0; i-- {
+ if s[i] != '0' {
+ end = i + 1
+ break
+ }
+ }
+
+ w = int64(len(s[:end]))
+ }
+
+ return
+}
+
+// F returns the visible fractional digits in N, with trailing zeros.
+func F(n float64, v uint64) (f int64) {
+
+ s := strconv.FormatFloat(n-float64(int64(n)), 'f', int(v), 64)
+
+ // with either be '0' or '0.xxxx', so if 1 then f will be zero
+ // otherwise need to parse
+ if len(s) != 1 {
+
+ // ignoring error, because it can't fail as we generated
+ // the string internally from a real number
+ f, _ = strconv.ParseInt(s[2:], 10, 64)
+ }
+
+ return
+}
+
+// T returns the visible fractional digits in N, without trailing zeros.
+func T(n float64, v uint64) (t int64) {
+
+ s := strconv.FormatFloat(n-float64(int64(n)), 'f', int(v), 64)
+
+ // with either be '0' or '0.xxxx', so if 1 then t will be zero
+ // otherwise need to parse
+ if len(s) != 1 {
+
+ s = s[2:]
+ end := len(s) + 1
+
+ for i := end; i >= 0; i-- {
+ if s[i] != '0' {
+ end = i + 1
+ break
+ }
+ }
+
+ // ignoring error, because it can't fail as we generated
+ // the string internally from a real number
+ t, _ = strconv.ParseInt(s[:end], 10, 64)
+ }
+
+ return
+}
diff --git a/vendor/github.com/go-playground/universal-translator/.gitignore b/vendor/github.com/go-playground/universal-translator/.gitignore
new file mode 100644
index 00000000..bc4e07f3
--- /dev/null
+++ b/vendor/github.com/go-playground/universal-translator/.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
+*.prof
+*.coverprofile
\ No newline at end of file
diff --git a/vendor/github.com/go-playground/universal-translator/.travis.yml b/vendor/github.com/go-playground/universal-translator/.travis.yml
new file mode 100644
index 00000000..39b8b923
--- /dev/null
+++ b/vendor/github.com/go-playground/universal-translator/.travis.yml
@@ -0,0 +1,27 @@
+language: go
+go:
+ - 1.13.4
+ - tip
+matrix:
+ allow_failures:
+ - go: tip
+
+notifications:
+ email:
+ recipients: dean.karn@gmail.com
+ on_success: change
+ on_failure: always
+
+before_install:
+ - go install github.com/mattn/goveralls
+
+# Only clone the most recent commit.
+git:
+ depth: 1
+
+script:
+ - go test -v -race -covermode=atomic -coverprofile=coverage.coverprofile ./...
+
+after_success: |
+ [ $TRAVIS_GO_VERSION = 1.13.4 ] &&
+ goveralls -coverprofile=coverage.coverprofile -service travis-ci -repotoken $COVERALLS_TOKEN
\ No newline at end of file
diff --git a/vendor/github.com/go-playground/universal-translator/LICENSE b/vendor/github.com/go-playground/universal-translator/LICENSE
new file mode 100644
index 00000000..8d8aba15
--- /dev/null
+++ b/vendor/github.com/go-playground/universal-translator/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Go Playground
+
+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/go-playground/universal-translator/Makefile b/vendor/github.com/go-playground/universal-translator/Makefile
new file mode 100644
index 00000000..ec3455bd
--- /dev/null
+++ b/vendor/github.com/go-playground/universal-translator/Makefile
@@ -0,0 +1,18 @@
+GOCMD=GO111MODULE=on go
+
+linters-install:
+ @golangci-lint --version >/dev/null 2>&1 || { \
+ echo "installing linting tools..."; \
+ curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s v1.41.1; \
+ }
+
+lint: linters-install
+ golangci-lint run
+
+test:
+ $(GOCMD) test -cover -race ./...
+
+bench:
+ $(GOCMD) test -bench=. -benchmem ./...
+
+.PHONY: test lint linters-install
\ No newline at end of file
diff --git a/vendor/github.com/go-playground/universal-translator/README.md b/vendor/github.com/go-playground/universal-translator/README.md
new file mode 100644
index 00000000..d9b66547
--- /dev/null
+++ b/vendor/github.com/go-playground/universal-translator/README.md
@@ -0,0 +1,87 @@
+## universal-translator
+ 
+[](https://coveralls.io/github/go-playground/universal-translator)
+[](https://goreportcard.com/report/github.com/go-playground/universal-translator)
+[](https://godoc.org/github.com/go-playground/universal-translator)
+
+
+Universal Translator is an i18n Translator for Go/Golang using CLDR data + pluralization rules
+
+Why another i18n library?
+--------------------------
+Because none of the plural rules seem to be correct out there, including the previous implementation of this package,
+so I took it upon myself to create [locales](https://github.com/go-playground/locales) for everyone to use; this package
+is a thin wrapper around [locales](https://github.com/go-playground/locales) in order to store and translate text for
+use in your applications.
+
+Features
+--------
+- [x] Rules generated from the [CLDR](http://cldr.unicode.org/index/downloads) data, v36.0.1
+- [x] Contains Cardinal, Ordinal and Range Plural Rules
+- [x] Contains Month, Weekday and Timezone translations built in
+- [x] Contains Date & Time formatting functions
+- [x] Contains Number, Currency, Accounting and Percent formatting functions
+- [x] Supports the "Gregorian" calendar only ( my time isn't unlimited, had to draw the line somewhere )
+- [x] Support loading translations from files
+- [x] Exporting translations to file(s), mainly for getting them professionally translated
+- [ ] Code Generation for translation files -> Go code.. i.e. after it has been professionally translated
+- [ ] Tests for all languages, I need help with this, please see [here](https://github.com/go-playground/locales/issues/1)
+
+Installation
+-----------
+
+Use go get
+
+```shell
+go get github.com/go-playground/universal-translator
+```
+
+Usage & Documentation
+-------
+
+Please see https://godoc.org/github.com/go-playground/universal-translator for usage docs
+
+##### Examples:
+
+- [Basic](https://github.com/go-playground/universal-translator/tree/master/_examples/basic)
+- [Full - no files](https://github.com/go-playground/universal-translator/tree/master/_examples/full-no-files)
+- [Full - with files](https://github.com/go-playground/universal-translator/tree/master/_examples/full-with-files)
+
+File formatting
+--------------
+All types, Plain substitution, Cardinal, Ordinal and Range translations can all be contained within the same file(s);
+they are only separated for easy viewing.
+
+##### Examples:
+
+- [Formats](https://github.com/go-playground/universal-translator/tree/master/_examples/file-formats)
+
+##### Basic Makeup
+NOTE: not all fields are needed for all translation types, see [examples](https://github.com/go-playground/universal-translator/tree/master/_examples/file-formats)
+```json
+{
+ "locale": "en",
+ "key": "days-left",
+ "trans": "You have {0} day left.",
+ "type": "Cardinal",
+ "rule": "One",
+ "override": false
+}
+```
+|Field|Description|
+|---|---|
+|locale|The locale for which the translation is for.|
+|key|The translation key that will be used to store and lookup each translation; normally it is a string or integer.|
+|trans|The actual translation text.|
+|type|The type of translation Cardinal, Ordinal, Range or "" for a plain substitution(not required to be defined if plain used)|
+|rule|The plural rule for which the translation is for eg. One, Two, Few, Many or Other.(not required to be defined if plain used)|
+|override|If you wish to override an existing translation that has already been registered, set this to 'true'. 99% of the time there is no need to define it.|
+
+Help With Tests
+---------------
+To anyone interesting in helping or contributing, I sure could use some help creating tests for each language.
+Please see issue [here](https://github.com/go-playground/locales/issues/1) for details.
+
+License
+------
+Distributed under MIT License, please see license file in code for more details.
diff --git a/vendor/github.com/go-playground/universal-translator/errors.go b/vendor/github.com/go-playground/universal-translator/errors.go
new file mode 100644
index 00000000..38b163b6
--- /dev/null
+++ b/vendor/github.com/go-playground/universal-translator/errors.go
@@ -0,0 +1,148 @@
+package ut
+
+import (
+ "errors"
+ "fmt"
+
+ "github.com/go-playground/locales"
+)
+
+var (
+ // ErrUnknowTranslation indicates the translation could not be found
+ ErrUnknowTranslation = errors.New("Unknown Translation")
+)
+
+var _ error = new(ErrConflictingTranslation)
+var _ error = new(ErrRangeTranslation)
+var _ error = new(ErrOrdinalTranslation)
+var _ error = new(ErrCardinalTranslation)
+var _ error = new(ErrMissingPluralTranslation)
+var _ error = new(ErrExistingTranslator)
+
+// ErrExistingTranslator is the error representing a conflicting translator
+type ErrExistingTranslator struct {
+ locale string
+}
+
+// Error returns ErrExistingTranslator's internal error text
+func (e *ErrExistingTranslator) Error() string {
+ return fmt.Sprintf("error: conflicting translator for locale '%s'", e.locale)
+}
+
+// ErrConflictingTranslation is the error representing a conflicting translation
+type ErrConflictingTranslation struct {
+ locale string
+ key interface{}
+ rule locales.PluralRule
+ text string
+}
+
+// Error returns ErrConflictingTranslation's internal error text
+func (e *ErrConflictingTranslation) Error() string {
+
+ if _, ok := e.key.(string); !ok {
+ return fmt.Sprintf("error: conflicting key '%#v' rule '%s' with text '%s' for locale '%s', value being ignored", e.key, e.rule, e.text, e.locale)
+ }
+
+ return fmt.Sprintf("error: conflicting key '%s' rule '%s' with text '%s' for locale '%s', value being ignored", e.key, e.rule, e.text, e.locale)
+}
+
+// ErrRangeTranslation is the error representing a range translation error
+type ErrRangeTranslation struct {
+ text string
+}
+
+// Error returns ErrRangeTranslation's internal error text
+func (e *ErrRangeTranslation) Error() string {
+ return e.text
+}
+
+// ErrOrdinalTranslation is the error representing an ordinal translation error
+type ErrOrdinalTranslation struct {
+ text string
+}
+
+// Error returns ErrOrdinalTranslation's internal error text
+func (e *ErrOrdinalTranslation) Error() string {
+ return e.text
+}
+
+// ErrCardinalTranslation is the error representing a cardinal translation error
+type ErrCardinalTranslation struct {
+ text string
+}
+
+// Error returns ErrCardinalTranslation's internal error text
+func (e *ErrCardinalTranslation) Error() string {
+ return e.text
+}
+
+// ErrMissingPluralTranslation is the error signifying a missing translation given
+// the locales plural rules.
+type ErrMissingPluralTranslation struct {
+ locale string
+ key interface{}
+ rule locales.PluralRule
+ translationType string
+}
+
+// Error returns ErrMissingPluralTranslation's internal error text
+func (e *ErrMissingPluralTranslation) Error() string {
+
+ if _, ok := e.key.(string); !ok {
+ return fmt.Sprintf("error: missing '%s' plural rule '%s' for translation with key '%#v' and locale '%s'", e.translationType, e.rule, e.key, e.locale)
+ }
+
+ return fmt.Sprintf("error: missing '%s' plural rule '%s' for translation with key '%s' and locale '%s'", e.translationType, e.rule, e.key, e.locale)
+}
+
+// ErrMissingBracket is the error representing a missing bracket in a translation
+// eg. This is a {0 <-- missing ending '}'
+type ErrMissingBracket struct {
+ locale string
+ key interface{}
+ text string
+}
+
+// Error returns ErrMissingBracket error message
+func (e *ErrMissingBracket) Error() string {
+ return fmt.Sprintf("error: missing bracket '{}', in translation. locale: '%s' key: '%v' text: '%s'", e.locale, e.key, e.text)
+}
+
+// ErrBadParamSyntax is the error representing a bad parameter definition in a translation
+// eg. This is a {must-be-int}
+type ErrBadParamSyntax struct {
+ locale string
+ param string
+ key interface{}
+ text string
+}
+
+// Error returns ErrBadParamSyntax error message
+func (e *ErrBadParamSyntax) Error() string {
+ return fmt.Sprintf("error: bad parameter syntax, missing parameter '%s' in translation. locale: '%s' key: '%v' text: '%s'", e.param, e.locale, e.key, e.text)
+}
+
+// import/export errors
+
+// ErrMissingLocale is the error representing an expected locale that could
+// not be found aka locale not registered with the UniversalTranslator Instance
+type ErrMissingLocale struct {
+ locale string
+}
+
+// Error returns ErrMissingLocale's internal error text
+func (e *ErrMissingLocale) Error() string {
+ return fmt.Sprintf("error: locale '%s' not registered.", e.locale)
+}
+
+// ErrBadPluralDefinition is the error representing an incorrect plural definition
+// usually found within translations defined within files during the import process.
+type ErrBadPluralDefinition struct {
+ tl translation
+}
+
+// Error returns ErrBadPluralDefinition's internal error text
+func (e *ErrBadPluralDefinition) Error() string {
+ return fmt.Sprintf("error: bad plural definition '%#v'", e.tl)
+}
diff --git a/vendor/github.com/go-playground/universal-translator/import_export.go b/vendor/github.com/go-playground/universal-translator/import_export.go
new file mode 100644
index 00000000..87a1b465
--- /dev/null
+++ b/vendor/github.com/go-playground/universal-translator/import_export.go
@@ -0,0 +1,274 @@
+package ut
+
+import (
+ "encoding/json"
+ "fmt"
+ "os"
+ "path/filepath"
+
+ "io"
+
+ "github.com/go-playground/locales"
+)
+
+type translation struct {
+ Locale string `json:"locale"`
+ Key interface{} `json:"key"` // either string or integer
+ Translation string `json:"trans"`
+ PluralType string `json:"type,omitempty"`
+ PluralRule string `json:"rule,omitempty"`
+ OverrideExisting bool `json:"override,omitempty"`
+}
+
+const (
+ cardinalType = "Cardinal"
+ ordinalType = "Ordinal"
+ rangeType = "Range"
+)
+
+// ImportExportFormat is the format of the file import or export
+type ImportExportFormat uint8
+
+// supported Export Formats
+const (
+ FormatJSON ImportExportFormat = iota
+)
+
+// Export writes the translations out to a file on disk.
+//
+// NOTE: this currently only works with string or int translations keys.
+func (t *UniversalTranslator) Export(format ImportExportFormat, dirname string) error {
+
+ _, err := os.Stat(dirname)
+ if err != nil {
+
+ if !os.IsNotExist(err) {
+ return err
+ }
+
+ if err = os.MkdirAll(dirname, 0744); err != nil {
+ return err
+ }
+ }
+
+ // build up translations
+ var trans []translation
+ var b []byte
+ var ext string
+
+ for _, locale := range t.translators {
+
+ for k, v := range locale.(*translator).translations {
+ trans = append(trans, translation{
+ Locale: locale.Locale(),
+ Key: k,
+ Translation: v.text,
+ })
+ }
+
+ for k, pluralTrans := range locale.(*translator).cardinalTanslations {
+
+ for i, plural := range pluralTrans {
+
+ // leave enough for all plural rules
+ // but not all are set for all languages.
+ if plural == nil {
+ continue
+ }
+
+ trans = append(trans, translation{
+ Locale: locale.Locale(),
+ Key: k.(string),
+ Translation: plural.text,
+ PluralType: cardinalType,
+ PluralRule: locales.PluralRule(i).String(),
+ })
+ }
+ }
+
+ for k, pluralTrans := range locale.(*translator).ordinalTanslations {
+
+ for i, plural := range pluralTrans {
+
+ // leave enough for all plural rules
+ // but not all are set for all languages.
+ if plural == nil {
+ continue
+ }
+
+ trans = append(trans, translation{
+ Locale: locale.Locale(),
+ Key: k.(string),
+ Translation: plural.text,
+ PluralType: ordinalType,
+ PluralRule: locales.PluralRule(i).String(),
+ })
+ }
+ }
+
+ for k, pluralTrans := range locale.(*translator).rangeTanslations {
+
+ for i, plural := range pluralTrans {
+
+ // leave enough for all plural rules
+ // but not all are set for all languages.
+ if plural == nil {
+ continue
+ }
+
+ trans = append(trans, translation{
+ Locale: locale.Locale(),
+ Key: k.(string),
+ Translation: plural.text,
+ PluralType: rangeType,
+ PluralRule: locales.PluralRule(i).String(),
+ })
+ }
+ }
+
+ switch format {
+ case FormatJSON:
+ b, err = json.MarshalIndent(trans, "", " ")
+ ext = ".json"
+ }
+
+ if err != nil {
+ return err
+ }
+
+ err = os.WriteFile(filepath.Join(dirname, fmt.Sprintf("%s%s", locale.Locale(), ext)), b, 0644)
+ if err != nil {
+ return err
+ }
+
+ trans = trans[0:0]
+ }
+
+ return nil
+}
+
+// Import reads the translations out of a file or directory on disk.
+//
+// NOTE: this currently only works with string or int translations keys.
+func (t *UniversalTranslator) Import(format ImportExportFormat, dirnameOrFilename string) error {
+
+ fi, err := os.Stat(dirnameOrFilename)
+ if err != nil {
+ return err
+ }
+
+ processFn := func(filename string) error {
+
+ f, err := os.Open(filename)
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+
+ return t.ImportByReader(format, f)
+ }
+
+ if !fi.IsDir() {
+ return processFn(dirnameOrFilename)
+ }
+
+ // recursively go through directory
+ walker := func(path string, info os.FileInfo, err error) error {
+
+ if info.IsDir() {
+ return nil
+ }
+
+ switch format {
+ case FormatJSON:
+ // skip non JSON files
+ if filepath.Ext(info.Name()) != ".json" {
+ return nil
+ }
+ }
+
+ return processFn(path)
+ }
+
+ return filepath.Walk(dirnameOrFilename, walker)
+}
+
+// ImportByReader imports the the translations found within the contents read from the supplied reader.
+//
+// NOTE: generally used when assets have been embedded into the binary and are already in memory.
+func (t *UniversalTranslator) ImportByReader(format ImportExportFormat, reader io.Reader) error {
+
+ b, err := io.ReadAll(reader)
+ if err != nil {
+ return err
+ }
+
+ var trans []translation
+
+ switch format {
+ case FormatJSON:
+ err = json.Unmarshal(b, &trans)
+ }
+
+ if err != nil {
+ return err
+ }
+
+ for _, tl := range trans {
+
+ locale, found := t.FindTranslator(tl.Locale)
+ if !found {
+ return &ErrMissingLocale{locale: tl.Locale}
+ }
+
+ pr := stringToPR(tl.PluralRule)
+
+ if pr == locales.PluralRuleUnknown {
+
+ err = locale.Add(tl.Key, tl.Translation, tl.OverrideExisting)
+ if err != nil {
+ return err
+ }
+
+ continue
+ }
+
+ switch tl.PluralType {
+ case cardinalType:
+ err = locale.AddCardinal(tl.Key, tl.Translation, pr, tl.OverrideExisting)
+ case ordinalType:
+ err = locale.AddOrdinal(tl.Key, tl.Translation, pr, tl.OverrideExisting)
+ case rangeType:
+ err = locale.AddRange(tl.Key, tl.Translation, pr, tl.OverrideExisting)
+ default:
+ return &ErrBadPluralDefinition{tl: tl}
+ }
+
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func stringToPR(s string) locales.PluralRule {
+
+ switch s {
+ case "Zero":
+ return locales.PluralRuleZero
+ case "One":
+ return locales.PluralRuleOne
+ case "Two":
+ return locales.PluralRuleTwo
+ case "Few":
+ return locales.PluralRuleFew
+ case "Many":
+ return locales.PluralRuleMany
+ case "Other":
+ return locales.PluralRuleOther
+ default:
+ return locales.PluralRuleUnknown
+ }
+
+}
diff --git a/vendor/github.com/go-playground/universal-translator/logo.png b/vendor/github.com/go-playground/universal-translator/logo.png
new file mode 100644
index 00000000..a37aa8c0
Binary files /dev/null and b/vendor/github.com/go-playground/universal-translator/logo.png differ
diff --git a/vendor/github.com/go-playground/universal-translator/translator.go b/vendor/github.com/go-playground/universal-translator/translator.go
new file mode 100644
index 00000000..24b18db9
--- /dev/null
+++ b/vendor/github.com/go-playground/universal-translator/translator.go
@@ -0,0 +1,420 @@
+package ut
+
+import (
+ "fmt"
+ "strconv"
+ "strings"
+
+ "github.com/go-playground/locales"
+)
+
+const (
+ paramZero = "{0}"
+ paramOne = "{1}"
+ unknownTranslation = ""
+)
+
+// Translator is universal translators
+// translator instance which is a thin wrapper
+// around locales.Translator instance providing
+// some extra functionality
+type Translator interface {
+ locales.Translator
+
+ // adds a normal translation for a particular language/locale
+ // {#} is the only replacement type accepted and are ad infinitum
+ // eg. one: '{0} day left' other: '{0} days left'
+ Add(key interface{}, text string, override bool) error
+
+ // adds a cardinal plural translation for a particular language/locale
+ // {0} is the only replacement type accepted and only one variable is accepted as
+ // multiple cannot be used for a plural rule determination, unless it is a range;
+ // see AddRange below.
+ // eg. in locale 'en' one: '{0} day left' other: '{0} days left'
+ AddCardinal(key interface{}, text string, rule locales.PluralRule, override bool) error
+
+ // adds an ordinal plural translation for a particular language/locale
+ // {0} is the only replacement type accepted and only one variable is accepted as
+ // multiple cannot be used for a plural rule determination, unless it is a range;
+ // see AddRange below.
+ // eg. in locale 'en' one: '{0}st day of spring' other: '{0}nd day of spring'
+ // - 1st, 2nd, 3rd...
+ AddOrdinal(key interface{}, text string, rule locales.PluralRule, override bool) error
+
+ // adds a range plural translation for a particular language/locale
+ // {0} and {1} are the only replacement types accepted and only these are accepted.
+ // eg. in locale 'nl' one: '{0}-{1} day left' other: '{0}-{1} days left'
+ AddRange(key interface{}, text string, rule locales.PluralRule, override bool) error
+
+ // creates the translation for the locale given the 'key' and params passed in
+ T(key interface{}, params ...string) (string, error)
+
+ // creates the cardinal translation for the locale given the 'key', 'num' and 'digit' arguments
+ // and param passed in
+ C(key interface{}, num float64, digits uint64, param string) (string, error)
+
+ // creates the ordinal translation for the locale given the 'key', 'num' and 'digit' arguments
+ // and param passed in
+ O(key interface{}, num float64, digits uint64, param string) (string, error)
+
+ // creates the range translation for the locale given the 'key', 'num1', 'digit1', 'num2' and
+ // 'digit2' arguments and 'param1' and 'param2' passed in
+ R(key interface{}, num1 float64, digits1 uint64, num2 float64, digits2 uint64, param1, param2 string) (string, error)
+
+ // VerifyTranslations checks to ensures that no plural rules have been
+ // missed within the translations.
+ VerifyTranslations() error
+}
+
+var _ Translator = new(translator)
+var _ locales.Translator = new(translator)
+
+type translator struct {
+ locales.Translator
+ translations map[interface{}]*transText
+ cardinalTanslations map[interface{}][]*transText // array index is mapped to locales.PluralRule index + the locales.PluralRuleUnknown
+ ordinalTanslations map[interface{}][]*transText
+ rangeTanslations map[interface{}][]*transText
+}
+
+type transText struct {
+ text string
+ indexes []int
+}
+
+func newTranslator(trans locales.Translator) Translator {
+ return &translator{
+ Translator: trans,
+ translations: make(map[interface{}]*transText), // translation text broken up by byte index
+ cardinalTanslations: make(map[interface{}][]*transText),
+ ordinalTanslations: make(map[interface{}][]*transText),
+ rangeTanslations: make(map[interface{}][]*transText),
+ }
+}
+
+// Add adds a normal translation for a particular language/locale
+// {#} is the only replacement type accepted and are ad infinitum
+// eg. one: '{0} day left' other: '{0} days left'
+func (t *translator) Add(key interface{}, text string, override bool) error {
+
+ if _, ok := t.translations[key]; ok && !override {
+ return &ErrConflictingTranslation{locale: t.Locale(), key: key, text: text}
+ }
+
+ lb := strings.Count(text, "{")
+ rb := strings.Count(text, "}")
+
+ if lb != rb {
+ return &ErrMissingBracket{locale: t.Locale(), key: key, text: text}
+ }
+
+ trans := &transText{
+ text: text,
+ }
+
+ var idx int
+
+ for i := 0; i < lb; i++ {
+ s := "{" + strconv.Itoa(i) + "}"
+ idx = strings.Index(text, s)
+ if idx == -1 {
+ return &ErrBadParamSyntax{locale: t.Locale(), param: s, key: key, text: text}
+ }
+
+ trans.indexes = append(trans.indexes, idx)
+ trans.indexes = append(trans.indexes, idx+len(s))
+ }
+
+ t.translations[key] = trans
+
+ return nil
+}
+
+// AddCardinal adds a cardinal plural translation for a particular language/locale
+// {0} is the only replacement type accepted and only one variable is accepted as
+// multiple cannot be used for a plural rule determination, unless it is a range;
+// see AddRange below.
+// eg. in locale 'en' one: '{0} day left' other: '{0} days left'
+func (t *translator) AddCardinal(key interface{}, text string, rule locales.PluralRule, override bool) error {
+
+ var verified bool
+
+ // verify plural rule exists for locale
+ for _, pr := range t.PluralsCardinal() {
+ if pr == rule {
+ verified = true
+ break
+ }
+ }
+
+ if !verified {
+ return &ErrCardinalTranslation{text: fmt.Sprintf("error: cardinal plural rule '%s' does not exist for locale '%s' key: '%v' text: '%s'", rule, t.Locale(), key, text)}
+ }
+
+ tarr, ok := t.cardinalTanslations[key]
+ if ok {
+ // verify not adding a conflicting record
+ if len(tarr) > 0 && tarr[rule] != nil && !override {
+ return &ErrConflictingTranslation{locale: t.Locale(), key: key, rule: rule, text: text}
+ }
+
+ } else {
+ tarr = make([]*transText, 7)
+ t.cardinalTanslations[key] = tarr
+ }
+
+ trans := &transText{
+ text: text,
+ indexes: make([]int, 2),
+ }
+
+ tarr[rule] = trans
+
+ idx := strings.Index(text, paramZero)
+ if idx == -1 {
+ tarr[rule] = nil
+ return &ErrCardinalTranslation{text: fmt.Sprintf("error: parameter '%s' not found, may want to use 'Add' instead of 'AddCardinal'. locale: '%s' key: '%v' text: '%s'", paramZero, t.Locale(), key, text)}
+ }
+
+ trans.indexes[0] = idx
+ trans.indexes[1] = idx + len(paramZero)
+
+ return nil
+}
+
+// AddOrdinal adds an ordinal plural translation for a particular language/locale
+// {0} is the only replacement type accepted and only one variable is accepted as
+// multiple cannot be used for a plural rule determination, unless it is a range;
+// see AddRange below.
+// eg. in locale 'en' one: '{0}st day of spring' other: '{0}nd day of spring' - 1st, 2nd, 3rd...
+func (t *translator) AddOrdinal(key interface{}, text string, rule locales.PluralRule, override bool) error {
+
+ var verified bool
+
+ // verify plural rule exists for locale
+ for _, pr := range t.PluralsOrdinal() {
+ if pr == rule {
+ verified = true
+ break
+ }
+ }
+
+ if !verified {
+ return &ErrOrdinalTranslation{text: fmt.Sprintf("error: ordinal plural rule '%s' does not exist for locale '%s' key: '%v' text: '%s'", rule, t.Locale(), key, text)}
+ }
+
+ tarr, ok := t.ordinalTanslations[key]
+ if ok {
+ // verify not adding a conflicting record
+ if len(tarr) > 0 && tarr[rule] != nil && !override {
+ return &ErrConflictingTranslation{locale: t.Locale(), key: key, rule: rule, text: text}
+ }
+
+ } else {
+ tarr = make([]*transText, 7)
+ t.ordinalTanslations[key] = tarr
+ }
+
+ trans := &transText{
+ text: text,
+ indexes: make([]int, 2),
+ }
+
+ tarr[rule] = trans
+
+ idx := strings.Index(text, paramZero)
+ if idx == -1 {
+ tarr[rule] = nil
+ return &ErrOrdinalTranslation{text: fmt.Sprintf("error: parameter '%s' not found, may want to use 'Add' instead of 'AddOrdinal'. locale: '%s' key: '%v' text: '%s'", paramZero, t.Locale(), key, text)}
+ }
+
+ trans.indexes[0] = idx
+ trans.indexes[1] = idx + len(paramZero)
+
+ return nil
+}
+
+// AddRange adds a range plural translation for a particular language/locale
+// {0} and {1} are the only replacement types accepted and only these are accepted.
+// eg. in locale 'nl' one: '{0}-{1} day left' other: '{0}-{1} days left'
+func (t *translator) AddRange(key interface{}, text string, rule locales.PluralRule, override bool) error {
+
+ var verified bool
+
+ // verify plural rule exists for locale
+ for _, pr := range t.PluralsRange() {
+ if pr == rule {
+ verified = true
+ break
+ }
+ }
+
+ if !verified {
+ return &ErrRangeTranslation{text: fmt.Sprintf("error: range plural rule '%s' does not exist for locale '%s' key: '%v' text: '%s'", rule, t.Locale(), key, text)}
+ }
+
+ tarr, ok := t.rangeTanslations[key]
+ if ok {
+ // verify not adding a conflicting record
+ if len(tarr) > 0 && tarr[rule] != nil && !override {
+ return &ErrConflictingTranslation{locale: t.Locale(), key: key, rule: rule, text: text}
+ }
+
+ } else {
+ tarr = make([]*transText, 7)
+ t.rangeTanslations[key] = tarr
+ }
+
+ trans := &transText{
+ text: text,
+ indexes: make([]int, 4),
+ }
+
+ tarr[rule] = trans
+
+ idx := strings.Index(text, paramZero)
+ if idx == -1 {
+ tarr[rule] = nil
+ return &ErrRangeTranslation{text: fmt.Sprintf("error: parameter '%s' not found, are you sure you're adding a Range Translation? locale: '%s' key: '%v' text: '%s'", paramZero, t.Locale(), key, text)}
+ }
+
+ trans.indexes[0] = idx
+ trans.indexes[1] = idx + len(paramZero)
+
+ idx = strings.Index(text, paramOne)
+ if idx == -1 {
+ tarr[rule] = nil
+ return &ErrRangeTranslation{text: fmt.Sprintf("error: parameter '%s' not found, a Range Translation requires two parameters. locale: '%s' key: '%v' text: '%s'", paramOne, t.Locale(), key, text)}
+ }
+
+ trans.indexes[2] = idx
+ trans.indexes[3] = idx + len(paramOne)
+
+ return nil
+}
+
+// T creates the translation for the locale given the 'key' and params passed in
+func (t *translator) T(key interface{}, params ...string) (string, error) {
+
+ trans, ok := t.translations[key]
+ if !ok {
+ return unknownTranslation, ErrUnknowTranslation
+ }
+
+ b := make([]byte, 0, 64)
+
+ var start, end, count int
+
+ for i := 0; i < len(trans.indexes); i++ {
+ end = trans.indexes[i]
+ b = append(b, trans.text[start:end]...)
+ b = append(b, params[count]...)
+ i++
+ start = trans.indexes[i]
+ count++
+ }
+
+ b = append(b, trans.text[start:]...)
+
+ return string(b), nil
+}
+
+// C creates the cardinal translation for the locale given the 'key', 'num' and 'digit' arguments and param passed in
+func (t *translator) C(key interface{}, num float64, digits uint64, param string) (string, error) {
+
+ tarr, ok := t.cardinalTanslations[key]
+ if !ok {
+ return unknownTranslation, ErrUnknowTranslation
+ }
+
+ rule := t.CardinalPluralRule(num, digits)
+
+ trans := tarr[rule]
+
+ b := make([]byte, 0, 64)
+ b = append(b, trans.text[:trans.indexes[0]]...)
+ b = append(b, param...)
+ b = append(b, trans.text[trans.indexes[1]:]...)
+
+ return string(b), nil
+}
+
+// O creates the ordinal translation for the locale given the 'key', 'num' and 'digit' arguments and param passed in
+func (t *translator) O(key interface{}, num float64, digits uint64, param string) (string, error) {
+
+ tarr, ok := t.ordinalTanslations[key]
+ if !ok {
+ return unknownTranslation, ErrUnknowTranslation
+ }
+
+ rule := t.OrdinalPluralRule(num, digits)
+
+ trans := tarr[rule]
+
+ b := make([]byte, 0, 64)
+ b = append(b, trans.text[:trans.indexes[0]]...)
+ b = append(b, param...)
+ b = append(b, trans.text[trans.indexes[1]:]...)
+
+ return string(b), nil
+}
+
+// R creates the range translation for the locale given the 'key', 'num1', 'digit1', 'num2' and 'digit2' arguments
+// and 'param1' and 'param2' passed in
+func (t *translator) R(key interface{}, num1 float64, digits1 uint64, num2 float64, digits2 uint64, param1, param2 string) (string, error) {
+
+ tarr, ok := t.rangeTanslations[key]
+ if !ok {
+ return unknownTranslation, ErrUnknowTranslation
+ }
+
+ rule := t.RangePluralRule(num1, digits1, num2, digits2)
+
+ trans := tarr[rule]
+
+ b := make([]byte, 0, 64)
+ b = append(b, trans.text[:trans.indexes[0]]...)
+ b = append(b, param1...)
+ b = append(b, trans.text[trans.indexes[1]:trans.indexes[2]]...)
+ b = append(b, param2...)
+ b = append(b, trans.text[trans.indexes[3]:]...)
+
+ return string(b), nil
+}
+
+// VerifyTranslations checks to ensures that no plural rules have been
+// missed within the translations.
+func (t *translator) VerifyTranslations() error {
+
+ for k, v := range t.cardinalTanslations {
+
+ for _, rule := range t.PluralsCardinal() {
+
+ if v[rule] == nil {
+ return &ErrMissingPluralTranslation{locale: t.Locale(), translationType: "plural", rule: rule, key: k}
+ }
+ }
+ }
+
+ for k, v := range t.ordinalTanslations {
+
+ for _, rule := range t.PluralsOrdinal() {
+
+ if v[rule] == nil {
+ return &ErrMissingPluralTranslation{locale: t.Locale(), translationType: "ordinal", rule: rule, key: k}
+ }
+ }
+ }
+
+ for k, v := range t.rangeTanslations {
+
+ for _, rule := range t.PluralsRange() {
+
+ if v[rule] == nil {
+ return &ErrMissingPluralTranslation{locale: t.Locale(), translationType: "range", rule: rule, key: k}
+ }
+ }
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/go-playground/universal-translator/universal_translator.go b/vendor/github.com/go-playground/universal-translator/universal_translator.go
new file mode 100644
index 00000000..dbf707f5
--- /dev/null
+++ b/vendor/github.com/go-playground/universal-translator/universal_translator.go
@@ -0,0 +1,113 @@
+package ut
+
+import (
+ "strings"
+
+ "github.com/go-playground/locales"
+)
+
+// UniversalTranslator holds all locale & translation data
+type UniversalTranslator struct {
+ translators map[string]Translator
+ fallback Translator
+}
+
+// New returns a new UniversalTranslator instance set with
+// the fallback locale and locales it should support
+func New(fallback locales.Translator, supportedLocales ...locales.Translator) *UniversalTranslator {
+
+ t := &UniversalTranslator{
+ translators: make(map[string]Translator),
+ }
+
+ for _, v := range supportedLocales {
+
+ trans := newTranslator(v)
+ t.translators[strings.ToLower(trans.Locale())] = trans
+
+ if fallback.Locale() == v.Locale() {
+ t.fallback = trans
+ }
+ }
+
+ if t.fallback == nil && fallback != nil {
+ t.fallback = newTranslator(fallback)
+ }
+
+ return t
+}
+
+// FindTranslator trys to find a Translator based on an array of locales
+// and returns the first one it can find, otherwise returns the
+// fallback translator.
+func (t *UniversalTranslator) FindTranslator(locales ...string) (trans Translator, found bool) {
+
+ for _, locale := range locales {
+
+ if trans, found = t.translators[strings.ToLower(locale)]; found {
+ return
+ }
+ }
+
+ return t.fallback, false
+}
+
+// GetTranslator returns the specified translator for the given locale,
+// or fallback if not found
+func (t *UniversalTranslator) GetTranslator(locale string) (trans Translator, found bool) {
+
+ if trans, found = t.translators[strings.ToLower(locale)]; found {
+ return
+ }
+
+ return t.fallback, false
+}
+
+// GetFallback returns the fallback locale
+func (t *UniversalTranslator) GetFallback() Translator {
+ return t.fallback
+}
+
+// AddTranslator adds the supplied translator, if it already exists the override param
+// will be checked and if false an error will be returned, otherwise the translator will be
+// overridden; if the fallback matches the supplied translator it will be overridden as well
+// NOTE: this is normally only used when translator is embedded within a library
+func (t *UniversalTranslator) AddTranslator(translator locales.Translator, override bool) error {
+
+ lc := strings.ToLower(translator.Locale())
+ _, ok := t.translators[lc]
+ if ok && !override {
+ return &ErrExistingTranslator{locale: translator.Locale()}
+ }
+
+ trans := newTranslator(translator)
+
+ if t.fallback.Locale() == translator.Locale() {
+
+ // because it's optional to have a fallback, I don't impose that limitation
+ // don't know why you wouldn't but...
+ if !override {
+ return &ErrExistingTranslator{locale: translator.Locale()}
+ }
+
+ t.fallback = trans
+ }
+
+ t.translators[lc] = trans
+
+ return nil
+}
+
+// VerifyTranslations runs through all locales and identifies any issues
+// eg. missing plural rules for a locale
+func (t *UniversalTranslator) VerifyTranslations() (err error) {
+
+ for _, trans := range t.translators {
+ err = trans.VerifyTranslations()
+ if err != nil {
+ return
+ }
+ }
+
+ return
+}
diff --git a/vendor/github.com/go-playground/validator/v10/.gitignore b/vendor/github.com/go-playground/validator/v10/.gitignore
new file mode 100644
index 00000000..6305e529
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/.gitignore
@@ -0,0 +1,32 @@
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+bin
+
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
+*.test
+*.prof
+*.test
+*.out
+*.txt
+/**/*.DS_Store
+cover.html
+README.html
+.idea
diff --git a/vendor/github.com/go-playground/validator/v10/.golangci.yaml b/vendor/github.com/go-playground/validator/v10/.golangci.yaml
new file mode 100644
index 00000000..dd9c05cc
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/.golangci.yaml
@@ -0,0 +1,54 @@
+version: "2"
+linters:
+ default: all
+ disable:
+ - noinlineerr
+ - wsl_v5
+ - copyloopvar
+ - cyclop
+ - depguard
+ - dogsled
+ - dupl
+ - dupword
+ - err113
+ - errorlint
+ - exhaustive
+ - exhaustruct
+ - forbidigo
+ - forcetypeassert
+ - funlen
+ - gochecknoglobals
+ - gocognit
+ - goconst
+ - gocritic
+ - gocyclo
+ - godot
+ - gosec
+ - gosmopolitan
+ - interfacebloat
+ - intrange
+ - ireturn
+ - lll
+ - maintidx
+ - misspell
+ - mnd
+ - nakedret
+ - nestif
+ - nilnil
+ - nlreturn
+ - nonamedreturns
+ - paralleltest
+ - perfsprint
+ - prealloc
+ - recvcheck
+ - revive
+ - staticcheck
+ - tagalign
+ - tagliatelle
+ - testpackage
+ - thelper
+ - tparallel
+ - unparam
+ - varnamelen
+ - wrapcheck
+ - wsl
diff --git a/vendor/github.com/go-playground/validator/v10/LICENSE b/vendor/github.com/go-playground/validator/v10/LICENSE
new file mode 100644
index 00000000..6a2ae9aa
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Dean Karn
+
+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/go-playground/validator/v10/MAINTAINERS.md b/vendor/github.com/go-playground/validator/v10/MAINTAINERS.md
new file mode 100644
index 00000000..b809c4ce
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/MAINTAINERS.md
@@ -0,0 +1,16 @@
+## Maintainers Guide
+
+### Semantic Versioning
+Semantic versioning as defined [here](https://semver.org) must be strictly adhered to.
+
+### External Dependencies
+Any new external dependencies MUST:
+- Have a compatible LICENSE present.
+- Be actively maintained.
+- Be approved by @go-playground/admins
+
+### PR Merge Requirements
+- Up-to-date branch.
+- Passing tests and linting.
+- CODEOWNERS approval.
+- Tests that cover both the Happy and Unhappy paths.
\ No newline at end of file
diff --git a/vendor/github.com/go-playground/validator/v10/Makefile b/vendor/github.com/go-playground/validator/v10/Makefile
new file mode 100644
index 00000000..e7caab7f
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/Makefile
@@ -0,0 +1,18 @@
+GOCMD=go
+
+linters-install:
+ @golangci-lint --version >/dev/null 2>&1 || { \
+ echo "installing linting tools..."; \
+ curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s v2.0.2; \
+ }
+
+lint: linters-install
+ golangci-lint run
+
+test:
+ $(GOCMD) test -cover -race ./...
+
+bench:
+ $(GOCMD) test -run=NONE -bench=. -benchmem ./...
+
+.PHONY: test lint linters-install
diff --git a/vendor/github.com/go-playground/validator/v10/README.md b/vendor/github.com/go-playground/validator/v10/README.md
new file mode 100644
index 00000000..28f7e159
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/README.md
@@ -0,0 +1,381 @@
+Package validator
+=================
+ [](https://github.com/go-playground/validator/releases)
+[](https://github.com/go-playground/validator/actions)
+[](https://coveralls.io/github/go-playground/validator?branch=master)
+[](https://goreportcard.com/report/github.com/go-playground/validator)
+[](https://pkg.go.dev/github.com/go-playground/validator/v10)
+
+
+Package validator implements value validations for structs and individual fields based on tags.
+
+It has the following **unique** features:
+
+- Cross Field and Cross Struct validations by using validation tags or custom validators.
+- Slice, Array and Map diving, which allows any or all levels of a multidimensional field to be validated.
+- Ability to dive into both map keys and values for validation
+- Handles type interface by determining it's underlying type prior to validation.
+- Handles custom field types such as sql driver Valuer see [Valuer](https://golang.org/src/database/sql/driver/types.go?s=1210:1293#L29)
+- Alias validation tags, which allows for mapping of several validations to a single tag for easier defining of validations on structs
+- Extraction of custom defined Field Name e.g. can specify to extract the JSON name while validating and have it available in the resulting FieldError
+- Customizable i18n aware error messages.
+- Default validator for the [gin](https://github.com/gin-gonic/gin) web framework; upgrading from v8 to v9 in gin see [here](https://github.com/go-playground/validator/tree/master/_examples/gin-upgrading-overriding)
+
+A Call for Maintainers
+----------------------
+
+Please read the discussiong started [here](https://github.com/go-playground/validator/discussions/1330) if you are interested in contributing/helping maintain this package.
+
+Installation
+------------
+
+Use go get.
+
+ go get github.com/go-playground/validator/v10
+
+Then import the validator package into your own code.
+
+ import "github.com/go-playground/validator/v10"
+
+Error Return Value
+-------
+
+Validation functions return type error
+
+They return type error to avoid the issue discussed in the following, where err is always != nil:
+
+* http://stackoverflow.com/a/29138676/3158232
+* https://github.com/go-playground/validator/issues/134
+
+Validator returns only InvalidValidationError for bad validation input, nil or ValidationErrors as type error; so, in your code all you need to do is check if the error returned is not nil, and if it's not check if error is InvalidValidationError ( if necessary, most of the time it isn't ) type cast it to type ValidationErrors like so:
+
+```go
+err := validate.Struct(mystruct)
+validationErrors := err.(validator.ValidationErrors)
+ ```
+
+Usage and documentation
+------
+
+Please see https://pkg.go.dev/github.com/go-playground/validator/v10 for detailed usage docs.
+
+##### Examples:
+
+- [Simple](https://github.com/go-playground/validator/blob/master/_examples/simple/main.go)
+- [Custom Field Types](https://github.com/go-playground/validator/blob/master/_examples/custom/main.go)
+- [Struct Level](https://github.com/go-playground/validator/blob/master/_examples/struct-level/main.go)
+- [Translations & Custom Errors](https://github.com/go-playground/validator/blob/master/_examples/translations/main.go)
+- [Gin upgrade and/or override validator](https://github.com/go-playground/validator/tree/v9/_examples/gin-upgrading-overriding)
+- [wash - an example application putting it all together](https://github.com/bluesuncorp/wash)
+
+Baked-in Validations
+------
+
+### Special Notes:
+- If new to using validator it is highly recommended to initialize it using the `WithRequiredStructEnabled` option which is opt-in to new behaviour that will become the default behaviour in v11+. See documentation for more details.
+```go
+validate := validator.New(validator.WithRequiredStructEnabled())
+```
+
+### Fields:
+
+| Tag | Description |
+| - | - |
+| eqcsfield | Field Equals Another Field (relative)|
+| eqfield | Field Equals Another Field |
+| fieldcontains | Check the indicated characters are present in the Field |
+| fieldexcludes | Check the indicated characters are not present in the field |
+| gtcsfield | Field Greater Than Another Relative Field |
+| gtecsfield | Field Greater Than or Equal To Another Relative Field |
+| gtefield | Field Greater Than or Equal To Another Field |
+| gtfield | Field Greater Than Another Field |
+| ltcsfield | Less Than Another Relative Field |
+| ltecsfield | Less Than or Equal To Another Relative Field |
+| ltefield | Less Than or Equal To Another Field |
+| ltfield | Less Than Another Field |
+| necsfield | Field Does Not Equal Another Field (relative) |
+| nefield | Field Does Not Equal Another Field |
+
+### Network:
+
+| Tag | Description |
+| - | - |
+| cidr | Classless Inter-Domain Routing CIDR |
+| cidrv4 | Classless Inter-Domain Routing CIDRv4 |
+| cidrv6 | Classless Inter-Domain Routing CIDRv6 |
+| datauri | Data URL |
+| fqdn | Full Qualified Domain Name (FQDN) |
+| hostname | Hostname RFC 952 |
+| hostname_port | HostPort |
+| hostname_rfc1123 | Hostname RFC 1123 |
+| ip | Internet Protocol Address IP |
+| ip4_addr | Internet Protocol Address IPv4 |
+| ip6_addr | Internet Protocol Address IPv6 |
+| ip_addr | Internet Protocol Address IP |
+| ipv4 | Internet Protocol Address IPv4 |
+| ipv6 | Internet Protocol Address IPv6 |
+| mac | Media Access Control Address MAC |
+| tcp4_addr | Transmission Control Protocol Address TCPv4 |
+| tcp6_addr | Transmission Control Protocol Address TCPv6 |
+| tcp_addr | Transmission Control Protocol Address TCP |
+| udp4_addr | User Datagram Protocol Address UDPv4 |
+| udp6_addr | User Datagram Protocol Address UDPv6 |
+| udp_addr | User Datagram Protocol Address UDP |
+| unix_addr | Unix domain socket end point Address |
+| uri | URI String |
+| url | URL String |
+| http_url | HTTP URL String |
+| url_encoded | URL Encoded |
+| urn_rfc2141 | Urn RFC 2141 String |
+
+### Strings:
+
+| Tag | Description |
+| - | - |
+| alpha | Alpha Only |
+| alphanum | Alphanumeric |
+| alphanumunicode | Alphanumeric Unicode |
+| alphaunicode | Alpha Unicode |
+| ascii | ASCII |
+| boolean | Boolean |
+| contains | Contains |
+| containsany | Contains Any |
+| containsrune | Contains Rune |
+| endsnotwith | Ends Not With |
+| endswith | Ends With |
+| excludes | Excludes |
+| excludesall | Excludes All |
+| excludesrune | Excludes Rune |
+| lowercase | Lowercase |
+| multibyte | Multi-Byte Characters |
+| number | Number |
+| numeric | Numeric |
+| printascii | Printable ASCII |
+| startsnotwith | Starts Not With |
+| startswith | Starts With |
+| uppercase | Uppercase |
+
+### Format:
+| Tag | Description |
+| - | - |
+| base64 | Base64 String |
+| base64url | Base64URL String |
+| base64rawurl | Base64RawURL String |
+| bic | Business Identifier Code (ISO 9362) |
+| bcp47_language_tag | Language tag (BCP 47) |
+| btc_addr | Bitcoin Address |
+| btc_addr_bech32 | Bitcoin Bech32 Address (segwit) |
+| credit_card | Credit Card Number |
+| mongodb | MongoDB ObjectID |
+| mongodb_connection_string | MongoDB Connection String |
+| cron | Cron |
+| spicedb | SpiceDb ObjectID/Permission/Type |
+| datetime | Datetime |
+| e164 | e164 formatted phone number |
+| ein | U.S. Employeer Identification Number |
+| email | E-mail String
+| eth_addr | Ethereum Address |
+| hexadecimal | Hexadecimal String |
+| hexcolor | Hexcolor String |
+| hsl | HSL String |
+| hsla | HSLA String |
+| html | HTML Tags |
+| html_encoded | HTML Encoded |
+| isbn | International Standard Book Number |
+| isbn10 | International Standard Book Number 10 |
+| isbn13 | International Standard Book Number 13 |
+| issn | International Standard Serial Number |
+| iso3166_1_alpha2 | Two-letter country code (ISO 3166-1 alpha-2) |
+| iso3166_1_alpha3 | Three-letter country code (ISO 3166-1 alpha-3) |
+| iso3166_1_alpha_numeric | Numeric country code (ISO 3166-1 numeric) |
+| iso3166_2 | Country subdivision code (ISO 3166-2) |
+| iso4217 | Currency code (ISO 4217) |
+| json | JSON |
+| jwt | JSON Web Token (JWT) |
+| latitude | Latitude |
+| longitude | Longitude |
+| luhn_checksum | Luhn Algorithm Checksum (for strings and (u)int) |
+| postcode_iso3166_alpha2 | Postcode |
+| postcode_iso3166_alpha2_field | Postcode |
+| rgb | RGB String |
+| rgba | RGBA String |
+| ssn | Social Security Number SSN |
+| timezone | Timezone |
+| uuid | Universally Unique Identifier UUID |
+| uuid3 | Universally Unique Identifier UUID v3 |
+| uuid3_rfc4122 | Universally Unique Identifier UUID v3 RFC4122 |
+| uuid4 | Universally Unique Identifier UUID v4 |
+| uuid4_rfc4122 | Universally Unique Identifier UUID v4 RFC4122 |
+| uuid5 | Universally Unique Identifier UUID v5 |
+| uuid5_rfc4122 | Universally Unique Identifier UUID v5 RFC4122 |
+| uuid_rfc4122 | Universally Unique Identifier UUID RFC4122 |
+| md4 | MD4 hash |
+| md5 | MD5 hash |
+| sha256 | SHA256 hash |
+| sha384 | SHA384 hash |
+| sha512 | SHA512 hash |
+| ripemd128 | RIPEMD-128 hash |
+| ripemd128 | RIPEMD-160 hash |
+| tiger128 | TIGER128 hash |
+| tiger160 | TIGER160 hash |
+| tiger192 | TIGER192 hash |
+| semver | Semantic Versioning 2.0.0 |
+| ulid | Universally Unique Lexicographically Sortable Identifier ULID |
+| cve | Common Vulnerabilities and Exposures Identifier (CVE id) |
+
+### Comparisons:
+| Tag | Description |
+| - | - |
+| eq | Equals |
+| eq_ignore_case | Equals ignoring case |
+| gt | Greater than|
+| gte | Greater than or equal |
+| lt | Less Than |
+| lte | Less Than or Equal |
+| ne | Not Equal |
+| ne_ignore_case | Not Equal ignoring case |
+
+### Other:
+| Tag | Description |
+| - | - |
+| dir | Existing Directory |
+| dirpath | Directory Path |
+| file | Existing File |
+| filepath | File Path |
+| image | Image |
+| isdefault | Is Default |
+| len | Length |
+| max | Maximum |
+| min | Minimum |
+| oneof | One Of |
+| required | Required |
+| required_if | Required If |
+| required_unless | Required Unless |
+| required_with | Required With |
+| required_with_all | Required With All |
+| required_without | Required Without |
+| required_without_all | Required Without All |
+| excluded_if | Excluded If |
+| excluded_unless | Excluded Unless |
+| excluded_with | Excluded With |
+| excluded_with_all | Excluded With All |
+| excluded_without | Excluded Without |
+| excluded_without_all | Excluded Without All |
+| unique | Unique |
+| validateFn | Verify if the method `Validate() error` does not return an error (or any specified method) |
+
+
+#### Aliases:
+| Tag | Description |
+| - | - |
+| iscolor | hexcolor\|rgb\|rgba\|hsl\|hsla |
+| country_code | iso3166_1_alpha2\|iso3166_1_alpha3\|iso3166_1_alpha_numeric |
+
+Benchmarks
+------
+###### Run on MacBook Pro Max M3
+```go
+go version go1.23.3 darwin/arm64
+goos: darwin
+goarch: arm64
+cpu: Apple M3 Max
+pkg: github.com/go-playground/validator/v10
+BenchmarkFieldSuccess-16 42461943 27.88 ns/op 0 B/op 0 allocs/op
+BenchmarkFieldSuccessParallel-16 486632887 2.289 ns/op 0 B/op 0 allocs/op
+BenchmarkFieldFailure-16 9566167 121.3 ns/op 200 B/op 4 allocs/op
+BenchmarkFieldFailureParallel-16 17551471 83.68 ns/op 200 B/op 4 allocs/op
+BenchmarkFieldArrayDiveSuccess-16 7602306 155.6 ns/op 97 B/op 5 allocs/op
+BenchmarkFieldArrayDiveSuccessParallel-16 20664610 59.80 ns/op 97 B/op 5 allocs/op
+BenchmarkFieldArrayDiveFailure-16 4659756 252.9 ns/op 301 B/op 10 allocs/op
+BenchmarkFieldArrayDiveFailureParallel-16 8010116 152.9 ns/op 301 B/op 10 allocs/op
+BenchmarkFieldMapDiveSuccess-16 2834575 421.2 ns/op 288 B/op 14 allocs/op
+BenchmarkFieldMapDiveSuccessParallel-16 7179700 171.8 ns/op 288 B/op 14 allocs/op
+BenchmarkFieldMapDiveFailure-16 3081728 384.4 ns/op 376 B/op 13 allocs/op
+BenchmarkFieldMapDiveFailureParallel-16 6058137 204.0 ns/op 377 B/op 13 allocs/op
+BenchmarkFieldMapDiveWithKeysSuccess-16 2544975 464.8 ns/op 288 B/op 14 allocs/op
+BenchmarkFieldMapDiveWithKeysSuccessParallel-16 6661954 181.4 ns/op 288 B/op 14 allocs/op
+BenchmarkFieldMapDiveWithKeysFailure-16 2435484 490.7 ns/op 553 B/op 16 allocs/op
+BenchmarkFieldMapDiveWithKeysFailureParallel-16 4249617 282.0 ns/op 554 B/op 16 allocs/op
+BenchmarkFieldCustomTypeSuccess-16 14943525 77.35 ns/op 32 B/op 2 allocs/op
+BenchmarkFieldCustomTypeSuccessParallel-16 64051954 20.61 ns/op 32 B/op 2 allocs/op
+BenchmarkFieldCustomTypeFailure-16 10721384 107.1 ns/op 184 B/op 3 allocs/op
+BenchmarkFieldCustomTypeFailureParallel-16 18714495 69.77 ns/op 184 B/op 3 allocs/op
+BenchmarkFieldOrTagSuccess-16 4063124 294.3 ns/op 16 B/op 1 allocs/op
+BenchmarkFieldOrTagSuccessParallel-16 31903756 41.22 ns/op 18 B/op 1 allocs/op
+BenchmarkFieldOrTagFailure-16 7748558 146.8 ns/op 216 B/op 5 allocs/op
+BenchmarkFieldOrTagFailureParallel-16 13139854 92.05 ns/op 216 B/op 5 allocs/op
+BenchmarkStructLevelValidationSuccess-16 16808389 70.25 ns/op 16 B/op 1 allocs/op
+BenchmarkStructLevelValidationSuccessParallel-16 90686955 14.47 ns/op 16 B/op 1 allocs/op
+BenchmarkStructLevelValidationFailure-16 5818791 200.2 ns/op 264 B/op 7 allocs/op
+BenchmarkStructLevelValidationFailureParallel-16 11115874 107.5 ns/op 264 B/op 7 allocs/op
+BenchmarkStructSimpleCustomTypeSuccess-16 7764956 151.9 ns/op 32 B/op 2 allocs/op
+BenchmarkStructSimpleCustomTypeSuccessParallel-16 52316265 30.37 ns/op 32 B/op 2 allocs/op
+BenchmarkStructSimpleCustomTypeFailure-16 4195429 277.2 ns/op 416 B/op 9 allocs/op
+BenchmarkStructSimpleCustomTypeFailureParallel-16 7305661 164.6 ns/op 432 B/op 10 allocs/op
+BenchmarkStructFilteredSuccess-16 6312625 186.1 ns/op 216 B/op 5 allocs/op
+BenchmarkStructFilteredSuccessParallel-16 13684459 93.42 ns/op 216 B/op 5 allocs/op
+BenchmarkStructFilteredFailure-16 6751482 171.2 ns/op 216 B/op 5 allocs/op
+BenchmarkStructFilteredFailureParallel-16 14146070 86.93 ns/op 216 B/op 5 allocs/op
+BenchmarkStructPartialSuccess-16 6544448 177.3 ns/op 224 B/op 4 allocs/op
+BenchmarkStructPartialSuccessParallel-16 13951946 88.73 ns/op 224 B/op 4 allocs/op
+BenchmarkStructPartialFailure-16 4075833 287.5 ns/op 440 B/op 9 allocs/op
+BenchmarkStructPartialFailureParallel-16 7490805 161.3 ns/op 440 B/op 9 allocs/op
+BenchmarkStructExceptSuccess-16 4107187 281.4 ns/op 424 B/op 8 allocs/op
+BenchmarkStructExceptSuccessParallel-16 15979173 80.86 ns/op 208 B/op 3 allocs/op
+BenchmarkStructExceptFailure-16 4434372 264.3 ns/op 424 B/op 8 allocs/op
+BenchmarkStructExceptFailureParallel-16 8081367 154.1 ns/op 424 B/op 8 allocs/op
+BenchmarkStructSimpleCrossFieldSuccess-16 6459542 183.4 ns/op 56 B/op 3 allocs/op
+BenchmarkStructSimpleCrossFieldSuccessParallel-16 41013781 37.95 ns/op 56 B/op 3 allocs/op
+BenchmarkStructSimpleCrossFieldFailure-16 4034998 292.1 ns/op 272 B/op 8 allocs/op
+BenchmarkStructSimpleCrossFieldFailureParallel-16 11348446 115.3 ns/op 272 B/op 8 allocs/op
+BenchmarkStructSimpleCrossStructCrossFieldSuccess-16 4448528 267.7 ns/op 64 B/op 4 allocs/op
+BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-16 26813619 48.33 ns/op 64 B/op 4 allocs/op
+BenchmarkStructSimpleCrossStructCrossFieldFailure-16 3090646 384.5 ns/op 288 B/op 9 allocs/op
+BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-16 9870906 129.5 ns/op 288 B/op 9 allocs/op
+BenchmarkStructSimpleSuccess-16 10675562 109.5 ns/op 0 B/op 0 allocs/op
+BenchmarkStructSimpleSuccessParallel-16 131159784 8.932 ns/op 0 B/op 0 allocs/op
+BenchmarkStructSimpleFailure-16 4094979 286.6 ns/op 416 B/op 9 allocs/op
+BenchmarkStructSimpleFailureParallel-16 7606663 157.9 ns/op 416 B/op 9 allocs/op
+BenchmarkStructComplexSuccess-16 2073470 576.0 ns/op 224 B/op 5 allocs/op
+BenchmarkStructComplexSuccessParallel-16 7821831 161.3 ns/op 224 B/op 5 allocs/op
+BenchmarkStructComplexFailure-16 576358 2001 ns/op 3042 B/op 48 allocs/op
+BenchmarkStructComplexFailureParallel-16 1000000 1171 ns/op 3041 B/op 48 allocs/op
+BenchmarkOneof-16 22503973 52.82 ns/op 0 B/op 0 allocs/op
+BenchmarkOneofParallel-16 8538474 140.4 ns/op 0 B/op 0 allocs/op
+```
+
+Complementary Software
+----------------------
+
+Here is a list of software that complements using this library either pre or post validation.
+
+* [form](https://github.com/go-playground/form) - Decodes url.Values into Go value(s) and Encodes Go value(s) into url.Values. Dual Array and Full map support.
+* [mold](https://github.com/go-playground/mold) - A general library to help modify or set data within data structures and other objects
+
+How to Contribute
+------
+
+Make a pull request...
+
+Maintenance and support for SDK major versions
+----------------------------------------------
+
+See prior discussion [here](https://github.com/go-playground/validator/discussions/1342) for more details.
+
+This package is aligned with the [Go release policy](https://go.dev/doc/devel/release) in that support is guaranteed for
+the two most recent major versions.
+
+This does not mean the package will not work with older versions of Go, only that we reserve the right to increase the
+MSGV(Minimum Supported Go Version) when the need arises to address Security issues/patches, OS issues & support or newly
+introduced functionality that would greatly benefit the maintenance and/or usage of this package.
+
+If and when the MSGV is increased it will be done so in a minimum of a `Minor` release bump.
+
+License
+-------
+Distributed under MIT License, please see license file within the code for more details.
+
+Maintainers
+-----------
+This project has grown large enough that more than one person is required to properly support the community.
+If you are interested in becoming a maintainer please reach out to me https://github.com/deankarn
diff --git a/vendor/github.com/go-playground/validator/v10/baked_in.go b/vendor/github.com/go-playground/validator/v10/baked_in.go
new file mode 100644
index 00000000..c968ad4a
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/baked_in.go
@@ -0,0 +1,3109 @@
+package validator
+
+import (
+ "bytes"
+ "cmp"
+ "context"
+ "crypto/sha256"
+ "encoding/hex"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io/fs"
+ "net"
+ "net/mail"
+ "net/url"
+ "os"
+ "reflect"
+ "strconv"
+ "strings"
+ "sync"
+ "syscall"
+ "time"
+ "unicode/utf8"
+
+ "golang.org/x/crypto/sha3"
+ "golang.org/x/text/language"
+
+ "github.com/gabriel-vasile/mimetype"
+ urn "github.com/leodido/go-urn"
+)
+
+// Func accepts a FieldLevel interface for all validation needs. The return
+// value should be true when validation succeeds.
+type Func func(fl FieldLevel) bool
+
+// FuncCtx accepts a context.Context and FieldLevel interface for all
+// validation needs. The return value should be true when validation succeeds.
+type FuncCtx func(ctx context.Context, fl FieldLevel) bool
+
+// wrapFunc wraps normal Func makes it compatible with FuncCtx
+func wrapFunc(fn Func) FuncCtx {
+ if fn == nil {
+ return nil // be sure not to wrap a bad function.
+ }
+ return func(ctx context.Context, fl FieldLevel) bool {
+ return fn(fl)
+ }
+}
+
+var (
+ restrictedTags = map[string]struct{}{
+ diveTag: {},
+ keysTag: {},
+ endKeysTag: {},
+ structOnlyTag: {},
+ omitzero: {},
+ omitempty: {},
+ omitnil: {},
+ skipValidationTag: {},
+ utf8HexComma: {},
+ utf8Pipe: {},
+ noStructLevelTag: {},
+ requiredTag: {},
+ isdefault: {},
+ }
+
+ // bakedInAliases is a default mapping of a single validation tag that
+ // defines a common or complex set of validation(s) to simplify
+ // adding validation to structs.
+ bakedInAliases = map[string]string{
+ "iscolor": "hexcolor|rgb|rgba|hsl|hsla",
+ "country_code": "iso3166_1_alpha2|iso3166_1_alpha3|iso3166_1_alpha_numeric",
+ "eu_country_code": "iso3166_1_alpha2_eu|iso3166_1_alpha3_eu|iso3166_1_alpha_numeric_eu",
+ }
+
+ // bakedInValidators is the default map of ValidationFunc
+ // you can add, remove or even replace items to suite your needs,
+ // or even disregard and use your own map if so desired.
+ bakedInValidators = map[string]Func{
+ "required": hasValue,
+ "required_if": requiredIf,
+ "required_unless": requiredUnless,
+ "skip_unless": skipUnless,
+ "required_with": requiredWith,
+ "required_with_all": requiredWithAll,
+ "required_without": requiredWithout,
+ "required_without_all": requiredWithoutAll,
+ "excluded_if": excludedIf,
+ "excluded_unless": excludedUnless,
+ "excluded_with": excludedWith,
+ "excluded_with_all": excludedWithAll,
+ "excluded_without": excludedWithout,
+ "excluded_without_all": excludedWithoutAll,
+ "isdefault": isDefault,
+ "len": hasLengthOf,
+ "min": hasMinOf,
+ "max": hasMaxOf,
+ "eq": isEq,
+ "eq_ignore_case": isEqIgnoreCase,
+ "ne": isNe,
+ "ne_ignore_case": isNeIgnoreCase,
+ "lt": isLt,
+ "lte": isLte,
+ "gt": isGt,
+ "gte": isGte,
+ "eqfield": isEqField,
+ "eqcsfield": isEqCrossStructField,
+ "necsfield": isNeCrossStructField,
+ "gtcsfield": isGtCrossStructField,
+ "gtecsfield": isGteCrossStructField,
+ "ltcsfield": isLtCrossStructField,
+ "ltecsfield": isLteCrossStructField,
+ "nefield": isNeField,
+ "gtefield": isGteField,
+ "gtfield": isGtField,
+ "ltefield": isLteField,
+ "ltfield": isLtField,
+ "fieldcontains": fieldContains,
+ "fieldexcludes": fieldExcludes,
+ "alpha": isAlpha,
+ "alphanum": isAlphanum,
+ "alphaunicode": isAlphaUnicode,
+ "alphanumunicode": isAlphanumUnicode,
+ "boolean": isBoolean,
+ "numeric": isNumeric,
+ "number": isNumber,
+ "hexadecimal": isHexadecimal,
+ "hexcolor": isHEXColor,
+ "rgb": isRGB,
+ "rgba": isRGBA,
+ "hsl": isHSL,
+ "hsla": isHSLA,
+ "e164": isE164,
+ "email": isEmail,
+ "url": isURL,
+ "http_url": isHttpURL,
+ "uri": isURI,
+ "urn_rfc2141": isUrnRFC2141, // RFC 2141
+ "file": isFile,
+ "filepath": isFilePath,
+ "base32": isBase32,
+ "base64": isBase64,
+ "base64url": isBase64URL,
+ "base64rawurl": isBase64RawURL,
+ "contains": contains,
+ "containsany": containsAny,
+ "containsrune": containsRune,
+ "excludes": excludes,
+ "excludesall": excludesAll,
+ "excludesrune": excludesRune,
+ "startswith": startsWith,
+ "endswith": endsWith,
+ "startsnotwith": startsNotWith,
+ "endsnotwith": endsNotWith,
+ "image": isImage,
+ "isbn": isISBN,
+ "isbn10": isISBN10,
+ "isbn13": isISBN13,
+ "issn": isISSN,
+ "eth_addr": isEthereumAddress,
+ "eth_addr_checksum": isEthereumAddressChecksum,
+ "btc_addr": isBitcoinAddress,
+ "btc_addr_bech32": isBitcoinBech32Address,
+ "uuid": isUUID,
+ "uuid3": isUUID3,
+ "uuid4": isUUID4,
+ "uuid5": isUUID5,
+ "uuid_rfc4122": isUUIDRFC4122,
+ "uuid3_rfc4122": isUUID3RFC4122,
+ "uuid4_rfc4122": isUUID4RFC4122,
+ "uuid5_rfc4122": isUUID5RFC4122,
+ "ulid": isULID,
+ "md4": isMD4,
+ "md5": isMD5,
+ "sha256": isSHA256,
+ "sha384": isSHA384,
+ "sha512": isSHA512,
+ "ripemd128": isRIPEMD128,
+ "ripemd160": isRIPEMD160,
+ "tiger128": isTIGER128,
+ "tiger160": isTIGER160,
+ "tiger192": isTIGER192,
+ "ascii": isASCII,
+ "printascii": isPrintableASCII,
+ "multibyte": hasMultiByteCharacter,
+ "datauri": isDataURI,
+ "latitude": isLatitude,
+ "longitude": isLongitude,
+ "ssn": isSSN,
+ "ipv4": isIPv4,
+ "ipv6": isIPv6,
+ "ip": isIP,
+ "cidrv4": isCIDRv4,
+ "cidrv6": isCIDRv6,
+ "cidr": isCIDR,
+ "tcp4_addr": isTCP4AddrResolvable,
+ "tcp6_addr": isTCP6AddrResolvable,
+ "tcp_addr": isTCPAddrResolvable,
+ "udp4_addr": isUDP4AddrResolvable,
+ "udp6_addr": isUDP6AddrResolvable,
+ "udp_addr": isUDPAddrResolvable,
+ "ip4_addr": isIP4AddrResolvable,
+ "ip6_addr": isIP6AddrResolvable,
+ "ip_addr": isIPAddrResolvable,
+ "unix_addr": isUnixAddrResolvable,
+ "mac": isMAC,
+ "hostname": isHostnameRFC952, // RFC 952
+ "hostname_rfc1123": isHostnameRFC1123, // RFC 1123
+ "fqdn": isFQDN,
+ "unique": isUnique,
+ "oneof": isOneOf,
+ "oneofci": isOneOfCI,
+ "html": isHTML,
+ "html_encoded": isHTMLEncoded,
+ "url_encoded": isURLEncoded,
+ "dir": isDir,
+ "dirpath": isDirPath,
+ "json": isJSON,
+ "jwt": isJWT,
+ "hostname_port": isHostnamePort,
+ "port": isPort,
+ "lowercase": isLowercase,
+ "uppercase": isUppercase,
+ "datetime": isDatetime,
+ "timezone": isTimeZone,
+ "iso3166_1_alpha2": isIso3166Alpha2,
+ "iso3166_1_alpha2_eu": isIso3166Alpha2EU,
+ "iso3166_1_alpha3": isIso3166Alpha3,
+ "iso3166_1_alpha3_eu": isIso3166Alpha3EU,
+ "iso3166_1_alpha_numeric": isIso3166AlphaNumeric,
+ "iso3166_1_alpha_numeric_eu": isIso3166AlphaNumericEU,
+ "iso3166_2": isIso31662,
+ "iso4217": isIso4217,
+ "iso4217_numeric": isIso4217Numeric,
+ "bcp47_language_tag": isBCP47LanguageTag,
+ "postcode_iso3166_alpha2": isPostcodeByIso3166Alpha2,
+ "postcode_iso3166_alpha2_field": isPostcodeByIso3166Alpha2Field,
+ "bic": isIsoBicFormat,
+ "semver": isSemverFormat,
+ "dns_rfc1035_label": isDnsRFC1035LabelFormat,
+ "credit_card": isCreditCard,
+ "cve": isCveFormat,
+ "luhn_checksum": hasLuhnChecksum,
+ "mongodb": isMongoDBObjectId,
+ "mongodb_connection_string": isMongoDBConnectionString,
+ "cron": isCron,
+ "spicedb": isSpiceDB,
+ "ein": isEIN,
+ "validateFn": isValidateFn,
+ }
+)
+
+var (
+ oneofValsCache = map[string][]string{}
+ oneofValsCacheRWLock = sync.RWMutex{}
+)
+
+func parseOneOfParam2(s string) []string {
+ oneofValsCacheRWLock.RLock()
+ vals, ok := oneofValsCache[s]
+ oneofValsCacheRWLock.RUnlock()
+ if !ok {
+ oneofValsCacheRWLock.Lock()
+ vals = splitParamsRegex().FindAllString(s, -1)
+ for i := 0; i < len(vals); i++ {
+ vals[i] = strings.ReplaceAll(vals[i], "'", "")
+ }
+ oneofValsCache[s] = vals
+ oneofValsCacheRWLock.Unlock()
+ }
+ return vals
+}
+
+func isURLEncoded(fl FieldLevel) bool {
+ return uRLEncodedRegex().MatchString(fl.Field().String())
+}
+
+func isHTMLEncoded(fl FieldLevel) bool {
+ return hTMLEncodedRegex().MatchString(fl.Field().String())
+}
+
+func isHTML(fl FieldLevel) bool {
+ return hTMLRegex().MatchString(fl.Field().String())
+}
+
+func isOneOf(fl FieldLevel) bool {
+ vals := parseOneOfParam2(fl.Param())
+
+ field := fl.Field()
+
+ var v string
+ switch field.Kind() {
+ case reflect.String:
+ v = field.String()
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ v = strconv.FormatInt(field.Int(), 10)
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ v = strconv.FormatUint(field.Uint(), 10)
+ default:
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+ }
+ for i := 0; i < len(vals); i++ {
+ if vals[i] == v {
+ return true
+ }
+ }
+ return false
+}
+
+// isOneOfCI is the validation function for validating if the current field's value is one of the provided string values (case insensitive).
+func isOneOfCI(fl FieldLevel) bool {
+ vals := parseOneOfParam2(fl.Param())
+ field := fl.Field()
+
+ if field.Kind() != reflect.String {
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+ }
+ v := field.String()
+ for _, val := range vals {
+ if strings.EqualFold(val, v) {
+ return true
+ }
+ }
+ return false
+}
+
+// isUnique is the validation function for validating if each array|slice|map value is unique
+func isUnique(fl FieldLevel) bool {
+ field := fl.Field()
+ param := fl.Param()
+ v := reflect.ValueOf(struct{}{})
+
+ switch field.Kind() {
+ case reflect.Slice, reflect.Array:
+ elem := field.Type().Elem()
+ if elem.Kind() == reflect.Ptr {
+ elem = elem.Elem()
+ }
+
+ if param == "" {
+ m := reflect.MakeMap(reflect.MapOf(elem, v.Type()))
+
+ for i := 0; i < field.Len(); i++ {
+ m.SetMapIndex(reflect.Indirect(field.Index(i)), v)
+ }
+ return field.Len() == m.Len()
+ }
+
+ sf, ok := elem.FieldByName(param)
+ if !ok {
+ panic(fmt.Sprintf("Bad field name %s", param))
+ }
+
+ sfTyp := sf.Type
+ if sfTyp.Kind() == reflect.Ptr {
+ sfTyp = sfTyp.Elem()
+ }
+
+ m := reflect.MakeMap(reflect.MapOf(sfTyp, v.Type()))
+ var fieldlen int
+ for i := 0; i < field.Len(); i++ {
+ key := reflect.Indirect(reflect.Indirect(field.Index(i)).FieldByName(param))
+ if key.IsValid() {
+ fieldlen++
+ m.SetMapIndex(key, v)
+ }
+ }
+ return fieldlen == m.Len()
+ case reflect.Map:
+ var m reflect.Value
+ if field.Type().Elem().Kind() == reflect.Ptr {
+ m = reflect.MakeMap(reflect.MapOf(field.Type().Elem().Elem(), v.Type()))
+ } else {
+ m = reflect.MakeMap(reflect.MapOf(field.Type().Elem(), v.Type()))
+ }
+
+ for _, k := range field.MapKeys() {
+ m.SetMapIndex(reflect.Indirect(field.MapIndex(k)), v)
+ }
+
+ return field.Len() == m.Len()
+ default:
+ if parent := fl.Parent(); parent.Kind() == reflect.Struct {
+ uniqueField := parent.FieldByName(param)
+ if uniqueField == reflect.ValueOf(nil) {
+ panic(fmt.Sprintf("Bad field name provided %s", param))
+ }
+
+ if uniqueField.Kind() != field.Kind() {
+ panic(fmt.Sprintf("Bad field type %s:%s", field.Type(), uniqueField.Type()))
+ }
+
+ return getValue(field) != getValue(uniqueField)
+ }
+
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+ }
+}
+
+// isMAC is the validation function for validating if the field's value is a valid MAC address.
+func isMAC(fl FieldLevel) bool {
+ _, err := net.ParseMAC(fl.Field().String())
+
+ return err == nil
+}
+
+// isCIDRv4 is the validation function for validating if the field's value is a valid v4 CIDR address.
+func isCIDRv4(fl FieldLevel) bool {
+ ip, net, err := net.ParseCIDR(fl.Field().String())
+
+ return err == nil && ip.To4() != nil && net.IP.Equal(ip)
+}
+
+// isCIDRv6 is the validation function for validating if the field's value is a valid v6 CIDR address.
+func isCIDRv6(fl FieldLevel) bool {
+ ip, _, err := net.ParseCIDR(fl.Field().String())
+
+ return err == nil && ip.To4() == nil
+}
+
+// isCIDR is the validation function for validating if the field's value is a valid v4 or v6 CIDR address.
+func isCIDR(fl FieldLevel) bool {
+ _, _, err := net.ParseCIDR(fl.Field().String())
+
+ return err == nil
+}
+
+// isIPv4 is the validation function for validating if a value is a valid v4 IP address.
+func isIPv4(fl FieldLevel) bool {
+ ip := net.ParseIP(fl.Field().String())
+
+ return ip != nil && ip.To4() != nil
+}
+
+// isIPv6 is the validation function for validating if the field's value is a valid v6 IP address.
+func isIPv6(fl FieldLevel) bool {
+ ip := net.ParseIP(fl.Field().String())
+
+ return ip != nil && ip.To4() == nil
+}
+
+// isIP is the validation function for validating if the field's value is a valid v4 or v6 IP address.
+func isIP(fl FieldLevel) bool {
+ ip := net.ParseIP(fl.Field().String())
+
+ return ip != nil
+}
+
+// isSSN is the validation function for validating if the field's value is a valid SSN.
+func isSSN(fl FieldLevel) bool {
+ field := fl.Field()
+
+ if field.Len() != 11 {
+ return false
+ }
+
+ return sSNRegex().MatchString(field.String())
+}
+
+// isLongitude is the validation function for validating if the field's value is a valid longitude coordinate.
+func isLongitude(fl FieldLevel) bool {
+ field := fl.Field()
+
+ var v string
+ switch field.Kind() {
+ case reflect.String:
+ v = field.String()
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ v = strconv.FormatInt(field.Int(), 10)
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ v = strconv.FormatUint(field.Uint(), 10)
+ case reflect.Float32:
+ v = strconv.FormatFloat(field.Float(), 'f', -1, 32)
+ case reflect.Float64:
+ v = strconv.FormatFloat(field.Float(), 'f', -1, 64)
+ default:
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+ }
+
+ return longitudeRegex().MatchString(v)
+}
+
+// isLatitude is the validation function for validating if the field's value is a valid latitude coordinate.
+func isLatitude(fl FieldLevel) bool {
+ field := fl.Field()
+
+ var v string
+ switch field.Kind() {
+ case reflect.String:
+ v = field.String()
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ v = strconv.FormatInt(field.Int(), 10)
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ v = strconv.FormatUint(field.Uint(), 10)
+ case reflect.Float32:
+ v = strconv.FormatFloat(field.Float(), 'f', -1, 32)
+ case reflect.Float64:
+ v = strconv.FormatFloat(field.Float(), 'f', -1, 64)
+ default:
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+ }
+
+ return latitudeRegex().MatchString(v)
+}
+
+// isDataURI is the validation function for validating if the field's value is a valid data URI.
+func isDataURI(fl FieldLevel) bool {
+ uri := strings.SplitN(fl.Field().String(), ",", 2)
+
+ if len(uri) != 2 {
+ return false
+ }
+
+ if !dataURIRegex().MatchString(uri[0]) {
+ return false
+ }
+
+ return base64Regex().MatchString(uri[1])
+}
+
+// hasMultiByteCharacter is the validation function for validating if the field's value has a multi byte character.
+func hasMultiByteCharacter(fl FieldLevel) bool {
+ field := fl.Field()
+
+ if field.Len() == 0 {
+ return true
+ }
+
+ return multibyteRegex().MatchString(field.String())
+}
+
+// isPrintableASCII is the validation function for validating if the field's value is a valid printable ASCII character.
+func isPrintableASCII(fl FieldLevel) bool {
+ return printableASCIIRegex().MatchString(fl.Field().String())
+}
+
+// isASCII is the validation function for validating if the field's value is a valid ASCII character.
+func isASCII(fl FieldLevel) bool {
+ return aSCIIRegex().MatchString(fl.Field().String())
+}
+
+// isUUID5 is the validation function for validating if the field's value is a valid v5 UUID.
+func isUUID5(fl FieldLevel) bool {
+ return fieldMatchesRegexByStringerValOrString(uUID5Regex, fl)
+}
+
+// isUUID4 is the validation function for validating if the field's value is a valid v4 UUID.
+func isUUID4(fl FieldLevel) bool {
+ return fieldMatchesRegexByStringerValOrString(uUID4Regex, fl)
+}
+
+// isUUID3 is the validation function for validating if the field's value is a valid v3 UUID.
+func isUUID3(fl FieldLevel) bool {
+ return fieldMatchesRegexByStringerValOrString(uUID3Regex, fl)
+}
+
+// isUUID is the validation function for validating if the field's value is a valid UUID of any version.
+func isUUID(fl FieldLevel) bool {
+ return fieldMatchesRegexByStringerValOrString(uUIDRegex, fl)
+}
+
+// isUUID5RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v5 UUID.
+func isUUID5RFC4122(fl FieldLevel) bool {
+ return fieldMatchesRegexByStringerValOrString(uUID5RFC4122Regex, fl)
+}
+
+// isUUID4RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v4 UUID.
+func isUUID4RFC4122(fl FieldLevel) bool {
+ return fieldMatchesRegexByStringerValOrString(uUID4RFC4122Regex, fl)
+}
+
+// isUUID3RFC4122 is the validation function for validating if the field's value is a valid RFC4122 v3 UUID.
+func isUUID3RFC4122(fl FieldLevel) bool {
+ return fieldMatchesRegexByStringerValOrString(uUID3RFC4122Regex, fl)
+}
+
+// isUUIDRFC4122 is the validation function for validating if the field's value is a valid RFC4122 UUID of any version.
+func isUUIDRFC4122(fl FieldLevel) bool {
+ return fieldMatchesRegexByStringerValOrString(uUIDRFC4122Regex, fl)
+}
+
+// isULID is the validation function for validating if the field's value is a valid ULID.
+func isULID(fl FieldLevel) bool {
+ return fieldMatchesRegexByStringerValOrString(uLIDRegex, fl)
+}
+
+// isMD4 is the validation function for validating if the field's value is a valid MD4.
+func isMD4(fl FieldLevel) bool {
+ return md4Regex().MatchString(fl.Field().String())
+}
+
+// isMD5 is the validation function for validating if the field's value is a valid MD5.
+func isMD5(fl FieldLevel) bool {
+ return md5Regex().MatchString(fl.Field().String())
+}
+
+// isSHA256 is the validation function for validating if the field's value is a valid SHA256.
+func isSHA256(fl FieldLevel) bool {
+ return sha256Regex().MatchString(fl.Field().String())
+}
+
+// isSHA384 is the validation function for validating if the field's value is a valid SHA384.
+func isSHA384(fl FieldLevel) bool {
+ return sha384Regex().MatchString(fl.Field().String())
+}
+
+// isSHA512 is the validation function for validating if the field's value is a valid SHA512.
+func isSHA512(fl FieldLevel) bool {
+ return sha512Regex().MatchString(fl.Field().String())
+}
+
+// isRIPEMD128 is the validation function for validating if the field's value is a valid PIPEMD128.
+func isRIPEMD128(fl FieldLevel) bool {
+ return ripemd128Regex().MatchString(fl.Field().String())
+}
+
+// isRIPEMD160 is the validation function for validating if the field's value is a valid PIPEMD160.
+func isRIPEMD160(fl FieldLevel) bool {
+ return ripemd160Regex().MatchString(fl.Field().String())
+}
+
+// isTIGER128 is the validation function for validating if the field's value is a valid TIGER128.
+func isTIGER128(fl FieldLevel) bool {
+ return tiger128Regex().MatchString(fl.Field().String())
+}
+
+// isTIGER160 is the validation function for validating if the field's value is a valid TIGER160.
+func isTIGER160(fl FieldLevel) bool {
+ return tiger160Regex().MatchString(fl.Field().String())
+}
+
+// isTIGER192 is the validation function for validating if the field's value is a valid isTIGER192.
+func isTIGER192(fl FieldLevel) bool {
+ return tiger192Regex().MatchString(fl.Field().String())
+}
+
+// isISBN is the validation function for validating if the field's value is a valid v10 or v13 ISBN.
+func isISBN(fl FieldLevel) bool {
+ return isISBN10(fl) || isISBN13(fl)
+}
+
+// isISBN13 is the validation function for validating if the field's value is a valid v13 ISBN.
+func isISBN13(fl FieldLevel) bool {
+ s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 4), " ", "", 4)
+
+ if !iSBN13Regex().MatchString(s) {
+ return false
+ }
+
+ var checksum int32
+ var i int32
+
+ factor := []int32{1, 3}
+
+ for i = 0; i < 12; i++ {
+ checksum += factor[i%2] * int32(s[i]-'0')
+ }
+
+ return (int32(s[12]-'0'))-((10-(checksum%10))%10) == 0
+}
+
+// isISBN10 is the validation function for validating if the field's value is a valid v10 ISBN.
+func isISBN10(fl FieldLevel) bool {
+ s := strings.Replace(strings.Replace(fl.Field().String(), "-", "", 3), " ", "", 3)
+
+ if !iSBN10Regex().MatchString(s) {
+ return false
+ }
+
+ var checksum int32
+ var i int32
+
+ for i = 0; i < 9; i++ {
+ checksum += (i + 1) * int32(s[i]-'0')
+ }
+
+ if s[9] == 'X' {
+ checksum += 10 * 10
+ } else {
+ checksum += 10 * int32(s[9]-'0')
+ }
+
+ return checksum%11 == 0
+}
+
+// isISSN is the validation function for validating if the field's value is a valid ISSN.
+func isISSN(fl FieldLevel) bool {
+ s := fl.Field().String()
+
+ if !iSSNRegex().MatchString(s) {
+ return false
+ }
+ s = strings.ReplaceAll(s, "-", "")
+
+ pos := 8
+ checksum := 0
+
+ for i := 0; i < 7; i++ {
+ checksum += pos * int(s[i]-'0')
+ pos--
+ }
+
+ if s[7] == 'X' {
+ checksum += 10
+ } else {
+ checksum += int(s[7] - '0')
+ }
+
+ return checksum%11 == 0
+}
+
+// isEthereumAddress is the validation function for validating if the field's value is a valid Ethereum address.
+func isEthereumAddress(fl FieldLevel) bool {
+ address := fl.Field().String()
+
+ return ethAddressRegex().MatchString(address)
+}
+
+// isEthereumAddressChecksum is the validation function for validating if the field's value is a valid checksummed Ethereum address.
+func isEthereumAddressChecksum(fl FieldLevel) bool {
+ address := fl.Field().String()
+
+ if !ethAddressRegex().MatchString(address) {
+ return false
+ }
+ // Checksum validation. Reference: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md
+ address = address[2:] // Skip "0x" prefix.
+ h := sha3.NewLegacyKeccak256()
+ // hash.Hash's io.Writer implementation says it never returns an error. https://golang.org/pkg/hash/#Hash
+ _, _ = h.Write([]byte(strings.ToLower(address)))
+ hash := hex.EncodeToString(h.Sum(nil))
+
+ for i := 0; i < len(address); i++ {
+ if address[i] <= '9' { // Skip 0-9 digits: they don't have upper/lower-case.
+ continue
+ }
+ if hash[i] > '7' && address[i] >= 'a' || hash[i] <= '7' && address[i] <= 'F' {
+ return false
+ }
+ }
+
+ return true
+}
+
+// isBitcoinAddress is the validation function for validating if the field's value is a valid btc address
+func isBitcoinAddress(fl FieldLevel) bool {
+ address := fl.Field().String()
+
+ if !btcAddressRegex().MatchString(address) {
+ return false
+ }
+
+ alphabet := []byte("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")
+
+ decode := [25]byte{}
+
+ for _, n := range []byte(address) {
+ d := bytes.IndexByte(alphabet, n)
+
+ for i := 24; i >= 0; i-- {
+ d += 58 * int(decode[i])
+ decode[i] = byte(d % 256)
+ d /= 256
+ }
+ }
+
+ h := sha256.New()
+ _, _ = h.Write(decode[:21])
+ d := h.Sum([]byte{})
+ h = sha256.New()
+ _, _ = h.Write(d)
+
+ validchecksum := [4]byte{}
+ computedchecksum := [4]byte{}
+
+ copy(computedchecksum[:], h.Sum(d[:0]))
+ copy(validchecksum[:], decode[21:])
+
+ return validchecksum == computedchecksum
+}
+
+// isBitcoinBech32Address is the validation function for validating if the field's value is a valid bech32 btc address
+func isBitcoinBech32Address(fl FieldLevel) bool {
+ address := fl.Field().String()
+
+ if !btcLowerAddressRegexBech32().MatchString(address) && !btcUpperAddressRegexBech32().MatchString(address) {
+ return false
+ }
+
+ am := len(address) % 8
+
+ if am == 0 || am == 3 || am == 5 {
+ return false
+ }
+
+ address = strings.ToLower(address)
+
+ alphabet := "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
+
+ hr := []int{3, 3, 0, 2, 3} // the human readable part will always be bc
+ addr := address[3:]
+ dp := make([]int, 0, len(addr))
+
+ for _, c := range addr {
+ dp = append(dp, strings.IndexRune(alphabet, c))
+ }
+
+ ver := dp[0]
+
+ if ver < 0 || ver > 16 {
+ return false
+ }
+
+ if ver == 0 {
+ if len(address) != 42 && len(address) != 62 {
+ return false
+ }
+ }
+
+ values := append(hr, dp...)
+
+ GEN := []int{0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3}
+
+ p := 1
+
+ for _, v := range values {
+ b := p >> 25
+ p = (p&0x1ffffff)<<5 ^ v
+
+ for i := 0; i < 5; i++ {
+ if (b>>uint(i))&1 == 1 {
+ p ^= GEN[i]
+ }
+ }
+ }
+
+ if p != 1 {
+ return false
+ }
+
+ b := uint(0)
+ acc := 0
+ mv := (1 << 5) - 1
+ var sw []int
+
+ for _, v := range dp[1 : len(dp)-6] {
+ acc = (acc << 5) | v
+ b += 5
+ for b >= 8 {
+ b -= 8
+ sw = append(sw, (acc>>b)&mv)
+ }
+ }
+
+ if len(sw) < 2 || len(sw) > 40 {
+ return false
+ }
+
+ return true
+}
+
+// excludesRune is the validation function for validating that the field's value does not contain the rune specified within the param.
+func excludesRune(fl FieldLevel) bool {
+ return !containsRune(fl)
+}
+
+// excludesAll is the validation function for validating that the field's value does not contain any of the characters specified within the param.
+func excludesAll(fl FieldLevel) bool {
+ return !containsAny(fl)
+}
+
+// excludes is the validation function for validating that the field's value does not contain the text specified within the param.
+func excludes(fl FieldLevel) bool {
+ return !contains(fl)
+}
+
+// containsRune is the validation function for validating that the field's value contains the rune specified within the param.
+func containsRune(fl FieldLevel) bool {
+ r, _ := utf8.DecodeRuneInString(fl.Param())
+
+ return strings.ContainsRune(fl.Field().String(), r)
+}
+
+// containsAny is the validation function for validating that the field's value contains any of the characters specified within the param.
+func containsAny(fl FieldLevel) bool {
+ return strings.ContainsAny(fl.Field().String(), fl.Param())
+}
+
+// contains is the validation function for validating that the field's value contains the text specified within the param.
+func contains(fl FieldLevel) bool {
+ return strings.Contains(fl.Field().String(), fl.Param())
+}
+
+// startsWith is the validation function for validating that the field's value starts with the text specified within the param.
+func startsWith(fl FieldLevel) bool {
+ return strings.HasPrefix(fl.Field().String(), fl.Param())
+}
+
+// endsWith is the validation function for validating that the field's value ends with the text specified within the param.
+func endsWith(fl FieldLevel) bool {
+ return strings.HasSuffix(fl.Field().String(), fl.Param())
+}
+
+// startsNotWith is the validation function for validating that the field's value does not start with the text specified within the param.
+func startsNotWith(fl FieldLevel) bool {
+ return !startsWith(fl)
+}
+
+// endsNotWith is the validation function for validating that the field's value does not end with the text specified within the param.
+func endsNotWith(fl FieldLevel) bool {
+ return !endsWith(fl)
+}
+
+// fieldContains is the validation function for validating if the current field's value contains the field specified by the param's value.
+func fieldContains(fl FieldLevel) bool {
+ field := fl.Field()
+
+ currentField, _, ok := fl.GetStructFieldOK()
+
+ if !ok {
+ return false
+ }
+
+ return strings.Contains(field.String(), currentField.String())
+}
+
+// fieldExcludes is the validation function for validating if the current field's value excludes the field specified by the param's value.
+func fieldExcludes(fl FieldLevel) bool {
+ field := fl.Field()
+
+ currentField, _, ok := fl.GetStructFieldOK()
+ if !ok {
+ return true
+ }
+
+ return !strings.Contains(field.String(), currentField.String())
+}
+
+// isNeField is the validation function for validating if the current field's value is not equal to the field specified by the param's value.
+func isNeField(fl FieldLevel) bool {
+ field := fl.Field()
+ kind := field.Kind()
+
+ currentField, currentKind, ok := fl.GetStructFieldOK()
+
+ if !ok || currentKind != kind {
+ return true
+ }
+
+ switch kind {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return field.Int() != currentField.Int()
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return field.Uint() != currentField.Uint()
+
+ case reflect.Float32, reflect.Float64:
+ return field.Float() != currentField.Float()
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ return int64(field.Len()) != int64(currentField.Len())
+
+ case reflect.Bool:
+ return field.Bool() != currentField.Bool()
+
+ case reflect.Struct:
+
+ fieldType := field.Type()
+
+ if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) {
+ t := getValue(currentField).(time.Time)
+ fieldTime := getValue(field).(time.Time)
+
+ return !fieldTime.Equal(t)
+ }
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != currentField.Type() {
+ return true
+ }
+ }
+
+ // default reflect.String:
+ return field.String() != currentField.String()
+}
+
+// isNe is the validation function for validating that the field's value does not equal the provided param value.
+func isNe(fl FieldLevel) bool {
+ return !isEq(fl)
+}
+
+// isNeIgnoreCase is the validation function for validating that the field's string value does not equal the
+// provided param value. The comparison is case-insensitive
+func isNeIgnoreCase(fl FieldLevel) bool {
+ return !isEqIgnoreCase(fl)
+}
+
+// isLteCrossStructField is the validation function for validating if the current field's value is less than or equal to the field, within a separate struct, specified by the param's value.
+func isLteCrossStructField(fl FieldLevel) bool {
+ field := fl.Field()
+ kind := field.Kind()
+
+ topField, topKind, ok := fl.GetStructFieldOK()
+ if !ok || topKind != kind {
+ return false
+ }
+
+ switch kind {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return field.Int() <= topField.Int()
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return field.Uint() <= topField.Uint()
+
+ case reflect.Float32, reflect.Float64:
+ return field.Float() <= topField.Float()
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ return int64(field.Len()) <= int64(topField.Len())
+
+ case reflect.Struct:
+
+ fieldType := field.Type()
+
+ if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) {
+ fieldTime := getValue(field.Convert(timeType)).(time.Time)
+ topTime := getValue(topField.Convert(timeType)).(time.Time)
+
+ return fieldTime.Before(topTime) || fieldTime.Equal(topTime)
+ }
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != topField.Type() {
+ return false
+ }
+ }
+
+ // default reflect.String:
+ return field.String() <= topField.String()
+}
+
+// isLtCrossStructField is the validation function for validating if the current field's value is less than the field, within a separate struct, specified by the param's value.
+// NOTE: This is exposed for use within your own custom functions and not intended to be called directly.
+func isLtCrossStructField(fl FieldLevel) bool {
+ field := fl.Field()
+ kind := field.Kind()
+
+ topField, topKind, ok := fl.GetStructFieldOK()
+ if !ok || topKind != kind {
+ return false
+ }
+
+ switch kind {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return field.Int() < topField.Int()
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return field.Uint() < topField.Uint()
+
+ case reflect.Float32, reflect.Float64:
+ return field.Float() < topField.Float()
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ return int64(field.Len()) < int64(topField.Len())
+
+ case reflect.Struct:
+
+ fieldType := field.Type()
+
+ if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) {
+ fieldTime := getValue(field.Convert(timeType)).(time.Time)
+ topTime := getValue(topField.Convert(timeType)).(time.Time)
+
+ return fieldTime.Before(topTime)
+ }
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != topField.Type() {
+ return false
+ }
+ }
+
+ // default reflect.String:
+ return field.String() < topField.String()
+}
+
+// isGteCrossStructField is the validation function for validating if the current field's value is greater than or equal to the field, within a separate struct, specified by the param's value.
+func isGteCrossStructField(fl FieldLevel) bool {
+ field := fl.Field()
+ kind := field.Kind()
+
+ topField, topKind, ok := fl.GetStructFieldOK()
+ if !ok || topKind != kind {
+ return false
+ }
+
+ switch kind {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return field.Int() >= topField.Int()
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return field.Uint() >= topField.Uint()
+
+ case reflect.Float32, reflect.Float64:
+ return field.Float() >= topField.Float()
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ return int64(field.Len()) >= int64(topField.Len())
+
+ case reflect.Struct:
+
+ fieldType := field.Type()
+
+ if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) {
+ fieldTime := getValue(field.Convert(timeType)).(time.Time)
+ topTime := getValue(topField.Convert(timeType)).(time.Time)
+
+ return fieldTime.After(topTime) || fieldTime.Equal(topTime)
+ }
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != topField.Type() {
+ return false
+ }
+ }
+
+ // default reflect.String:
+ return field.String() >= topField.String()
+}
+
+// isGtCrossStructField is the validation function for validating if the current field's value is greater than the field, within a separate struct, specified by the param's value.
+func isGtCrossStructField(fl FieldLevel) bool {
+ field := fl.Field()
+ kind := field.Kind()
+
+ topField, topKind, ok := fl.GetStructFieldOK()
+ if !ok || topKind != kind {
+ return false
+ }
+
+ switch kind {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return field.Int() > topField.Int()
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return field.Uint() > topField.Uint()
+
+ case reflect.Float32, reflect.Float64:
+ return field.Float() > topField.Float()
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ return int64(field.Len()) > int64(topField.Len())
+
+ case reflect.Struct:
+
+ fieldType := field.Type()
+
+ if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) {
+ fieldTime := getValue(field.Convert(timeType)).(time.Time)
+ topTime := getValue(topField.Convert(timeType)).(time.Time)
+
+ return fieldTime.After(topTime)
+ }
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != topField.Type() {
+ return false
+ }
+ }
+
+ // default reflect.String:
+ return field.String() > topField.String()
+}
+
+// isNeCrossStructField is the validation function for validating that the current field's value is not equal to the field, within a separate struct, specified by the param's value.
+func isNeCrossStructField(fl FieldLevel) bool {
+ field := fl.Field()
+ kind := field.Kind()
+
+ topField, currentKind, ok := fl.GetStructFieldOK()
+ if !ok || currentKind != kind {
+ return true
+ }
+
+ switch kind {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return topField.Int() != field.Int()
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return topField.Uint() != field.Uint()
+
+ case reflect.Float32, reflect.Float64:
+ return topField.Float() != field.Float()
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ return int64(topField.Len()) != int64(field.Len())
+
+ case reflect.Bool:
+ return topField.Bool() != field.Bool()
+
+ case reflect.Struct:
+
+ fieldType := field.Type()
+
+ if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) {
+ t := getValue(field.Convert(timeType)).(time.Time)
+ fieldTime := getValue(topField.Convert(timeType)).(time.Time)
+
+ return !fieldTime.Equal(t)
+ }
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != topField.Type() {
+ return true
+ }
+ }
+
+ // default reflect.String:
+ return topField.String() != field.String()
+}
+
+// isEqCrossStructField is the validation function for validating that the current field's value is equal to the field, within a separate struct, specified by the param's value.
+func isEqCrossStructField(fl FieldLevel) bool {
+ field := fl.Field()
+ kind := field.Kind()
+
+ topField, topKind, ok := fl.GetStructFieldOK()
+ if !ok || topKind != kind {
+ return false
+ }
+
+ switch kind {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return topField.Int() == field.Int()
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return topField.Uint() == field.Uint()
+
+ case reflect.Float32, reflect.Float64:
+ return topField.Float() == field.Float()
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ return int64(topField.Len()) == int64(field.Len())
+
+ case reflect.Bool:
+ return topField.Bool() == field.Bool()
+
+ case reflect.Struct:
+
+ fieldType := field.Type()
+
+ if fieldType.ConvertibleTo(timeType) && topField.Type().ConvertibleTo(timeType) {
+ t := getValue(field.Convert(timeType)).(time.Time)
+ fieldTime := getValue(topField.Convert(timeType)).(time.Time)
+
+ return fieldTime.Equal(t)
+ }
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != topField.Type() {
+ return false
+ }
+ }
+
+ // default reflect.String:
+ return topField.String() == field.String()
+}
+
+// isEqField is the validation function for validating if the current field's value is equal to the field specified by the param's value.
+func isEqField(fl FieldLevel) bool {
+ field := fl.Field()
+ kind := field.Kind()
+
+ currentField, currentKind, ok := fl.GetStructFieldOK()
+ if !ok || currentKind != kind {
+ return false
+ }
+
+ switch kind {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return field.Int() == currentField.Int()
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return field.Uint() == currentField.Uint()
+
+ case reflect.Float32, reflect.Float64:
+ return field.Float() == currentField.Float()
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ return int64(field.Len()) == int64(currentField.Len())
+
+ case reflect.Bool:
+ return field.Bool() == currentField.Bool()
+
+ case reflect.Struct:
+
+ fieldType := field.Type()
+
+ if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) {
+ t := getValue(currentField.Convert(timeType)).(time.Time)
+ fieldTime := getValue(field.Convert(timeType)).(time.Time)
+
+ return fieldTime.Equal(t)
+ }
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != currentField.Type() {
+ return false
+ }
+ }
+
+ // default reflect.String:
+ return field.String() == currentField.String()
+}
+
+// isEq is the validation function for validating if the current field's value is equal to the param's value.
+func isEq(fl FieldLevel) bool {
+ field := fl.Field()
+ param := fl.Param()
+
+ switch field.Kind() {
+ case reflect.String:
+ return field.String() == param
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ p := asInt(param)
+
+ return int64(field.Len()) == p
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ p := asIntFromType(field.Type(), param)
+
+ return field.Int() == p
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ p := asUint(param)
+
+ return field.Uint() == p
+
+ case reflect.Float32:
+ p := asFloat32(param)
+
+ return field.Float() == p
+
+ case reflect.Float64:
+ p := asFloat64(param)
+
+ return field.Float() == p
+
+ case reflect.Bool:
+ p := asBool(param)
+
+ return field.Bool() == p
+ }
+
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+}
+
+// isEqIgnoreCase is the validation function for validating if the current field's string value is
+// equal to the param's value.
+// The comparison is case-insensitive.
+func isEqIgnoreCase(fl FieldLevel) bool {
+ field := fl.Field()
+ param := fl.Param()
+
+ switch field.Kind() {
+ case reflect.String:
+ return strings.EqualFold(field.String(), param)
+ }
+
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+}
+
+// isPostcodeByIso3166Alpha2 validates by value which is country code in iso 3166 alpha 2
+// example: `postcode_iso3166_alpha2=US`
+func isPostcodeByIso3166Alpha2(fl FieldLevel) bool {
+ field := fl.Field()
+ param := fl.Param()
+
+ postcodeRegexInit.Do(initPostcodes)
+ reg, found := postCodeRegexDict[param]
+ if !found {
+ return false
+ }
+
+ return reg.MatchString(field.String())
+}
+
+// isPostcodeByIso3166Alpha2Field validates by field which represents for a value of country code in iso 3166 alpha 2
+// example: `postcode_iso3166_alpha2_field=CountryCode`
+func isPostcodeByIso3166Alpha2Field(fl FieldLevel) bool {
+ field := fl.Field()
+ params := parseOneOfParam2(fl.Param())
+
+ if len(params) != 1 {
+ return false
+ }
+
+ currentField, kind, _, found := fl.GetStructFieldOKAdvanced2(fl.Parent(), params[0])
+ if !found {
+ return false
+ }
+
+ if kind != reflect.String {
+ panic(fmt.Sprintf("Bad field type %s", currentField.Type()))
+ }
+
+ postcodeRegexInit.Do(initPostcodes)
+ reg, found := postCodeRegexDict[currentField.String()]
+ if !found {
+ return false
+ }
+
+ return reg.MatchString(field.String())
+}
+
+// isBase32 is the validation function for validating if the current field's value is a valid base 32.
+func isBase32(fl FieldLevel) bool {
+ return base32Regex().MatchString(fl.Field().String())
+}
+
+// isBase64 is the validation function for validating if the current field's value is a valid base 64.
+func isBase64(fl FieldLevel) bool {
+ return base64Regex().MatchString(fl.Field().String())
+}
+
+// isBase64URL is the validation function for validating if the current field's value is a valid base64 URL safe string.
+func isBase64URL(fl FieldLevel) bool {
+ return base64URLRegex().MatchString(fl.Field().String())
+}
+
+// isBase64RawURL is the validation function for validating if the current field's value is a valid base64 URL safe string without '=' padding.
+func isBase64RawURL(fl FieldLevel) bool {
+ return base64RawURLRegex().MatchString(fl.Field().String())
+}
+
+// isURI is the validation function for validating if the current field's value is a valid URI.
+func isURI(fl FieldLevel) bool {
+ field := fl.Field()
+
+ switch field.Kind() {
+ case reflect.String:
+
+ s := field.String()
+
+ // checks needed as of Go 1.6 because of change https://github.com/golang/go/commit/617c93ce740c3c3cc28cdd1a0d712be183d0b328#diff-6c2d018290e298803c0c9419d8739885L195
+ // emulate browser and strip the '#' suffix prior to validation. see issue-#237
+ if i := strings.Index(s, "#"); i > -1 {
+ s = s[:i]
+ }
+
+ if len(s) == 0 {
+ return false
+ }
+
+ _, err := url.ParseRequestURI(s)
+
+ return err == nil
+ }
+
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+}
+
+// isURL is the validation function for validating if the current field's value is a valid URL.
+func isURL(fl FieldLevel) bool {
+ field := fl.Field()
+
+ switch field.Kind() {
+ case reflect.String:
+
+ s := strings.ToLower(field.String())
+
+ if len(s) == 0 {
+ return false
+ }
+
+ url, err := url.Parse(s)
+ if err != nil || url.Scheme == "" {
+ return false
+ }
+ isFileScheme := url.Scheme == "file"
+
+ if (isFileScheme && (len(url.Path) == 0 || url.Path == "/")) || (!isFileScheme && len(url.Host) == 0 && len(url.Fragment) == 0 && len(url.Opaque) == 0) {
+ return false
+ }
+
+ return true
+ }
+
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+}
+
+// isHttpURL is the validation function for validating if the current field's value is a valid HTTP(s) URL.
+func isHttpURL(fl FieldLevel) bool {
+ if !isURL(fl) {
+ return false
+ }
+
+ field := fl.Field()
+ switch field.Kind() {
+ case reflect.String:
+
+ s := strings.ToLower(field.String())
+
+ url, err := url.Parse(s)
+ if err != nil || url.Host == "" {
+ return false
+ }
+
+ return url.Scheme == "http" || url.Scheme == "https"
+ }
+
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+}
+
+// isUrnRFC2141 is the validation function for validating if the current field's value is a valid URN as per RFC 2141.
+func isUrnRFC2141(fl FieldLevel) bool {
+ field := fl.Field()
+
+ switch field.Kind() {
+ case reflect.String:
+
+ str := field.String()
+
+ _, match := urn.Parse([]byte(str))
+
+ return match
+ }
+
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+}
+
+// isFile is the validation function for validating if the current field's value is a valid existing file path.
+func isFile(fl FieldLevel) bool {
+ field := fl.Field()
+
+ switch field.Kind() {
+ case reflect.String:
+ fileInfo, err := os.Stat(field.String())
+ if err != nil {
+ return false
+ }
+
+ return !fileInfo.IsDir()
+ }
+
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+}
+
+// isImage is the validation function for validating if the current field's value contains the path to a valid image file
+func isImage(fl FieldLevel) bool {
+ mimetypes := map[string]bool{
+ "image/bmp": true,
+ "image/cis-cod": true,
+ "image/gif": true,
+ "image/ief": true,
+ "image/jpeg": true,
+ "image/jp2": true,
+ "image/jpx": true,
+ "image/jpm": true,
+ "image/pipeg": true,
+ "image/png": true,
+ "image/svg+xml": true,
+ "image/tiff": true,
+ "image/webp": true,
+ "image/x-cmu-raster": true,
+ "image/x-cmx": true,
+ "image/x-icon": true,
+ "image/x-portable-anymap": true,
+ "image/x-portable-bitmap": true,
+ "image/x-portable-graymap": true,
+ "image/x-portable-pixmap": true,
+ "image/x-rgb": true,
+ "image/x-xbitmap": true,
+ "image/x-xpixmap": true,
+ "image/x-xwindowdump": true,
+ }
+ field := fl.Field()
+
+ switch field.Kind() {
+ case reflect.String:
+ filePath := field.String()
+ fileInfo, err := os.Stat(filePath)
+ if err != nil {
+ return false
+ }
+
+ if fileInfo.IsDir() {
+ return false
+ }
+
+ file, err := os.Open(filePath)
+ if err != nil {
+ return false
+ }
+ defer func() {
+ _ = file.Close()
+ }()
+
+ mime, err := mimetype.DetectReader(file)
+ if err != nil {
+ return false
+ }
+
+ if _, ok := mimetypes[mime.String()]; ok {
+ return true
+ }
+ }
+
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+}
+
+// isFilePath is the validation function for validating if the current field's value is a valid file path.
+func isFilePath(fl FieldLevel) bool {
+ var exists bool
+ var err error
+
+ field := fl.Field()
+
+ // Not valid if it is a directory.
+ if isDir(fl) {
+ return false
+ }
+ // If it exists, it obviously is valid.
+ // This is done first to avoid code duplication and unnecessary additional logic.
+ if exists = isFile(fl); exists {
+ return true
+ }
+
+ // It does not exist but may still be a valid filepath.
+ switch field.Kind() {
+ case reflect.String:
+ // Every OS allows for whitespace, but none
+ // let you use a file with no filename (to my knowledge).
+ // Unless you're dealing with raw inodes, but I digress.
+ if strings.TrimSpace(field.String()) == "" {
+ return false
+ }
+ // We make sure it isn't a directory.
+ if strings.HasSuffix(field.String(), string(os.PathSeparator)) {
+ return false
+ }
+ if _, err = os.Stat(field.String()); err != nil {
+ switch t := err.(type) {
+ case *fs.PathError:
+ if t.Err == syscall.EINVAL {
+ // It's definitely an invalid character in the filepath.
+ return false
+ }
+ // It could be a permission error, a does-not-exist error, etc.
+ // Out-of-scope for this validation, though.
+ return true
+ default:
+ // Something went *seriously* wrong.
+ /*
+ Per https://pkg.go.dev/os#Stat:
+ "If there is an error, it will be of type *PathError."
+ */
+ panic(err)
+ }
+ }
+ }
+
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+}
+
+// isE164 is the validation function for validating if the current field's value is a valid e.164 formatted phone number.
+func isE164(fl FieldLevel) bool {
+ return e164Regex().MatchString(fl.Field().String())
+}
+
+// isEmail is the validation function for validating if the current field's value is a valid email address.
+func isEmail(fl FieldLevel) bool {
+ _, err := mail.ParseAddress(fl.Field().String())
+ if err != nil {
+ return false
+ }
+ return emailRegex().MatchString(fl.Field().String())
+}
+
+// isHSLA is the validation function for validating if the current field's value is a valid HSLA color.
+func isHSLA(fl FieldLevel) bool {
+ return hslaRegex().MatchString(fl.Field().String())
+}
+
+// isHSL is the validation function for validating if the current field's value is a valid HSL color.
+func isHSL(fl FieldLevel) bool {
+ return hslRegex().MatchString(fl.Field().String())
+}
+
+// isRGBA is the validation function for validating if the current field's value is a valid RGBA color.
+func isRGBA(fl FieldLevel) bool {
+ return rgbaRegex().MatchString(fl.Field().String())
+}
+
+// isRGB is the validation function for validating if the current field's value is a valid RGB color.
+func isRGB(fl FieldLevel) bool {
+ return rgbRegex().MatchString(fl.Field().String())
+}
+
+// isHEXColor is the validation function for validating if the current field's value is a valid HEX color.
+func isHEXColor(fl FieldLevel) bool {
+ return hexColorRegex().MatchString(fl.Field().String())
+}
+
+// isHexadecimal is the validation function for validating if the current field's value is a valid hexadecimal.
+func isHexadecimal(fl FieldLevel) bool {
+ return hexadecimalRegex().MatchString(fl.Field().String())
+}
+
+// isNumber is the validation function for validating if the current field's value is a valid number.
+func isNumber(fl FieldLevel) bool {
+ switch fl.Field().Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64:
+ return true
+ default:
+ return numberRegex().MatchString(fl.Field().String())
+ }
+}
+
+// isNumeric is the validation function for validating if the current field's value is a valid numeric value.
+func isNumeric(fl FieldLevel) bool {
+ switch fl.Field().Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64:
+ return true
+ default:
+ return numericRegex().MatchString(fl.Field().String())
+ }
+}
+
+// isAlphanum is the validation function for validating if the current field's value is a valid alphanumeric value.
+func isAlphanum(fl FieldLevel) bool {
+ return alphaNumericRegex().MatchString(fl.Field().String())
+}
+
+// isAlpha is the validation function for validating if the current field's value is a valid alpha value.
+func isAlpha(fl FieldLevel) bool {
+ return alphaRegex().MatchString(fl.Field().String())
+}
+
+// isAlphanumUnicode is the validation function for validating if the current field's value is a valid alphanumeric unicode value.
+func isAlphanumUnicode(fl FieldLevel) bool {
+ return alphaUnicodeNumericRegex().MatchString(fl.Field().String())
+}
+
+// isAlphaUnicode is the validation function for validating if the current field's value is a valid alpha unicode value.
+func isAlphaUnicode(fl FieldLevel) bool {
+ return alphaUnicodeRegex().MatchString(fl.Field().String())
+}
+
+// isBoolean is the validation function for validating if the current field's value is a valid boolean value or can be safely converted to a boolean value.
+func isBoolean(fl FieldLevel) bool {
+ switch fl.Field().Kind() {
+ case reflect.Bool:
+ return true
+ default:
+ _, err := strconv.ParseBool(fl.Field().String())
+ return err == nil
+ }
+}
+
+// isDefault is the opposite of required aka hasValue
+func isDefault(fl FieldLevel) bool {
+ return !hasValue(fl)
+}
+
+// hasValue is the validation function for validating if the current field's value is not the default static value.
+func hasValue(fl FieldLevel) bool {
+ field := fl.Field()
+ switch field.Kind() {
+ case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func:
+ return !field.IsNil()
+ default:
+ if fl.(*validate).fldIsPointer && getValue(field) != nil {
+ return true
+ }
+ return field.IsValid() && !field.IsZero()
+ }
+}
+
+// hasNotZeroValue is the validation function for validating if the current field's value is not the zero value for its type.
+func hasNotZeroValue(fl FieldLevel) bool {
+ field := fl.Field()
+ switch field.Kind() {
+ case reflect.Slice, reflect.Map:
+ // For slices and maps, consider them "not zero" only if they're both non-nil AND have elements
+ return !field.IsNil() && field.Len() > 0
+ case reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func:
+ return !field.IsNil()
+ default:
+ if fl.(*validate).fldIsPointer && getValue(field) != nil {
+ return !field.IsZero()
+ }
+ return field.IsValid() && !field.IsZero()
+ }
+}
+
+// requireCheckFieldKind is a func for check field kind
+func requireCheckFieldKind(fl FieldLevel, param string, defaultNotFoundValue bool) bool {
+ field := fl.Field()
+ kind := field.Kind()
+ var nullable, found bool
+ if len(param) > 0 {
+ field, kind, nullable, found = fl.GetStructFieldOKAdvanced2(fl.Parent(), param)
+ if !found {
+ return defaultNotFoundValue
+ }
+ }
+ switch kind {
+ case reflect.Invalid:
+ return defaultNotFoundValue
+ case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func:
+ return field.IsNil()
+ default:
+ if nullable && getValue(field) != nil {
+ return false
+ }
+ return field.IsValid() && field.IsZero()
+ }
+}
+
+// requireCheckFieldValue is a func for check field value
+func requireCheckFieldValue(
+ fl FieldLevel, param string, value string, defaultNotFoundValue bool,
+) bool {
+ field, kind, _, found := fl.GetStructFieldOKAdvanced2(fl.Parent(), param)
+ if !found {
+ return defaultNotFoundValue
+ }
+
+ switch kind {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return field.Int() == asInt(value)
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return field.Uint() == asUint(value)
+
+ case reflect.Float32:
+ return field.Float() == asFloat32(value)
+
+ case reflect.Float64:
+ return field.Float() == asFloat64(value)
+
+ case reflect.Slice, reflect.Map:
+ if value == "nil" {
+ return field.IsNil()
+ }
+ return int64(field.Len()) == asInt(value)
+ case reflect.Array:
+ // Arrays can't be nil, so only compare lengths
+ return int64(field.Len()) == asInt(value)
+
+ case reflect.Bool:
+ return field.Bool() == (value == "true")
+
+ case reflect.Ptr:
+ if field.IsNil() {
+ return value == "nil"
+ }
+ // Handle non-nil pointers
+ return requireCheckFieldValue(fl, param, value, defaultNotFoundValue)
+ }
+
+ // default reflect.String:
+ return field.String() == value
+}
+
+// requiredIf is the validation function
+// The field under validation must be present and not empty only if all the other specified fields are equal to the value following with the specified field.
+func requiredIf(fl FieldLevel) bool {
+ params := parseOneOfParam2(fl.Param())
+ if len(params)%2 != 0 {
+ panic(fmt.Sprintf("Bad param number for required_if %s", fl.FieldName()))
+ }
+ for i := 0; i < len(params); i += 2 {
+ if !requireCheckFieldValue(fl, params[i], params[i+1], false) {
+ return true
+ }
+ }
+ return hasValue(fl)
+}
+
+// excludedIf is the validation function
+// The field under validation must not be present or is empty only if all the other specified fields are equal to the value following with the specified field.
+func excludedIf(fl FieldLevel) bool {
+ params := parseOneOfParam2(fl.Param())
+ if len(params)%2 != 0 {
+ panic(fmt.Sprintf("Bad param number for excluded_if %s", fl.FieldName()))
+ }
+
+ for i := 0; i < len(params); i += 2 {
+ if !requireCheckFieldValue(fl, params[i], params[i+1], false) {
+ return true
+ }
+ }
+ return !hasValue(fl)
+}
+
+// requiredUnless is the validation function
+// The field under validation must be present and not empty only unless all the other specified fields are equal to the value following with the specified field.
+func requiredUnless(fl FieldLevel) bool {
+ params := parseOneOfParam2(fl.Param())
+ if len(params)%2 != 0 {
+ panic(fmt.Sprintf("Bad param number for required_unless %s", fl.FieldName()))
+ }
+
+ for i := 0; i < len(params); i += 2 {
+ if requireCheckFieldValue(fl, params[i], params[i+1], false) {
+ return true
+ }
+ }
+ return hasValue(fl)
+}
+
+// skipUnless is the validation function
+// The field under validation must be present and not empty only unless all the other specified fields are equal to the value following with the specified field.
+func skipUnless(fl FieldLevel) bool {
+ params := parseOneOfParam2(fl.Param())
+ if len(params)%2 != 0 {
+ panic(fmt.Sprintf("Bad param number for skip_unless %s", fl.FieldName()))
+ }
+ for i := 0; i < len(params); i += 2 {
+ if !requireCheckFieldValue(fl, params[i], params[i+1], false) {
+ return true
+ }
+ }
+ return hasValue(fl)
+}
+
+// excludedUnless is the validation function
+// The field under validation must not be present or is empty unless all the other specified fields are equal to the value following with the specified field.
+func excludedUnless(fl FieldLevel) bool {
+ params := parseOneOfParam2(fl.Param())
+ if len(params)%2 != 0 {
+ panic(fmt.Sprintf("Bad param number for excluded_unless %s", fl.FieldName()))
+ }
+ for i := 0; i < len(params); i += 2 {
+ if !requireCheckFieldValue(fl, params[i], params[i+1], false) {
+ return !hasValue(fl)
+ }
+ }
+ return true
+}
+
+// excludedWith is the validation function
+// The field under validation must not be present or is empty if any of the other specified fields are present.
+func excludedWith(fl FieldLevel) bool {
+ params := parseOneOfParam2(fl.Param())
+ for _, param := range params {
+ if !requireCheckFieldKind(fl, param, true) {
+ return !hasValue(fl)
+ }
+ }
+ return true
+}
+
+// requiredWith is the validation function
+// The field under validation must be present and not empty only if any of the other specified fields are present.
+func requiredWith(fl FieldLevel) bool {
+ params := parseOneOfParam2(fl.Param())
+ for _, param := range params {
+ if !requireCheckFieldKind(fl, param, true) {
+ return hasValue(fl)
+ }
+ }
+ return true
+}
+
+// excludedWithAll is the validation function
+// The field under validation must not be present or is empty if all of the other specified fields are present.
+func excludedWithAll(fl FieldLevel) bool {
+ params := parseOneOfParam2(fl.Param())
+ for _, param := range params {
+ if requireCheckFieldKind(fl, param, true) {
+ return true
+ }
+ }
+ return !hasValue(fl)
+}
+
+// requiredWithAll is the validation function
+// The field under validation must be present and not empty only if all of the other specified fields are present.
+func requiredWithAll(fl FieldLevel) bool {
+ params := parseOneOfParam2(fl.Param())
+ for _, param := range params {
+ if requireCheckFieldKind(fl, param, true) {
+ return true
+ }
+ }
+ return hasValue(fl)
+}
+
+// excludedWithout is the validation function
+// The field under validation must not be present or is empty when any of the other specified fields are not present.
+func excludedWithout(fl FieldLevel) bool {
+ if requireCheckFieldKind(fl, strings.TrimSpace(fl.Param()), true) {
+ return !hasValue(fl)
+ }
+ return true
+}
+
+// requiredWithout is the validation function
+// The field under validation must be present and not empty only when any of the other specified fields are not present.
+func requiredWithout(fl FieldLevel) bool {
+ params := parseOneOfParam2(fl.Param())
+ for _, param := range params {
+ if requireCheckFieldKind(fl, param, true) {
+ return hasValue(fl)
+ }
+ }
+ return true
+}
+
+// excludedWithoutAll is the validation function
+// The field under validation must not be present or is empty when all of the other specified fields are not present.
+func excludedWithoutAll(fl FieldLevel) bool {
+ params := parseOneOfParam2(fl.Param())
+ for _, param := range params {
+ if !requireCheckFieldKind(fl, param, true) {
+ return true
+ }
+ }
+ return !hasValue(fl)
+}
+
+// requiredWithoutAll is the validation function
+// The field under validation must be present and not empty only when all of the other specified fields are not present.
+func requiredWithoutAll(fl FieldLevel) bool {
+ params := parseOneOfParam2(fl.Param())
+ for _, param := range params {
+ if !requireCheckFieldKind(fl, param, true) {
+ return true
+ }
+ }
+ return hasValue(fl)
+}
+
+// isGteField is the validation function for validating if the current field's value is greater than or equal to the field specified by the param's value.
+func isGteField(fl FieldLevel) bool {
+ field := fl.Field()
+ kind := field.Kind()
+
+ currentField, currentKind, ok := fl.GetStructFieldOK()
+ if !ok || currentKind != kind {
+ return false
+ }
+
+ switch kind {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+
+ return field.Int() >= currentField.Int()
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+
+ return field.Uint() >= currentField.Uint()
+
+ case reflect.Float32, reflect.Float64:
+
+ return field.Float() >= currentField.Float()
+
+ case reflect.Struct:
+
+ fieldType := field.Type()
+
+ if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) {
+ t := getValue(currentField.Convert(timeType)).(time.Time)
+ fieldTime := getValue(field.Convert(timeType)).(time.Time)
+
+ return fieldTime.After(t) || fieldTime.Equal(t)
+ }
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != currentField.Type() {
+ return false
+ }
+ }
+
+ // default reflect.String
+ return len(field.String()) >= len(currentField.String())
+}
+
+// isGtField is the validation function for validating if the current field's value is greater than the field specified by the param's value.
+func isGtField(fl FieldLevel) bool {
+ field := fl.Field()
+ kind := field.Kind()
+
+ currentField, currentKind, ok := fl.GetStructFieldOK()
+ if !ok || currentKind != kind {
+ return false
+ }
+
+ switch kind {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+
+ return field.Int() > currentField.Int()
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+
+ return field.Uint() > currentField.Uint()
+
+ case reflect.Float32, reflect.Float64:
+
+ return field.Float() > currentField.Float()
+
+ case reflect.Struct:
+
+ fieldType := field.Type()
+
+ if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) {
+ t := getValue(currentField.Convert(timeType)).(time.Time)
+ fieldTime := getValue(field.Convert(timeType)).(time.Time)
+
+ return fieldTime.After(t)
+ }
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != currentField.Type() {
+ return false
+ }
+ }
+
+ // default reflect.String
+ return len(field.String()) > len(currentField.String())
+}
+
+// isGte is the validation function for validating if the current field's value is greater than or equal to the param's value.
+func isGte(fl FieldLevel) bool {
+ field := fl.Field()
+ param := fl.Param()
+
+ switch field.Kind() {
+ case reflect.String:
+ p := asInt(param)
+
+ return int64(utf8.RuneCountInString(field.String())) >= p
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ p := asInt(param)
+
+ return int64(field.Len()) >= p
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ p := asIntFromType(field.Type(), param)
+
+ return field.Int() >= p
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ p := asUint(param)
+
+ return field.Uint() >= p
+
+ case reflect.Float32:
+ p := asFloat32(param)
+
+ return field.Float() >= p
+
+ case reflect.Float64:
+ p := asFloat64(param)
+
+ return field.Float() >= p
+
+ case reflect.Struct:
+
+ if field.Type().ConvertibleTo(timeType) {
+ now := time.Now().UTC()
+ t := getValue(field.Convert(timeType)).(time.Time)
+
+ return t.After(now) || t.Equal(now)
+ }
+ }
+
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+}
+
+// isGt is the validation function for validating if the current field's value is greater than the param's value.
+func isGt(fl FieldLevel) bool {
+ field := fl.Field()
+ param := fl.Param()
+
+ switch field.Kind() {
+ case reflect.String:
+ p := asInt(param)
+
+ return int64(utf8.RuneCountInString(field.String())) > p
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ p := asInt(param)
+
+ return int64(field.Len()) > p
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ p := asIntFromType(field.Type(), param)
+
+ return field.Int() > p
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ p := asUint(param)
+
+ return field.Uint() > p
+
+ case reflect.Float32:
+ p := asFloat32(param)
+
+ return field.Float() > p
+
+ case reflect.Float64:
+ p := asFloat64(param)
+
+ return field.Float() > p
+
+ case reflect.Struct:
+
+ if field.Type().ConvertibleTo(timeType) {
+ return getValue(field.Convert(timeType)).(time.Time).After(time.Now().UTC())
+ }
+ }
+
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+}
+
+// hasLengthOf is the validation function for validating if the current field's value is equal to the param's value.
+func hasLengthOf(fl FieldLevel) bool {
+ field := fl.Field()
+ param := fl.Param()
+
+ switch field.Kind() {
+ case reflect.String:
+ p := asInt(param)
+
+ return int64(utf8.RuneCountInString(field.String())) == p
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ p := asInt(param)
+
+ return int64(field.Len()) == p
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ p := asIntFromType(field.Type(), param)
+
+ return field.Int() == p
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ p := asUint(param)
+
+ return field.Uint() == p
+
+ case reflect.Float32:
+ p := asFloat32(param)
+
+ return field.Float() == p
+
+ case reflect.Float64:
+ p := asFloat64(param)
+
+ return field.Float() == p
+ }
+
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+}
+
+// hasMinOf is the validation function for validating if the current field's value is greater than or equal to the param's value.
+func hasMinOf(fl FieldLevel) bool {
+ return isGte(fl)
+}
+
+// isLteField is the validation function for validating if the current field's value is less than or equal to the field specified by the param's value.
+func isLteField(fl FieldLevel) bool {
+ field := fl.Field()
+ kind := field.Kind()
+
+ currentField, currentKind, ok := fl.GetStructFieldOK()
+ if !ok || currentKind != kind {
+ return false
+ }
+
+ switch kind {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+
+ return field.Int() <= currentField.Int()
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+
+ return field.Uint() <= currentField.Uint()
+
+ case reflect.Float32, reflect.Float64:
+
+ return field.Float() <= currentField.Float()
+
+ case reflect.Struct:
+
+ fieldType := field.Type()
+
+ if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) {
+ t := getValue(currentField.Convert(timeType)).(time.Time)
+ fieldTime := getValue(field.Convert(timeType)).(time.Time)
+
+ return fieldTime.Before(t) || fieldTime.Equal(t)
+ }
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != currentField.Type() {
+ return false
+ }
+ }
+
+ // default reflect.String
+ return len(field.String()) <= len(currentField.String())
+}
+
+// isLtField is the validation function for validating if the current field's value is less than the field specified by the param's value.
+func isLtField(fl FieldLevel) bool {
+ field := fl.Field()
+ kind := field.Kind()
+
+ currentField, currentKind, ok := fl.GetStructFieldOK()
+ if !ok || currentKind != kind {
+ return false
+ }
+
+ switch kind {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+
+ return field.Int() < currentField.Int()
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+
+ return field.Uint() < currentField.Uint()
+
+ case reflect.Float32, reflect.Float64:
+
+ return field.Float() < currentField.Float()
+
+ case reflect.Struct:
+
+ fieldType := field.Type()
+
+ if fieldType.ConvertibleTo(timeType) && currentField.Type().ConvertibleTo(timeType) {
+ t := getValue(currentField.Convert(timeType)).(time.Time)
+ fieldTime := getValue(field.Convert(timeType)).(time.Time)
+
+ return fieldTime.Before(t)
+ }
+
+ // Not Same underlying type i.e. struct and time
+ if fieldType != currentField.Type() {
+ return false
+ }
+ }
+
+ // default reflect.String
+ return len(field.String()) < len(currentField.String())
+}
+
+// isLte is the validation function for validating if the current field's value is less than or equal to the param's value.
+func isLte(fl FieldLevel) bool {
+ field := fl.Field()
+ param := fl.Param()
+
+ switch field.Kind() {
+ case reflect.String:
+ p := asInt(param)
+
+ return int64(utf8.RuneCountInString(field.String())) <= p
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ p := asInt(param)
+
+ return int64(field.Len()) <= p
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ p := asIntFromType(field.Type(), param)
+
+ return field.Int() <= p
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ p := asUint(param)
+
+ return field.Uint() <= p
+
+ case reflect.Float32:
+ p := asFloat32(param)
+
+ return field.Float() <= p
+
+ case reflect.Float64:
+ p := asFloat64(param)
+
+ return field.Float() <= p
+
+ case reflect.Struct:
+
+ if field.Type().ConvertibleTo(timeType) {
+ now := time.Now().UTC()
+ t := getValue(field.Convert(timeType)).(time.Time)
+
+ return t.Before(now) || t.Equal(now)
+ }
+ }
+
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+}
+
+// isLt is the validation function for validating if the current field's value is less than the param's value.
+func isLt(fl FieldLevel) bool {
+ field := fl.Field()
+ param := fl.Param()
+
+ switch field.Kind() {
+ case reflect.String:
+ p := asInt(param)
+
+ return int64(utf8.RuneCountInString(field.String())) < p
+
+ case reflect.Slice, reflect.Map, reflect.Array:
+ p := asInt(param)
+
+ return int64(field.Len()) < p
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ p := asIntFromType(field.Type(), param)
+
+ return field.Int() < p
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ p := asUint(param)
+
+ return field.Uint() < p
+
+ case reflect.Float32:
+ p := asFloat32(param)
+
+ return field.Float() < p
+
+ case reflect.Float64:
+ p := asFloat64(param)
+
+ return field.Float() < p
+
+ case reflect.Struct:
+
+ if field.Type().ConvertibleTo(timeType) {
+ return getValue(field.Convert(timeType)).(time.Time).Before(time.Now().UTC())
+ }
+ }
+
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+}
+
+// hasMaxOf is the validation function for validating if the current field's value is less than or equal to the param's value.
+func hasMaxOf(fl FieldLevel) bool {
+ return isLte(fl)
+}
+
+// isTCP4AddrResolvable is the validation function for validating if the field's value is a resolvable tcp4 address.
+func isTCP4AddrResolvable(fl FieldLevel) bool {
+ if !isIP4Addr(fl) {
+ return false
+ }
+
+ _, err := net.ResolveTCPAddr("tcp4", fl.Field().String())
+ return err == nil
+}
+
+// isTCP6AddrResolvable is the validation function for validating if the field's value is a resolvable tcp6 address.
+func isTCP6AddrResolvable(fl FieldLevel) bool {
+ if !isIP6Addr(fl) {
+ return false
+ }
+
+ _, err := net.ResolveTCPAddr("tcp6", fl.Field().String())
+
+ return err == nil
+}
+
+// isTCPAddrResolvable is the validation function for validating if the field's value is a resolvable tcp address.
+func isTCPAddrResolvable(fl FieldLevel) bool {
+ if !isIP4Addr(fl) && !isIP6Addr(fl) {
+ return false
+ }
+
+ _, err := net.ResolveTCPAddr("tcp", fl.Field().String())
+
+ return err == nil
+}
+
+// isUDP4AddrResolvable is the validation function for validating if the field's value is a resolvable udp4 address.
+func isUDP4AddrResolvable(fl FieldLevel) bool {
+ if !isIP4Addr(fl) {
+ return false
+ }
+
+ _, err := net.ResolveUDPAddr("udp4", fl.Field().String())
+
+ return err == nil
+}
+
+// isUDP6AddrResolvable is the validation function for validating if the field's value is a resolvable udp6 address.
+func isUDP6AddrResolvable(fl FieldLevel) bool {
+ if !isIP6Addr(fl) {
+ return false
+ }
+
+ _, err := net.ResolveUDPAddr("udp6", fl.Field().String())
+
+ return err == nil
+}
+
+// isUDPAddrResolvable is the validation function for validating if the field's value is a resolvable udp address.
+func isUDPAddrResolvable(fl FieldLevel) bool {
+ if !isIP4Addr(fl) && !isIP6Addr(fl) {
+ return false
+ }
+
+ _, err := net.ResolveUDPAddr("udp", fl.Field().String())
+
+ return err == nil
+}
+
+// isIP4AddrResolvable is the validation function for validating if the field's value is a resolvable ip4 address.
+func isIP4AddrResolvable(fl FieldLevel) bool {
+ if !isIPv4(fl) {
+ return false
+ }
+
+ _, err := net.ResolveIPAddr("ip4", fl.Field().String())
+
+ return err == nil
+}
+
+// isIP6AddrResolvable is the validation function for validating if the field's value is a resolvable ip6 address.
+func isIP6AddrResolvable(fl FieldLevel) bool {
+ if !isIPv6(fl) {
+ return false
+ }
+
+ _, err := net.ResolveIPAddr("ip6", fl.Field().String())
+
+ return err == nil
+}
+
+// isIPAddrResolvable is the validation function for validating if the field's value is a resolvable ip address.
+func isIPAddrResolvable(fl FieldLevel) bool {
+ if !isIP(fl) {
+ return false
+ }
+
+ _, err := net.ResolveIPAddr("ip", fl.Field().String())
+
+ return err == nil
+}
+
+// isUnixAddrResolvable is the validation function for validating if the field's value is a resolvable unix address.
+func isUnixAddrResolvable(fl FieldLevel) bool {
+ _, err := net.ResolveUnixAddr("unix", fl.Field().String())
+
+ return err == nil
+}
+
+func isIP4Addr(fl FieldLevel) bool {
+ val := fl.Field().String()
+
+ if idx := strings.LastIndex(val, ":"); idx != -1 {
+ val = val[0:idx]
+ }
+
+ ip := net.ParseIP(val)
+
+ return ip != nil && ip.To4() != nil
+}
+
+func isIP6Addr(fl FieldLevel) bool {
+ val := fl.Field().String()
+
+ if idx := strings.LastIndex(val, ":"); idx != -1 {
+ if idx != 0 && val[idx-1:idx] == "]" {
+ val = val[1 : idx-1]
+ }
+ }
+
+ ip := net.ParseIP(val)
+
+ return ip != nil && ip.To4() == nil
+}
+
+func isHostnameRFC952(fl FieldLevel) bool {
+ return hostnameRegexRFC952().MatchString(fl.Field().String())
+}
+
+func isHostnameRFC1123(fl FieldLevel) bool {
+ return hostnameRegexRFC1123().MatchString(fl.Field().String())
+}
+
+func isFQDN(fl FieldLevel) bool {
+ val := fl.Field().String()
+
+ if val == "" {
+ return false
+ }
+
+ return fqdnRegexRFC1123().MatchString(val)
+}
+
+// isDir is the validation function for validating if the current field's value is a valid existing directory.
+func isDir(fl FieldLevel) bool {
+ field := fl.Field()
+
+ if field.Kind() == reflect.String {
+ fileInfo, err := os.Stat(field.String())
+ if err != nil {
+ return false
+ }
+
+ return fileInfo.IsDir()
+ }
+
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+}
+
+// isDirPath is the validation function for validating if the current field's value is a valid directory.
+func isDirPath(fl FieldLevel) bool {
+ var exists bool
+ var err error
+
+ field := fl.Field()
+
+ // If it exists, it obviously is valid.
+ // This is done first to avoid code duplication and unnecessary additional logic.
+ if exists = isDir(fl); exists {
+ return true
+ }
+
+ // It does not exist but may still be a valid path.
+ switch field.Kind() {
+ case reflect.String:
+ // Every OS allows for whitespace, but none
+ // let you use a dir with no name (to my knowledge).
+ // Unless you're dealing with raw inodes, but I digress.
+ if strings.TrimSpace(field.String()) == "" {
+ return false
+ }
+ if _, err = os.Stat(field.String()); err != nil {
+ switch t := err.(type) {
+ case *fs.PathError:
+ if t.Err == syscall.EINVAL {
+ // It's definitely an invalid character in the path.
+ return false
+ }
+ // It could be a permission error, a does-not-exist error, etc.
+ // Out-of-scope for this validation, though.
+ // Lastly, we make sure it is a directory.
+ if strings.HasSuffix(field.String(), string(os.PathSeparator)) {
+ return true
+ } else {
+ return false
+ }
+ default:
+ // Something went *seriously* wrong.
+ /*
+ Per https://pkg.go.dev/os#Stat:
+ "If there is an error, it will be of type *PathError."
+ */
+ panic(err)
+ }
+ }
+ // We repeat the check here to make sure it is an explicit directory in case the above os.Stat didn't trigger an error.
+ if strings.HasSuffix(field.String(), string(os.PathSeparator)) {
+ return true
+ } else {
+ return false
+ }
+ }
+
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+}
+
+// isJSON is the validation function for validating if the current field's value is a valid json string.
+func isJSON(fl FieldLevel) bool {
+ field := fl.Field()
+
+ switch field.Kind() {
+ case reflect.String:
+ val := field.String()
+ return json.Valid([]byte(val))
+ case reflect.Slice:
+ fieldType := field.Type()
+
+ if fieldType.ConvertibleTo(byteSliceType) {
+ b := getValue(field.Convert(byteSliceType)).([]byte)
+ return json.Valid(b)
+ }
+ }
+
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+}
+
+// isJWT is the validation function for validating if the current field's value is a valid JWT string.
+func isJWT(fl FieldLevel) bool {
+ return jWTRegex().MatchString(fl.Field().String())
+}
+
+// isHostnamePort validates a : combination for fields typically used for socket address.
+func isHostnamePort(fl FieldLevel) bool {
+ val := fl.Field().String()
+ host, port, err := net.SplitHostPort(val)
+ if err != nil {
+ return false
+ }
+ // Port must be a iny <= 65535.
+ if portNum, err := strconv.ParseInt(
+ port, 10, 32,
+ ); err != nil || portNum > 65535 || portNum < 1 {
+ return false
+ }
+
+ // If host is specified, it should match a DNS name
+ if host != "" {
+ return hostnameRegexRFC1123().MatchString(host)
+ }
+ return true
+}
+
+// IsPort validates if the current field's value represents a valid port
+func isPort(fl FieldLevel) bool {
+ val := fl.Field().Uint()
+
+ return val >= 1 && val <= 65535
+}
+
+// isLowercase is the validation function for validating if the current field's value is a lowercase string.
+func isLowercase(fl FieldLevel) bool {
+ field := fl.Field()
+
+ if field.Kind() == reflect.String {
+ if field.String() == "" {
+ return false
+ }
+ return field.String() == strings.ToLower(field.String())
+ }
+
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+}
+
+// isUppercase is the validation function for validating if the current field's value is an uppercase string.
+func isUppercase(fl FieldLevel) bool {
+ field := fl.Field()
+
+ if field.Kind() == reflect.String {
+ if field.String() == "" {
+ return false
+ }
+ return field.String() == strings.ToUpper(field.String())
+ }
+
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+}
+
+// isDatetime is the validation function for validating if the current field's value is a valid datetime string.
+func isDatetime(fl FieldLevel) bool {
+ field := fl.Field()
+ param := fl.Param()
+
+ if field.Kind() == reflect.String {
+ _, err := time.Parse(param, field.String())
+
+ return err == nil
+ }
+
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+}
+
+// isTimeZone is the validation function for validating if the current field's value is a valid time zone string.
+func isTimeZone(fl FieldLevel) bool {
+ field := fl.Field()
+
+ if field.Kind() == reflect.String {
+ // empty value is converted to UTC by time.LoadLocation but disallow it as it is not a valid time zone name
+ if field.String() == "" {
+ return false
+ }
+
+ // Local value is converted to the current system time zone by time.LoadLocation but disallow it as it is not a valid time zone name
+ if strings.ToLower(field.String()) == "local" {
+ return false
+ }
+
+ _, err := time.LoadLocation(field.String())
+ return err == nil
+ }
+
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+}
+
+// isIso3166Alpha2 is the validation function for validating if the current field's value is a valid iso3166-1 alpha-2 country code.
+func isIso3166Alpha2(fl FieldLevel) bool {
+ _, ok := iso3166_1_alpha2[fl.Field().String()]
+ return ok
+}
+
+// isIso3166Alpha2EU is the validation function for validating if the current field's value is a valid iso3166-1 alpha-2 European Union country code.
+func isIso3166Alpha2EU(fl FieldLevel) bool {
+ _, ok := iso3166_1_alpha2_eu[fl.Field().String()]
+ return ok
+}
+
+// isIso3166Alpha3 is the validation function for validating if the current field's value is a valid iso3166-1 alpha-3 country code.
+func isIso3166Alpha3(fl FieldLevel) bool {
+ _, ok := iso3166_1_alpha3[fl.Field().String()]
+ return ok
+}
+
+// isIso3166Alpha3EU is the validation function for validating if the current field's value is a valid iso3166-1 alpha-3 European Union country code.
+func isIso3166Alpha3EU(fl FieldLevel) bool {
+ _, ok := iso3166_1_alpha3_eu[fl.Field().String()]
+ return ok
+}
+
+// isIso3166AlphaNumeric is the validation function for validating if the current field's value is a valid iso3166-1 alpha-numeric country code.
+func isIso3166AlphaNumeric(fl FieldLevel) bool {
+ field := fl.Field()
+
+ var code int
+ switch field.Kind() {
+ case reflect.String:
+ i, err := strconv.Atoi(field.String())
+ if err != nil {
+ return false
+ }
+ code = i % 1000
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ code = int(field.Int() % 1000)
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ code = int(field.Uint() % 1000)
+ default:
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+ }
+
+ _, ok := iso3166_1_alpha_numeric[code]
+ return ok
+}
+
+// isIso3166AlphaNumericEU is the validation function for validating if the current field's value is a valid iso3166-1 alpha-numeric European Union country code.
+func isIso3166AlphaNumericEU(fl FieldLevel) bool {
+ field := fl.Field()
+
+ var code int
+ switch field.Kind() {
+ case reflect.String:
+ i, err := strconv.Atoi(field.String())
+ if err != nil {
+ return false
+ }
+ code = i % 1000
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ code = int(field.Int() % 1000)
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ code = int(field.Uint() % 1000)
+ default:
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+ }
+
+ _, ok := iso3166_1_alpha_numeric_eu[code]
+ return ok
+}
+
+// isIso31662 is the validation function for validating if the current field's value is a valid iso3166-2 code.
+func isIso31662(fl FieldLevel) bool {
+ _, ok := iso3166_2[fl.Field().String()]
+ return ok
+}
+
+// isIso4217 is the validation function for validating if the current field's value is a valid iso4217 currency code.
+func isIso4217(fl FieldLevel) bool {
+ _, ok := iso4217[fl.Field().String()]
+ return ok
+}
+
+// isIso4217Numeric is the validation function for validating if the current field's value is a valid iso4217 numeric currency code.
+func isIso4217Numeric(fl FieldLevel) bool {
+ field := fl.Field()
+
+ var code int
+ switch field.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ code = int(field.Int())
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ code = int(field.Uint())
+ default:
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+ }
+
+ _, ok := iso4217_numeric[code]
+ return ok
+}
+
+// isBCP47LanguageTag is the validation function for validating if the current field's value is a valid BCP 47 language tag, as parsed by language.Parse
+func isBCP47LanguageTag(fl FieldLevel) bool {
+ field := fl.Field()
+
+ if field.Kind() == reflect.String {
+ _, err := language.Parse(field.String())
+ return err == nil
+ }
+
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+}
+
+// isIsoBicFormat is the validation function for validating if the current field's value is a valid Business Identifier Code (SWIFT code), defined in ISO 9362
+func isIsoBicFormat(fl FieldLevel) bool {
+ bicString := fl.Field().String()
+
+ return bicRegex().MatchString(bicString)
+}
+
+// isSemverFormat is the validation function for validating if the current field's value is a valid semver version, defined in Semantic Versioning 2.0.0
+func isSemverFormat(fl FieldLevel) bool {
+ semverString := fl.Field().String()
+
+ return semverRegex().MatchString(semverString)
+}
+
+// isCveFormat is the validation function for validating if the current field's value is a valid cve id, defined in CVE mitre org
+func isCveFormat(fl FieldLevel) bool {
+ cveString := fl.Field().String()
+
+ return cveRegex().MatchString(cveString)
+}
+
+// isDnsRFC1035LabelFormat is the validation function
+// for validating if the current field's value is
+// a valid dns RFC 1035 label, defined in RFC 1035.
+func isDnsRFC1035LabelFormat(fl FieldLevel) bool {
+ val := fl.Field().String()
+
+ size := len(val)
+ if size > 63 {
+ return false
+ }
+
+ return dnsRegexRFC1035Label().MatchString(val)
+}
+
+// digitsHaveLuhnChecksum returns true if and only if the last element of the given digits slice is the Luhn checksum of the previous elements
+func digitsHaveLuhnChecksum(digits []string) bool {
+ size := len(digits)
+ sum := 0
+ for i, digit := range digits {
+ value, err := strconv.Atoi(digit)
+ if err != nil {
+ return false
+ }
+ if size%2 == 0 && i%2 == 0 || size%2 == 1 && i%2 == 1 {
+ v := value * 2
+ if v >= 10 {
+ sum += 1 + (v % 10)
+ } else {
+ sum += v
+ }
+ } else {
+ sum += value
+ }
+ }
+ return (sum % 10) == 0
+}
+
+// isMongoDBObjectId is the validation function for validating if the current field's value is valid MongoDB ObjectID
+func isMongoDBObjectId(fl FieldLevel) bool {
+ val := fl.Field().String()
+ return mongodbIdRegex().MatchString(val)
+}
+
+// isMongoDBConnectionString is the validation function for validating if the current field's value is valid MongoDB Connection String
+func isMongoDBConnectionString(fl FieldLevel) bool {
+ val := fl.Field().String()
+ return mongodbConnectionRegex().MatchString(val)
+}
+
+// isSpiceDB is the validation function for validating if the current field's value is valid for use with Authzed SpiceDB in the indicated way
+func isSpiceDB(fl FieldLevel) bool {
+ val := fl.Field().String()
+ param := fl.Param()
+
+ switch param {
+ case "permission":
+ return spicedbPermissionRegex().MatchString(val)
+ case "type":
+ return spicedbTypeRegex().MatchString(val)
+ case "id", "":
+ return spicedbIDRegex().MatchString(val)
+ }
+
+ panic("Unrecognized parameter: " + param)
+}
+
+// isCreditCard is the validation function for validating if the current field's value is a valid credit card number
+func isCreditCard(fl FieldLevel) bool {
+ val := fl.Field().String()
+ var creditCard bytes.Buffer
+ segments := strings.Split(val, " ")
+ for _, segment := range segments {
+ if len(segment) < 3 {
+ return false
+ }
+ creditCard.WriteString(segment)
+ }
+
+ ccDigits := strings.Split(creditCard.String(), "")
+ size := len(ccDigits)
+ if size < 12 || size > 19 {
+ return false
+ }
+
+ return digitsHaveLuhnChecksum(ccDigits)
+}
+
+// hasLuhnChecksum is the validation for validating if the current field's value has a valid Luhn checksum
+func hasLuhnChecksum(fl FieldLevel) bool {
+ field := fl.Field()
+ var str string // convert to a string which will then be split into single digits; easier and more readable than shifting/extracting single digits from a number
+ switch field.Kind() {
+ case reflect.String:
+ str = field.String()
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ str = strconv.FormatInt(field.Int(), 10)
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ str = strconv.FormatUint(field.Uint(), 10)
+ default:
+ panic(fmt.Sprintf("Bad field type %s", field.Type()))
+ }
+ size := len(str)
+ if size < 2 { // there has to be at least one digit that carries a meaning + the checksum
+ return false
+ }
+ digits := strings.Split(str, "")
+ return digitsHaveLuhnChecksum(digits)
+}
+
+// isCron is the validation function for validating if the current field's value is a valid cron expression
+func isCron(fl FieldLevel) bool {
+ cronString := fl.Field().String()
+ return cronRegex().MatchString(cronString)
+}
+
+// isEIN is the validation function for validating if the current field's value is a valid U.S. Employer Identification Number (EIN)
+func isEIN(fl FieldLevel) bool {
+ field := fl.Field()
+
+ if field.Len() != 10 {
+ return false
+ }
+
+ return einRegex().MatchString(field.String())
+}
+
+func isValidateFn(fl FieldLevel) bool {
+ const defaultParam = `Validate`
+
+ field := fl.Field()
+ validateFn := cmp.Or(fl.Param(), defaultParam)
+
+ ok, err := tryCallValidateFn(field, validateFn)
+ if err != nil {
+ return false
+ }
+
+ return ok
+}
+
+var (
+ errMethodNotFound = errors.New(`method not found`)
+ errMethodReturnNoValues = errors.New(`method return o values (void)`)
+ errMethodReturnInvalidType = errors.New(`method should return invalid type`)
+)
+
+func tryCallValidateFn(field reflect.Value, validateFn string) (bool, error) {
+ method := field.MethodByName(validateFn)
+ if field.CanAddr() && !method.IsValid() {
+ method = field.Addr().MethodByName(validateFn)
+ }
+
+ if !method.IsValid() {
+ return false, fmt.Errorf("unable to call %q on type %q: %w",
+ validateFn, field.Type().String(), errMethodNotFound)
+ }
+
+ returnValues := method.Call([]reflect.Value{})
+ if len(returnValues) == 0 {
+ return false, fmt.Errorf("unable to use result of method %q on type %q: %w",
+ validateFn, field.Type().String(), errMethodReturnNoValues)
+ }
+
+ firstReturnValue := returnValues[0]
+
+ switch firstReturnValue.Kind() {
+ case reflect.Bool:
+ return firstReturnValue.Bool(), nil
+ case reflect.Interface:
+ errorType := reflect.TypeOf((*error)(nil)).Elem()
+
+ if firstReturnValue.Type().Implements(errorType) {
+ return firstReturnValue.IsNil(), nil
+ }
+
+ return false, fmt.Errorf("unable to use result of method %q on type %q: %w (got interface %v expect error)",
+ validateFn, field.Type().String(), errMethodReturnInvalidType, firstReturnValue.Type().String())
+ default:
+ return false, fmt.Errorf("unable to use result of method %q on type %q: %w (got %v expect error or bool)",
+ validateFn, field.Type().String(), errMethodReturnInvalidType, firstReturnValue.Type().String())
+ }
+}
diff --git a/vendor/github.com/go-playground/validator/v10/cache.go b/vendor/github.com/go-playground/validator/v10/cache.go
new file mode 100644
index 00000000..fb101b06
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/cache.go
@@ -0,0 +1,326 @@
+package validator
+
+import (
+ "fmt"
+ "reflect"
+ "strings"
+ "sync"
+ "sync/atomic"
+)
+
+type tagType uint8
+
+const (
+ typeDefault tagType = iota
+ typeOmitEmpty
+ typeIsDefault
+ typeNoStructLevel
+ typeStructOnly
+ typeDive
+ typeOr
+ typeKeys
+ typeEndKeys
+ typeOmitNil
+ typeOmitZero
+)
+
+const (
+ invalidValidation = "Invalid validation tag on field '%s'"
+ undefinedValidation = "Undefined validation function '%s' on field '%s'"
+ keysTagNotDefined = "'" + endKeysTag + "' tag encountered without a corresponding '" + keysTag + "' tag"
+)
+
+type structCache struct {
+ lock sync.Mutex
+ m atomic.Value // map[reflect.Type]*cStruct
+}
+
+func (sc *structCache) Get(key reflect.Type) (c *cStruct, found bool) {
+ c, found = sc.m.Load().(map[reflect.Type]*cStruct)[key]
+ return
+}
+
+func (sc *structCache) Set(key reflect.Type, value *cStruct) {
+ m := sc.m.Load().(map[reflect.Type]*cStruct)
+ nm := make(map[reflect.Type]*cStruct, len(m)+1)
+ for k, v := range m {
+ nm[k] = v
+ }
+ nm[key] = value
+ sc.m.Store(nm)
+}
+
+type tagCache struct {
+ lock sync.Mutex
+ m atomic.Value // map[string]*cTag
+}
+
+func (tc *tagCache) Get(key string) (c *cTag, found bool) {
+ c, found = tc.m.Load().(map[string]*cTag)[key]
+ return
+}
+
+func (tc *tagCache) Set(key string, value *cTag) {
+ m := tc.m.Load().(map[string]*cTag)
+ nm := make(map[string]*cTag, len(m)+1)
+ for k, v := range m {
+ nm[k] = v
+ }
+ nm[key] = value
+ tc.m.Store(nm)
+}
+
+type cStruct struct {
+ name string
+ fields []*cField
+ fn StructLevelFuncCtx
+}
+
+type cField struct {
+ idx int
+ name string
+ altName string
+ namesEqual bool
+ cTags *cTag
+}
+
+type cTag struct {
+ tag string
+ aliasTag string
+ actualAliasTag string
+ param string
+ keys *cTag // only populated when using tag's 'keys' and 'endkeys' for map key validation
+ next *cTag
+ fn FuncCtx
+ typeof tagType
+ hasTag bool
+ hasAlias bool
+ hasParam bool // true if parameter used eg. eq= where the equal sign has been set
+ isBlockEnd bool // indicates the current tag represents the last validation in the block
+ runValidationWhenNil bool
+}
+
+func (v *Validate) extractStructCache(current reflect.Value, sName string) *cStruct {
+ v.structCache.lock.Lock()
+ defer v.structCache.lock.Unlock() // leave as defer! because if inner panics, it will never get unlocked otherwise!
+
+ typ := current.Type()
+
+ // could have been multiple trying to access, but once first is done this ensures struct
+ // isn't parsed again.
+ cs, ok := v.structCache.Get(typ)
+ if ok {
+ return cs
+ }
+
+ cs = &cStruct{name: sName, fields: make([]*cField, 0), fn: v.structLevelFuncs[typ]}
+
+ numFields := current.NumField()
+ rules := v.rules[typ]
+
+ var ctag *cTag
+ var fld reflect.StructField
+ var tag string
+ var customName string
+
+ for i := 0; i < numFields; i++ {
+ fld = typ.Field(i)
+
+ if !v.privateFieldValidation && !fld.Anonymous && len(fld.PkgPath) > 0 {
+ continue
+ }
+
+ if rtag, ok := rules[fld.Name]; ok {
+ tag = rtag
+ } else {
+ tag = fld.Tag.Get(v.tagName)
+ }
+
+ if tag == skipValidationTag {
+ continue
+ }
+
+ customName = fld.Name
+
+ if v.hasTagNameFunc {
+ name := v.tagNameFunc(fld)
+ if len(name) > 0 {
+ customName = name
+ }
+ }
+
+ // NOTE: cannot use shared tag cache, because tags may be equal, but things like alias may be different
+ // and so only struct level caching can be used instead of combined with Field tag caching
+
+ if len(tag) > 0 {
+ ctag, _ = v.parseFieldTagsRecursive(tag, fld.Name, "", false)
+ } else {
+ // even if field doesn't have validations need cTag for traversing to potential inner/nested
+ // elements of the field.
+ ctag = new(cTag)
+ }
+
+ cs.fields = append(cs.fields, &cField{
+ idx: i,
+ name: fld.Name,
+ altName: customName,
+ cTags: ctag,
+ namesEqual: fld.Name == customName,
+ })
+ }
+ v.structCache.Set(typ, cs)
+ return cs
+}
+
+func (v *Validate) parseFieldTagsRecursive(tag string, fieldName string, alias string, hasAlias bool) (firstCtag *cTag, current *cTag) {
+ var t string
+ noAlias := len(alias) == 0
+ tags := strings.Split(tag, tagSeparator)
+
+ for i := 0; i < len(tags); i++ {
+ t = tags[i]
+ if noAlias {
+ alias = t
+ }
+
+ // check map for alias and process new tags, otherwise process as usual
+ if tagsVal, found := v.aliases[t]; found {
+ if i == 0 {
+ firstCtag, current = v.parseFieldTagsRecursive(tagsVal, fieldName, t, true)
+ } else {
+ next, curr := v.parseFieldTagsRecursive(tagsVal, fieldName, t, true)
+ current.next, current = next, curr
+ }
+ continue
+ }
+
+ var prevTag tagType
+
+ if i == 0 {
+ current = &cTag{aliasTag: alias, hasAlias: hasAlias, hasTag: true, typeof: typeDefault}
+ firstCtag = current
+ } else {
+ prevTag = current.typeof
+ current.next = &cTag{aliasTag: alias, hasAlias: hasAlias, hasTag: true}
+ current = current.next
+ }
+
+ switch t {
+ case diveTag:
+ current.typeof = typeDive
+
+ case keysTag:
+ current.typeof = typeKeys
+
+ if i == 0 || prevTag != typeDive {
+ panic(fmt.Sprintf("'%s' tag must be immediately preceded by the '%s' tag", keysTag, diveTag))
+ }
+
+ // need to pass along only keys tag
+ // need to increment i to skip over the keys tags
+ b := make([]byte, 0, 64)
+
+ i++
+
+ for ; i < len(tags); i++ {
+ b = append(b, tags[i]...)
+ b = append(b, ',')
+
+ if tags[i] == endKeysTag {
+ break
+ }
+ }
+
+ current.keys, _ = v.parseFieldTagsRecursive(string(b[:len(b)-1]), fieldName, "", false)
+
+ case endKeysTag:
+ current.typeof = typeEndKeys
+
+ // if there are more in tags then there was no keysTag defined
+ // and an error should be thrown
+ if i != len(tags)-1 {
+ panic(keysTagNotDefined)
+ }
+ return
+
+ case omitzero:
+ current.typeof = typeOmitZero
+ continue
+
+ case omitempty:
+ current.typeof = typeOmitEmpty
+
+ case omitnil:
+ current.typeof = typeOmitNil
+
+ case structOnlyTag:
+ current.typeof = typeStructOnly
+
+ case noStructLevelTag:
+ current.typeof = typeNoStructLevel
+
+ default:
+ if t == isdefault {
+ current.typeof = typeIsDefault
+ }
+ // if a pipe character is needed within the param you must use the utf8Pipe representation "0x7C"
+ orVals := strings.Split(t, orSeparator)
+
+ for j := 0; j < len(orVals); j++ {
+ vals := strings.SplitN(orVals[j], tagKeySeparator, 2)
+ if noAlias {
+ alias = vals[0]
+ current.aliasTag = alias
+ } else {
+ current.actualAliasTag = t
+ }
+
+ if j > 0 {
+ current.next = &cTag{aliasTag: alias, actualAliasTag: current.actualAliasTag, hasAlias: hasAlias, hasTag: true}
+ current = current.next
+ }
+ current.hasParam = len(vals) > 1
+
+ current.tag = vals[0]
+ if len(current.tag) == 0 {
+ panic(strings.TrimSpace(fmt.Sprintf(invalidValidation, fieldName)))
+ }
+
+ if wrapper, ok := v.validations[current.tag]; ok {
+ current.fn = wrapper.fn
+ current.runValidationWhenNil = wrapper.runValidationOnNil
+ } else {
+ panic(strings.TrimSpace(fmt.Sprintf(undefinedValidation, current.tag, fieldName)))
+ }
+
+ if len(orVals) > 1 {
+ current.typeof = typeOr
+ }
+
+ if len(vals) > 1 {
+ current.param = strings.ReplaceAll(strings.ReplaceAll(vals[1], utf8HexComma, ","), utf8Pipe, "|")
+ }
+ }
+ current.isBlockEnd = true
+ }
+ }
+ return
+}
+
+func (v *Validate) fetchCacheTag(tag string) *cTag {
+ // find cached tag
+ ctag, found := v.tagCache.Get(tag)
+ if !found {
+ v.tagCache.lock.Lock()
+ defer v.tagCache.lock.Unlock()
+
+ // could have been multiple trying to access, but once first is done this ensures tag
+ // isn't parsed again.
+ ctag, found = v.tagCache.Get(tag)
+ if !found {
+ ctag, _ = v.parseFieldTagsRecursive(tag, "", "", false)
+ v.tagCache.Set(tag, ctag)
+ }
+ }
+ return ctag
+}
diff --git a/vendor/github.com/go-playground/validator/v10/country_codes.go b/vendor/github.com/go-playground/validator/v10/country_codes.go
new file mode 100644
index 00000000..b5f10d3c
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/country_codes.go
@@ -0,0 +1,1177 @@
+package validator
+
+var iso3166_1_alpha2 = map[string]struct{}{
+ // see: https://www.iso.org/iso-3166-country-codes.html
+ "AF": {}, "AX": {}, "AL": {}, "DZ": {}, "AS": {},
+ "AD": {}, "AO": {}, "AI": {}, "AQ": {}, "AG": {},
+ "AR": {}, "AM": {}, "AW": {}, "AU": {}, "AT": {},
+ "AZ": {}, "BS": {}, "BH": {}, "BD": {}, "BB": {},
+ "BY": {}, "BE": {}, "BZ": {}, "BJ": {}, "BM": {},
+ "BT": {}, "BO": {}, "BQ": {}, "BA": {}, "BW": {},
+ "BV": {}, "BR": {}, "IO": {}, "BN": {}, "BG": {},
+ "BF": {}, "BI": {}, "KH": {}, "CM": {}, "CA": {},
+ "CV": {}, "KY": {}, "CF": {}, "TD": {}, "CL": {},
+ "CN": {}, "CX": {}, "CC": {}, "CO": {}, "KM": {},
+ "CG": {}, "CD": {}, "CK": {}, "CR": {}, "CI": {},
+ "HR": {}, "CU": {}, "CW": {}, "CY": {}, "CZ": {},
+ "DK": {}, "DJ": {}, "DM": {}, "DO": {}, "EC": {},
+ "EG": {}, "SV": {}, "GQ": {}, "ER": {}, "EE": {},
+ "ET": {}, "FK": {}, "FO": {}, "FJ": {}, "FI": {},
+ "FR": {}, "GF": {}, "PF": {}, "TF": {}, "GA": {},
+ "GM": {}, "GE": {}, "DE": {}, "GH": {}, "GI": {},
+ "GR": {}, "GL": {}, "GD": {}, "GP": {}, "GU": {},
+ "GT": {}, "GG": {}, "GN": {}, "GW": {}, "GY": {},
+ "HT": {}, "HM": {}, "VA": {}, "HN": {}, "HK": {},
+ "HU": {}, "IS": {}, "IN": {}, "ID": {}, "IR": {},
+ "IQ": {}, "IE": {}, "IM": {}, "IL": {}, "IT": {},
+ "JM": {}, "JP": {}, "JE": {}, "JO": {}, "KZ": {},
+ "KE": {}, "KI": {}, "KP": {}, "KR": {}, "KW": {},
+ "KG": {}, "LA": {}, "LV": {}, "LB": {}, "LS": {},
+ "LR": {}, "LY": {}, "LI": {}, "LT": {}, "LU": {},
+ "MO": {}, "MK": {}, "MG": {}, "MW": {}, "MY": {},
+ "MV": {}, "ML": {}, "MT": {}, "MH": {}, "MQ": {},
+ "MR": {}, "MU": {}, "YT": {}, "MX": {}, "FM": {},
+ "MD": {}, "MC": {}, "MN": {}, "ME": {}, "MS": {},
+ "MA": {}, "MZ": {}, "MM": {}, "NA": {}, "NR": {},
+ "NP": {}, "NL": {}, "NC": {}, "NZ": {}, "NI": {},
+ "NE": {}, "NG": {}, "NU": {}, "NF": {}, "MP": {},
+ "NO": {}, "OM": {}, "PK": {}, "PW": {}, "PS": {},
+ "PA": {}, "PG": {}, "PY": {}, "PE": {}, "PH": {},
+ "PN": {}, "PL": {}, "PT": {}, "PR": {}, "QA": {},
+ "RE": {}, "RO": {}, "RU": {}, "RW": {}, "BL": {},
+ "SH": {}, "KN": {}, "LC": {}, "MF": {}, "PM": {},
+ "VC": {}, "WS": {}, "SM": {}, "ST": {}, "SA": {},
+ "SN": {}, "RS": {}, "SC": {}, "SL": {}, "SG": {},
+ "SX": {}, "SK": {}, "SI": {}, "SB": {}, "SO": {},
+ "ZA": {}, "GS": {}, "SS": {}, "ES": {}, "LK": {},
+ "SD": {}, "SR": {}, "SJ": {}, "SZ": {}, "SE": {},
+ "CH": {}, "SY": {}, "TW": {}, "TJ": {}, "TZ": {},
+ "TH": {}, "TL": {}, "TG": {}, "TK": {}, "TO": {},
+ "TT": {}, "TN": {}, "TR": {}, "TM": {}, "TC": {},
+ "TV": {}, "UG": {}, "UA": {}, "AE": {}, "GB": {},
+ "US": {}, "UM": {}, "UY": {}, "UZ": {}, "VU": {},
+ "VE": {}, "VN": {}, "VG": {}, "VI": {}, "WF": {},
+ "EH": {}, "YE": {}, "ZM": {}, "ZW": {}, "XK": {},
+}
+
+var iso3166_1_alpha2_eu = map[string]struct{}{
+ "AT": {}, "BE": {}, "BG": {}, "HR": {}, "CY": {},
+ "CZ": {}, "DK": {}, "EE": {}, "FI": {}, "FR": {},
+ "DE": {}, "GR": {}, "HU": {}, "IE": {}, "IT": {},
+ "LV": {}, "LT": {}, "LU": {}, "MT": {}, "NL": {},
+ "PL": {}, "PT": {}, "RO": {}, "SK": {}, "SI": {},
+ "ES": {}, "SE": {},
+}
+
+var iso3166_1_alpha3 = map[string]struct{}{
+ // see: https://www.iso.org/iso-3166-country-codes.html
+ "AFG": {}, "ALB": {}, "DZA": {}, "ASM": {}, "AND": {},
+ "AGO": {}, "AIA": {}, "ATA": {}, "ATG": {}, "ARG": {},
+ "ARM": {}, "ABW": {}, "AUS": {}, "AUT": {}, "AZE": {},
+ "BHS": {}, "BHR": {}, "BGD": {}, "BRB": {}, "BLR": {},
+ "BEL": {}, "BLZ": {}, "BEN": {}, "BMU": {}, "BTN": {},
+ "BOL": {}, "BES": {}, "BIH": {}, "BWA": {}, "BVT": {},
+ "BRA": {}, "IOT": {}, "BRN": {}, "BGR": {}, "BFA": {},
+ "BDI": {}, "CPV": {}, "KHM": {}, "CMR": {}, "CAN": {},
+ "CYM": {}, "CAF": {}, "TCD": {}, "CHL": {}, "CHN": {},
+ "CXR": {}, "CCK": {}, "COL": {}, "COM": {}, "COD": {},
+ "COG": {}, "COK": {}, "CRI": {}, "HRV": {}, "CUB": {},
+ "CUW": {}, "CYP": {}, "CZE": {}, "CIV": {}, "DNK": {},
+ "DJI": {}, "DMA": {}, "DOM": {}, "ECU": {}, "EGY": {},
+ "SLV": {}, "GNQ": {}, "ERI": {}, "EST": {}, "SWZ": {},
+ "ETH": {}, "FLK": {}, "FRO": {}, "FJI": {}, "FIN": {},
+ "FRA": {}, "GUF": {}, "PYF": {}, "ATF": {}, "GAB": {},
+ "GMB": {}, "GEO": {}, "DEU": {}, "GHA": {}, "GIB": {},
+ "GRC": {}, "GRL": {}, "GRD": {}, "GLP": {}, "GUM": {},
+ "GTM": {}, "GGY": {}, "GIN": {}, "GNB": {}, "GUY": {},
+ "HTI": {}, "HMD": {}, "VAT": {}, "HND": {}, "HKG": {},
+ "HUN": {}, "ISL": {}, "IND": {}, "IDN": {}, "IRN": {},
+ "IRQ": {}, "IRL": {}, "IMN": {}, "ISR": {}, "ITA": {},
+ "JAM": {}, "JPN": {}, "JEY": {}, "JOR": {}, "KAZ": {},
+ "KEN": {}, "KIR": {}, "PRK": {}, "KOR": {}, "KWT": {},
+ "KGZ": {}, "LAO": {}, "LVA": {}, "LBN": {}, "LSO": {},
+ "LBR": {}, "LBY": {}, "LIE": {}, "LTU": {}, "LUX": {},
+ "MAC": {}, "MDG": {}, "MWI": {}, "MYS": {}, "MDV": {},
+ "MLI": {}, "MLT": {}, "MHL": {}, "MTQ": {}, "MRT": {},
+ "MUS": {}, "MYT": {}, "MEX": {}, "FSM": {}, "MDA": {},
+ "MCO": {}, "MNG": {}, "MNE": {}, "MSR": {}, "MAR": {},
+ "MOZ": {}, "MMR": {}, "NAM": {}, "NRU": {}, "NPL": {},
+ "NLD": {}, "NCL": {}, "NZL": {}, "NIC": {}, "NER": {},
+ "NGA": {}, "NIU": {}, "NFK": {}, "MKD": {}, "MNP": {},
+ "NOR": {}, "OMN": {}, "PAK": {}, "PLW": {}, "PSE": {},
+ "PAN": {}, "PNG": {}, "PRY": {}, "PER": {}, "PHL": {},
+ "PCN": {}, "POL": {}, "PRT": {}, "PRI": {}, "QAT": {},
+ "ROU": {}, "RUS": {}, "RWA": {}, "REU": {}, "BLM": {},
+ "SHN": {}, "KNA": {}, "LCA": {}, "MAF": {}, "SPM": {},
+ "VCT": {}, "WSM": {}, "SMR": {}, "STP": {}, "SAU": {},
+ "SEN": {}, "SRB": {}, "SYC": {}, "SLE": {}, "SGP": {},
+ "SXM": {}, "SVK": {}, "SVN": {}, "SLB": {}, "SOM": {},
+ "ZAF": {}, "SGS": {}, "SSD": {}, "ESP": {}, "LKA": {},
+ "SDN": {}, "SUR": {}, "SJM": {}, "SWE": {}, "CHE": {},
+ "SYR": {}, "TWN": {}, "TJK": {}, "TZA": {}, "THA": {},
+ "TLS": {}, "TGO": {}, "TKL": {}, "TON": {}, "TTO": {},
+ "TUN": {}, "TUR": {}, "TKM": {}, "TCA": {}, "TUV": {},
+ "UGA": {}, "UKR": {}, "ARE": {}, "GBR": {}, "UMI": {},
+ "USA": {}, "URY": {}, "UZB": {}, "VUT": {}, "VEN": {},
+ "VNM": {}, "VGB": {}, "VIR": {}, "WLF": {}, "ESH": {},
+ "YEM": {}, "ZMB": {}, "ZWE": {}, "ALA": {}, "UNK": {},
+}
+
+var iso3166_1_alpha3_eu = map[string]struct{}{
+ "AUT": {}, "BEL": {}, "BGR": {}, "HRV": {}, "CYP": {},
+ "CZE": {}, "DNK": {}, "EST": {}, "FIN": {}, "FRA": {},
+ "DEU": {}, "GRC": {}, "HUN": {}, "IRL": {}, "ITA": {},
+ "LVA": {}, "LTU": {}, "LUX": {}, "MLT": {}, "NLD": {},
+ "POL": {}, "PRT": {}, "ROU": {}, "SVK": {}, "SVN": {},
+ "ESP": {}, "SWE": {},
+}
+var iso3166_1_alpha_numeric = map[int]struct{}{
+ // see: https://www.iso.org/iso-3166-country-codes.html
+ 4: {}, 8: {}, 12: {}, 16: {}, 20: {},
+ 24: {}, 660: {}, 10: {}, 28: {}, 32: {},
+ 51: {}, 533: {}, 36: {}, 40: {}, 31: {},
+ 44: {}, 48: {}, 50: {}, 52: {}, 112: {},
+ 56: {}, 84: {}, 204: {}, 60: {}, 64: {},
+ 68: {}, 535: {}, 70: {}, 72: {}, 74: {},
+ 76: {}, 86: {}, 96: {}, 100: {}, 854: {},
+ 108: {}, 132: {}, 116: {}, 120: {}, 124: {},
+ 136: {}, 140: {}, 148: {}, 152: {}, 156: {},
+ 162: {}, 166: {}, 170: {}, 174: {}, 180: {},
+ 178: {}, 184: {}, 188: {}, 191: {}, 192: {},
+ 531: {}, 196: {}, 203: {}, 384: {}, 208: {},
+ 262: {}, 212: {}, 214: {}, 218: {}, 818: {},
+ 222: {}, 226: {}, 232: {}, 233: {}, 748: {},
+ 231: {}, 238: {}, 234: {}, 242: {}, 246: {},
+ 250: {}, 254: {}, 258: {}, 260: {}, 266: {},
+ 270: {}, 268: {}, 276: {}, 288: {}, 292: {},
+ 300: {}, 304: {}, 308: {}, 312: {}, 316: {},
+ 320: {}, 831: {}, 324: {}, 624: {}, 328: {},
+ 332: {}, 334: {}, 336: {}, 340: {}, 344: {},
+ 348: {}, 352: {}, 356: {}, 360: {}, 364: {},
+ 368: {}, 372: {}, 833: {}, 376: {}, 380: {},
+ 388: {}, 392: {}, 832: {}, 400: {}, 398: {},
+ 404: {}, 296: {}, 408: {}, 410: {}, 414: {},
+ 417: {}, 418: {}, 428: {}, 422: {}, 426: {},
+ 430: {}, 434: {}, 438: {}, 440: {}, 442: {},
+ 446: {}, 450: {}, 454: {}, 458: {}, 462: {},
+ 466: {}, 470: {}, 584: {}, 474: {}, 478: {},
+ 480: {}, 175: {}, 484: {}, 583: {}, 498: {},
+ 492: {}, 496: {}, 499: {}, 500: {}, 504: {},
+ 508: {}, 104: {}, 516: {}, 520: {}, 524: {},
+ 528: {}, 540: {}, 554: {}, 558: {}, 562: {},
+ 566: {}, 570: {}, 574: {}, 807: {}, 580: {},
+ 578: {}, 512: {}, 586: {}, 585: {}, 275: {},
+ 591: {}, 598: {}, 600: {}, 604: {}, 608: {},
+ 612: {}, 616: {}, 620: {}, 630: {}, 634: {},
+ 642: {}, 643: {}, 646: {}, 638: {}, 652: {},
+ 654: {}, 659: {}, 662: {}, 663: {}, 666: {},
+ 670: {}, 882: {}, 674: {}, 678: {}, 682: {},
+ 686: {}, 688: {}, 690: {}, 694: {}, 702: {},
+ 534: {}, 703: {}, 705: {}, 90: {}, 706: {},
+ 710: {}, 239: {}, 728: {}, 724: {}, 144: {},
+ 729: {}, 740: {}, 744: {}, 752: {}, 756: {},
+ 760: {}, 158: {}, 762: {}, 834: {}, 764: {},
+ 626: {}, 768: {}, 772: {}, 776: {}, 780: {},
+ 788: {}, 792: {}, 795: {}, 796: {}, 798: {},
+ 800: {}, 804: {}, 784: {}, 826: {}, 581: {},
+ 840: {}, 858: {}, 860: {}, 548: {}, 862: {},
+ 704: {}, 92: {}, 850: {}, 876: {}, 732: {},
+ 887: {}, 894: {}, 716: {}, 248: {}, 153: {},
+}
+
+var iso3166_1_alpha_numeric_eu = map[int]struct{}{
+ 40: {}, 56: {}, 100: {}, 191: {}, 196: {},
+ 200: {}, 208: {}, 233: {}, 246: {}, 250: {},
+ 276: {}, 300: {}, 348: {}, 372: {}, 380: {},
+ 428: {}, 440: {}, 442: {}, 470: {}, 528: {},
+ 616: {}, 620: {}, 642: {}, 703: {}, 705: {},
+ 724: {}, 752: {},
+}
+
+var iso3166_2 = map[string]struct{}{
+ "AD-02": {}, "AD-03": {}, "AD-04": {}, "AD-05": {}, "AD-06": {},
+ "AD-07": {}, "AD-08": {}, "AE-AJ": {}, "AE-AZ": {}, "AE-DU": {},
+ "AE-FU": {}, "AE-RK": {}, "AE-SH": {}, "AE-UQ": {}, "AF-BAL": {},
+ "AF-BAM": {}, "AF-BDG": {}, "AF-BDS": {}, "AF-BGL": {}, "AF-DAY": {},
+ "AF-FRA": {}, "AF-FYB": {}, "AF-GHA": {}, "AF-GHO": {}, "AF-HEL": {},
+ "AF-HER": {}, "AF-JOW": {}, "AF-KAB": {}, "AF-KAN": {}, "AF-KAP": {},
+ "AF-KDZ": {}, "AF-KHO": {}, "AF-KNR": {}, "AF-LAG": {}, "AF-LOG": {},
+ "AF-NAN": {}, "AF-NIM": {}, "AF-NUR": {}, "AF-PAN": {}, "AF-PAR": {},
+ "AF-PIA": {}, "AF-PKA": {}, "AF-SAM": {}, "AF-SAR": {}, "AF-TAK": {},
+ "AF-URU": {}, "AF-WAR": {}, "AF-ZAB": {}, "AG-03": {}, "AG-04": {},
+ "AG-05": {}, "AG-06": {}, "AG-07": {}, "AG-08": {}, "AG-10": {},
+ "AG-11": {}, "AL-01": {}, "AL-02": {}, "AL-03": {}, "AL-04": {},
+ "AL-05": {}, "AL-06": {}, "AL-07": {}, "AL-08": {}, "AL-09": {},
+ "AL-10": {}, "AL-11": {}, "AL-12": {}, "AL-BR": {}, "AL-BU": {},
+ "AL-DI": {}, "AL-DL": {}, "AL-DR": {}, "AL-DV": {}, "AL-EL": {},
+ "AL-ER": {}, "AL-FR": {}, "AL-GJ": {}, "AL-GR": {}, "AL-HA": {},
+ "AL-KA": {}, "AL-KB": {}, "AL-KC": {}, "AL-KO": {}, "AL-KR": {},
+ "AL-KU": {}, "AL-LB": {}, "AL-LE": {}, "AL-LU": {}, "AL-MK": {},
+ "AL-MM": {}, "AL-MR": {}, "AL-MT": {}, "AL-PG": {}, "AL-PQ": {},
+ "AL-PR": {}, "AL-PU": {}, "AL-SH": {}, "AL-SK": {}, "AL-SR": {},
+ "AL-TE": {}, "AL-TP": {}, "AL-TR": {}, "AL-VL": {}, "AM-AG": {},
+ "AM-AR": {}, "AM-AV": {}, "AM-ER": {}, "AM-GR": {}, "AM-KT": {},
+ "AM-LO": {}, "AM-SH": {}, "AM-SU": {}, "AM-TV": {}, "AM-VD": {},
+ "AO-BGO": {}, "AO-BGU": {}, "AO-BIE": {}, "AO-CAB": {}, "AO-CCU": {},
+ "AO-CNN": {}, "AO-CNO": {}, "AO-CUS": {}, "AO-HUA": {}, "AO-HUI": {},
+ "AO-LNO": {}, "AO-LSU": {}, "AO-LUA": {}, "AO-MAL": {}, "AO-MOX": {},
+ "AO-NAM": {}, "AO-UIG": {}, "AO-ZAI": {}, "AR-A": {}, "AR-B": {},
+ "AR-C": {}, "AR-D": {}, "AR-E": {}, "AR-F": {}, "AR-G": {}, "AR-H": {},
+ "AR-J": {}, "AR-K": {}, "AR-L": {}, "AR-M": {}, "AR-N": {},
+ "AR-P": {}, "AR-Q": {}, "AR-R": {}, "AR-S": {}, "AR-T": {},
+ "AR-U": {}, "AR-V": {}, "AR-W": {}, "AR-X": {}, "AR-Y": {},
+ "AR-Z": {}, "AT-1": {}, "AT-2": {}, "AT-3": {}, "AT-4": {},
+ "AT-5": {}, "AT-6": {}, "AT-7": {}, "AT-8": {}, "AT-9": {},
+ "AU-ACT": {}, "AU-NSW": {}, "AU-NT": {}, "AU-QLD": {}, "AU-SA": {},
+ "AU-TAS": {}, "AU-VIC": {}, "AU-WA": {}, "AZ-ABS": {}, "AZ-AGA": {},
+ "AZ-AGC": {}, "AZ-AGM": {}, "AZ-AGS": {}, "AZ-AGU": {}, "AZ-AST": {},
+ "AZ-BA": {}, "AZ-BAB": {}, "AZ-BAL": {}, "AZ-BAR": {}, "AZ-BEY": {},
+ "AZ-BIL": {}, "AZ-CAB": {}, "AZ-CAL": {}, "AZ-CUL": {}, "AZ-DAS": {},
+ "AZ-FUZ": {}, "AZ-GA": {}, "AZ-GAD": {}, "AZ-GOR": {}, "AZ-GOY": {},
+ "AZ-GYG": {}, "AZ-HAC": {}, "AZ-IMI": {}, "AZ-ISM": {}, "AZ-KAL": {},
+ "AZ-KAN": {}, "AZ-KUR": {}, "AZ-LA": {}, "AZ-LAC": {}, "AZ-LAN": {},
+ "AZ-LER": {}, "AZ-MAS": {}, "AZ-MI": {}, "AZ-NA": {}, "AZ-NEF": {},
+ "AZ-NV": {}, "AZ-NX": {}, "AZ-OGU": {}, "AZ-ORD": {}, "AZ-QAB": {},
+ "AZ-QAX": {}, "AZ-QAZ": {}, "AZ-QBA": {}, "AZ-QBI": {}, "AZ-QOB": {},
+ "AZ-QUS": {}, "AZ-SA": {}, "AZ-SAB": {}, "AZ-SAD": {}, "AZ-SAH": {},
+ "AZ-SAK": {}, "AZ-SAL": {}, "AZ-SAR": {}, "AZ-SAT": {}, "AZ-SBN": {},
+ "AZ-SIY": {}, "AZ-SKR": {}, "AZ-SM": {}, "AZ-SMI": {}, "AZ-SMX": {},
+ "AZ-SR": {}, "AZ-SUS": {}, "AZ-TAR": {}, "AZ-TOV": {}, "AZ-UCA": {},
+ "AZ-XA": {}, "AZ-XAC": {}, "AZ-XCI": {}, "AZ-XIZ": {}, "AZ-XVD": {},
+ "AZ-YAR": {}, "AZ-YE": {}, "AZ-YEV": {}, "AZ-ZAN": {}, "AZ-ZAQ": {},
+ "AZ-ZAR": {}, "BA-01": {}, "BA-02": {}, "BA-03": {}, "BA-04": {},
+ "BA-05": {}, "BA-06": {}, "BA-07": {}, "BA-08": {}, "BA-09": {},
+ "BA-10": {}, "BA-BIH": {}, "BA-BRC": {}, "BA-SRP": {}, "BB-01": {},
+ "BB-02": {}, "BB-03": {}, "BB-04": {}, "BB-05": {}, "BB-06": {},
+ "BB-07": {}, "BB-08": {}, "BB-09": {}, "BB-10": {}, "BB-11": {},
+ "BD-01": {}, "BD-02": {}, "BD-03": {}, "BD-04": {}, "BD-05": {},
+ "BD-06": {}, "BD-07": {}, "BD-08": {}, "BD-09": {}, "BD-10": {},
+ "BD-11": {}, "BD-12": {}, "BD-13": {}, "BD-14": {}, "BD-15": {},
+ "BD-16": {}, "BD-17": {}, "BD-18": {}, "BD-19": {}, "BD-20": {},
+ "BD-21": {}, "BD-22": {}, "BD-23": {}, "BD-24": {}, "BD-25": {},
+ "BD-26": {}, "BD-27": {}, "BD-28": {}, "BD-29": {}, "BD-30": {},
+ "BD-31": {}, "BD-32": {}, "BD-33": {}, "BD-34": {}, "BD-35": {},
+ "BD-36": {}, "BD-37": {}, "BD-38": {}, "BD-39": {}, "BD-40": {},
+ "BD-41": {}, "BD-42": {}, "BD-43": {}, "BD-44": {}, "BD-45": {},
+ "BD-46": {}, "BD-47": {}, "BD-48": {}, "BD-49": {}, "BD-50": {},
+ "BD-51": {}, "BD-52": {}, "BD-53": {}, "BD-54": {}, "BD-55": {},
+ "BD-56": {}, "BD-57": {}, "BD-58": {}, "BD-59": {}, "BD-60": {},
+ "BD-61": {}, "BD-62": {}, "BD-63": {}, "BD-64": {}, "BD-A": {},
+ "BD-B": {}, "BD-C": {}, "BD-D": {}, "BD-E": {}, "BD-F": {},
+ "BD-G": {}, "BE-BRU": {}, "BE-VAN": {}, "BE-VBR": {}, "BE-VLG": {},
+ "BE-VLI": {}, "BE-VOV": {}, "BE-VWV": {}, "BE-WAL": {}, "BE-WBR": {},
+ "BE-WHT": {}, "BE-WLG": {}, "BE-WLX": {}, "BE-WNA": {}, "BF-01": {},
+ "BF-02": {}, "BF-03": {}, "BF-04": {}, "BF-05": {}, "BF-06": {},
+ "BF-07": {}, "BF-08": {}, "BF-09": {}, "BF-10": {}, "BF-11": {},
+ "BF-12": {}, "BF-13": {}, "BF-BAL": {}, "BF-BAM": {}, "BF-BAN": {},
+ "BF-BAZ": {}, "BF-BGR": {}, "BF-BLG": {}, "BF-BLK": {}, "BF-COM": {},
+ "BF-GAN": {}, "BF-GNA": {}, "BF-GOU": {}, "BF-HOU": {}, "BF-IOB": {},
+ "BF-KAD": {}, "BF-KEN": {}, "BF-KMD": {}, "BF-KMP": {}, "BF-KOP": {},
+ "BF-KOS": {}, "BF-KOT": {}, "BF-KOW": {}, "BF-LER": {}, "BF-LOR": {},
+ "BF-MOU": {}, "BF-NAM": {}, "BF-NAO": {}, "BF-NAY": {}, "BF-NOU": {},
+ "BF-OUB": {}, "BF-OUD": {}, "BF-PAS": {}, "BF-PON": {}, "BF-SEN": {},
+ "BF-SIS": {}, "BF-SMT": {}, "BF-SNG": {}, "BF-SOM": {}, "BF-SOR": {},
+ "BF-TAP": {}, "BF-TUI": {}, "BF-YAG": {}, "BF-YAT": {}, "BF-ZIR": {},
+ "BF-ZON": {}, "BF-ZOU": {}, "BG-01": {}, "BG-02": {}, "BG-03": {},
+ "BG-04": {}, "BG-05": {}, "BG-06": {}, "BG-07": {}, "BG-08": {},
+ "BG-09": {}, "BG-10": {}, "BG-11": {}, "BG-12": {}, "BG-13": {},
+ "BG-14": {}, "BG-15": {}, "BG-16": {}, "BG-17": {}, "BG-18": {},
+ "BG-19": {}, "BG-20": {}, "BG-21": {}, "BG-22": {}, "BG-23": {},
+ "BG-24": {}, "BG-25": {}, "BG-26": {}, "BG-27": {}, "BG-28": {},
+ "BH-13": {}, "BH-14": {}, "BH-15": {}, "BH-16": {}, "BH-17": {},
+ "BI-BB": {}, "BI-BL": {}, "BI-BM": {}, "BI-BR": {}, "BI-CA": {},
+ "BI-CI": {}, "BI-GI": {}, "BI-KI": {}, "BI-KR": {}, "BI-KY": {},
+ "BI-MA": {}, "BI-MU": {}, "BI-MW": {}, "BI-NG": {}, "BI-RM": {}, "BI-RT": {},
+ "BI-RY": {}, "BJ-AK": {}, "BJ-AL": {}, "BJ-AQ": {}, "BJ-BO": {},
+ "BJ-CO": {}, "BJ-DO": {}, "BJ-KO": {}, "BJ-LI": {}, "BJ-MO": {},
+ "BJ-OU": {}, "BJ-PL": {}, "BJ-ZO": {}, "BN-BE": {}, "BN-BM": {},
+ "BN-TE": {}, "BN-TU": {}, "BO-B": {}, "BO-C": {}, "BO-H": {},
+ "BO-L": {}, "BO-N": {}, "BO-O": {}, "BO-P": {}, "BO-S": {},
+ "BO-T": {}, "BQ-BO": {}, "BQ-SA": {}, "BQ-SE": {}, "BR-AC": {},
+ "BR-AL": {}, "BR-AM": {}, "BR-AP": {}, "BR-BA": {}, "BR-CE": {},
+ "BR-DF": {}, "BR-ES": {}, "BR-FN": {}, "BR-GO": {}, "BR-MA": {},
+ "BR-MG": {}, "BR-MS": {}, "BR-MT": {}, "BR-PA": {}, "BR-PB": {},
+ "BR-PE": {}, "BR-PI": {}, "BR-PR": {}, "BR-RJ": {}, "BR-RN": {},
+ "BR-RO": {}, "BR-RR": {}, "BR-RS": {}, "BR-SC": {}, "BR-SE": {},
+ "BR-SP": {}, "BR-TO": {}, "BS-AK": {}, "BS-BI": {}, "BS-BP": {},
+ "BS-BY": {}, "BS-CE": {}, "BS-CI": {}, "BS-CK": {}, "BS-CO": {},
+ "BS-CS": {}, "BS-EG": {}, "BS-EX": {}, "BS-FP": {}, "BS-GC": {},
+ "BS-HI": {}, "BS-HT": {}, "BS-IN": {}, "BS-LI": {}, "BS-MC": {},
+ "BS-MG": {}, "BS-MI": {}, "BS-NE": {}, "BS-NO": {}, "BS-NP": {}, "BS-NS": {},
+ "BS-RC": {}, "BS-RI": {}, "BS-SA": {}, "BS-SE": {}, "BS-SO": {},
+ "BS-SS": {}, "BS-SW": {}, "BS-WG": {}, "BT-11": {}, "BT-12": {},
+ "BT-13": {}, "BT-14": {}, "BT-15": {}, "BT-21": {}, "BT-22": {},
+ "BT-23": {}, "BT-24": {}, "BT-31": {}, "BT-32": {}, "BT-33": {},
+ "BT-34": {}, "BT-41": {}, "BT-42": {}, "BT-43": {}, "BT-44": {},
+ "BT-45": {}, "BT-GA": {}, "BT-TY": {}, "BW-CE": {}, "BW-CH": {}, "BW-GH": {},
+ "BW-KG": {}, "BW-KL": {}, "BW-KW": {}, "BW-NE": {}, "BW-NW": {},
+ "BW-SE": {}, "BW-SO": {}, "BY-BR": {}, "BY-HM": {}, "BY-HO": {},
+ "BY-HR": {}, "BY-MA": {}, "BY-MI": {}, "BY-VI": {}, "BZ-BZ": {},
+ "BZ-CY": {}, "BZ-CZL": {}, "BZ-OW": {}, "BZ-SC": {}, "BZ-TOL": {},
+ "CA-AB": {}, "CA-BC": {}, "CA-MB": {}, "CA-NB": {}, "CA-NL": {},
+ "CA-NS": {}, "CA-NT": {}, "CA-NU": {}, "CA-ON": {}, "CA-PE": {},
+ "CA-QC": {}, "CA-SK": {}, "CA-YT": {}, "CD-BC": {}, "CD-BN": {},
+ "CD-EQ": {}, "CD-HK": {}, "CD-IT": {}, "CD-KA": {}, "CD-KC": {}, "CD-KE": {}, "CD-KG": {}, "CD-KN": {},
+ "CD-KW": {}, "CD-KS": {}, "CD-LU": {}, "CD-MA": {}, "CD-NK": {}, "CD-OR": {}, "CD-SA": {}, "CD-SK": {},
+ "CD-TA": {}, "CD-TO": {}, "CF-AC": {}, "CF-BB": {}, "CF-BGF": {}, "CF-BK": {}, "CF-HK": {}, "CF-HM": {},
+ "CF-HS": {}, "CF-KB": {}, "CF-KG": {}, "CF-LB": {}, "CF-MB": {},
+ "CF-MP": {}, "CF-NM": {}, "CF-OP": {}, "CF-SE": {}, "CF-UK": {},
+ "CF-VK": {}, "CG-11": {}, "CG-12": {}, "CG-13": {}, "CG-14": {},
+ "CG-15": {}, "CG-16": {}, "CG-2": {}, "CG-5": {}, "CG-7": {}, "CG-8": {},
+ "CG-9": {}, "CG-BZV": {}, "CH-AG": {}, "CH-AI": {}, "CH-AR": {},
+ "CH-BE": {}, "CH-BL": {}, "CH-BS": {}, "CH-FR": {}, "CH-GE": {},
+ "CH-GL": {}, "CH-GR": {}, "CH-JU": {}, "CH-LU": {}, "CH-NE": {},
+ "CH-NW": {}, "CH-OW": {}, "CH-SG": {}, "CH-SH": {}, "CH-SO": {},
+ "CH-SZ": {}, "CH-TG": {}, "CH-TI": {}, "CH-UR": {}, "CH-VD": {},
+ "CH-VS": {}, "CH-ZG": {}, "CH-ZH": {}, "CI-AB": {}, "CI-BS": {},
+ "CI-CM": {}, "CI-DN": {}, "CI-GD": {}, "CI-LC": {}, "CI-LG": {},
+ "CI-MG": {}, "CI-SM": {}, "CI-SV": {}, "CI-VB": {}, "CI-WR": {},
+ "CI-YM": {}, "CI-ZZ": {}, "CL-AI": {}, "CL-AN": {}, "CL-AP": {},
+ "CL-AR": {}, "CL-AT": {}, "CL-BI": {}, "CL-CO": {}, "CL-LI": {},
+ "CL-LL": {}, "CL-LR": {}, "CL-MA": {}, "CL-ML": {}, "CL-NB": {}, "CL-RM": {},
+ "CL-TA": {}, "CL-VS": {}, "CM-AD": {}, "CM-CE": {}, "CM-EN": {},
+ "CM-ES": {}, "CM-LT": {}, "CM-NO": {}, "CM-NW": {}, "CM-OU": {},
+ "CM-SU": {}, "CM-SW": {}, "CN-AH": {}, "CN-BJ": {}, "CN-CQ": {},
+ "CN-FJ": {}, "CN-GS": {}, "CN-GD": {}, "CN-GX": {}, "CN-GZ": {},
+ "CN-HI": {}, "CN-HE": {}, "CN-HL": {}, "CN-HA": {}, "CN-HB": {},
+ "CN-HN": {}, "CN-JS": {}, "CN-JX": {}, "CN-JL": {}, "CN-LN": {},
+ "CN-NM": {}, "CN-NX": {}, "CN-QH": {}, "CN-SN": {}, "CN-SD": {}, "CN-SH": {},
+ "CN-SX": {}, "CN-SC": {}, "CN-TJ": {}, "CN-XJ": {}, "CN-XZ": {}, "CN-YN": {},
+ "CN-ZJ": {}, "CO-AMA": {}, "CO-ANT": {}, "CO-ARA": {}, "CO-ATL": {},
+ "CO-BOL": {}, "CO-BOY": {}, "CO-CAL": {}, "CO-CAQ": {}, "CO-CAS": {},
+ "CO-CAU": {}, "CO-CES": {}, "CO-CHO": {}, "CO-COR": {}, "CO-CUN": {},
+ "CO-DC": {}, "CO-GUA": {}, "CO-GUV": {}, "CO-HUI": {}, "CO-LAG": {},
+ "CO-MAG": {}, "CO-MET": {}, "CO-NAR": {}, "CO-NSA": {}, "CO-PUT": {},
+ "CO-QUI": {}, "CO-RIS": {}, "CO-SAN": {}, "CO-SAP": {}, "CO-SUC": {},
+ "CO-TOL": {}, "CO-VAC": {}, "CO-VAU": {}, "CO-VID": {}, "CR-A": {},
+ "CR-C": {}, "CR-G": {}, "CR-H": {}, "CR-L": {}, "CR-P": {},
+ "CR-SJ": {}, "CU-01": {}, "CU-02": {}, "CU-03": {}, "CU-04": {},
+ "CU-05": {}, "CU-06": {}, "CU-07": {}, "CU-08": {}, "CU-09": {},
+ "CU-10": {}, "CU-11": {}, "CU-12": {}, "CU-13": {}, "CU-14": {}, "CU-15": {},
+ "CU-16": {}, "CU-99": {}, "CV-B": {}, "CV-BR": {}, "CV-BV": {}, "CV-CA": {},
+ "CV-CF": {}, "CV-CR": {}, "CV-MA": {}, "CV-MO": {}, "CV-PA": {},
+ "CV-PN": {}, "CV-PR": {}, "CV-RB": {}, "CV-RG": {}, "CV-RS": {},
+ "CV-S": {}, "CV-SD": {}, "CV-SF": {}, "CV-SL": {}, "CV-SM": {},
+ "CV-SO": {}, "CV-SS": {}, "CV-SV": {}, "CV-TA": {}, "CV-TS": {},
+ "CY-01": {}, "CY-02": {}, "CY-03": {}, "CY-04": {}, "CY-05": {},
+ "CY-06": {}, "CZ-10": {}, "CZ-101": {}, "CZ-102": {}, "CZ-103": {},
+ "CZ-104": {}, "CZ-105": {}, "CZ-106": {}, "CZ-107": {}, "CZ-108": {},
+ "CZ-109": {}, "CZ-110": {}, "CZ-111": {}, "CZ-112": {}, "CZ-113": {},
+ "CZ-114": {}, "CZ-115": {}, "CZ-116": {}, "CZ-117": {}, "CZ-118": {},
+ "CZ-119": {}, "CZ-120": {}, "CZ-121": {}, "CZ-122": {}, "CZ-20": {},
+ "CZ-201": {}, "CZ-202": {}, "CZ-203": {}, "CZ-204": {}, "CZ-205": {},
+ "CZ-206": {}, "CZ-207": {}, "CZ-208": {}, "CZ-209": {}, "CZ-20A": {},
+ "CZ-20B": {}, "CZ-20C": {}, "CZ-31": {}, "CZ-311": {}, "CZ-312": {},
+ "CZ-313": {}, "CZ-314": {}, "CZ-315": {}, "CZ-316": {}, "CZ-317": {},
+ "CZ-32": {}, "CZ-321": {}, "CZ-322": {}, "CZ-323": {}, "CZ-324": {},
+ "CZ-325": {}, "CZ-326": {}, "CZ-327": {}, "CZ-41": {}, "CZ-411": {},
+ "CZ-412": {}, "CZ-413": {}, "CZ-42": {}, "CZ-421": {}, "CZ-422": {},
+ "CZ-423": {}, "CZ-424": {}, "CZ-425": {}, "CZ-426": {}, "CZ-427": {},
+ "CZ-51": {}, "CZ-511": {}, "CZ-512": {}, "CZ-513": {}, "CZ-514": {},
+ "CZ-52": {}, "CZ-521": {}, "CZ-522": {}, "CZ-523": {}, "CZ-524": {},
+ "CZ-525": {}, "CZ-53": {}, "CZ-531": {}, "CZ-532": {}, "CZ-533": {},
+ "CZ-534": {}, "CZ-63": {}, "CZ-631": {}, "CZ-632": {}, "CZ-633": {},
+ "CZ-634": {}, "CZ-635": {}, "CZ-64": {}, "CZ-641": {}, "CZ-642": {},
+ "CZ-643": {}, "CZ-644": {}, "CZ-645": {}, "CZ-646": {}, "CZ-647": {},
+ "CZ-71": {}, "CZ-711": {}, "CZ-712": {}, "CZ-713": {}, "CZ-714": {},
+ "CZ-715": {}, "CZ-72": {}, "CZ-721": {}, "CZ-722": {}, "CZ-723": {},
+ "CZ-724": {}, "CZ-80": {}, "CZ-801": {}, "CZ-802": {}, "CZ-803": {},
+ "CZ-804": {}, "CZ-805": {}, "CZ-806": {}, "DE-BB": {}, "DE-BE": {},
+ "DE-BW": {}, "DE-BY": {}, "DE-HB": {}, "DE-HE": {}, "DE-HH": {},
+ "DE-MV": {}, "DE-NI": {}, "DE-NW": {}, "DE-RP": {}, "DE-SH": {},
+ "DE-SL": {}, "DE-SN": {}, "DE-ST": {}, "DE-TH": {}, "DJ-AR": {},
+ "DJ-AS": {}, "DJ-DI": {}, "DJ-DJ": {}, "DJ-OB": {}, "DJ-TA": {},
+ "DK-81": {}, "DK-82": {}, "DK-83": {}, "DK-84": {}, "DK-85": {},
+ "DM-01": {}, "DM-02": {}, "DM-03": {}, "DM-04": {}, "DM-05": {},
+ "DM-06": {}, "DM-07": {}, "DM-08": {}, "DM-09": {}, "DM-10": {},
+ "DO-01": {}, "DO-02": {}, "DO-03": {}, "DO-04": {}, "DO-05": {},
+ "DO-06": {}, "DO-07": {}, "DO-08": {}, "DO-09": {}, "DO-10": {},
+ "DO-11": {}, "DO-12": {}, "DO-13": {}, "DO-14": {}, "DO-15": {},
+ "DO-16": {}, "DO-17": {}, "DO-18": {}, "DO-19": {}, "DO-20": {},
+ "DO-21": {}, "DO-22": {}, "DO-23": {}, "DO-24": {}, "DO-25": {},
+ "DO-26": {}, "DO-27": {}, "DO-28": {}, "DO-29": {}, "DO-30": {}, "DO-31": {},
+ "DZ-01": {}, "DZ-02": {}, "DZ-03": {}, "DZ-04": {}, "DZ-05": {},
+ "DZ-06": {}, "DZ-07": {}, "DZ-08": {}, "DZ-09": {}, "DZ-10": {},
+ "DZ-11": {}, "DZ-12": {}, "DZ-13": {}, "DZ-14": {}, "DZ-15": {},
+ "DZ-16": {}, "DZ-17": {}, "DZ-18": {}, "DZ-19": {}, "DZ-20": {},
+ "DZ-21": {}, "DZ-22": {}, "DZ-23": {}, "DZ-24": {}, "DZ-25": {},
+ "DZ-26": {}, "DZ-27": {}, "DZ-28": {}, "DZ-29": {}, "DZ-30": {},
+ "DZ-31": {}, "DZ-32": {}, "DZ-33": {}, "DZ-34": {}, "DZ-35": {},
+ "DZ-36": {}, "DZ-37": {}, "DZ-38": {}, "DZ-39": {}, "DZ-40": {},
+ "DZ-41": {}, "DZ-42": {}, "DZ-43": {}, "DZ-44": {}, "DZ-45": {},
+ "DZ-46": {}, "DZ-47": {}, "DZ-48": {}, "DZ-49": {}, "DZ-51": {},
+ "DZ-53": {}, "DZ-55": {}, "DZ-56": {}, "DZ-57": {}, "EC-A": {}, "EC-B": {},
+ "EC-C": {}, "EC-D": {}, "EC-E": {}, "EC-F": {}, "EC-G": {},
+ "EC-H": {}, "EC-I": {}, "EC-L": {}, "EC-M": {}, "EC-N": {},
+ "EC-O": {}, "EC-P": {}, "EC-R": {}, "EC-S": {}, "EC-SD": {},
+ "EC-SE": {}, "EC-T": {}, "EC-U": {}, "EC-W": {}, "EC-X": {},
+ "EC-Y": {}, "EC-Z": {}, "EE-37": {}, "EE-39": {}, "EE-44": {}, "EE-45": {},
+ "EE-49": {}, "EE-50": {}, "EE-51": {}, "EE-52": {}, "EE-56": {}, "EE-57": {},
+ "EE-59": {}, "EE-60": {}, "EE-64": {}, "EE-65": {}, "EE-67": {}, "EE-68": {},
+ "EE-70": {}, "EE-71": {}, "EE-74": {}, "EE-78": {}, "EE-79": {}, "EE-81": {}, "EE-82": {},
+ "EE-84": {}, "EE-86": {}, "EE-87": {}, "EG-ALX": {}, "EG-ASN": {}, "EG-AST": {},
+ "EG-BA": {}, "EG-BH": {}, "EG-BNS": {}, "EG-C": {}, "EG-DK": {},
+ "EG-DT": {}, "EG-FYM": {}, "EG-GH": {}, "EG-GZ": {}, "EG-HU": {},
+ "EG-IS": {}, "EG-JS": {}, "EG-KB": {}, "EG-KFS": {}, "EG-KN": {},
+ "EG-LX": {}, "EG-MN": {}, "EG-MNF": {}, "EG-MT": {}, "EG-PTS": {}, "EG-SHG": {},
+ "EG-SHR": {}, "EG-SIN": {}, "EG-SU": {}, "EG-SUZ": {}, "EG-WAD": {},
+ "ER-AN": {}, "ER-DK": {}, "ER-DU": {}, "ER-GB": {}, "ER-MA": {},
+ "ER-SK": {}, "ES-A": {}, "ES-AB": {}, "ES-AL": {}, "ES-AN": {},
+ "ES-AR": {}, "ES-AS": {}, "ES-AV": {}, "ES-B": {}, "ES-BA": {},
+ "ES-BI": {}, "ES-BU": {}, "ES-C": {}, "ES-CA": {}, "ES-CB": {},
+ "ES-CC": {}, "ES-CE": {}, "ES-CL": {}, "ES-CM": {}, "ES-CN": {},
+ "ES-CO": {}, "ES-CR": {}, "ES-CS": {}, "ES-CT": {}, "ES-CU": {},
+ "ES-EX": {}, "ES-GA": {}, "ES-GC": {}, "ES-GI": {}, "ES-GR": {},
+ "ES-GU": {}, "ES-H": {}, "ES-HU": {}, "ES-IB": {}, "ES-J": {},
+ "ES-L": {}, "ES-LE": {}, "ES-LO": {}, "ES-LU": {}, "ES-M": {},
+ "ES-MA": {}, "ES-MC": {}, "ES-MD": {}, "ES-ML": {}, "ES-MU": {},
+ "ES-NA": {}, "ES-NC": {}, "ES-O": {}, "ES-OR": {}, "ES-P": {},
+ "ES-PM": {}, "ES-PO": {}, "ES-PV": {}, "ES-RI": {}, "ES-S": {},
+ "ES-SA": {}, "ES-SE": {}, "ES-SG": {}, "ES-SO": {}, "ES-SS": {},
+ "ES-T": {}, "ES-TE": {}, "ES-TF": {}, "ES-TO": {}, "ES-V": {},
+ "ES-VA": {}, "ES-VC": {}, "ES-VI": {}, "ES-Z": {}, "ES-ZA": {},
+ "ET-AA": {}, "ET-AF": {}, "ET-AM": {}, "ET-BE": {}, "ET-DD": {},
+ "ET-GA": {}, "ET-HA": {}, "ET-OR": {}, "ET-SN": {}, "ET-SO": {},
+ "ET-TI": {}, "FI-01": {}, "FI-02": {}, "FI-03": {}, "FI-04": {},
+ "FI-05": {}, "FI-06": {}, "FI-07": {}, "FI-08": {}, "FI-09": {},
+ "FI-10": {}, "FI-11": {}, "FI-12": {}, "FI-13": {}, "FI-14": {},
+ "FI-15": {}, "FI-16": {}, "FI-17": {}, "FI-18": {}, "FI-19": {},
+ "FJ-C": {}, "FJ-E": {}, "FJ-N": {}, "FJ-R": {}, "FJ-W": {},
+ "FM-KSA": {}, "FM-PNI": {}, "FM-TRK": {}, "FM-YAP": {}, "FR-01": {},
+ "FR-02": {}, "FR-03": {}, "FR-04": {}, "FR-05": {}, "FR-06": {},
+ "FR-07": {}, "FR-08": {}, "FR-09": {}, "FR-10": {}, "FR-11": {},
+ "FR-12": {}, "FR-13": {}, "FR-14": {}, "FR-15": {}, "FR-16": {},
+ "FR-17": {}, "FR-18": {}, "FR-19": {}, "FR-20R": {}, "FR-21": {}, "FR-22": {},
+ "FR-23": {}, "FR-24": {}, "FR-25": {}, "FR-26": {}, "FR-27": {},
+ "FR-28": {}, "FR-29": {}, "FR-2A": {}, "FR-2B": {}, "FR-30": {},
+ "FR-31": {}, "FR-32": {}, "FR-33": {}, "FR-34": {}, "FR-35": {},
+ "FR-36": {}, "FR-37": {}, "FR-38": {}, "FR-39": {}, "FR-40": {},
+ "FR-41": {}, "FR-42": {}, "FR-43": {}, "FR-44": {}, "FR-45": {},
+ "FR-46": {}, "FR-47": {}, "FR-48": {}, "FR-49": {}, "FR-50": {},
+ "FR-51": {}, "FR-52": {}, "FR-53": {}, "FR-54": {}, "FR-55": {},
+ "FR-56": {}, "FR-57": {}, "FR-58": {}, "FR-59": {}, "FR-60": {},
+ "FR-61": {}, "FR-62": {}, "FR-63": {}, "FR-64": {}, "FR-65": {},
+ "FR-66": {}, "FR-67": {}, "FR-68": {}, "FR-69": {}, "FR-70": {},
+ "FR-71": {}, "FR-72": {}, "FR-73": {}, "FR-74": {}, "FR-75": {},
+ "FR-76": {}, "FR-77": {}, "FR-78": {}, "FR-79": {}, "FR-80": {},
+ "FR-81": {}, "FR-82": {}, "FR-83": {}, "FR-84": {}, "FR-85": {},
+ "FR-86": {}, "FR-87": {}, "FR-88": {}, "FR-89": {}, "FR-90": {},
+ "FR-91": {}, "FR-92": {}, "FR-93": {}, "FR-94": {}, "FR-95": {},
+ "FR-ARA": {}, "FR-BFC": {}, "FR-BL": {}, "FR-BRE": {}, "FR-COR": {},
+ "FR-CP": {}, "FR-CVL": {}, "FR-GES": {}, "FR-GF": {}, "FR-GP": {},
+ "FR-GUA": {}, "FR-HDF": {}, "FR-IDF": {}, "FR-LRE": {}, "FR-MAY": {},
+ "FR-MF": {}, "FR-MQ": {}, "FR-NAQ": {}, "FR-NC": {}, "FR-NOR": {},
+ "FR-OCC": {}, "FR-PAC": {}, "FR-PDL": {}, "FR-PF": {}, "FR-PM": {},
+ "FR-RE": {}, "FR-TF": {}, "FR-WF": {}, "FR-YT": {}, "GA-1": {},
+ "GA-2": {}, "GA-3": {}, "GA-4": {}, "GA-5": {}, "GA-6": {},
+ "GA-7": {}, "GA-8": {}, "GA-9": {}, "GB-ABC": {}, "GB-ABD": {},
+ "GB-ABE": {}, "GB-AGB": {}, "GB-AGY": {}, "GB-AND": {}, "GB-ANN": {},
+ "GB-ANS": {}, "GB-BAS": {}, "GB-BBD": {}, "GB-BDF": {}, "GB-BDG": {},
+ "GB-BEN": {}, "GB-BEX": {}, "GB-BFS": {}, "GB-BGE": {}, "GB-BGW": {},
+ "GB-BIR": {}, "GB-BKM": {}, "GB-BMH": {}, "GB-BNE": {}, "GB-BNH": {},
+ "GB-BNS": {}, "GB-BOL": {}, "GB-BPL": {}, "GB-BRC": {}, "GB-BRD": {},
+ "GB-BRY": {}, "GB-BST": {}, "GB-BUR": {}, "GB-CAM": {}, "GB-CAY": {},
+ "GB-CBF": {}, "GB-CCG": {}, "GB-CGN": {}, "GB-CHE": {}, "GB-CHW": {},
+ "GB-CLD": {}, "GB-CLK": {}, "GB-CMA": {}, "GB-CMD": {}, "GB-CMN": {},
+ "GB-CON": {}, "GB-COV": {}, "GB-CRF": {}, "GB-CRY": {}, "GB-CWY": {},
+ "GB-DAL": {}, "GB-DBY": {}, "GB-DEN": {}, "GB-DER": {}, "GB-DEV": {},
+ "GB-DGY": {}, "GB-DNC": {}, "GB-DND": {}, "GB-DOR": {}, "GB-DRS": {},
+ "GB-DUD": {}, "GB-DUR": {}, "GB-EAL": {}, "GB-EAW": {}, "GB-EAY": {},
+ "GB-EDH": {}, "GB-EDU": {}, "GB-ELN": {}, "GB-ELS": {}, "GB-ENF": {},
+ "GB-ENG": {}, "GB-ERW": {}, "GB-ERY": {}, "GB-ESS": {}, "GB-ESX": {},
+ "GB-FAL": {}, "GB-FIF": {}, "GB-FLN": {}, "GB-FMO": {}, "GB-GAT": {},
+ "GB-GBN": {}, "GB-GLG": {}, "GB-GLS": {}, "GB-GRE": {}, "GB-GWN": {},
+ "GB-HAL": {}, "GB-HAM": {}, "GB-HAV": {}, "GB-HCK": {}, "GB-HEF": {},
+ "GB-HIL": {}, "GB-HLD": {}, "GB-HMF": {}, "GB-HNS": {}, "GB-HPL": {},
+ "GB-HRT": {}, "GB-HRW": {}, "GB-HRY": {}, "GB-IOS": {}, "GB-IOW": {},
+ "GB-ISL": {}, "GB-IVC": {}, "GB-KEC": {}, "GB-KEN": {}, "GB-KHL": {},
+ "GB-KIR": {}, "GB-KTT": {}, "GB-KWL": {}, "GB-LAN": {}, "GB-LBC": {},
+ "GB-LBH": {}, "GB-LCE": {}, "GB-LDS": {}, "GB-LEC": {}, "GB-LEW": {},
+ "GB-LIN": {}, "GB-LIV": {}, "GB-LND": {}, "GB-LUT": {}, "GB-MAN": {},
+ "GB-MDB": {}, "GB-MDW": {}, "GB-MEA": {}, "GB-MIK": {}, "GD-01": {},
+ "GB-MLN": {}, "GB-MON": {}, "GB-MRT": {}, "GB-MRY": {}, "GB-MTY": {},
+ "GB-MUL": {}, "GB-NAY": {}, "GB-NBL": {}, "GB-NEL": {}, "GB-NET": {},
+ "GB-NFK": {}, "GB-NGM": {}, "GB-NIR": {}, "GB-NLK": {}, "GB-NLN": {},
+ "GB-NMD": {}, "GB-NSM": {}, "GB-NTH": {}, "GB-NTL": {}, "GB-NTT": {},
+ "GB-NTY": {}, "GB-NWM": {}, "GB-NWP": {}, "GB-NYK": {}, "GB-OLD": {},
+ "GB-ORK": {}, "GB-OXF": {}, "GB-PEM": {}, "GB-PKN": {}, "GB-PLY": {},
+ "GB-POL": {}, "GB-POR": {}, "GB-POW": {}, "GB-PTE": {}, "GB-RCC": {},
+ "GB-RCH": {}, "GB-RCT": {}, "GB-RDB": {}, "GB-RDG": {}, "GB-RFW": {},
+ "GB-RIC": {}, "GB-ROT": {}, "GB-RUT": {}, "GB-SAW": {}, "GB-SAY": {},
+ "GB-SCB": {}, "GB-SCT": {}, "GB-SFK": {}, "GB-SFT": {}, "GB-SGC": {},
+ "GB-SHF": {}, "GB-SHN": {}, "GB-SHR": {}, "GB-SKP": {}, "GB-SLF": {},
+ "GB-SLG": {}, "GB-SLK": {}, "GB-SND": {}, "GB-SOL": {}, "GB-SOM": {},
+ "GB-SOS": {}, "GB-SRY": {}, "GB-STE": {}, "GB-STG": {}, "GB-STH": {},
+ "GB-STN": {}, "GB-STS": {}, "GB-STT": {}, "GB-STY": {}, "GB-SWA": {},
+ "GB-SWD": {}, "GB-SWK": {}, "GB-TAM": {}, "GB-TFW": {}, "GB-THR": {},
+ "GB-TOB": {}, "GB-TOF": {}, "GB-TRF": {}, "GB-TWH": {}, "GB-UKM": {},
+ "GB-VGL": {}, "GB-WAR": {}, "GB-WBK": {}, "GB-WDU": {}, "GB-WFT": {},
+ "GB-WGN": {}, "GB-WIL": {}, "GB-WKF": {}, "GB-WLL": {}, "GB-WLN": {},
+ "GB-WLS": {}, "GB-WLV": {}, "GB-WND": {}, "GB-WNM": {}, "GB-WOK": {},
+ "GB-WOR": {}, "GB-WRL": {}, "GB-WRT": {}, "GB-WRX": {}, "GB-WSM": {},
+ "GB-WSX": {}, "GB-YOR": {}, "GB-ZET": {}, "GD-02": {}, "GD-03": {},
+ "GD-04": {}, "GD-05": {}, "GD-06": {}, "GD-10": {}, "GE-AB": {},
+ "GE-AJ": {}, "GE-GU": {}, "GE-IM": {}, "GE-KA": {}, "GE-KK": {},
+ "GE-MM": {}, "GE-RL": {}, "GE-SJ": {}, "GE-SK": {}, "GE-SZ": {},
+ "GE-TB": {}, "GH-AA": {}, "GH-AH": {}, "GH-AF": {}, "GH-BA": {}, "GH-BO": {}, "GH-BE": {}, "GH-CP": {},
+ "GH-EP": {}, "GH-NP": {}, "GH-TV": {}, "GH-UE": {}, "GH-UW": {},
+ "GH-WP": {}, "GL-AV": {}, "GL-KU": {}, "GL-QA": {}, "GL-QT": {}, "GL-QE": {}, "GL-SM": {},
+ "GM-B": {}, "GM-L": {}, "GM-M": {}, "GM-N": {}, "GM-U": {},
+ "GM-W": {}, "GN-B": {}, "GN-BE": {}, "GN-BF": {}, "GN-BK": {},
+ "GN-C": {}, "GN-CO": {}, "GN-D": {}, "GN-DB": {}, "GN-DI": {},
+ "GN-DL": {}, "GN-DU": {}, "GN-F": {}, "GN-FA": {}, "GN-FO": {},
+ "GN-FR": {}, "GN-GA": {}, "GN-GU": {}, "GN-K": {}, "GN-KA": {},
+ "GN-KB": {}, "GN-KD": {}, "GN-KE": {}, "GN-KN": {}, "GN-KO": {},
+ "GN-KS": {}, "GN-L": {}, "GN-LA": {}, "GN-LE": {}, "GN-LO": {},
+ "GN-M": {}, "GN-MC": {}, "GN-MD": {}, "GN-ML": {}, "GN-MM": {},
+ "GN-N": {}, "GN-NZ": {}, "GN-PI": {}, "GN-SI": {}, "GN-TE": {},
+ "GN-TO": {}, "GN-YO": {}, "GQ-AN": {}, "GQ-BN": {}, "GQ-BS": {},
+ "GQ-C": {}, "GQ-CS": {}, "GQ-I": {}, "GQ-KN": {}, "GQ-LI": {},
+ "GQ-WN": {}, "GR-01": {}, "GR-03": {}, "GR-04": {}, "GR-05": {},
+ "GR-06": {}, "GR-07": {}, "GR-11": {}, "GR-12": {}, "GR-13": {},
+ "GR-14": {}, "GR-15": {}, "GR-16": {}, "GR-17": {}, "GR-21": {},
+ "GR-22": {}, "GR-23": {}, "GR-24": {}, "GR-31": {}, "GR-32": {},
+ "GR-33": {}, "GR-34": {}, "GR-41": {}, "GR-42": {}, "GR-43": {},
+ "GR-44": {}, "GR-51": {}, "GR-52": {}, "GR-53": {}, "GR-54": {},
+ "GR-55": {}, "GR-56": {}, "GR-57": {}, "GR-58": {}, "GR-59": {},
+ "GR-61": {}, "GR-62": {}, "GR-63": {}, "GR-64": {}, "GR-69": {},
+ "GR-71": {}, "GR-72": {}, "GR-73": {}, "GR-81": {}, "GR-82": {},
+ "GR-83": {}, "GR-84": {}, "GR-85": {}, "GR-91": {}, "GR-92": {},
+ "GR-93": {}, "GR-94": {}, "GR-A": {}, "GR-A1": {}, "GR-B": {},
+ "GR-C": {}, "GR-D": {}, "GR-E": {}, "GR-F": {}, "GR-G": {},
+ "GR-H": {}, "GR-I": {}, "GR-J": {}, "GR-K": {}, "GR-L": {},
+ "GR-M": {}, "GT-01": {}, "GT-02": {}, "GT-03": {}, "GT-04": {},
+ "GT-05": {}, "GT-06": {}, "GT-07": {}, "GT-08": {}, "GT-09": {},
+ "GT-10": {}, "GT-11": {}, "GT-12": {}, "GT-13": {}, "GT-14": {},
+ "GT-15": {}, "GT-16": {}, "GT-17": {}, "GT-18": {}, "GT-19": {},
+ "GT-20": {}, "GT-21": {}, "GT-22": {}, "GW-BA": {}, "GW-BL": {},
+ "GW-BM": {}, "GW-BS": {}, "GW-CA": {}, "GW-GA": {}, "GW-L": {},
+ "GW-N": {}, "GW-OI": {}, "GW-QU": {}, "GW-S": {}, "GW-TO": {},
+ "GY-BA": {}, "GY-CU": {}, "GY-DE": {}, "GY-EB": {}, "GY-ES": {},
+ "GY-MA": {}, "GY-PM": {}, "GY-PT": {}, "GY-UD": {}, "GY-UT": {},
+ "HN-AT": {}, "HN-CH": {}, "HN-CL": {}, "HN-CM": {}, "HN-CP": {},
+ "HN-CR": {}, "HN-EP": {}, "HN-FM": {}, "HN-GD": {}, "HN-IB": {},
+ "HN-IN": {}, "HN-LE": {}, "HN-LP": {}, "HN-OC": {}, "HN-OL": {},
+ "HN-SB": {}, "HN-VA": {}, "HN-YO": {}, "HR-01": {}, "HR-02": {},
+ "HR-03": {}, "HR-04": {}, "HR-05": {}, "HR-06": {}, "HR-07": {},
+ "HR-08": {}, "HR-09": {}, "HR-10": {}, "HR-11": {}, "HR-12": {},
+ "HR-13": {}, "HR-14": {}, "HR-15": {}, "HR-16": {}, "HR-17": {},
+ "HR-18": {}, "HR-19": {}, "HR-20": {}, "HR-21": {}, "HT-AR": {},
+ "HT-CE": {}, "HT-GA": {}, "HT-ND": {}, "HT-NE": {}, "HT-NO": {}, "HT-NI": {},
+ "HT-OU": {}, "HT-SD": {}, "HT-SE": {}, "HU-BA": {}, "HU-BC": {},
+ "HU-BE": {}, "HU-BK": {}, "HU-BU": {}, "HU-BZ": {}, "HU-CS": {},
+ "HU-DE": {}, "HU-DU": {}, "HU-EG": {}, "HU-ER": {}, "HU-FE": {},
+ "HU-GS": {}, "HU-GY": {}, "HU-HB": {}, "HU-HE": {}, "HU-HV": {},
+ "HU-JN": {}, "HU-KE": {}, "HU-KM": {}, "HU-KV": {}, "HU-MI": {},
+ "HU-NK": {}, "HU-NO": {}, "HU-NY": {}, "HU-PE": {}, "HU-PS": {},
+ "HU-SD": {}, "HU-SF": {}, "HU-SH": {}, "HU-SK": {}, "HU-SN": {},
+ "HU-SO": {}, "HU-SS": {}, "HU-ST": {}, "HU-SZ": {}, "HU-TB": {},
+ "HU-TO": {}, "HU-VA": {}, "HU-VE": {}, "HU-VM": {}, "HU-ZA": {},
+ "HU-ZE": {}, "ID-AC": {}, "ID-BA": {}, "ID-BB": {}, "ID-BE": {},
+ "ID-BT": {}, "ID-GO": {}, "ID-IJ": {}, "ID-JA": {}, "ID-JB": {},
+ "ID-JI": {}, "ID-JK": {}, "ID-JT": {}, "ID-JW": {}, "ID-KA": {},
+ "ID-KB": {}, "ID-KI": {}, "ID-KU": {}, "ID-KR": {}, "ID-KS": {},
+ "ID-KT": {}, "ID-LA": {}, "ID-MA": {}, "ID-ML": {}, "ID-MU": {},
+ "ID-NB": {}, "ID-NT": {}, "ID-NU": {}, "ID-PA": {}, "ID-PB": {},
+ "ID-PE": {}, "ID-PP": {}, "ID-PS": {}, "ID-PT": {}, "ID-RI": {},
+ "ID-SA": {}, "ID-SB": {}, "ID-SG": {}, "ID-SL": {}, "ID-SM": {},
+ "ID-SN": {}, "ID-SR": {}, "ID-SS": {}, "ID-ST": {}, "ID-SU": {},
+ "ID-YO": {}, "IE-C": {}, "IE-CE": {}, "IE-CN": {}, "IE-CO": {},
+ "IE-CW": {}, "IE-D": {}, "IE-DL": {}, "IE-G": {}, "IE-KE": {},
+ "IE-KK": {}, "IE-KY": {}, "IE-L": {}, "IE-LD": {}, "IE-LH": {},
+ "IE-LK": {}, "IE-LM": {}, "IE-LS": {}, "IE-M": {}, "IE-MH": {},
+ "IE-MN": {}, "IE-MO": {}, "IE-OY": {}, "IE-RN": {}, "IE-SO": {},
+ "IE-TA": {}, "IE-U": {}, "IE-WD": {}, "IE-WH": {}, "IE-WW": {},
+ "IE-WX": {}, "IL-D": {}, "IL-HA": {}, "IL-JM": {}, "IL-M": {},
+ "IL-TA": {}, "IL-Z": {}, "IN-AN": {}, "IN-AP": {}, "IN-AR": {},
+ "IN-AS": {}, "IN-BR": {}, "IN-CH": {}, "IN-CT": {}, "IN-DH": {},
+ "IN-DL": {}, "IN-DN": {}, "IN-GA": {}, "IN-GJ": {}, "IN-HP": {},
+ "IN-HR": {}, "IN-JH": {}, "IN-JK": {}, "IN-KA": {}, "IN-KL": {},
+ "IN-LD": {}, "IN-MH": {}, "IN-ML": {}, "IN-MN": {}, "IN-MP": {},
+ "IN-MZ": {}, "IN-NL": {}, "IN-TG": {}, "IN-OR": {}, "IN-PB": {}, "IN-PY": {},
+ "IN-RJ": {}, "IN-SK": {}, "IN-TN": {}, "IN-TR": {}, "IN-UP": {},
+ "IN-UT": {}, "IN-WB": {}, "IQ-AN": {}, "IQ-AR": {}, "IQ-BA": {},
+ "IQ-BB": {}, "IQ-BG": {}, "IQ-DA": {}, "IQ-DI": {}, "IQ-DQ": {},
+ "IQ-KA": {}, "IQ-KI": {}, "IQ-MA": {}, "IQ-MU": {}, "IQ-NA": {}, "IQ-NI": {},
+ "IQ-QA": {}, "IQ-SD": {}, "IQ-SW": {}, "IQ-SU": {}, "IQ-TS": {}, "IQ-WA": {},
+ "IR-00": {}, "IR-01": {}, "IR-02": {}, "IR-03": {}, "IR-04": {}, "IR-05": {},
+ "IR-06": {}, "IR-07": {}, "IR-08": {}, "IR-09": {}, "IR-10": {}, "IR-11": {},
+ "IR-12": {}, "IR-13": {}, "IR-14": {}, "IR-15": {}, "IR-16": {},
+ "IR-17": {}, "IR-18": {}, "IR-19": {}, "IR-20": {}, "IR-21": {},
+ "IR-22": {}, "IR-23": {}, "IR-24": {}, "IR-25": {}, "IR-26": {},
+ "IR-27": {}, "IR-28": {}, "IR-29": {}, "IR-30": {}, "IR-31": {},
+ "IS-0": {}, "IS-1": {}, "IS-2": {}, "IS-3": {}, "IS-4": {},
+ "IS-5": {}, "IS-6": {}, "IS-7": {}, "IS-8": {}, "IT-21": {},
+ "IT-23": {}, "IT-25": {}, "IT-32": {}, "IT-34": {}, "IT-36": {},
+ "IT-42": {}, "IT-45": {}, "IT-52": {}, "IT-55": {}, "IT-57": {},
+ "IT-62": {}, "IT-65": {}, "IT-67": {}, "IT-72": {}, "IT-75": {},
+ "IT-77": {}, "IT-78": {}, "IT-82": {}, "IT-88": {}, "IT-AG": {},
+ "IT-AL": {}, "IT-AN": {}, "IT-AO": {}, "IT-AP": {}, "IT-AQ": {},
+ "IT-AR": {}, "IT-AT": {}, "IT-AV": {}, "IT-BA": {}, "IT-BG": {},
+ "IT-BI": {}, "IT-BL": {}, "IT-BN": {}, "IT-BO": {}, "IT-BR": {},
+ "IT-BS": {}, "IT-BT": {}, "IT-BZ": {}, "IT-CA": {}, "IT-CB": {},
+ "IT-CE": {}, "IT-CH": {}, "IT-CI": {}, "IT-CL": {}, "IT-CN": {},
+ "IT-CO": {}, "IT-CR": {}, "IT-CS": {}, "IT-CT": {}, "IT-CZ": {},
+ "IT-EN": {}, "IT-FC": {}, "IT-FE": {}, "IT-FG": {}, "IT-FI": {},
+ "IT-FM": {}, "IT-FR": {}, "IT-GE": {}, "IT-GO": {}, "IT-GR": {},
+ "IT-IM": {}, "IT-IS": {}, "IT-KR": {}, "IT-LC": {}, "IT-LE": {},
+ "IT-LI": {}, "IT-LO": {}, "IT-LT": {}, "IT-LU": {}, "IT-MB": {},
+ "IT-MC": {}, "IT-ME": {}, "IT-MI": {}, "IT-MN": {}, "IT-MO": {},
+ "IT-MS": {}, "IT-MT": {}, "IT-NA": {}, "IT-NO": {}, "IT-NU": {},
+ "IT-OG": {}, "IT-OR": {}, "IT-OT": {}, "IT-PA": {}, "IT-PC": {},
+ "IT-PD": {}, "IT-PE": {}, "IT-PG": {}, "IT-PI": {}, "IT-PN": {},
+ "IT-PO": {}, "IT-PR": {}, "IT-PT": {}, "IT-PU": {}, "IT-PV": {},
+ "IT-PZ": {}, "IT-RA": {}, "IT-RC": {}, "IT-RE": {}, "IT-RG": {},
+ "IT-RI": {}, "IT-RM": {}, "IT-RN": {}, "IT-RO": {}, "IT-SA": {},
+ "IT-SI": {}, "IT-SO": {}, "IT-SP": {}, "IT-SR": {}, "IT-SS": {},
+ "IT-SV": {}, "IT-TA": {}, "IT-TE": {}, "IT-TN": {}, "IT-TO": {},
+ "IT-TP": {}, "IT-TR": {}, "IT-TS": {}, "IT-TV": {}, "IT-UD": {},
+ "IT-VA": {}, "IT-VB": {}, "IT-VC": {}, "IT-VE": {}, "IT-VI": {},
+ "IT-VR": {}, "IT-VS": {}, "IT-VT": {}, "IT-VV": {}, "JM-01": {},
+ "JM-02": {}, "JM-03": {}, "JM-04": {}, "JM-05": {}, "JM-06": {},
+ "JM-07": {}, "JM-08": {}, "JM-09": {}, "JM-10": {}, "JM-11": {},
+ "JM-12": {}, "JM-13": {}, "JM-14": {}, "JO-AJ": {}, "JO-AM": {},
+ "JO-AQ": {}, "JO-AT": {}, "JO-AZ": {}, "JO-BA": {}, "JO-IR": {},
+ "JO-JA": {}, "JO-KA": {}, "JO-MA": {}, "JO-MD": {}, "JO-MN": {},
+ "JP-01": {}, "JP-02": {}, "JP-03": {}, "JP-04": {}, "JP-05": {},
+ "JP-06": {}, "JP-07": {}, "JP-08": {}, "JP-09": {}, "JP-10": {},
+ "JP-11": {}, "JP-12": {}, "JP-13": {}, "JP-14": {}, "JP-15": {},
+ "JP-16": {}, "JP-17": {}, "JP-18": {}, "JP-19": {}, "JP-20": {},
+ "JP-21": {}, "JP-22": {}, "JP-23": {}, "JP-24": {}, "JP-25": {},
+ "JP-26": {}, "JP-27": {}, "JP-28": {}, "JP-29": {}, "JP-30": {},
+ "JP-31": {}, "JP-32": {}, "JP-33": {}, "JP-34": {}, "JP-35": {},
+ "JP-36": {}, "JP-37": {}, "JP-38": {}, "JP-39": {}, "JP-40": {},
+ "JP-41": {}, "JP-42": {}, "JP-43": {}, "JP-44": {}, "JP-45": {},
+ "JP-46": {}, "JP-47": {}, "KE-01": {}, "KE-02": {}, "KE-03": {},
+ "KE-04": {}, "KE-05": {}, "KE-06": {}, "KE-07": {}, "KE-08": {},
+ "KE-09": {}, "KE-10": {}, "KE-11": {}, "KE-12": {}, "KE-13": {},
+ "KE-14": {}, "KE-15": {}, "KE-16": {}, "KE-17": {}, "KE-18": {},
+ "KE-19": {}, "KE-20": {}, "KE-21": {}, "KE-22": {}, "KE-23": {},
+ "KE-24": {}, "KE-25": {}, "KE-26": {}, "KE-27": {}, "KE-28": {},
+ "KE-29": {}, "KE-30": {}, "KE-31": {}, "KE-32": {}, "KE-33": {},
+ "KE-34": {}, "KE-35": {}, "KE-36": {}, "KE-37": {}, "KE-38": {},
+ "KE-39": {}, "KE-40": {}, "KE-41": {}, "KE-42": {}, "KE-43": {},
+ "KE-44": {}, "KE-45": {}, "KE-46": {}, "KE-47": {}, "KG-B": {},
+ "KG-C": {}, "KG-GB": {}, "KG-GO": {}, "KG-J": {}, "KG-N": {}, "KG-O": {},
+ "KG-T": {}, "KG-Y": {}, "KH-1": {}, "KH-10": {}, "KH-11": {},
+ "KH-12": {}, "KH-13": {}, "KH-14": {}, "KH-15": {}, "KH-16": {},
+ "KH-17": {}, "KH-18": {}, "KH-19": {}, "KH-2": {}, "KH-20": {},
+ "KH-21": {}, "KH-22": {}, "KH-23": {}, "KH-24": {}, "KH-3": {},
+ "KH-4": {}, "KH-5": {}, "KH-6": {}, "KH-7": {}, "KH-8": {},
+ "KH-9": {}, "KI-G": {}, "KI-L": {}, "KI-P": {}, "KM-A": {},
+ "KM-G": {}, "KM-M": {}, "KN-01": {}, "KN-02": {}, "KN-03": {},
+ "KN-04": {}, "KN-05": {}, "KN-06": {}, "KN-07": {}, "KN-08": {},
+ "KN-09": {}, "KN-10": {}, "KN-11": {}, "KN-12": {}, "KN-13": {},
+ "KN-15": {}, "KN-K": {}, "KN-N": {}, "KP-01": {}, "KP-02": {},
+ "KP-03": {}, "KP-04": {}, "KP-05": {}, "KP-06": {}, "KP-07": {},
+ "KP-08": {}, "KP-09": {}, "KP-10": {}, "KP-13": {}, "KR-11": {},
+ "KR-26": {}, "KR-27": {}, "KR-28": {}, "KR-29": {}, "KR-30": {},
+ "KR-31": {}, "KR-41": {}, "KR-42": {}, "KR-43": {}, "KR-44": {},
+ "KR-45": {}, "KR-46": {}, "KR-47": {}, "KR-48": {}, "KR-49": {},
+ "KW-AH": {}, "KW-FA": {}, "KW-HA": {}, "KW-JA": {}, "KW-KU": {},
+ "KW-MU": {}, "KZ-10": {}, "KZ-75": {}, "KZ-19": {}, "KZ-11": {},
+ "KZ-15": {}, "KZ-71": {}, "KZ-23": {}, "KZ-27": {}, "KZ-47": {},
+ "KZ-55": {}, "KZ-35": {}, "KZ-39": {}, "KZ-43": {}, "KZ-63": {},
+ "KZ-79": {}, "KZ-59": {}, "KZ-61": {}, "KZ-62": {}, "KZ-31": {},
+ "KZ-33": {}, "LA-AT": {}, "LA-BK": {}, "LA-BL": {},
+ "LA-CH": {}, "LA-HO": {}, "LA-KH": {}, "LA-LM": {}, "LA-LP": {},
+ "LA-OU": {}, "LA-PH": {}, "LA-SL": {}, "LA-SV": {}, "LA-VI": {},
+ "LA-VT": {}, "LA-XA": {}, "LA-XE": {}, "LA-XI": {}, "LA-XS": {},
+ "LB-AK": {}, "LB-AS": {}, "LB-BA": {}, "LB-BH": {}, "LB-BI": {},
+ "LB-JA": {}, "LB-JL": {}, "LB-NA": {}, "LC-01": {}, "LC-02": {},
+ "LC-03": {}, "LC-05": {}, "LC-06": {}, "LC-07": {}, "LC-08": {},
+ "LC-10": {}, "LC-11": {}, "LI-01": {}, "LI-02": {},
+ "LI-03": {}, "LI-04": {}, "LI-05": {}, "LI-06": {}, "LI-07": {},
+ "LI-08": {}, "LI-09": {}, "LI-10": {}, "LI-11": {}, "LK-1": {},
+ "LK-11": {}, "LK-12": {}, "LK-13": {}, "LK-2": {}, "LK-21": {},
+ "LK-22": {}, "LK-23": {}, "LK-3": {}, "LK-31": {}, "LK-32": {},
+ "LK-33": {}, "LK-4": {}, "LK-41": {}, "LK-42": {}, "LK-43": {},
+ "LK-44": {}, "LK-45": {}, "LK-5": {}, "LK-51": {}, "LK-52": {},
+ "LK-53": {}, "LK-6": {}, "LK-61": {}, "LK-62": {}, "LK-7": {},
+ "LK-71": {}, "LK-72": {}, "LK-8": {}, "LK-81": {}, "LK-82": {},
+ "LK-9": {}, "LK-91": {}, "LK-92": {}, "LR-BG": {}, "LR-BM": {},
+ "LR-CM": {}, "LR-GB": {}, "LR-GG": {}, "LR-GK": {}, "LR-LO": {},
+ "LR-MG": {}, "LR-MO": {}, "LR-MY": {}, "LR-NI": {}, "LR-RI": {},
+ "LR-SI": {}, "LS-A": {}, "LS-B": {}, "LS-C": {}, "LS-D": {},
+ "LS-E": {}, "LS-F": {}, "LS-G": {}, "LS-H": {}, "LS-J": {},
+ "LS-K": {}, "LT-AL": {}, "LT-KL": {}, "LT-KU": {}, "LT-MR": {},
+ "LT-PN": {}, "LT-SA": {}, "LT-TA": {}, "LT-TE": {}, "LT-UT": {},
+ "LT-VL": {}, "LU-CA": {}, "LU-CL": {}, "LU-DI": {}, "LU-EC": {},
+ "LU-ES": {}, "LU-GR": {}, "LU-LU": {}, "LU-ME": {}, "LU-RD": {},
+ "LU-RM": {}, "LU-VD": {}, "LU-WI": {}, "LU-D": {}, "LU-G": {}, "LU-L": {},
+ "LV-001": {}, "LV-111": {}, "LV-112": {}, "LV-113": {},
+ "LV-002": {}, "LV-003": {}, "LV-004": {}, "LV-005": {}, "LV-006": {},
+ "LV-007": {}, "LV-008": {}, "LV-009": {}, "LV-010": {}, "LV-011": {},
+ "LV-012": {}, "LV-013": {}, "LV-014": {}, "LV-015": {}, "LV-016": {},
+ "LV-017": {}, "LV-018": {}, "LV-019": {}, "LV-020": {}, "LV-021": {},
+ "LV-022": {}, "LV-023": {}, "LV-024": {}, "LV-025": {}, "LV-026": {},
+ "LV-027": {}, "LV-028": {}, "LV-029": {}, "LV-030": {}, "LV-031": {},
+ "LV-032": {}, "LV-033": {}, "LV-034": {}, "LV-035": {}, "LV-036": {},
+ "LV-037": {}, "LV-038": {}, "LV-039": {}, "LV-040": {}, "LV-041": {},
+ "LV-042": {}, "LV-043": {}, "LV-044": {}, "LV-045": {}, "LV-046": {},
+ "LV-047": {}, "LV-048": {}, "LV-049": {}, "LV-050": {}, "LV-051": {},
+ "LV-052": {}, "LV-053": {}, "LV-054": {}, "LV-055": {}, "LV-056": {},
+ "LV-057": {}, "LV-058": {}, "LV-059": {}, "LV-060": {}, "LV-061": {},
+ "LV-062": {}, "LV-063": {}, "LV-064": {}, "LV-065": {}, "LV-066": {},
+ "LV-067": {}, "LV-068": {}, "LV-069": {}, "LV-070": {}, "LV-071": {},
+ "LV-072": {}, "LV-073": {}, "LV-074": {}, "LV-075": {}, "LV-076": {},
+ "LV-077": {}, "LV-078": {}, "LV-079": {}, "LV-080": {}, "LV-081": {},
+ "LV-082": {}, "LV-083": {}, "LV-084": {}, "LV-085": {}, "LV-086": {},
+ "LV-087": {}, "LV-088": {}, "LV-089": {}, "LV-090": {}, "LV-091": {},
+ "LV-092": {}, "LV-093": {}, "LV-094": {}, "LV-095": {}, "LV-096": {},
+ "LV-097": {}, "LV-098": {}, "LV-099": {}, "LV-100": {}, "LV-101": {},
+ "LV-102": {}, "LV-103": {}, "LV-104": {}, "LV-105": {}, "LV-106": {},
+ "LV-107": {}, "LV-108": {}, "LV-109": {}, "LV-110": {}, "LV-DGV": {},
+ "LV-JEL": {}, "LV-JKB": {}, "LV-JUR": {}, "LV-LPX": {}, "LV-REZ": {},
+ "LV-RIX": {}, "LV-VEN": {}, "LV-VMR": {}, "LY-BA": {}, "LY-BU": {},
+ "LY-DR": {}, "LY-GT": {}, "LY-JA": {}, "LY-JB": {}, "LY-JG": {},
+ "LY-JI": {}, "LY-JU": {}, "LY-KF": {}, "LY-MB": {}, "LY-MI": {},
+ "LY-MJ": {}, "LY-MQ": {}, "LY-NL": {}, "LY-NQ": {}, "LY-SB": {},
+ "LY-SR": {}, "LY-TB": {}, "LY-WA": {}, "LY-WD": {}, "LY-WS": {},
+ "LY-ZA": {}, "MA-01": {}, "MA-02": {}, "MA-03": {}, "MA-04": {},
+ "MA-05": {}, "MA-06": {}, "MA-07": {}, "MA-08": {}, "MA-09": {},
+ "MA-10": {}, "MA-11": {}, "MA-12": {}, "MA-13": {}, "MA-14": {},
+ "MA-15": {}, "MA-16": {}, "MA-AGD": {}, "MA-AOU": {}, "MA-ASZ": {},
+ "MA-AZI": {}, "MA-BEM": {}, "MA-BER": {}, "MA-BES": {}, "MA-BOD": {},
+ "MA-BOM": {}, "MA-CAS": {}, "MA-CHE": {}, "MA-CHI": {}, "MA-CHT": {},
+ "MA-ERR": {}, "MA-ESI": {}, "MA-ESM": {}, "MA-FAH": {}, "MA-FES": {},
+ "MA-FIG": {}, "MA-GUE": {}, "MA-HAJ": {}, "MA-HAO": {}, "MA-HOC": {},
+ "MA-IFR": {}, "MA-INE": {}, "MA-JDI": {}, "MA-JRA": {}, "MA-KEN": {},
+ "MA-KES": {}, "MA-KHE": {}, "MA-KHN": {}, "MA-KHO": {}, "MA-LAA": {},
+ "MA-LAR": {}, "MA-MED": {}, "MA-MEK": {}, "MA-MMD": {}, "MA-MMN": {},
+ "MA-MOH": {}, "MA-MOU": {}, "MA-NAD": {}, "MA-NOU": {}, "MA-OUA": {},
+ "MA-OUD": {}, "MA-OUJ": {}, "MA-RAB": {}, "MA-SAF": {}, "MA-SAL": {},
+ "MA-SEF": {}, "MA-SET": {}, "MA-SIK": {}, "MA-SKH": {}, "MA-SYB": {},
+ "MA-TAI": {}, "MA-TAO": {}, "MA-TAR": {}, "MA-TAT": {}, "MA-TAZ": {},
+ "MA-TET": {}, "MA-TIZ": {}, "MA-TNG": {}, "MA-TNT": {}, "MA-ZAG": {},
+ "MC-CL": {}, "MC-CO": {}, "MC-FO": {}, "MC-GA": {}, "MC-JE": {},
+ "MC-LA": {}, "MC-MA": {}, "MC-MC": {}, "MC-MG": {}, "MC-MO": {},
+ "MC-MU": {}, "MC-PH": {}, "MC-SD": {}, "MC-SO": {}, "MC-SP": {},
+ "MC-SR": {}, "MC-VR": {}, "MD-AN": {}, "MD-BA": {}, "MD-BD": {},
+ "MD-BR": {}, "MD-BS": {}, "MD-CA": {}, "MD-CL": {}, "MD-CM": {},
+ "MD-CR": {}, "MD-CS": {}, "MD-CT": {}, "MD-CU": {}, "MD-DO": {},
+ "MD-DR": {}, "MD-DU": {}, "MD-ED": {}, "MD-FA": {}, "MD-FL": {},
+ "MD-GA": {}, "MD-GL": {}, "MD-HI": {}, "MD-IA": {}, "MD-LE": {},
+ "MD-NI": {}, "MD-OC": {}, "MD-OR": {}, "MD-RE": {}, "MD-RI": {},
+ "MD-SD": {}, "MD-SI": {}, "MD-SN": {}, "MD-SO": {}, "MD-ST": {},
+ "MD-SV": {}, "MD-TA": {}, "MD-TE": {}, "MD-UN": {}, "ME-01": {},
+ "ME-02": {}, "ME-03": {}, "ME-04": {}, "ME-05": {}, "ME-06": {},
+ "ME-07": {}, "ME-08": {}, "ME-09": {}, "ME-10": {}, "ME-11": {},
+ "ME-12": {}, "ME-13": {}, "ME-14": {}, "ME-15": {}, "ME-16": {},
+ "ME-17": {}, "ME-18": {}, "ME-19": {}, "ME-20": {}, "ME-21": {}, "ME-24": {},
+ "MG-A": {}, "MG-D": {}, "MG-F": {}, "MG-M": {}, "MG-T": {},
+ "MG-U": {}, "MH-ALK": {}, "MH-ALL": {}, "MH-ARN": {}, "MH-AUR": {},
+ "MH-EBO": {}, "MH-ENI": {}, "MH-JAB": {}, "MH-JAL": {}, "MH-KIL": {},
+ "MH-KWA": {}, "MH-L": {}, "MH-LAE": {}, "MH-LIB": {}, "MH-LIK": {},
+ "MH-MAJ": {}, "MH-MAL": {}, "MH-MEJ": {}, "MH-MIL": {}, "MH-NMK": {},
+ "MH-NMU": {}, "MH-RON": {}, "MH-T": {}, "MH-UJA": {}, "MH-UTI": {},
+ "MH-WTJ": {}, "MH-WTN": {}, "MK-101": {}, "MK-102": {}, "MK-103": {},
+ "MK-104": {}, "MK-105": {},
+ "MK-106": {}, "MK-107": {}, "MK-108": {}, "MK-109": {}, "MK-201": {},
+ "MK-202": {}, "MK-205": {}, "MK-206": {}, "MK-207": {}, "MK-208": {},
+ "MK-209": {}, "MK-210": {}, "MK-211": {}, "MK-301": {}, "MK-303": {},
+ "MK-307": {}, "MK-308": {}, "MK-310": {}, "MK-311": {}, "MK-312": {},
+ "MK-401": {}, "MK-402": {}, "MK-403": {}, "MK-404": {}, "MK-405": {},
+ "MK-406": {}, "MK-408": {}, "MK-409": {}, "MK-410": {}, "MK-501": {},
+ "MK-502": {}, "MK-503": {}, "MK-505": {}, "MK-506": {}, "MK-507": {},
+ "MK-508": {}, "MK-509": {}, "MK-601": {}, "MK-602": {}, "MK-604": {},
+ "MK-605": {}, "MK-606": {}, "MK-607": {}, "MK-608": {}, "MK-609": {},
+ "MK-701": {}, "MK-702": {}, "MK-703": {}, "MK-704": {}, "MK-705": {},
+ "MK-803": {}, "MK-804": {}, "MK-806": {}, "MK-807": {}, "MK-809": {},
+ "MK-810": {}, "MK-811": {}, "MK-812": {}, "MK-813": {}, "MK-814": {},
+ "MK-816": {}, "ML-1": {}, "ML-2": {}, "ML-3": {}, "ML-4": {},
+ "ML-5": {}, "ML-6": {}, "ML-7": {}, "ML-8": {}, "ML-BKO": {},
+ "MM-01": {}, "MM-02": {}, "MM-03": {}, "MM-04": {}, "MM-05": {},
+ "MM-06": {}, "MM-07": {}, "MM-11": {}, "MM-12": {}, "MM-13": {},
+ "MM-14": {}, "MM-15": {}, "MM-16": {}, "MM-17": {}, "MM-18": {}, "MN-035": {},
+ "MN-037": {}, "MN-039": {}, "MN-041": {}, "MN-043": {}, "MN-046": {},
+ "MN-047": {}, "MN-049": {}, "MN-051": {}, "MN-053": {}, "MN-055": {},
+ "MN-057": {}, "MN-059": {}, "MN-061": {}, "MN-063": {}, "MN-064": {},
+ "MN-065": {}, "MN-067": {}, "MN-069": {}, "MN-071": {}, "MN-073": {},
+ "MN-1": {}, "MR-01": {}, "MR-02": {}, "MR-03": {}, "MR-04": {},
+ "MR-05": {}, "MR-06": {}, "MR-07": {}, "MR-08": {}, "MR-09": {},
+ "MR-10": {}, "MR-11": {}, "MR-12": {}, "MR-13": {}, "MR-NKC": {}, "MT-01": {},
+ "MT-02": {}, "MT-03": {}, "MT-04": {}, "MT-05": {}, "MT-06": {},
+ "MT-07": {}, "MT-08": {}, "MT-09": {}, "MT-10": {}, "MT-11": {},
+ "MT-12": {}, "MT-13": {}, "MT-14": {}, "MT-15": {}, "MT-16": {},
+ "MT-17": {}, "MT-18": {}, "MT-19": {}, "MT-20": {}, "MT-21": {},
+ "MT-22": {}, "MT-23": {}, "MT-24": {}, "MT-25": {}, "MT-26": {},
+ "MT-27": {}, "MT-28": {}, "MT-29": {}, "MT-30": {}, "MT-31": {},
+ "MT-32": {}, "MT-33": {}, "MT-34": {}, "MT-35": {}, "MT-36": {},
+ "MT-37": {}, "MT-38": {}, "MT-39": {}, "MT-40": {}, "MT-41": {},
+ "MT-42": {}, "MT-43": {}, "MT-44": {}, "MT-45": {}, "MT-46": {},
+ "MT-47": {}, "MT-48": {}, "MT-49": {}, "MT-50": {}, "MT-51": {},
+ "MT-52": {}, "MT-53": {}, "MT-54": {}, "MT-55": {}, "MT-56": {},
+ "MT-57": {}, "MT-58": {}, "MT-59": {}, "MT-60": {}, "MT-61": {},
+ "MT-62": {}, "MT-63": {}, "MT-64": {}, "MT-65": {}, "MT-66": {},
+ "MT-67": {}, "MT-68": {}, "MU-AG": {}, "MU-BL": {}, "MU-BR": {},
+ "MU-CC": {}, "MU-CU": {}, "MU-FL": {}, "MU-GP": {}, "MU-MO": {},
+ "MU-PA": {}, "MU-PL": {}, "MU-PU": {}, "MU-PW": {}, "MU-QB": {},
+ "MU-RO": {}, "MU-RP": {}, "MU-RR": {}, "MU-SA": {}, "MU-VP": {}, "MV-00": {},
+ "MV-01": {}, "MV-02": {}, "MV-03": {}, "MV-04": {}, "MV-05": {},
+ "MV-07": {}, "MV-08": {}, "MV-12": {}, "MV-13": {}, "MV-14": {},
+ "MV-17": {}, "MV-20": {}, "MV-23": {}, "MV-24": {}, "MV-25": {},
+ "MV-26": {}, "MV-27": {}, "MV-28": {}, "MV-29": {}, "MV-CE": {},
+ "MV-MLE": {}, "MV-NC": {}, "MV-NO": {}, "MV-SC": {}, "MV-SU": {},
+ "MV-UN": {}, "MV-US": {}, "MW-BA": {}, "MW-BL": {}, "MW-C": {},
+ "MW-CK": {}, "MW-CR": {}, "MW-CT": {}, "MW-DE": {}, "MW-DO": {},
+ "MW-KR": {}, "MW-KS": {}, "MW-LI": {}, "MW-LK": {}, "MW-MC": {},
+ "MW-MG": {}, "MW-MH": {}, "MW-MU": {}, "MW-MW": {}, "MW-MZ": {},
+ "MW-N": {}, "MW-NB": {}, "MW-NE": {}, "MW-NI": {}, "MW-NK": {},
+ "MW-NS": {}, "MW-NU": {}, "MW-PH": {}, "MW-RU": {}, "MW-S": {},
+ "MW-SA": {}, "MW-TH": {}, "MW-ZO": {}, "MX-AGU": {}, "MX-BCN": {},
+ "MX-BCS": {}, "MX-CAM": {}, "MX-CHH": {}, "MX-CHP": {}, "MX-COA": {},
+ "MX-COL": {}, "MX-CMX": {}, "MX-DIF": {}, "MX-DUR": {}, "MX-GRO": {}, "MX-GUA": {},
+ "MX-HID": {}, "MX-JAL": {}, "MX-MEX": {}, "MX-MIC": {}, "MX-MOR": {},
+ "MX-NAY": {}, "MX-NLE": {}, "MX-OAX": {}, "MX-PUE": {}, "MX-QUE": {},
+ "MX-ROO": {}, "MX-SIN": {}, "MX-SLP": {}, "MX-SON": {}, "MX-TAB": {},
+ "MX-TAM": {}, "MX-TLA": {}, "MX-VER": {}, "MX-YUC": {}, "MX-ZAC": {},
+ "MY-01": {}, "MY-02": {}, "MY-03": {}, "MY-04": {}, "MY-05": {},
+ "MY-06": {}, "MY-07": {}, "MY-08": {}, "MY-09": {}, "MY-10": {},
+ "MY-11": {}, "MY-12": {}, "MY-13": {}, "MY-14": {}, "MY-15": {},
+ "MY-16": {}, "MZ-A": {}, "MZ-B": {}, "MZ-G": {}, "MZ-I": {},
+ "MZ-L": {}, "MZ-MPM": {}, "MZ-N": {}, "MZ-P": {}, "MZ-Q": {},
+ "MZ-S": {}, "MZ-T": {}, "NA-CA": {}, "NA-ER": {}, "NA-HA": {},
+ "NA-KA": {}, "NA-KE": {}, "NA-KH": {}, "NA-KU": {}, "NA-KW": {}, "NA-OD": {}, "NA-OH": {},
+ "NA-OK": {}, "NA-ON": {}, "NA-OS": {}, "NA-OT": {}, "NA-OW": {},
+ "NE-1": {}, "NE-2": {}, "NE-3": {}, "NE-4": {}, "NE-5": {},
+ "NE-6": {}, "NE-7": {}, "NE-8": {}, "NG-AB": {}, "NG-AD": {},
+ "NG-AK": {}, "NG-AN": {}, "NG-BA": {}, "NG-BE": {}, "NG-BO": {},
+ "NG-BY": {}, "NG-CR": {}, "NG-DE": {}, "NG-EB": {}, "NG-ED": {},
+ "NG-EK": {}, "NG-EN": {}, "NG-FC": {}, "NG-GO": {}, "NG-IM": {},
+ "NG-JI": {}, "NG-KD": {}, "NG-KE": {}, "NG-KN": {}, "NG-KO": {},
+ "NG-KT": {}, "NG-KW": {}, "NG-LA": {}, "NG-NA": {}, "NG-NI": {},
+ "NG-OG": {}, "NG-ON": {}, "NG-OS": {}, "NG-OY": {}, "NG-PL": {},
+ "NG-RI": {}, "NG-SO": {}, "NG-TA": {}, "NG-YO": {}, "NG-ZA": {},
+ "NI-AN": {}, "NI-AS": {}, "NI-BO": {}, "NI-CA": {}, "NI-CI": {},
+ "NI-CO": {}, "NI-ES": {}, "NI-GR": {}, "NI-JI": {}, "NI-LE": {},
+ "NI-MD": {}, "NI-MN": {}, "NI-MS": {}, "NI-MT": {}, "NI-NS": {},
+ "NI-RI": {}, "NI-SJ": {}, "NL-AW": {}, "NL-BQ1": {}, "NL-BQ2": {},
+ "NL-BQ3": {}, "NL-CW": {}, "NL-DR": {}, "NL-FL": {}, "NL-FR": {},
+ "NL-GE": {}, "NL-GR": {}, "NL-LI": {}, "NL-NB": {}, "NL-NH": {},
+ "NL-OV": {}, "NL-SX": {}, "NL-UT": {}, "NL-ZE": {}, "NL-ZH": {},
+ "NO-03": {}, "NO-11": {}, "NO-15": {}, "NO-16": {}, "NO-17": {},
+ "NO-18": {}, "NO-21": {}, "NO-30": {}, "NO-34": {}, "NO-38": {},
+ "NO-42": {}, "NO-46": {}, "NO-50": {}, "NO-54": {},
+ "NO-22": {}, "NP-1": {}, "NP-2": {}, "NP-3": {}, "NP-4": {},
+ "NP-5": {}, "NP-BA": {}, "NP-BH": {}, "NP-DH": {}, "NP-GA": {},
+ "NP-JA": {}, "NP-KA": {}, "NP-KO": {}, "NP-LU": {}, "NP-MA": {},
+ "NP-ME": {}, "NP-NA": {}, "NP-RA": {}, "NP-SA": {}, "NP-SE": {},
+ "NR-01": {}, "NR-02": {}, "NR-03": {}, "NR-04": {}, "NR-05": {},
+ "NR-06": {}, "NR-07": {}, "NR-08": {}, "NR-09": {}, "NR-10": {},
+ "NR-11": {}, "NR-12": {}, "NR-13": {}, "NR-14": {}, "NZ-AUK": {},
+ "NZ-BOP": {}, "NZ-CAN": {}, "NZ-CIT": {}, "NZ-GIS": {}, "NZ-HKB": {},
+ "NZ-MBH": {}, "NZ-MWT": {}, "NZ-N": {}, "NZ-NSN": {}, "NZ-NTL": {},
+ "NZ-OTA": {}, "NZ-S": {}, "NZ-STL": {}, "NZ-TAS": {}, "NZ-TKI": {},
+ "NZ-WGN": {}, "NZ-WKO": {}, "NZ-WTC": {}, "OM-BA": {}, "OM-BS": {}, "OM-BU": {}, "OM-BJ": {},
+ "OM-DA": {}, "OM-MA": {}, "OM-MU": {}, "OM-SH": {}, "OM-SJ": {}, "OM-SS": {}, "OM-WU": {},
+ "OM-ZA": {}, "OM-ZU": {}, "PA-1": {}, "PA-2": {}, "PA-3": {},
+ "PA-4": {}, "PA-5": {}, "PA-6": {}, "PA-7": {}, "PA-8": {},
+ "PA-9": {}, "PA-EM": {}, "PA-KY": {}, "PA-NB": {}, "PE-AMA": {},
+ "PE-ANC": {}, "PE-APU": {}, "PE-ARE": {}, "PE-AYA": {}, "PE-CAJ": {},
+ "PE-CAL": {}, "PE-CUS": {}, "PE-HUC": {}, "PE-HUV": {}, "PE-ICA": {},
+ "PE-JUN": {}, "PE-LAL": {}, "PE-LAM": {}, "PE-LIM": {}, "PE-LMA": {},
+ "PE-LOR": {}, "PE-MDD": {}, "PE-MOQ": {}, "PE-PAS": {}, "PE-PIU": {},
+ "PE-PUN": {}, "PE-SAM": {}, "PE-TAC": {}, "PE-TUM": {}, "PE-UCA": {},
+ "PG-CPK": {}, "PG-CPM": {}, "PG-EBR": {}, "PG-EHG": {}, "PG-EPW": {},
+ "PG-ESW": {}, "PG-GPK": {}, "PG-MBA": {}, "PG-MPL": {}, "PG-MPM": {},
+ "PG-MRL": {}, "PG-NCD": {}, "PG-NIK": {}, "PG-NPP": {}, "PG-NSB": {},
+ "PG-SAN": {}, "PG-SHM": {}, "PG-WBK": {}, "PG-WHM": {}, "PG-WPD": {},
+ "PH-00": {}, "PH-01": {}, "PH-02": {}, "PH-03": {}, "PH-05": {},
+ "PH-06": {}, "PH-07": {}, "PH-08": {}, "PH-09": {}, "PH-10": {},
+ "PH-11": {}, "PH-12": {}, "PH-13": {}, "PH-14": {}, "PH-15": {},
+ "PH-40": {}, "PH-41": {}, "PH-ABR": {}, "PH-AGN": {}, "PH-AGS": {},
+ "PH-AKL": {}, "PH-ALB": {}, "PH-ANT": {}, "PH-APA": {}, "PH-AUR": {},
+ "PH-BAN": {}, "PH-BAS": {}, "PH-BEN": {}, "PH-BIL": {}, "PH-BOH": {},
+ "PH-BTG": {}, "PH-BTN": {}, "PH-BUK": {}, "PH-BUL": {}, "PH-CAG": {},
+ "PH-CAM": {}, "PH-CAN": {}, "PH-CAP": {}, "PH-CAS": {}, "PH-CAT": {},
+ "PH-CAV": {}, "PH-CEB": {}, "PH-COM": {}, "PH-DAO": {}, "PH-DAS": {},
+ "PH-DAV": {}, "PH-DIN": {}, "PH-EAS": {}, "PH-GUI": {}, "PH-IFU": {},
+ "PH-ILI": {}, "PH-ILN": {}, "PH-ILS": {}, "PH-ISA": {}, "PH-KAL": {},
+ "PH-LAG": {}, "PH-LAN": {}, "PH-LAS": {}, "PH-LEY": {}, "PH-LUN": {},
+ "PH-MAD": {}, "PH-MAG": {}, "PH-MAS": {}, "PH-MDC": {}, "PH-MDR": {},
+ "PH-MOU": {}, "PH-MSC": {}, "PH-MSR": {}, "PH-NCO": {}, "PH-NEC": {},
+ "PH-NER": {}, "PH-NSA": {}, "PH-NUE": {}, "PH-NUV": {}, "PH-PAM": {},
+ "PH-PAN": {}, "PH-PLW": {}, "PH-QUE": {}, "PH-QUI": {}, "PH-RIZ": {},
+ "PH-ROM": {}, "PH-SAR": {}, "PH-SCO": {}, "PH-SIG": {}, "PH-SLE": {},
+ "PH-SLU": {}, "PH-SOR": {}, "PH-SUK": {}, "PH-SUN": {}, "PH-SUR": {},
+ "PH-TAR": {}, "PH-TAW": {}, "PH-WSA": {}, "PH-ZAN": {}, "PH-ZAS": {},
+ "PH-ZMB": {}, "PH-ZSI": {}, "PK-BA": {}, "PK-GB": {}, "PK-IS": {},
+ "PK-JK": {}, "PK-KP": {}, "PK-PB": {}, "PK-SD": {}, "PK-TA": {},
+ "PL-02": {}, "PL-04": {}, "PL-06": {}, "PL-08": {}, "PL-10": {},
+ "PL-12": {}, "PL-14": {}, "PL-16": {}, "PL-18": {}, "PL-20": {},
+ "PL-22": {}, "PL-24": {}, "PL-26": {}, "PL-28": {}, "PL-30": {}, "PL-32": {},
+ "PS-BTH": {}, "PS-DEB": {}, "PS-GZA": {}, "PS-HBN": {},
+ "PS-JEM": {}, "PS-JEN": {}, "PS-JRH": {}, "PS-KYS": {}, "PS-NBS": {},
+ "PS-NGZ": {}, "PS-QQA": {}, "PS-RBH": {}, "PS-RFH": {}, "PS-SLT": {},
+ "PS-TBS": {}, "PS-TKM": {}, "PT-01": {}, "PT-02": {}, "PT-03": {},
+ "PT-04": {}, "PT-05": {}, "PT-06": {}, "PT-07": {}, "PT-08": {},
+ "PT-09": {}, "PT-10": {}, "PT-11": {}, "PT-12": {}, "PT-13": {},
+ "PT-14": {}, "PT-15": {}, "PT-16": {}, "PT-17": {}, "PT-18": {},
+ "PT-20": {}, "PT-30": {}, "PW-002": {}, "PW-004": {}, "PW-010": {},
+ "PW-050": {}, "PW-100": {}, "PW-150": {}, "PW-212": {}, "PW-214": {},
+ "PW-218": {}, "PW-222": {}, "PW-224": {}, "PW-226": {}, "PW-227": {},
+ "PW-228": {}, "PW-350": {}, "PW-370": {}, "PY-1": {}, "PY-10": {},
+ "PY-11": {}, "PY-12": {}, "PY-13": {}, "PY-14": {}, "PY-15": {},
+ "PY-16": {}, "PY-19": {}, "PY-2": {}, "PY-3": {}, "PY-4": {},
+ "PY-5": {}, "PY-6": {}, "PY-7": {}, "PY-8": {}, "PY-9": {},
+ "PY-ASU": {}, "QA-DA": {}, "QA-KH": {}, "QA-MS": {}, "QA-RA": {},
+ "QA-US": {}, "QA-WA": {}, "QA-ZA": {}, "RO-AB": {}, "RO-AG": {},
+ "RO-AR": {}, "RO-B": {}, "RO-BC": {}, "RO-BH": {}, "RO-BN": {},
+ "RO-BR": {}, "RO-BT": {}, "RO-BV": {}, "RO-BZ": {}, "RO-CJ": {},
+ "RO-CL": {}, "RO-CS": {}, "RO-CT": {}, "RO-CV": {}, "RO-DB": {},
+ "RO-DJ": {}, "RO-GJ": {}, "RO-GL": {}, "RO-GR": {}, "RO-HD": {},
+ "RO-HR": {}, "RO-IF": {}, "RO-IL": {}, "RO-IS": {}, "RO-MH": {},
+ "RO-MM": {}, "RO-MS": {}, "RO-NT": {}, "RO-OT": {}, "RO-PH": {},
+ "RO-SB": {}, "RO-SJ": {}, "RO-SM": {}, "RO-SV": {}, "RO-TL": {},
+ "RO-TM": {}, "RO-TR": {}, "RO-VL": {}, "RO-VN": {}, "RO-VS": {},
+ "RS-00": {}, "RS-01": {}, "RS-02": {}, "RS-03": {}, "RS-04": {},
+ "RS-05": {}, "RS-06": {}, "RS-07": {}, "RS-08": {}, "RS-09": {},
+ "RS-10": {}, "RS-11": {}, "RS-12": {}, "RS-13": {}, "RS-14": {},
+ "RS-15": {}, "RS-16": {}, "RS-17": {}, "RS-18": {}, "RS-19": {},
+ "RS-20": {}, "RS-21": {}, "RS-22": {}, "RS-23": {}, "RS-24": {},
+ "RS-25": {}, "RS-26": {}, "RS-27": {}, "RS-28": {}, "RS-29": {},
+ "RS-KM": {}, "RS-VO": {}, "RU-AD": {}, "RU-AL": {}, "RU-ALT": {},
+ "RU-AMU": {}, "RU-ARK": {}, "RU-AST": {}, "RU-BA": {}, "RU-BEL": {},
+ "RU-BRY": {}, "RU-BU": {}, "RU-CE": {}, "RU-CHE": {}, "RU-CHU": {},
+ "RU-CU": {}, "RU-DA": {}, "RU-IN": {}, "RU-IRK": {}, "RU-IVA": {},
+ "RU-KAM": {}, "RU-KB": {}, "RU-KC": {}, "RU-KDA": {}, "RU-KEM": {},
+ "RU-KGD": {}, "RU-KGN": {}, "RU-KHA": {}, "RU-KHM": {}, "RU-KIR": {},
+ "RU-KK": {}, "RU-KL": {}, "RU-KLU": {}, "RU-KO": {}, "RU-KOS": {},
+ "RU-KR": {}, "RU-KRS": {}, "RU-KYA": {}, "RU-LEN": {}, "RU-LIP": {},
+ "RU-MAG": {}, "RU-ME": {}, "RU-MO": {}, "RU-MOS": {}, "RU-MOW": {},
+ "RU-MUR": {}, "RU-NEN": {}, "RU-NGR": {}, "RU-NIZ": {}, "RU-NVS": {},
+ "RU-OMS": {}, "RU-ORE": {}, "RU-ORL": {}, "RU-PER": {}, "RU-PNZ": {},
+ "RU-PRI": {}, "RU-PSK": {}, "RU-ROS": {}, "RU-RYA": {}, "RU-SA": {},
+ "RU-SAK": {}, "RU-SAM": {}, "RU-SAR": {}, "RU-SE": {}, "RU-SMO": {},
+ "RU-SPE": {}, "RU-STA": {}, "RU-SVE": {}, "RU-TA": {}, "RU-TAM": {},
+ "RU-TOM": {}, "RU-TUL": {}, "RU-TVE": {}, "RU-TY": {}, "RU-TYU": {},
+ "RU-UD": {}, "RU-ULY": {}, "RU-VGG": {}, "RU-VLA": {}, "RU-VLG": {},
+ "RU-VOR": {}, "RU-YAN": {}, "RU-YAR": {}, "RU-YEV": {}, "RU-ZAB": {},
+ "RW-01": {}, "RW-02": {}, "RW-03": {}, "RW-04": {}, "RW-05": {},
+ "SA-01": {}, "SA-02": {}, "SA-03": {}, "SA-04": {}, "SA-05": {},
+ "SA-06": {}, "SA-07": {}, "SA-08": {}, "SA-09": {}, "SA-10": {},
+ "SA-11": {}, "SA-12": {}, "SA-14": {}, "SB-CE": {}, "SB-CH": {},
+ "SB-CT": {}, "SB-GU": {}, "SB-IS": {}, "SB-MK": {}, "SB-ML": {},
+ "SB-RB": {}, "SB-TE": {}, "SB-WE": {}, "SC-01": {}, "SC-02": {},
+ "SC-03": {}, "SC-04": {}, "SC-05": {}, "SC-06": {}, "SC-07": {},
+ "SC-08": {}, "SC-09": {}, "SC-10": {}, "SC-11": {}, "SC-12": {},
+ "SC-13": {}, "SC-14": {}, "SC-15": {}, "SC-16": {}, "SC-17": {},
+ "SC-18": {}, "SC-19": {}, "SC-20": {}, "SC-21": {}, "SC-22": {},
+ "SC-23": {}, "SC-24": {}, "SC-25": {}, "SD-DC": {}, "SD-DE": {},
+ "SD-DN": {}, "SD-DS": {}, "SD-DW": {}, "SD-GD": {}, "SD-GK": {}, "SD-GZ": {},
+ "SD-KA": {}, "SD-KH": {}, "SD-KN": {}, "SD-KS": {}, "SD-NB": {},
+ "SD-NO": {}, "SD-NR": {}, "SD-NW": {}, "SD-RS": {}, "SD-SI": {},
+ "SE-AB": {}, "SE-AC": {}, "SE-BD": {}, "SE-C": {}, "SE-D": {},
+ "SE-E": {}, "SE-F": {}, "SE-G": {}, "SE-H": {}, "SE-I": {},
+ "SE-K": {}, "SE-M": {}, "SE-N": {}, "SE-O": {}, "SE-S": {},
+ "SE-T": {}, "SE-U": {}, "SE-W": {}, "SE-X": {}, "SE-Y": {},
+ "SE-Z": {}, "SG-01": {}, "SG-02": {}, "SG-03": {}, "SG-04": {},
+ "SG-05": {}, "SH-AC": {}, "SH-HL": {}, "SH-TA": {}, "SI-001": {},
+ "SI-002": {}, "SI-003": {}, "SI-004": {}, "SI-005": {}, "SI-006": {},
+ "SI-007": {}, "SI-008": {}, "SI-009": {}, "SI-010": {}, "SI-011": {},
+ "SI-012": {}, "SI-013": {}, "SI-014": {}, "SI-015": {}, "SI-016": {},
+ "SI-017": {}, "SI-018": {}, "SI-019": {}, "SI-020": {}, "SI-021": {},
+ "SI-022": {}, "SI-023": {}, "SI-024": {}, "SI-025": {}, "SI-026": {},
+ "SI-027": {}, "SI-028": {}, "SI-029": {}, "SI-030": {}, "SI-031": {},
+ "SI-032": {}, "SI-033": {}, "SI-034": {}, "SI-035": {}, "SI-036": {},
+ "SI-037": {}, "SI-038": {}, "SI-039": {}, "SI-040": {}, "SI-041": {},
+ "SI-042": {}, "SI-043": {}, "SI-044": {}, "SI-045": {}, "SI-046": {},
+ "SI-047": {}, "SI-048": {}, "SI-049": {}, "SI-050": {}, "SI-051": {},
+ "SI-052": {}, "SI-053": {}, "SI-054": {}, "SI-055": {}, "SI-056": {},
+ "SI-057": {}, "SI-058": {}, "SI-059": {}, "SI-060": {}, "SI-061": {},
+ "SI-062": {}, "SI-063": {}, "SI-064": {}, "SI-065": {}, "SI-066": {},
+ "SI-067": {}, "SI-068": {}, "SI-069": {}, "SI-070": {}, "SI-071": {},
+ "SI-072": {}, "SI-073": {}, "SI-074": {}, "SI-075": {}, "SI-076": {},
+ "SI-077": {}, "SI-078": {}, "SI-079": {}, "SI-080": {}, "SI-081": {},
+ "SI-082": {}, "SI-083": {}, "SI-084": {}, "SI-085": {}, "SI-086": {},
+ "SI-087": {}, "SI-088": {}, "SI-089": {}, "SI-090": {}, "SI-091": {},
+ "SI-092": {}, "SI-093": {}, "SI-094": {}, "SI-095": {}, "SI-096": {},
+ "SI-097": {}, "SI-098": {}, "SI-099": {}, "SI-100": {}, "SI-101": {},
+ "SI-102": {}, "SI-103": {}, "SI-104": {}, "SI-105": {}, "SI-106": {},
+ "SI-107": {}, "SI-108": {}, "SI-109": {}, "SI-110": {}, "SI-111": {},
+ "SI-112": {}, "SI-113": {}, "SI-114": {}, "SI-115": {}, "SI-116": {},
+ "SI-117": {}, "SI-118": {}, "SI-119": {}, "SI-120": {}, "SI-121": {},
+ "SI-122": {}, "SI-123": {}, "SI-124": {}, "SI-125": {}, "SI-126": {},
+ "SI-127": {}, "SI-128": {}, "SI-129": {}, "SI-130": {}, "SI-131": {},
+ "SI-132": {}, "SI-133": {}, "SI-134": {}, "SI-135": {}, "SI-136": {},
+ "SI-137": {}, "SI-138": {}, "SI-139": {}, "SI-140": {}, "SI-141": {},
+ "SI-142": {}, "SI-143": {}, "SI-144": {}, "SI-146": {}, "SI-147": {},
+ "SI-148": {}, "SI-149": {}, "SI-150": {}, "SI-151": {}, "SI-152": {},
+ "SI-153": {}, "SI-154": {}, "SI-155": {}, "SI-156": {}, "SI-157": {},
+ "SI-158": {}, "SI-159": {}, "SI-160": {}, "SI-161": {}, "SI-162": {},
+ "SI-163": {}, "SI-164": {}, "SI-165": {}, "SI-166": {}, "SI-167": {},
+ "SI-168": {}, "SI-169": {}, "SI-170": {}, "SI-171": {}, "SI-172": {},
+ "SI-173": {}, "SI-174": {}, "SI-175": {}, "SI-176": {}, "SI-177": {},
+ "SI-178": {}, "SI-179": {}, "SI-180": {}, "SI-181": {}, "SI-182": {},
+ "SI-183": {}, "SI-184": {}, "SI-185": {}, "SI-186": {}, "SI-187": {},
+ "SI-188": {}, "SI-189": {}, "SI-190": {}, "SI-191": {}, "SI-192": {},
+ "SI-193": {}, "SI-194": {}, "SI-195": {}, "SI-196": {}, "SI-197": {},
+ "SI-198": {}, "SI-199": {}, "SI-200": {}, "SI-201": {}, "SI-202": {},
+ "SI-203": {}, "SI-204": {}, "SI-205": {}, "SI-206": {}, "SI-207": {},
+ "SI-208": {}, "SI-209": {}, "SI-210": {}, "SI-211": {}, "SI-212": {}, "SI-213": {}, "SK-BC": {},
+ "SK-BL": {}, "SK-KI": {}, "SK-NI": {}, "SK-PV": {}, "SK-TA": {},
+ "SK-TC": {}, "SK-ZI": {}, "SL-E": {}, "SL-N": {}, "SL-S": {},
+ "SL-W": {}, "SM-01": {}, "SM-02": {}, "SM-03": {}, "SM-04": {},
+ "SM-05": {}, "SM-06": {}, "SM-07": {}, "SM-08": {}, "SM-09": {},
+ "SN-DB": {}, "SN-DK": {}, "SN-FK": {}, "SN-KA": {}, "SN-KD": {},
+ "SN-KE": {}, "SN-KL": {}, "SN-LG": {}, "SN-MT": {}, "SN-SE": {},
+ "SN-SL": {}, "SN-TC": {}, "SN-TH": {}, "SN-ZG": {}, "SO-AW": {},
+ "SO-BK": {}, "SO-BN": {}, "SO-BR": {}, "SO-BY": {}, "SO-GA": {},
+ "SO-GE": {}, "SO-HI": {}, "SO-JD": {}, "SO-JH": {}, "SO-MU": {},
+ "SO-NU": {}, "SO-SA": {}, "SO-SD": {}, "SO-SH": {}, "SO-SO": {},
+ "SO-TO": {}, "SO-WO": {}, "SR-BR": {}, "SR-CM": {}, "SR-CR": {},
+ "SR-MA": {}, "SR-NI": {}, "SR-PM": {}, "SR-PR": {}, "SR-SA": {},
+ "SR-SI": {}, "SR-WA": {}, "SS-BN": {}, "SS-BW": {}, "SS-EC": {},
+ "SS-EE8": {}, "SS-EE": {}, "SS-EW": {}, "SS-JG": {}, "SS-LK": {}, "SS-NU": {},
+ "SS-UY": {}, "SS-WR": {}, "ST-01": {}, "ST-P": {}, "ST-S": {}, "SV-AH": {},
+ "SV-CA": {}, "SV-CH": {}, "SV-CU": {}, "SV-LI": {}, "SV-MO": {},
+ "SV-PA": {}, "SV-SA": {}, "SV-SM": {}, "SV-SO": {}, "SV-SS": {},
+ "SV-SV": {}, "SV-UN": {}, "SV-US": {}, "SY-DI": {}, "SY-DR": {},
+ "SY-DY": {}, "SY-HA": {}, "SY-HI": {}, "SY-HL": {}, "SY-HM": {},
+ "SY-ID": {}, "SY-LA": {}, "SY-QU": {}, "SY-RA": {}, "SY-RD": {},
+ "SY-SU": {}, "SY-TA": {}, "SZ-HH": {}, "SZ-LU": {}, "SZ-MA": {},
+ "SZ-SH": {}, "TD-BA": {}, "TD-BG": {}, "TD-BO": {}, "TD-CB": {},
+ "TD-EN": {}, "TD-GR": {}, "TD-HL": {}, "TD-KA": {}, "TD-LC": {},
+ "TD-LO": {}, "TD-LR": {}, "TD-MA": {}, "TD-MC": {}, "TD-ME": {},
+ "TD-MO": {}, "TD-ND": {}, "TD-OD": {}, "TD-SA": {}, "TD-SI": {},
+ "TD-TA": {}, "TD-TI": {}, "TD-WF": {}, "TG-C": {}, "TG-K": {},
+ "TG-M": {}, "TG-P": {}, "TG-S": {}, "TH-10": {}, "TH-11": {},
+ "TH-12": {}, "TH-13": {}, "TH-14": {}, "TH-15": {}, "TH-16": {},
+ "TH-17": {}, "TH-18": {}, "TH-19": {}, "TH-20": {}, "TH-21": {},
+ "TH-22": {}, "TH-23": {}, "TH-24": {}, "TH-25": {}, "TH-26": {},
+ "TH-27": {}, "TH-30": {}, "TH-31": {}, "TH-32": {}, "TH-33": {},
+ "TH-34": {}, "TH-35": {}, "TH-36": {}, "TH-37": {}, "TH-38": {}, "TH-39": {},
+ "TH-40": {}, "TH-41": {}, "TH-42": {}, "TH-43": {}, "TH-44": {},
+ "TH-45": {}, "TH-46": {}, "TH-47": {}, "TH-48": {}, "TH-49": {},
+ "TH-50": {}, "TH-51": {}, "TH-52": {}, "TH-53": {}, "TH-54": {},
+ "TH-55": {}, "TH-56": {}, "TH-57": {}, "TH-58": {}, "TH-60": {},
+ "TH-61": {}, "TH-62": {}, "TH-63": {}, "TH-64": {}, "TH-65": {},
+ "TH-66": {}, "TH-67": {}, "TH-70": {}, "TH-71": {}, "TH-72": {},
+ "TH-73": {}, "TH-74": {}, "TH-75": {}, "TH-76": {}, "TH-77": {},
+ "TH-80": {}, "TH-81": {}, "TH-82": {}, "TH-83": {}, "TH-84": {},
+ "TH-85": {}, "TH-86": {}, "TH-90": {}, "TH-91": {}, "TH-92": {},
+ "TH-93": {}, "TH-94": {}, "TH-95": {}, "TH-96": {}, "TH-S": {},
+ "TJ-GB": {}, "TJ-KT": {}, "TJ-SU": {}, "TJ-DU": {}, "TJ-RA": {}, "TL-AL": {}, "TL-AN": {},
+ "TL-BA": {}, "TL-BO": {}, "TL-CO": {}, "TL-DI": {}, "TL-ER": {},
+ "TL-LA": {}, "TL-LI": {}, "TL-MF": {}, "TL-MT": {}, "TL-OE": {},
+ "TL-VI": {}, "TM-A": {}, "TM-B": {}, "TM-D": {}, "TM-L": {},
+ "TM-M": {}, "TM-S": {}, "TN-11": {}, "TN-12": {}, "TN-13": {},
+ "TN-14": {}, "TN-21": {}, "TN-22": {}, "TN-23": {}, "TN-31": {},
+ "TN-32": {}, "TN-33": {}, "TN-34": {}, "TN-41": {}, "TN-42": {},
+ "TN-43": {}, "TN-51": {}, "TN-52": {}, "TN-53": {}, "TN-61": {},
+ "TN-71": {}, "TN-72": {}, "TN-73": {}, "TN-81": {}, "TN-82": {},
+ "TN-83": {}, "TO-01": {}, "TO-02": {}, "TO-03": {}, "TO-04": {},
+ "TO-05": {}, "TR-01": {}, "TR-02": {}, "TR-03": {}, "TR-04": {},
+ "TR-05": {}, "TR-06": {}, "TR-07": {}, "TR-08": {}, "TR-09": {},
+ "TR-10": {}, "TR-11": {}, "TR-12": {}, "TR-13": {}, "TR-14": {},
+ "TR-15": {}, "TR-16": {}, "TR-17": {}, "TR-18": {}, "TR-19": {},
+ "TR-20": {}, "TR-21": {}, "TR-22": {}, "TR-23": {}, "TR-24": {},
+ "TR-25": {}, "TR-26": {}, "TR-27": {}, "TR-28": {}, "TR-29": {},
+ "TR-30": {}, "TR-31": {}, "TR-32": {}, "TR-33": {}, "TR-34": {},
+ "TR-35": {}, "TR-36": {}, "TR-37": {}, "TR-38": {}, "TR-39": {},
+ "TR-40": {}, "TR-41": {}, "TR-42": {}, "TR-43": {}, "TR-44": {},
+ "TR-45": {}, "TR-46": {}, "TR-47": {}, "TR-48": {}, "TR-49": {},
+ "TR-50": {}, "TR-51": {}, "TR-52": {}, "TR-53": {}, "TR-54": {},
+ "TR-55": {}, "TR-56": {}, "TR-57": {}, "TR-58": {}, "TR-59": {},
+ "TR-60": {}, "TR-61": {}, "TR-62": {}, "TR-63": {}, "TR-64": {},
+ "TR-65": {}, "TR-66": {}, "TR-67": {}, "TR-68": {}, "TR-69": {},
+ "TR-70": {}, "TR-71": {}, "TR-72": {}, "TR-73": {}, "TR-74": {},
+ "TR-75": {}, "TR-76": {}, "TR-77": {}, "TR-78": {}, "TR-79": {},
+ "TR-80": {}, "TR-81": {}, "TT-ARI": {}, "TT-CHA": {}, "TT-CTT": {},
+ "TT-DMN": {}, "TT-ETO": {}, "TT-MRC": {}, "TT-TOB": {}, "TT-PED": {}, "TT-POS": {}, "TT-PRT": {},
+ "TT-PTF": {}, "TT-RCM": {}, "TT-SFO": {}, "TT-SGE": {}, "TT-SIP": {},
+ "TT-SJL": {}, "TT-TUP": {}, "TT-WTO": {}, "TV-FUN": {}, "TV-NIT": {},
+ "TV-NKF": {}, "TV-NKL": {}, "TV-NMA": {}, "TV-NMG": {}, "TV-NUI": {},
+ "TV-VAI": {}, "TW-CHA": {}, "TW-CYI": {}, "TW-CYQ": {}, "TW-KIN": {}, "TW-HSQ": {},
+ "TW-HSZ": {}, "TW-HUA": {}, "TW-LIE": {}, "TW-ILA": {}, "TW-KEE": {}, "TW-KHH": {},
+ "TW-KHQ": {}, "TW-MIA": {}, "TW-NAN": {}, "TW-NWT": {}, "TW-PEN": {}, "TW-PIF": {},
+ "TW-TAO": {}, "TW-TNN": {}, "TW-TNQ": {}, "TW-TPE": {}, "TW-TPQ": {},
+ "TW-TTT": {}, "TW-TXG": {}, "TW-TXQ": {}, "TW-YUN": {}, "TZ-01": {},
+ "TZ-02": {}, "TZ-03": {}, "TZ-04": {}, "TZ-05": {}, "TZ-06": {},
+ "TZ-07": {}, "TZ-08": {}, "TZ-09": {}, "TZ-10": {}, "TZ-11": {},
+ "TZ-12": {}, "TZ-13": {}, "TZ-14": {}, "TZ-15": {}, "TZ-16": {},
+ "TZ-17": {}, "TZ-18": {}, "TZ-19": {}, "TZ-20": {}, "TZ-21": {},
+ "TZ-22": {}, "TZ-23": {}, "TZ-24": {}, "TZ-25": {}, "TZ-26": {}, "TZ-27": {}, "TZ-28": {}, "TZ-29": {}, "TZ-30": {}, "TZ-31": {},
+ "UA-05": {}, "UA-07": {}, "UA-09": {}, "UA-12": {}, "UA-14": {},
+ "UA-18": {}, "UA-21": {}, "UA-23": {}, "UA-26": {}, "UA-30": {},
+ "UA-32": {}, "UA-35": {}, "UA-40": {}, "UA-43": {}, "UA-46": {},
+ "UA-48": {}, "UA-51": {}, "UA-53": {}, "UA-56": {}, "UA-59": {},
+ "UA-61": {}, "UA-63": {}, "UA-65": {}, "UA-68": {}, "UA-71": {},
+ "UA-74": {}, "UA-77": {}, "UG-101": {}, "UG-102": {}, "UG-103": {},
+ "UG-104": {}, "UG-105": {}, "UG-106": {}, "UG-107": {}, "UG-108": {},
+ "UG-109": {}, "UG-110": {}, "UG-111": {}, "UG-112": {}, "UG-113": {},
+ "UG-114": {}, "UG-115": {}, "UG-116": {}, "UG-201": {}, "UG-202": {},
+ "UG-203": {}, "UG-204": {}, "UG-205": {}, "UG-206": {}, "UG-207": {},
+ "UG-208": {}, "UG-209": {}, "UG-210": {}, "UG-211": {}, "UG-212": {},
+ "UG-213": {}, "UG-214": {}, "UG-215": {}, "UG-216": {}, "UG-217": {},
+ "UG-218": {}, "UG-219": {}, "UG-220": {}, "UG-221": {}, "UG-222": {},
+ "UG-223": {}, "UG-224": {}, "UG-301": {}, "UG-302": {}, "UG-303": {},
+ "UG-304": {}, "UG-305": {}, "UG-306": {}, "UG-307": {}, "UG-308": {},
+ "UG-309": {}, "UG-310": {}, "UG-311": {}, "UG-312": {}, "UG-313": {},
+ "UG-314": {}, "UG-315": {}, "UG-316": {}, "UG-317": {}, "UG-318": {},
+ "UG-319": {}, "UG-320": {}, "UG-321": {}, "UG-401": {}, "UG-402": {},
+ "UG-403": {}, "UG-404": {}, "UG-405": {}, "UG-406": {}, "UG-407": {},
+ "UG-408": {}, "UG-409": {}, "UG-410": {}, "UG-411": {}, "UG-412": {},
+ "UG-413": {}, "UG-414": {}, "UG-415": {}, "UG-416": {}, "UG-417": {},
+ "UG-418": {}, "UG-419": {}, "UG-C": {}, "UG-E": {}, "UG-N": {},
+ "UG-W": {}, "UG-322": {}, "UG-323": {}, "UG-420": {}, "UG-117": {},
+ "UG-118": {}, "UG-225": {}, "UG-120": {}, "UG-226": {},
+ "UG-121": {}, "UG-122": {}, "UG-227": {}, "UG-421": {},
+ "UG-325": {}, "UG-228": {}, "UG-123": {}, "UG-422": {},
+ "UG-326": {}, "UG-229": {}, "UG-124": {}, "UG-423": {},
+ "UG-230": {}, "UG-327": {}, "UG-424": {}, "UG-328": {},
+ "UG-425": {}, "UG-426": {}, "UG-330": {},
+ "UM-67": {}, "UM-71": {}, "UM-76": {}, "UM-79": {},
+ "UM-81": {}, "UM-84": {}, "UM-86": {}, "UM-89": {}, "UM-95": {},
+ "US-AK": {}, "US-AL": {}, "US-AR": {}, "US-AS": {}, "US-AZ": {},
+ "US-CA": {}, "US-CO": {}, "US-CT": {}, "US-DC": {}, "US-DE": {},
+ "US-FL": {}, "US-GA": {}, "US-GU": {}, "US-HI": {}, "US-IA": {},
+ "US-ID": {}, "US-IL": {}, "US-IN": {}, "US-KS": {}, "US-KY": {},
+ "US-LA": {}, "US-MA": {}, "US-MD": {}, "US-ME": {}, "US-MI": {},
+ "US-MN": {}, "US-MO": {}, "US-MP": {}, "US-MS": {}, "US-MT": {},
+ "US-NC": {}, "US-ND": {}, "US-NE": {}, "US-NH": {}, "US-NJ": {},
+ "US-NM": {}, "US-NV": {}, "US-NY": {}, "US-OH": {}, "US-OK": {},
+ "US-OR": {}, "US-PA": {}, "US-PR": {}, "US-RI": {}, "US-SC": {},
+ "US-SD": {}, "US-TN": {}, "US-TX": {}, "US-UM": {}, "US-UT": {},
+ "US-VA": {}, "US-VI": {}, "US-VT": {}, "US-WA": {}, "US-WI": {},
+ "US-WV": {}, "US-WY": {}, "UY-AR": {}, "UY-CA": {}, "UY-CL": {},
+ "UY-CO": {}, "UY-DU": {}, "UY-FD": {}, "UY-FS": {}, "UY-LA": {},
+ "UY-MA": {}, "UY-MO": {}, "UY-PA": {}, "UY-RN": {}, "UY-RO": {},
+ "UY-RV": {}, "UY-SA": {}, "UY-SJ": {}, "UY-SO": {}, "UY-TA": {},
+ "UY-TT": {}, "UZ-AN": {}, "UZ-BU": {}, "UZ-FA": {}, "UZ-JI": {},
+ "UZ-NG": {}, "UZ-NW": {}, "UZ-QA": {}, "UZ-QR": {}, "UZ-SA": {},
+ "UZ-SI": {}, "UZ-SU": {}, "UZ-TK": {}, "UZ-TO": {}, "UZ-XO": {},
+ "VC-01": {}, "VC-02": {}, "VC-03": {}, "VC-04": {}, "VC-05": {},
+ "VC-06": {}, "VE-A": {}, "VE-B": {}, "VE-C": {}, "VE-D": {},
+ "VE-E": {}, "VE-F": {}, "VE-G": {}, "VE-H": {}, "VE-I": {},
+ "VE-J": {}, "VE-K": {}, "VE-L": {}, "VE-M": {}, "VE-N": {},
+ "VE-O": {}, "VE-P": {}, "VE-R": {}, "VE-S": {}, "VE-T": {},
+ "VE-U": {}, "VE-V": {}, "VE-W": {}, "VE-X": {}, "VE-Y": {},
+ "VE-Z": {}, "VN-01": {}, "VN-02": {}, "VN-03": {}, "VN-04": {},
+ "VN-05": {}, "VN-06": {}, "VN-07": {}, "VN-09": {}, "VN-13": {},
+ "VN-14": {}, "VN-15": {}, "VN-18": {}, "VN-20": {}, "VN-21": {},
+ "VN-22": {}, "VN-23": {}, "VN-24": {}, "VN-25": {}, "VN-26": {},
+ "VN-27": {}, "VN-28": {}, "VN-29": {}, "VN-30": {}, "VN-31": {},
+ "VN-32": {}, "VN-33": {}, "VN-34": {}, "VN-35": {}, "VN-36": {},
+ "VN-37": {}, "VN-39": {}, "VN-40": {}, "VN-41": {}, "VN-43": {},
+ "VN-44": {}, "VN-45": {}, "VN-46": {}, "VN-47": {}, "VN-49": {},
+ "VN-50": {}, "VN-51": {}, "VN-52": {}, "VN-53": {}, "VN-54": {},
+ "VN-55": {}, "VN-56": {}, "VN-57": {}, "VN-58": {}, "VN-59": {},
+ "VN-61": {}, "VN-63": {}, "VN-66": {}, "VN-67": {}, "VN-68": {},
+ "VN-69": {}, "VN-70": {}, "VN-71": {}, "VN-72": {}, "VN-73": {},
+ "VN-CT": {}, "VN-DN": {}, "VN-HN": {}, "VN-HP": {}, "VN-SG": {},
+ "VU-MAP": {}, "VU-PAM": {}, "VU-SAM": {}, "VU-SEE": {}, "VU-TAE": {},
+ "VU-TOB": {}, "WF-SG": {}, "WF-UV": {}, "WS-AA": {}, "WS-AL": {}, "WS-AT": {}, "WS-FA": {},
+ "WS-GE": {}, "WS-GI": {}, "WS-PA": {}, "WS-SA": {}, "WS-TU": {},
+ "WS-VF": {}, "WS-VS": {}, "YE-AB": {}, "YE-AD": {}, "YE-AM": {},
+ "YE-BA": {}, "YE-DA": {}, "YE-DH": {}, "YE-HD": {}, "YE-HJ": {}, "YE-HU": {},
+ "YE-IB": {}, "YE-JA": {}, "YE-LA": {}, "YE-MA": {}, "YE-MR": {},
+ "YE-MU": {}, "YE-MW": {}, "YE-RA": {}, "YE-SA": {}, "YE-SD": {}, "YE-SH": {},
+ "YE-SN": {}, "YE-TA": {}, "ZA-EC": {}, "ZA-FS": {}, "ZA-GP": {},
+ "ZA-LP": {}, "ZA-MP": {}, "ZA-NC": {}, "ZA-NW": {}, "ZA-WC": {},
+ "ZA-ZN": {}, "ZA-KZN": {}, "ZM-01": {}, "ZM-02": {}, "ZM-03": {}, "ZM-04": {},
+ "ZM-05": {}, "ZM-06": {}, "ZM-07": {}, "ZM-08": {}, "ZM-09": {}, "ZM-10": {},
+ "ZW-BU": {}, "ZW-HA": {}, "ZW-MA": {}, "ZW-MC": {}, "ZW-ME": {},
+ "ZW-MI": {}, "ZW-MN": {}, "ZW-MS": {}, "ZW-MV": {}, "ZW-MW": {},
+}
diff --git a/vendor/github.com/go-playground/validator/v10/currency_codes.go b/vendor/github.com/go-playground/validator/v10/currency_codes.go
new file mode 100644
index 00000000..d0317f89
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/currency_codes.go
@@ -0,0 +1,79 @@
+package validator
+
+var iso4217 = map[string]struct{}{
+ "AFN": {}, "EUR": {}, "ALL": {}, "DZD": {}, "USD": {},
+ "AOA": {}, "XCD": {}, "ARS": {}, "AMD": {}, "AWG": {},
+ "AUD": {}, "AZN": {}, "BSD": {}, "BHD": {}, "BDT": {},
+ "BBD": {}, "BYN": {}, "BZD": {}, "XOF": {}, "BMD": {},
+ "INR": {}, "BTN": {}, "BOB": {}, "BOV": {}, "BAM": {},
+ "BWP": {}, "NOK": {}, "BRL": {}, "BND": {}, "BGN": {},
+ "BIF": {}, "CVE": {}, "KHR": {}, "XAF": {}, "CAD": {},
+ "KYD": {}, "CLP": {}, "CLF": {}, "CNY": {}, "COP": {},
+ "COU": {}, "KMF": {}, "CDF": {}, "NZD": {}, "CRC": {},
+ "HRK": {}, "CUP": {}, "CUC": {}, "ANG": {}, "CZK": {},
+ "DKK": {}, "DJF": {}, "DOP": {}, "EGP": {}, "SVC": {},
+ "ERN": {}, "SZL": {}, "ETB": {}, "FKP": {}, "FJD": {},
+ "XPF": {}, "GMD": {}, "GEL": {}, "GHS": {}, "GIP": {},
+ "GTQ": {}, "GBP": {}, "GNF": {}, "GYD": {}, "HTG": {},
+ "HNL": {}, "HKD": {}, "HUF": {}, "ISK": {}, "IDR": {},
+ "XDR": {}, "IRR": {}, "IQD": {}, "ILS": {}, "JMD": {},
+ "JPY": {}, "JOD": {}, "KZT": {}, "KES": {}, "KPW": {},
+ "KRW": {}, "KWD": {}, "KGS": {}, "LAK": {}, "LBP": {},
+ "LSL": {}, "ZAR": {}, "LRD": {}, "LYD": {}, "CHF": {},
+ "MOP": {}, "MKD": {}, "MGA": {}, "MWK": {}, "MYR": {},
+ "MVR": {}, "MRU": {}, "MUR": {}, "XUA": {}, "MXN": {},
+ "MXV": {}, "MDL": {}, "MNT": {}, "MAD": {}, "MZN": {},
+ "MMK": {}, "NAD": {}, "NPR": {}, "NIO": {}, "NGN": {},
+ "OMR": {}, "PKR": {}, "PAB": {}, "PGK": {}, "PYG": {},
+ "PEN": {}, "PHP": {}, "PLN": {}, "QAR": {}, "RON": {},
+ "RUB": {}, "RWF": {}, "SHP": {}, "WST": {}, "STN": {},
+ "SAR": {}, "RSD": {}, "SCR": {}, "SLL": {}, "SGD": {},
+ "XSU": {}, "SBD": {}, "SOS": {}, "SSP": {}, "LKR": {},
+ "SDG": {}, "SRD": {}, "SEK": {}, "CHE": {}, "CHW": {},
+ "SYP": {}, "TWD": {}, "TJS": {}, "TZS": {}, "THB": {},
+ "TOP": {}, "TTD": {}, "TND": {}, "TRY": {}, "TMT": {},
+ "UGX": {}, "UAH": {}, "AED": {}, "USN": {}, "UYU": {},
+ "UYI": {}, "UYW": {}, "UZS": {}, "VUV": {}, "VES": {},
+ "VND": {}, "YER": {}, "ZMW": {}, "ZWL": {}, "XBA": {},
+ "XBB": {}, "XBC": {}, "XBD": {}, "XTS": {}, "XXX": {},
+ "XAU": {}, "XPD": {}, "XPT": {}, "XAG": {},
+}
+
+var iso4217_numeric = map[int]struct{}{
+ 8: {}, 12: {}, 32: {}, 36: {}, 44: {},
+ 48: {}, 50: {}, 51: {}, 52: {}, 60: {},
+ 64: {}, 68: {}, 72: {}, 84: {}, 90: {},
+ 96: {}, 104: {}, 108: {}, 116: {}, 124: {},
+ 132: {}, 136: {}, 144: {}, 152: {}, 156: {},
+ 170: {}, 174: {}, 188: {}, 191: {}, 192: {},
+ 203: {}, 208: {}, 214: {}, 222: {}, 230: {},
+ 232: {}, 238: {}, 242: {}, 262: {}, 270: {},
+ 292: {}, 320: {}, 324: {}, 328: {}, 332: {},
+ 340: {}, 344: {}, 348: {}, 352: {}, 356: {},
+ 360: {}, 364: {}, 368: {}, 376: {}, 388: {},
+ 392: {}, 398: {}, 400: {}, 404: {}, 408: {},
+ 410: {}, 414: {}, 417: {}, 418: {}, 422: {},
+ 426: {}, 430: {}, 434: {}, 446: {}, 454: {},
+ 458: {}, 462: {}, 480: {}, 484: {}, 496: {},
+ 498: {}, 504: {}, 512: {}, 516: {}, 524: {},
+ 532: {}, 533: {}, 548: {}, 554: {}, 558: {},
+ 566: {}, 578: {}, 586: {}, 590: {}, 598: {},
+ 600: {}, 604: {}, 608: {}, 634: {}, 643: {},
+ 646: {}, 654: {}, 682: {}, 690: {}, 694: {},
+ 702: {}, 704: {}, 706: {}, 710: {}, 728: {},
+ 748: {}, 752: {}, 756: {}, 760: {}, 764: {},
+ 776: {}, 780: {}, 784: {}, 788: {}, 800: {},
+ 807: {}, 818: {}, 826: {}, 834: {}, 840: {},
+ 858: {}, 860: {}, 882: {}, 886: {}, 901: {},
+ 927: {}, 928: {}, 929: {}, 930: {}, 931: {},
+ 932: {}, 933: {}, 934: {}, 936: {}, 938: {},
+ 940: {}, 941: {}, 943: {}, 944: {}, 946: {},
+ 947: {}, 948: {}, 949: {}, 950: {}, 951: {},
+ 952: {}, 953: {}, 955: {}, 956: {}, 957: {},
+ 958: {}, 959: {}, 960: {}, 961: {}, 962: {},
+ 963: {}, 964: {}, 965: {}, 967: {}, 968: {},
+ 969: {}, 970: {}, 971: {}, 972: {}, 973: {},
+ 975: {}, 976: {}, 977: {}, 978: {}, 979: {},
+ 980: {}, 981: {}, 984: {}, 985: {}, 986: {},
+ 990: {}, 994: {}, 997: {}, 999: {},
+}
diff --git a/vendor/github.com/go-playground/validator/v10/doc.go b/vendor/github.com/go-playground/validator/v10/doc.go
new file mode 100644
index 00000000..23cce991
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/doc.go
@@ -0,0 +1,1518 @@
+/*
+Package validator implements value validations for structs and individual fields
+based on tags.
+
+It can also handle Cross-Field and Cross-Struct validation for nested structs
+and has the ability to dive into arrays and maps of any type.
+
+see more examples https://github.com/go-playground/validator/tree/master/_examples
+
+# Singleton
+
+Validator is designed to be thread-safe and used as a singleton instance.
+It caches information about your struct and validations,
+in essence only parsing your validation tags once per struct type.
+Using multiple instances neglects the benefit of caching.
+The not thread-safe functions are explicitly marked as such in the documentation.
+
+# Validation Functions Return Type error
+
+Doing things this way is actually the way the standard library does, see the
+file.Open method here:
+
+ https://golang.org/pkg/os/#Open.
+
+The authors return type "error" to avoid the issue discussed in the following,
+where err is always != nil:
+
+ http://stackoverflow.com/a/29138676/3158232
+ https://github.com/go-playground/validator/issues/134
+
+Validator only InvalidValidationError for bad validation input, nil or
+ValidationErrors as type error; so, in your code all you need to do is check
+if the error returned is not nil, and if it's not check if error is
+InvalidValidationError ( if necessary, most of the time it isn't ) type cast
+it to type ValidationErrors like so err.(validator.ValidationErrors).
+
+# Custom Validation Functions
+
+Custom Validation functions can be added. Example:
+
+ // Structure
+ func customFunc(fl validator.FieldLevel) bool {
+
+ if fl.Field().String() == "invalid" {
+ return false
+ }
+
+ return true
+ }
+
+ validate.RegisterValidation("custom tag name", customFunc)
+ // NOTES: using the same tag name as an existing function
+ // will overwrite the existing one
+
+# Cross-Field Validation
+
+Cross-Field Validation can be done via the following tags:
+ - eqfield
+ - nefield
+ - gtfield
+ - gtefield
+ - ltfield
+ - ltefield
+ - eqcsfield
+ - necsfield
+ - gtcsfield
+ - gtecsfield
+ - ltcsfield
+ - ltecsfield
+
+If, however, some custom cross-field validation is required, it can be done
+using a custom validation.
+
+Why not just have cross-fields validation tags (i.e. only eqcsfield and not
+eqfield)?
+
+The reason is efficiency. If you want to check a field within the same struct
+"eqfield" only has to find the field on the same struct (1 level). But, if we
+used "eqcsfield" it could be multiple levels down. Example:
+
+ type Inner struct {
+ StartDate time.Time
+ }
+
+ type Outer struct {
+ InnerStructField *Inner
+ CreatedAt time.Time `validate:"ltecsfield=InnerStructField.StartDate"`
+ }
+
+ now := time.Now()
+
+ inner := &Inner{
+ StartDate: now,
+ }
+
+ outer := &Outer{
+ InnerStructField: inner,
+ CreatedAt: now,
+ }
+
+ errs := validate.Struct(outer)
+
+ // NOTE: when calling validate.Struct(val) topStruct will be the top level struct passed
+ // into the function
+ // when calling validate.VarWithValue(val, field, tag) val will be
+ // whatever you pass, struct, field...
+ // when calling validate.Field(field, tag) val will be nil
+
+# Multiple Validators
+
+Multiple validators on a field will process in the order defined. Example:
+
+ type Test struct {
+ Field `validate:"max=10,min=1"`
+ }
+
+ // max will be checked then min
+
+Bad Validator definitions are not handled by the library. Example:
+
+ type Test struct {
+ Field `validate:"min=10,max=0"`
+ }
+
+ // this definition of min max will never succeed
+
+# Using Validator Tags
+
+Baked In Cross-Field validation only compares fields on the same struct.
+If Cross-Field + Cross-Struct validation is needed you should implement your
+own custom validator.
+
+Comma (",") is the default separator of validation tags. If you wish to
+have a comma included within the parameter (i.e. excludesall=,) you will need to
+use the UTF-8 hex representation 0x2C, which is replaced in the code as a comma,
+so the above will become excludesall=0x2C.
+
+ type Test struct {
+ Field `validate:"excludesall=,"` // BAD! Do not include a comma.
+ Field `validate:"excludesall=0x2C"` // GOOD! Use the UTF-8 hex representation.
+ }
+
+Pipe ("|") is the 'or' validation tags deparator. If you wish to
+have a pipe included within the parameter i.e. excludesall=| you will need to
+use the UTF-8 hex representation 0x7C, which is replaced in the code as a pipe,
+so the above will become excludesall=0x7C
+
+ type Test struct {
+ Field `validate:"excludesall=|"` // BAD! Do not include a pipe!
+ Field `validate:"excludesall=0x7C"` // GOOD! Use the UTF-8 hex representation.
+ }
+
+# Baked In Validators and Tags
+
+Here is a list of the current built in validators:
+
+# Skip Field
+
+Tells the validation to skip this struct field; this is particularly
+handy in ignoring embedded structs from being validated. (Usage: -)
+
+ Usage: -
+
+# Or Operator
+
+This is the 'or' operator allowing multiple validators to be used and
+accepted. (Usage: rgb|rgba) <-- this would allow either rgb or rgba
+colors to be accepted. This can also be combined with 'and' for example
+( Usage: omitempty,rgb|rgba)
+
+ Usage: |
+
+# StructOnly
+
+When a field that is a nested struct is encountered, and contains this flag
+any validation on the nested struct will be run, but none of the nested
+struct fields will be validated. This is useful if inside of your program
+you know the struct will be valid, but need to verify it has been assigned.
+NOTE: only "required" and "omitempty" can be used on a struct itself.
+
+ Usage: structonly
+
+# NoStructLevel
+
+Same as structonly tag except that any struct level validations will not run.
+
+ Usage: nostructlevel
+
+# Omit Empty
+
+Allows conditional validation, for example, if a field is not set with
+a value (Determined by the "required" validator) then other validation
+such as min or max won't run, but if a value is set validation will run.
+
+ Usage: omitempty
+
+# Omit Nil
+
+Allows to skip the validation if the value is nil (same as omitempty, but
+only for the nil-values).
+
+ Usage: omitnil
+
+# Dive
+
+This tells the validator to dive into a slice, array or map and validate that
+level of the slice, array or map with the validation tags that follow.
+Multidimensional nesting is also supported, each level you wish to dive will
+require another dive tag. dive has some sub-tags, 'keys' & 'endkeys', please see
+the Keys & EndKeys section just below.
+
+ Usage: dive
+
+Example #1
+
+ [][]string with validation tag "gt=0,dive,len=1,dive,required"
+ // gt=0 will be applied to []
+ // len=1 will be applied to []string
+ // required will be applied to string
+
+Example #2
+
+ [][]string with validation tag "gt=0,dive,dive,required"
+ // gt=0 will be applied to []
+ // []string will be spared validation
+ // required will be applied to string
+
+Keys & EndKeys
+
+These are to be used together directly after the dive tag and tells the validator
+that anything between 'keys' and 'endkeys' applies to the keys of a map and not the
+values; think of it like the 'dive' tag, but for map keys instead of values.
+Multidimensional nesting is also supported, each level you wish to validate will
+require another 'keys' and 'endkeys' tag. These tags are only valid for maps.
+
+ Usage: dive,keys,othertagvalidation(s),endkeys,valuevalidationtags
+
+Example #1
+
+ map[string]string with validation tag "gt=0,dive,keys,eq=1|eq=2,endkeys,required"
+ // gt=0 will be applied to the map itself
+ // eq=1|eq=2 will be applied to the map keys
+ // required will be applied to map values
+
+Example #2
+
+ map[[2]string]string with validation tag "gt=0,dive,keys,dive,eq=1|eq=2,endkeys,required"
+ // gt=0 will be applied to the map itself
+ // eq=1|eq=2 will be applied to each array element in the map keys
+ // required will be applied to map values
+
+# Required
+
+This validates that the value is not the data types default zero value.
+For numbers ensures value is not zero. For strings ensures value is
+not "". For booleans ensures value is not false. For slices, maps, pointers, interfaces, channels and functions
+ensures the value is not nil. For structs ensures value is not the zero value when using WithRequiredStructEnabled.
+
+ Usage: required
+
+# Required If
+
+The field under validation must be present and not empty only if all
+the other specified fields are equal to the value following the specified
+field. For strings ensures value is not "". For slices, maps, pointers,
+interfaces, channels and functions ensures the value is not nil. For structs ensures value is not the zero value.
+
+ Usage: required_if
+
+Examples:
+
+ // require the field if the Field1 is equal to the parameter given:
+ Usage: required_if=Field1 foobar
+
+ // require the field if the Field1 and Field2 is equal to the value respectively:
+ Usage: required_if=Field1 foo Field2 bar
+
+# Required Unless
+
+The field under validation must be present and not empty unless all
+the other specified fields are equal to the value following the specified
+field. For strings ensures value is not "". For slices, maps, pointers,
+interfaces, channels and functions ensures the value is not nil. For structs ensures value is not the zero value.
+
+ Usage: required_unless
+
+Examples:
+
+ // require the field unless the Field1 is equal to the parameter given:
+ Usage: required_unless=Field1 foobar
+
+ // require the field unless the Field1 and Field2 is equal to the value respectively:
+ Usage: required_unless=Field1 foo Field2 bar
+
+# Required With
+
+The field under validation must be present and not empty only if any
+of the other specified fields are present. For strings ensures value is
+not "". For slices, maps, pointers, interfaces, channels and functions
+ensures the value is not nil. For structs ensures value is not the zero value.
+
+ Usage: required_with
+
+Examples:
+
+ // require the field if the Field1 is present:
+ Usage: required_with=Field1
+
+ // require the field if the Field1 or Field2 is present:
+ Usage: required_with=Field1 Field2
+
+# Required With All
+
+The field under validation must be present and not empty only if all
+of the other specified fields are present. For strings ensures value is
+not "". For slices, maps, pointers, interfaces, channels and functions
+ensures the value is not nil. For structs ensures value is not the zero value.
+
+ Usage: required_with_all
+
+Example:
+
+ // require the field if the Field1 and Field2 is present:
+ Usage: required_with_all=Field1 Field2
+
+# Required Without
+
+The field under validation must be present and not empty only when any
+of the other specified fields are not present. For strings ensures value is
+not "". For slices, maps, pointers, interfaces, channels and functions
+ensures the value is not nil. For structs ensures value is not the zero value.
+
+ Usage: required_without
+
+Examples:
+
+ // require the field if the Field1 is not present:
+ Usage: required_without=Field1
+
+ // require the field if the Field1 or Field2 is not present:
+ Usage: required_without=Field1 Field2
+
+# Required Without All
+
+The field under validation must be present and not empty only when all
+of the other specified fields are not present. For strings ensures value is
+not "". For slices, maps, pointers, interfaces, channels and functions
+ensures the value is not nil. For structs ensures value is not the zero value.
+
+ Usage: required_without_all
+
+Example:
+
+ // require the field if the Field1 and Field2 is not present:
+ Usage: required_without_all=Field1 Field2
+
+# Excluded If
+
+The field under validation must not be present or not empty only if all
+the other specified fields are equal to the value following the specified
+field. For strings ensures value is not "". For slices, maps, pointers,
+interfaces, channels and functions ensures the value is not nil. For structs ensures value is not the zero value.
+
+ Usage: excluded_if
+
+Examples:
+
+ // exclude the field if the Field1 is equal to the parameter given:
+ Usage: excluded_if=Field1 foobar
+
+ // exclude the field if the Field1 and Field2 is equal to the value respectively:
+ Usage: excluded_if=Field1 foo Field2 bar
+
+# Excluded Unless
+
+The field under validation must not be present or empty unless all
+the other specified fields are equal to the value following the specified
+field. For strings ensures value is not "". For slices, maps, pointers,
+interfaces, channels and functions ensures the value is not nil. For structs ensures value is not the zero value.
+
+ Usage: excluded_unless
+
+Examples:
+
+ // exclude the field unless the Field1 is equal to the parameter given:
+ Usage: excluded_unless=Field1 foobar
+
+ // exclude the field unless the Field1 and Field2 is equal to the value respectively:
+ Usage: excluded_unless=Field1 foo Field2 bar
+
+# Is Default
+
+This validates that the value is the default value and is almost the
+opposite of required.
+
+ Usage: isdefault
+
+# Length
+
+For numbers, length will ensure that the value is
+equal to the parameter given. For strings, it checks that
+the string length is exactly that number of characters. For slices,
+arrays, and maps, validates the number of items.
+
+Example #1
+
+ Usage: len=10
+
+Example #2 (time.Duration)
+
+For time.Duration, len will ensure that the value is equal to the duration given
+in the parameter.
+
+ Usage: len=1h30m
+
+# Maximum
+
+For numbers, max will ensure that the value is
+less than or equal to the parameter given. For strings, it checks
+that the string length is at most that number of characters. For
+slices, arrays, and maps, validates the number of items.
+
+Example #1
+
+ Usage: max=10
+
+Example #2 (time.Duration)
+
+For time.Duration, max will ensure that the value is less than or equal to the
+duration given in the parameter.
+
+ Usage: max=1h30m
+
+# Minimum
+
+For numbers, min will ensure that the value is
+greater or equal to the parameter given. For strings, it checks that
+the string length is at least that number of characters. For slices,
+arrays, and maps, validates the number of items.
+
+Example #1
+
+ Usage: min=10
+
+Example #2 (time.Duration)
+
+For time.Duration, min will ensure that the value is greater than or equal to
+the duration given in the parameter.
+
+ Usage: min=1h30m
+
+# Equals
+
+For strings & numbers, eq will ensure that the value is
+equal to the parameter given. For slices, arrays, and maps,
+validates the number of items.
+
+Example #1
+
+ Usage: eq=10
+
+Example #2 (time.Duration)
+
+For time.Duration, eq will ensure that the value is equal to the duration given
+in the parameter.
+
+ Usage: eq=1h30m
+
+# Not Equal
+
+For strings & numbers, ne will ensure that the value is not
+equal to the parameter given. For slices, arrays, and maps,
+validates the number of items.
+
+Example #1
+
+ Usage: ne=10
+
+Example #2 (time.Duration)
+
+For time.Duration, ne will ensure that the value is not equal to the duration
+given in the parameter.
+
+ Usage: ne=1h30m
+
+# One Of
+
+For strings, ints, and uints, oneof will ensure that the value
+is one of the values in the parameter. The parameter should be
+a list of values separated by whitespace. Values may be
+strings or numbers. To match strings with spaces in them, include
+the target string between single quotes. Kind of like an 'enum'.
+
+ Usage: oneof=red green
+ oneof='red green' 'blue yellow'
+ oneof=5 7 9
+
+# One Of Case Insensitive
+
+Works the same as oneof but is case insensitive and therefore only accepts strings.
+
+ Usage: oneofci=red green
+ oneofci='red green' 'blue yellow'
+
+# Greater Than
+
+For numbers, this will ensure that the value is greater than the
+parameter given. For strings, it checks that the string length
+is greater than that number of characters. For slices, arrays
+and maps it validates the number of items.
+
+Example #1
+
+ Usage: gt=10
+
+Example #2 (time.Time)
+
+For time.Time ensures the time value is greater than time.Now.UTC().
+
+ Usage: gt
+
+Example #3 (time.Duration)
+
+For time.Duration, gt will ensure that the value is greater than the duration
+given in the parameter.
+
+ Usage: gt=1h30m
+
+# Greater Than or Equal
+
+Same as 'min' above. Kept both to make terminology with 'len' easier.
+
+Example #1
+
+ Usage: gte=10
+
+Example #2 (time.Time)
+
+For time.Time ensures the time value is greater than or equal to time.Now.UTC().
+
+ Usage: gte
+
+Example #3 (time.Duration)
+
+For time.Duration, gte will ensure that the value is greater than or equal to
+the duration given in the parameter.
+
+ Usage: gte=1h30m
+
+# Less Than
+
+For numbers, this will ensure that the value is less than the parameter given.
+For strings, it checks that the string length is less than that number of
+characters. For slices, arrays, and maps it validates the number of items.
+
+Example #1
+
+ Usage: lt=10
+
+Example #2 (time.Time)
+
+For time.Time ensures the time value is less than time.Now.UTC().
+
+ Usage: lt
+
+Example #3 (time.Duration)
+
+For time.Duration, lt will ensure that the value is less than the duration given
+in the parameter.
+
+ Usage: lt=1h30m
+
+# Less Than or Equal
+
+Same as 'max' above. Kept both to make terminology with 'len' easier.
+
+Example #1
+
+ Usage: lte=10
+
+Example #2 (time.Time)
+
+For time.Time ensures the time value is less than or equal to time.Now.UTC().
+
+ Usage: lte
+
+Example #3 (time.Duration)
+
+For time.Duration, lte will ensure that the value is less than or equal to the
+duration given in the parameter.
+
+ Usage: lte=1h30m
+
+# Field Equals Another Field
+
+This will validate the field value against another fields value either within
+a struct or passed in field.
+
+Example #1:
+
+ // Validation on Password field using:
+ Usage: eqfield=ConfirmPassword
+
+Example #2:
+
+ // Validating by field:
+ validate.VarWithValue(password, confirmpassword, "eqfield")
+
+Field Equals Another Field (relative)
+
+This does the same as eqfield except that it validates the field provided relative
+to the top level struct.
+
+ Usage: eqcsfield=InnerStructField.Field)
+
+# Field Does Not Equal Another Field
+
+This will validate the field value against another fields value either within
+a struct or passed in field.
+
+Examples:
+
+ // Confirm two colors are not the same:
+ //
+ // Validation on Color field:
+ Usage: nefield=Color2
+
+ // Validating by field:
+ validate.VarWithValue(color1, color2, "nefield")
+
+Field Does Not Equal Another Field (relative)
+
+This does the same as nefield except that it validates the field provided
+relative to the top level struct.
+
+ Usage: necsfield=InnerStructField.Field
+
+# Field Greater Than Another Field
+
+Only valid for Numbers, time.Duration and time.Time types, this will validate
+the field value against another fields value either within a struct or passed in
+field. usage examples are for validation of a Start and End date:
+
+Example #1:
+
+ // Validation on End field using:
+ validate.Struct Usage(gtfield=Start)
+
+Example #2:
+
+ // Validating by field:
+ validate.VarWithValue(start, end, "gtfield")
+
+# Field Greater Than Another Relative Field
+
+This does the same as gtfield except that it validates the field provided
+relative to the top level struct.
+
+ Usage: gtcsfield=InnerStructField.Field
+
+# Field Greater Than or Equal To Another Field
+
+Only valid for Numbers, time.Duration and time.Time types, this will validate
+the field value against another fields value either within a struct or passed in
+field. usage examples are for validation of a Start and End date:
+
+Example #1:
+
+ // Validation on End field using:
+ validate.Struct Usage(gtefield=Start)
+
+Example #2:
+
+ // Validating by field:
+ validate.VarWithValue(start, end, "gtefield")
+
+# Field Greater Than or Equal To Another Relative Field
+
+This does the same as gtefield except that it validates the field provided relative
+to the top level struct.
+
+ Usage: gtecsfield=InnerStructField.Field
+
+# Less Than Another Field
+
+Only valid for Numbers, time.Duration and time.Time types, this will validate
+the field value against another fields value either within a struct or passed in
+field. usage examples are for validation of a Start and End date:
+
+Example #1:
+
+ // Validation on End field using:
+ validate.Struct Usage(ltfield=Start)
+
+Example #2:
+
+ // Validating by field:
+ validate.VarWithValue(start, end, "ltfield")
+
+# Less Than Another Relative Field
+
+This does the same as ltfield except that it validates the field provided relative
+to the top level struct.
+
+ Usage: ltcsfield=InnerStructField.Field
+
+# Less Than or Equal To Another Field
+
+Only valid for Numbers, time.Duration and time.Time types, this will validate
+the field value against another fields value either within a struct or passed in
+field. usage examples are for validation of a Start and End date:
+
+Example #1:
+
+ // Validation on End field using:
+ validate.Struct Usage(ltefield=Start)
+
+Example #2:
+
+ // Validating by field:
+ validate.VarWithValue(start, end, "ltefield")
+
+# Less Than or Equal To Another Relative Field
+
+This does the same as ltefield except that it validates the field provided relative
+to the top level struct.
+
+ Usage: ltecsfield=InnerStructField.Field
+
+# Field Contains Another Field
+
+This does the same as contains except for struct fields. It should only be used
+with string types. See the behavior of reflect.Value.String() for behavior on
+other types.
+
+ Usage: containsfield=InnerStructField.Field
+
+# Field Excludes Another Field
+
+This does the same as excludes except for struct fields. It should only be used
+with string types. See the behavior of reflect.Value.String() for behavior on
+other types.
+
+ Usage: excludesfield=InnerStructField.Field
+
+# Unique
+
+For arrays & slices, unique will ensure that there are no duplicates.
+For maps, unique will ensure that there are no duplicate values.
+For slices of struct, unique will ensure that there are no duplicate values
+in a field of the struct specified via a parameter.
+
+ // For arrays, slices, and maps:
+ Usage: unique
+
+ // For slices of struct:
+ Usage: unique=field
+
+# ValidateFn
+
+This validates that an object responds to a method that can return error or bool.
+By default it expects an interface `Validate() error` and check that the method
+does not return an error. Other methods can be specified using two signatures:
+If the method returns an error, it check if the return value is nil.
+If the method returns a boolean, it checks if the value is true.
+
+ // to use the default method Validate() error
+ Usage: validateFn
+
+ // to use the custom method IsValid() bool (or error)
+ Usage: validateFn=IsValid
+
+# Alpha Only
+
+This validates that a string value contains ASCII alpha characters only
+
+ Usage: alpha
+
+# Alphanumeric
+
+This validates that a string value contains ASCII alphanumeric characters only
+
+ Usage: alphanum
+
+# Alpha Unicode
+
+This validates that a string value contains unicode alpha characters only
+
+ Usage: alphaunicode
+
+# Alphanumeric Unicode
+
+This validates that a string value contains unicode alphanumeric characters only
+
+ Usage: alphanumunicode
+
+# Boolean
+
+This validates that a string value can successfully be parsed into a boolean with strconv.ParseBool
+
+ Usage: boolean
+
+# Number
+
+This validates that a string value contains number values only.
+For integers or float it returns true.
+
+ Usage: number
+
+# Numeric
+
+This validates that a string value contains a basic numeric value.
+basic excludes exponents etc...
+for integers or float it returns true.
+
+ Usage: numeric
+
+# Hexadecimal String
+
+This validates that a string value contains a valid hexadecimal.
+
+ Usage: hexadecimal
+
+# Hexcolor String
+
+This validates that a string value contains a valid hex color including
+hashtag (#)
+
+ Usage: hexcolor
+
+# Lowercase String
+
+This validates that a string value contains only lowercase characters. An empty string is not a valid lowercase string.
+
+ Usage: lowercase
+
+# Uppercase String
+
+This validates that a string value contains only uppercase characters. An empty string is not a valid uppercase string.
+
+ Usage: uppercase
+
+# RGB String
+
+This validates that a string value contains a valid rgb color
+
+ Usage: rgb
+
+# RGBA String
+
+This validates that a string value contains a valid rgba color
+
+ Usage: rgba
+
+# HSL String
+
+This validates that a string value contains a valid hsl color
+
+ Usage: hsl
+
+# HSLA String
+
+This validates that a string value contains a valid hsla color
+
+ Usage: hsla
+
+# E.164 Phone Number String
+
+This validates that a string value contains a valid E.164 Phone number
+https://en.wikipedia.org/wiki/E.164 (ex. +1123456789)
+
+ Usage: e164
+
+# E-mail String
+
+This validates that a string value contains a valid email
+This may not conform to all possibilities of any rfc standard, but neither
+does any email provider accept all possibilities.
+
+ Usage: email
+
+# JSON String
+
+This validates that a string value is valid JSON
+
+ Usage: json
+
+# JWT String
+
+This validates that a string value is a valid JWT
+
+ Usage: jwt
+
+# File
+
+This validates that a string value contains a valid file path and that
+the file exists on the machine.
+This is done using os.Stat, which is a platform independent function.
+
+ Usage: file
+
+# Image path
+
+This validates that a string value contains a valid file path and that
+the file exists on the machine and is an image.
+This is done using os.Stat and github.com/gabriel-vasile/mimetype
+
+ Usage: image
+
+# File Path
+
+This validates that a string value contains a valid file path but does not
+validate the existence of that file.
+This is done using os.Stat, which is a platform independent function.
+
+ Usage: filepath
+
+# URL String
+
+This validates that a string value contains a valid url
+This will accept any url the golang request uri accepts but must contain
+a schema for example http:// or rtmp://
+
+ Usage: url
+
+# URI String
+
+This validates that a string value contains a valid uri
+This will accept any uri the golang request uri accepts
+
+ Usage: uri
+
+# Urn RFC 2141 String
+
+This validates that a string value contains a valid URN
+according to the RFC 2141 spec.
+
+ Usage: urn_rfc2141
+
+# Base32 String
+
+This validates that a string value contains a valid bas324 value.
+Although an empty string is valid base32 this will report an empty string
+as an error, if you wish to accept an empty string as valid you can use
+this with the omitempty tag.
+
+ Usage: base32
+
+# Base64 String
+
+This validates that a string value contains a valid base64 value.
+Although an empty string is valid base64 this will report an empty string
+as an error, if you wish to accept an empty string as valid you can use
+this with the omitempty tag.
+
+ Usage: base64
+
+# Base64URL String
+
+This validates that a string value contains a valid base64 URL safe value
+according the RFC4648 spec.
+Although an empty string is a valid base64 URL safe value, this will report
+an empty string as an error, if you wish to accept an empty string as valid
+you can use this with the omitempty tag.
+
+ Usage: base64url
+
+# Base64RawURL String
+
+This validates that a string value contains a valid base64 URL safe value,
+but without = padding, according the RFC4648 spec, section 3.2.
+Although an empty string is a valid base64 URL safe value, this will report
+an empty string as an error, if you wish to accept an empty string as valid
+you can use this with the omitempty tag.
+
+ Usage: base64rawurl
+
+# Bitcoin Address
+
+This validates that a string value contains a valid bitcoin address.
+The format of the string is checked to ensure it matches one of the three formats
+P2PKH, P2SH and performs checksum validation.
+
+ Usage: btc_addr
+
+Bitcoin Bech32 Address (segwit)
+
+This validates that a string value contains a valid bitcoin Bech32 address as defined
+by bip-0173 (https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki)
+Special thanks to Pieter Wuille for providing reference implementations.
+
+ Usage: btc_addr_bech32
+
+# Ethereum Address
+
+This validates that a string value contains a valid ethereum address.
+The format of the string is checked to ensure it matches the standard Ethereum address format.
+
+ Usage: eth_addr
+
+# Contains
+
+This validates that a string value contains the substring value.
+
+ Usage: contains=@
+
+# Contains Any
+
+This validates that a string value contains any Unicode code points
+in the substring value.
+
+ Usage: containsany=!@#?
+
+# Contains Rune
+
+This validates that a string value contains the supplied rune value.
+
+ Usage: containsrune=@
+
+# Excludes
+
+This validates that a string value does not contain the substring value.
+
+ Usage: excludes=@
+
+# Excludes All
+
+This validates that a string value does not contain any Unicode code
+points in the substring value.
+
+ Usage: excludesall=!@#?
+
+# Excludes Rune
+
+This validates that a string value does not contain the supplied rune value.
+
+ Usage: excludesrune=@
+
+# Starts With
+
+This validates that a string value starts with the supplied string value
+
+ Usage: startswith=hello
+
+# Ends With
+
+This validates that a string value ends with the supplied string value
+
+ Usage: endswith=goodbye
+
+# Does Not Start With
+
+This validates that a string value does not start with the supplied string value
+
+ Usage: startsnotwith=hello
+
+# Does Not End With
+
+This validates that a string value does not end with the supplied string value
+
+ Usage: endsnotwith=goodbye
+
+# International Standard Book Number
+
+This validates that a string value contains a valid isbn10 or isbn13 value.
+
+ Usage: isbn
+
+# International Standard Book Number 10
+
+This validates that a string value contains a valid isbn10 value.
+
+ Usage: isbn10
+
+# International Standard Book Number 13
+
+This validates that a string value contains a valid isbn13 value.
+
+ Usage: isbn13
+
+# Universally Unique Identifier UUID
+
+This validates that a string value contains a valid UUID. Uppercase UUID values will not pass - use `uuid_rfc4122` instead.
+
+ Usage: uuid
+
+# Universally Unique Identifier UUID v3
+
+This validates that a string value contains a valid version 3 UUID. Uppercase UUID values will not pass - use `uuid3_rfc4122` instead.
+
+ Usage: uuid3
+
+# Universally Unique Identifier UUID v4
+
+This validates that a string value contains a valid version 4 UUID. Uppercase UUID values will not pass - use `uuid4_rfc4122` instead.
+
+ Usage: uuid4
+
+# Universally Unique Identifier UUID v5
+
+This validates that a string value contains a valid version 5 UUID. Uppercase UUID values will not pass - use `uuid5_rfc4122` instead.
+
+ Usage: uuid5
+
+# Universally Unique Lexicographically Sortable Identifier ULID
+
+This validates that a string value contains a valid ULID value.
+
+ Usage: ulid
+
+# ASCII
+
+This validates that a string value contains only ASCII characters.
+NOTE: if the string is blank, this validates as true.
+
+ Usage: ascii
+
+# Printable ASCII
+
+This validates that a string value contains only printable ASCII characters.
+NOTE: if the string is blank, this validates as true.
+
+ Usage: printascii
+
+# Multi-Byte Characters
+
+This validates that a string value contains one or more multibyte characters.
+NOTE: if the string is blank, this validates as true.
+
+ Usage: multibyte
+
+# Data URL
+
+This validates that a string value contains a valid DataURI.
+NOTE: this will also validate that the data portion is valid base64
+
+ Usage: datauri
+
+# Latitude
+
+This validates that a string value contains a valid latitude.
+
+ Usage: latitude
+
+# Longitude
+
+This validates that a string value contains a valid longitude.
+
+ Usage: longitude
+
+# Employeer Identification Number EIN
+
+This validates that a string value contains a valid U.S. Employer Identification Number.
+
+ Usage: ein
+
+# Social Security Number SSN
+
+This validates that a string value contains a valid U.S. Social Security Number.
+
+ Usage: ssn
+
+# Internet Protocol Address IP
+
+This validates that a string value contains a valid IP Address.
+
+ Usage: ip
+
+# Internet Protocol Address IPv4
+
+This validates that a string value contains a valid v4 IP Address.
+
+ Usage: ipv4
+
+# Internet Protocol Address IPv6
+
+This validates that a string value contains a valid v6 IP Address.
+
+ Usage: ipv6
+
+# Classless Inter-Domain Routing CIDR
+
+This validates that a string value contains a valid CIDR Address.
+
+ Usage: cidr
+
+# Classless Inter-Domain Routing CIDRv4
+
+This validates that a string value contains a valid v4 CIDR Address.
+
+ Usage: cidrv4
+
+# Classless Inter-Domain Routing CIDRv6
+
+This validates that a string value contains a valid v6 CIDR Address.
+
+ Usage: cidrv6
+
+# Transmission Control Protocol Address TCP
+
+This validates that a string value contains a valid resolvable TCP Address.
+
+ Usage: tcp_addr
+
+# Transmission Control Protocol Address TCPv4
+
+This validates that a string value contains a valid resolvable v4 TCP Address.
+
+ Usage: tcp4_addr
+
+# Transmission Control Protocol Address TCPv6
+
+This validates that a string value contains a valid resolvable v6 TCP Address.
+
+ Usage: tcp6_addr
+
+# User Datagram Protocol Address UDP
+
+This validates that a string value contains a valid resolvable UDP Address.
+
+ Usage: udp_addr
+
+# User Datagram Protocol Address UDPv4
+
+This validates that a string value contains a valid resolvable v4 UDP Address.
+
+ Usage: udp4_addr
+
+# User Datagram Protocol Address UDPv6
+
+This validates that a string value contains a valid resolvable v6 UDP Address.
+
+ Usage: udp6_addr
+
+# Internet Protocol Address IP
+
+This validates that a string value contains a valid resolvable IP Address.
+
+ Usage: ip_addr
+
+# Internet Protocol Address IPv4
+
+This validates that a string value contains a valid resolvable v4 IP Address.
+
+ Usage: ip4_addr
+
+# Internet Protocol Address IPv6
+
+This validates that a string value contains a valid resolvable v6 IP Address.
+
+ Usage: ip6_addr
+
+# Unix domain socket end point Address
+
+This validates that a string value contains a valid Unix Address.
+
+ Usage: unix_addr
+
+# Media Access Control Address MAC
+
+This validates that a string value contains a valid MAC Address.
+
+ Usage: mac
+
+Note: See Go's ParseMAC for accepted formats and types:
+
+ http://golang.org/src/net/mac.go?s=866:918#L29
+
+# Hostname RFC 952
+
+This validates that a string value is a valid Hostname according to RFC 952 https://tools.ietf.org/html/rfc952
+
+ Usage: hostname
+
+# Hostname RFC 1123
+
+This validates that a string value is a valid Hostname according to RFC 1123 https://tools.ietf.org/html/rfc1123
+
+ Usage: hostname_rfc1123 or if you want to continue to use 'hostname' in your tags, create an alias.
+
+Full Qualified Domain Name (FQDN)
+
+This validates that a string value contains a valid FQDN.
+
+ Usage: fqdn
+
+# HTML Tags
+
+This validates that a string value appears to be an HTML element tag
+including those described at https://developer.mozilla.org/en-US/docs/Web/HTML/Element
+
+ Usage: html
+
+# HTML Encoded
+
+This validates that a string value is a proper character reference in decimal
+or hexadecimal format
+
+ Usage: html_encoded
+
+# URL Encoded
+
+This validates that a string value is percent-encoded (URL encoded) according
+to https://tools.ietf.org/html/rfc3986#section-2.1
+
+ Usage: url_encoded
+
+# Directory
+
+This validates that a string value contains a valid directory and that
+it exists on the machine.
+This is done using os.Stat, which is a platform independent function.
+
+ Usage: dir
+
+# Directory Path
+
+This validates that a string value contains a valid directory but does
+not validate the existence of that directory.
+This is done using os.Stat, which is a platform independent function.
+It is safest to suffix the string with os.PathSeparator if the directory
+may not exist at the time of validation.
+
+ Usage: dirpath
+
+# HostPort
+
+This validates that a string value contains a valid DNS hostname and port that
+can be used to validate fields typically passed to sockets and connections.
+
+ Usage: hostname_port
+
+# Datetime
+
+This validates that a string value is a valid datetime based on the supplied datetime format.
+Supplied format must match the official Go time format layout as documented in https://golang.org/pkg/time/
+
+ Usage: datetime=2006-01-02
+
+# Iso3166-1 alpha-2
+
+This validates that a string value is a valid country code based on iso3166-1 alpha-2 standard.
+see: https://www.iso.org/iso-3166-country-codes.html
+
+ Usage: iso3166_1_alpha2
+
+# Iso3166-1 alpha-3
+
+This validates that a string value is a valid country code based on iso3166-1 alpha-3 standard.
+see: https://www.iso.org/iso-3166-country-codes.html
+
+ Usage: iso3166_1_alpha3
+
+# Iso3166-1 alpha-numeric
+
+This validates that a string value is a valid country code based on iso3166-1 alpha-numeric standard.
+see: https://www.iso.org/iso-3166-country-codes.html
+
+ Usage: iso3166_1_alpha3
+
+# BCP 47 Language Tag
+
+This validates that a string value is a valid BCP 47 language tag, as parsed by language.Parse.
+More information on https://pkg.go.dev/golang.org/x/text/language
+
+ Usage: bcp47_language_tag
+
+BIC (SWIFT code)
+
+This validates that a string value is a valid Business Identifier Code (SWIFT code), defined in ISO 9362.
+More information on https://www.iso.org/standard/60390.html
+
+ Usage: bic
+
+# RFC 1035 label
+
+This validates that a string value is a valid dns RFC 1035 label, defined in RFC 1035.
+More information on https://datatracker.ietf.org/doc/html/rfc1035
+
+ Usage: dns_rfc1035_label
+
+# TimeZone
+
+This validates that a string value is a valid time zone based on the time zone database present on the system.
+Although empty value and Local value are allowed by time.LoadLocation golang function, they are not allowed by this validator.
+More information on https://golang.org/pkg/time/#LoadLocation
+
+ Usage: timezone
+
+# Semantic Version
+
+This validates that a string value is a valid semver version, defined in Semantic Versioning 2.0.0.
+More information on https://semver.org/
+
+ Usage: semver
+
+# CVE Identifier
+
+This validates that a string value is a valid cve id, defined in cve mitre.
+More information on https://cve.mitre.org/
+
+ Usage: cve
+
+# Credit Card
+
+This validates that a string value contains a valid credit card number using Luhn algorithm.
+
+ Usage: credit_card
+
+# Luhn Checksum
+
+ Usage: luhn_checksum
+
+This validates that a string or (u)int value contains a valid checksum using the Luhn algorithm.
+
+# MongoDB
+
+This validates that a string is a valid 24 character hexadecimal string or valid connection string.
+
+ Usage: mongodb
+ mongodb_connection_string
+
+Example:
+
+ type Test struct {
+ ObjectIdField string `validate:"mongodb"`
+ ConnectionStringField string `validate:"mongodb_connection_string"`
+ }
+
+# Cron
+
+This validates that a string value contains a valid cron expression.
+
+ Usage: cron
+
+# SpiceDb ObjectID/Permission/Object Type
+
+This validates that a string is valid for use with SpiceDb for the indicated purpose. If no purpose is given, a purpose of 'id' is assumed.
+
+ Usage: spicedb=id|permission|type
+
+# Alias Validators and Tags
+
+Alias Validators and Tags
+NOTE: When returning an error, the tag returned in "FieldError" will be
+the alias tag unless the dive tag is part of the alias. Everything after the
+dive tag is not reported as the alias tag. Also, the "ActualTag" in the before
+case will be the actual tag within the alias that failed.
+
+Here is a list of the current built in alias tags:
+
+ "iscolor"
+ alias is "hexcolor|rgb|rgba|hsl|hsla" (Usage: iscolor)
+ "country_code"
+ alias is "iso3166_1_alpha2|iso3166_1_alpha3|iso3166_1_alpha_numeric" (Usage: country_code)
+
+Validator notes:
+
+ regex
+ a regex validator won't be added because commas and = signs can be part
+ of a regex which conflict with the validation definitions. Although
+ workarounds can be made, they take away from using pure regex's.
+ Furthermore it's quick and dirty but the regex's become harder to
+ maintain and are not reusable, so it's as much a programming philosophy
+ as anything.
+
+ In place of this new validator functions should be created; a regex can
+ be used within the validator function and even be precompiled for better
+ efficiency within regexes.go.
+
+ And the best reason, you can submit a pull request and we can keep on
+ adding to the validation library of this package!
+
+# Non standard validators
+
+A collection of validation rules that are frequently needed but are more
+complex than the ones found in the baked in validators.
+A non standard validator must be registered manually like you would
+with your own custom validation functions.
+
+Example of registration and use:
+
+ type Test struct {
+ TestField string `validate:"yourtag"`
+ }
+
+ t := &Test{
+ TestField: "Test"
+ }
+
+ validate := validator.New()
+ validate.RegisterValidation("yourtag", validators.NotBlank)
+
+Here is a list of the current non standard validators:
+
+ NotBlank
+ This validates that the value is not blank or with length zero.
+ For strings ensures they do not contain only spaces. For channels, maps, slices and arrays
+ ensures they don't have zero length. For others, a non empty value is required.
+
+ Usage: notblank
+
+# Panics
+
+This package panics when bad input is provided, this is by design, bad code like
+that should not make it to production.
+
+ type Test struct {
+ TestField string `validate:"nonexistantfunction=1"`
+ }
+
+ t := &Test{
+ TestField: "Test"
+ }
+
+ validate.Struct(t) // this will panic
+*/
+package validator
diff --git a/vendor/github.com/go-playground/validator/v10/errors.go b/vendor/github.com/go-playground/validator/v10/errors.go
new file mode 100644
index 00000000..fd906256
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/errors.go
@@ -0,0 +1,273 @@
+package validator
+
+import (
+ "bytes"
+ "fmt"
+ "reflect"
+ "strings"
+
+ ut "github.com/go-playground/universal-translator"
+)
+
+const (
+ fieldErrMsg = "Key: '%s' Error:Field validation for '%s' failed on the '%s' tag"
+)
+
+// ValidationErrorsTranslations is the translation return type
+type ValidationErrorsTranslations map[string]string
+
+// InvalidValidationError describes an invalid argument passed to
+// `Struct`, `StructExcept`, StructPartial` or `Field`
+type InvalidValidationError struct {
+ Type reflect.Type
+}
+
+// Error returns InvalidValidationError message
+func (e *InvalidValidationError) Error() string {
+ if e.Type == nil {
+ return "validator: (nil)"
+ }
+
+ return "validator: (nil " + e.Type.String() + ")"
+}
+
+// ValidationErrors is an array of FieldError's
+// for use in custom error messages post validation.
+type ValidationErrors []FieldError
+
+// Error is intended for use in development + debugging and not intended to be a production error message.
+// It allows ValidationErrors to subscribe to the Error interface.
+// All information to create an error message specific to your application is contained within
+// the FieldError found within the ValidationErrors array
+func (ve ValidationErrors) Error() string {
+ buff := bytes.NewBufferString("")
+
+ for i := 0; i < len(ve); i++ {
+ buff.WriteString(ve[i].Error())
+ buff.WriteString("\n")
+ }
+
+ return strings.TrimSpace(buff.String())
+}
+
+// Translate translates all of the ValidationErrors
+func (ve ValidationErrors) Translate(ut ut.Translator) ValidationErrorsTranslations {
+ trans := make(ValidationErrorsTranslations)
+
+ var fe *fieldError
+
+ for i := 0; i < len(ve); i++ {
+ fe = ve[i].(*fieldError)
+
+ // // in case an Anonymous struct was used, ensure that the key
+ // // would be 'Username' instead of ".Username"
+ // if len(fe.ns) > 0 && fe.ns[:1] == "." {
+ // trans[fe.ns[1:]] = fe.Translate(ut)
+ // continue
+ // }
+
+ trans[fe.ns] = fe.Translate(ut)
+ }
+
+ return trans
+}
+
+// FieldError contains all functions to get error details
+type FieldError interface {
+
+ // Tag returns the validation tag that failed. if the
+ // validation was an alias, this will return the
+ // alias name and not the underlying tag that failed.
+ //
+ // eg. alias "iscolor": "hexcolor|rgb|rgba|hsl|hsla"
+ // will return "iscolor"
+ Tag() string
+
+ // ActualTag returns the validation tag that failed, even if an
+ // alias the actual tag within the alias will be returned.
+ // If an 'or' validation fails the entire or will be returned.
+ //
+ // eg. alias "iscolor": "hexcolor|rgb|rgba|hsl|hsla"
+ // will return "hexcolor|rgb|rgba|hsl|hsla"
+ ActualTag() string
+
+ // Namespace returns the namespace for the field error, with the tag
+ // name taking precedence over the field's actual name.
+ //
+ // eg. JSON name "User.fname"
+ //
+ // See StructNamespace() for a version that returns actual names.
+ //
+ // NOTE: this field can be blank when validating a single primitive field
+ // using validate.Field(...) as there is no way to extract it's name
+ Namespace() string
+
+ // StructNamespace returns the namespace for the field error, with the field's
+ // actual name.
+ //
+ // eg. "User.FirstName" see Namespace for comparison
+ //
+ // NOTE: this field can be blank when validating a single primitive field
+ // using validate.Field(...) as there is no way to extract its name
+ StructNamespace() string
+
+ // Field returns the field's name with the tag name taking precedence over the
+ // field's actual name.
+ //
+ // `RegisterTagNameFunc` must be registered to get tag value.
+ //
+ // eg. JSON name "fname"
+ // see StructField for comparison
+ Field() string
+
+ // StructField returns the field's actual name from the struct, when able to determine.
+ //
+ // eg. "FirstName"
+ // see Field for comparison
+ StructField() string
+
+ // Value returns the actual field's value in case needed for creating the error
+ // message
+ Value() interface{}
+
+ // Param returns the param value, in string form for comparison; this will also
+ // help with generating an error message
+ Param() string
+
+ // Kind returns the Field's reflect Kind
+ //
+ // eg. time.Time's kind is a struct
+ Kind() reflect.Kind
+
+ // Type returns the Field's reflect Type
+ //
+ // eg. time.Time's type is time.Time
+ Type() reflect.Type
+
+ // Translate returns the FieldError's translated error
+ // from the provided 'ut.Translator' and registered 'TranslationFunc'
+ //
+ // NOTE: if no registered translator can be found it returns the same as
+ // calling fe.Error()
+ Translate(ut ut.Translator) string
+
+ // Error returns the FieldError's message
+ Error() string
+}
+
+// compile time interface checks
+var _ FieldError = new(fieldError)
+var _ error = new(fieldError)
+
+// fieldError contains a single field's validation error along
+// with other properties that may be needed for error message creation
+// it complies with the FieldError interface
+type fieldError struct {
+ v *Validate
+ tag string
+ actualTag string
+ ns string
+ structNs string
+ fieldLen uint8
+ structfieldLen uint8
+ value interface{}
+ param string
+ kind reflect.Kind
+ typ reflect.Type
+}
+
+// Tag returns the validation tag that failed.
+func (fe *fieldError) Tag() string {
+ return fe.tag
+}
+
+// ActualTag returns the validation tag that failed, even if an
+// alias the actual tag within the alias will be returned.
+func (fe *fieldError) ActualTag() string {
+ return fe.actualTag
+}
+
+// Namespace returns the namespace for the field error, with the tag
+// name taking precedence over the field's actual name.
+func (fe *fieldError) Namespace() string {
+ return fe.ns
+}
+
+// StructNamespace returns the namespace for the field error, with the field's
+// actual name.
+func (fe *fieldError) StructNamespace() string {
+ return fe.structNs
+}
+
+// Field returns the field's name with the tag name taking precedence over the
+// field's actual name.
+func (fe *fieldError) Field() string {
+ return fe.ns[len(fe.ns)-int(fe.fieldLen):]
+ // // return fe.field
+ // fld := fe.ns[len(fe.ns)-int(fe.fieldLen):]
+
+ // log.Println("FLD:", fld)
+
+ // if len(fld) > 0 && fld[:1] == "." {
+ // return fld[1:]
+ // }
+
+ // return fld
+}
+
+// StructField returns the field's actual name from the struct, when able to determine.
+func (fe *fieldError) StructField() string {
+ // return fe.structField
+ return fe.structNs[len(fe.structNs)-int(fe.structfieldLen):]
+}
+
+// Value returns the actual field's value in case needed for creating the error
+// message
+func (fe *fieldError) Value() interface{} {
+ return fe.value
+}
+
+// Param returns the param value, in string form for comparison; this will
+// also help with generating an error message
+func (fe *fieldError) Param() string {
+ return fe.param
+}
+
+// Kind returns the Field's reflect Kind
+func (fe *fieldError) Kind() reflect.Kind {
+ return fe.kind
+}
+
+// Type returns the Field's reflect Type
+func (fe *fieldError) Type() reflect.Type {
+ return fe.typ
+}
+
+// Error returns the fieldError's error message
+func (fe *fieldError) Error() string {
+ return fmt.Sprintf(fieldErrMsg, fe.ns, fe.Field(), fe.tag)
+}
+
+// Translate returns the FieldError's translated error
+// from the provided 'ut.Translator' and registered 'TranslationFunc'
+//
+// NOTE: if no registered translation can be found, it returns the original
+// untranslated error message.
+func (fe *fieldError) Translate(ut ut.Translator) string {
+ var fn TranslationFunc
+
+ m, ok := fe.v.transTagFunc[ut]
+ if !ok {
+ return fe.Error()
+ }
+
+ fn, ok = m[fe.tag]
+ if !ok {
+ fn, ok = m[fe.actualTag]
+ if !ok {
+ return fe.Error()
+ }
+ }
+
+ return fn(ut, fe)
+}
diff --git a/vendor/github.com/go-playground/validator/v10/field_level.go b/vendor/github.com/go-playground/validator/v10/field_level.go
new file mode 100644
index 00000000..ef35826e
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/field_level.go
@@ -0,0 +1,120 @@
+package validator
+
+import "reflect"
+
+// FieldLevel contains all the information and helper functions
+// to validate a field
+type FieldLevel interface {
+
+ // Top returns the top level struct, if any
+ Top() reflect.Value
+
+ // Parent returns the current fields parent struct, if any or
+ // the comparison value if called 'VarWithValue'
+ Parent() reflect.Value
+
+ // Field returns current field for validation
+ Field() reflect.Value
+
+ // FieldName returns the field's name with the tag
+ // name taking precedence over the fields actual name.
+ FieldName() string
+
+ // StructFieldName returns the struct field's name
+ StructFieldName() string
+
+ // Param returns param for validation against current field
+ Param() string
+
+ // GetTag returns the current validations tag name
+ GetTag() string
+
+ // ExtractType gets the actual underlying type of field value.
+ // It will dive into pointers, customTypes and return you the
+ // underlying value and it's kind.
+ ExtractType(field reflect.Value) (value reflect.Value, kind reflect.Kind, nullable bool)
+
+ // GetStructFieldOK traverses the parent struct to retrieve a specific field denoted by the provided namespace
+ // in the param and returns the field, field kind and whether is was successful in retrieving
+ // the field at all.
+ //
+ // NOTE: when not successful ok will be false, this can happen when a nested struct is nil and so the field
+ // could not be retrieved because it didn't exist.
+ //
+ // Deprecated: Use GetStructFieldOK2() instead which also return if the value is nullable.
+ GetStructFieldOK() (reflect.Value, reflect.Kind, bool)
+
+ // GetStructFieldOKAdvanced is the same as GetStructFieldOK except that it accepts the parent struct to start looking for
+ // the field and namespace allowing more extensibility for validators.
+ //
+ // Deprecated: Use GetStructFieldOKAdvanced2() instead which also return if the value is nullable.
+ GetStructFieldOKAdvanced(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool)
+
+ // GetStructFieldOK2 traverses the parent struct to retrieve a specific field denoted by the provided namespace
+ // in the param and returns the field, field kind, if it's a nullable type and whether is was successful in retrieving
+ // the field at all.
+ //
+ // NOTE: when not successful ok will be false, this can happen when a nested struct is nil and so the field
+ // could not be retrieved because it didn't exist.
+ GetStructFieldOK2() (reflect.Value, reflect.Kind, bool, bool)
+
+ // GetStructFieldOKAdvanced2 is the same as GetStructFieldOK except that it accepts the parent struct to start looking for
+ // the field and namespace allowing more extensibility for validators.
+ GetStructFieldOKAdvanced2(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool, bool)
+}
+
+var _ FieldLevel = new(validate)
+
+// Field returns current field for validation
+func (v *validate) Field() reflect.Value {
+ return v.flField
+}
+
+// FieldName returns the field's name with the tag
+// name taking precedence over the fields actual name.
+func (v *validate) FieldName() string {
+ return v.cf.altName
+}
+
+// GetTag returns the current validations tag name
+func (v *validate) GetTag() string {
+ return v.ct.tag
+}
+
+// StructFieldName returns the struct field's name
+func (v *validate) StructFieldName() string {
+ return v.cf.name
+}
+
+// Param returns param for validation against current field
+func (v *validate) Param() string {
+ return v.ct.param
+}
+
+// GetStructFieldOK returns Param returns param for validation against current field
+//
+// Deprecated: Use GetStructFieldOK2() instead which also return if the value is nullable.
+func (v *validate) GetStructFieldOK() (reflect.Value, reflect.Kind, bool) {
+ current, kind, _, found := v.getStructFieldOKInternal(v.slflParent, v.ct.param)
+ return current, kind, found
+}
+
+// GetStructFieldOKAdvanced is the same as GetStructFieldOK except that it accepts the parent struct to start looking for
+// the field and namespace allowing more extensibility for validators.
+//
+// Deprecated: Use GetStructFieldOKAdvanced2() instead which also return if the value is nullable.
+func (v *validate) GetStructFieldOKAdvanced(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool) {
+ current, kind, _, found := v.GetStructFieldOKAdvanced2(val, namespace)
+ return current, kind, found
+}
+
+// GetStructFieldOK2 returns Param returns param for validation against current field
+func (v *validate) GetStructFieldOK2() (reflect.Value, reflect.Kind, bool, bool) {
+ return v.getStructFieldOKInternal(v.slflParent, v.ct.param)
+}
+
+// GetStructFieldOKAdvanced2 is the same as GetStructFieldOK except that it accepts the parent struct to start looking for
+// the field and namespace allowing more extensibility for validators.
+func (v *validate) GetStructFieldOKAdvanced2(val reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool, bool) {
+ return v.getStructFieldOKInternal(val, namespace)
+}
diff --git a/vendor/github.com/go-playground/validator/v10/logo.png b/vendor/github.com/go-playground/validator/v10/logo.png
new file mode 100644
index 00000000..355000f5
Binary files /dev/null and b/vendor/github.com/go-playground/validator/v10/logo.png differ
diff --git a/vendor/github.com/go-playground/validator/v10/options.go b/vendor/github.com/go-playground/validator/v10/options.go
new file mode 100644
index 00000000..86a0db21
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/options.go
@@ -0,0 +1,26 @@
+package validator
+
+// Option represents a configurations option to be applied to validator during initialization.
+type Option func(*Validate)
+
+// WithRequiredStructEnabled enables required tag on non-pointer structs to be applied instead of ignored.
+//
+// This was made opt-in behaviour in order to maintain backward compatibility with the behaviour previous
+// to being able to apply struct level validations on struct fields directly.
+//
+// It is recommended you enabled this as it will be the default behaviour in v11+
+func WithRequiredStructEnabled() Option {
+ return func(v *Validate) {
+ v.requiredStructEnabled = true
+ }
+}
+
+// WithPrivateFieldValidation activates validation for unexported fields via the use of the `unsafe` package.
+//
+// By opting into this feature you are acknowledging that you are aware of the risks and accept any current or future
+// consequences of using this feature.
+func WithPrivateFieldValidation() Option {
+ return func(v *Validate) {
+ v.privateFieldValidation = true
+ }
+}
diff --git a/vendor/github.com/go-playground/validator/v10/postcode_regexes.go b/vendor/github.com/go-playground/validator/v10/postcode_regexes.go
new file mode 100644
index 00000000..326b8f75
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/postcode_regexes.go
@@ -0,0 +1,179 @@
+package validator
+
+import (
+ "regexp"
+ "sync"
+)
+
+var postCodePatternDict = map[string]string{
+ "GB": `^GIR[ ]?0AA|((AB|AL|B|BA|BB|BD|BH|BL|BN|BR|BS|BT|CA|CB|CF|CH|CM|CO|CR|CT|CV|CW|DA|DD|DE|DG|DH|DL|DN|DT|DY|E|EC|EH|EN|EX|FK|FY|G|GL|GY|GU|HA|HD|HG|HP|HR|HS|HU|HX|IG|IM|IP|IV|JE|KA|KT|KW|KY|L|LA|LD|LE|LL|LN|LS|LU|M|ME|MK|ML|N|NE|NG|NN|NP|NR|NW|OL|OX|PA|PE|PH|PL|PO|PR|RG|RH|RM|S|SA|SE|SG|SK|SL|SM|SN|SO|SP|SR|SS|ST|SW|SY|TA|TD|TF|TN|TQ|TR|TS|TW|UB|W|WA|WC|WD|WF|WN|WR|WS|WV|YO|ZE)(\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}))|BFPO[ ]?\d{1,4}$`,
+ "JE": `^JE\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}$`,
+ "GG": `^GY\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}$`,
+ "IM": `^IM\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}$`,
+ "US": `^\d{5}([ \-]\d{4})?$`,
+ "CA": `^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][ ]?\d[ABCEGHJ-NPRSTV-Z]\d$`,
+ "DE": `^\d{5}$`,
+ "JP": `^\d{3}-\d{4}$`,
+ "FR": `^\d{2}[ ]?\d{3}$`,
+ "AU": `^\d{4}$`,
+ "IT": `^\d{5}$`,
+ "CH": `^\d{4}$`,
+ "AT": `^\d{4}$`,
+ "ES": `^\d{5}$`,
+ "NL": `^\d{4}[ ]?[A-Z]{2}$`,
+ "BE": `^\d{4}$`,
+ "DK": `^\d{4}$`,
+ "SE": `^\d{3}[ ]?\d{2}$`,
+ "NO": `^\d{4}$`,
+ "BR": `^\d{5}[\-]?\d{3}$`,
+ "PT": `^\d{4}([\-]\d{3})?$`,
+ "FI": `^\d{5}$`,
+ "AX": `^22\d{3}$`,
+ "KR": `^\d{3}[\-]\d{3}$`,
+ "CN": `^\d{6}$`,
+ "TW": `^\d{3}(\d{2})?$`,
+ "SG": `^\d{6}$`,
+ "DZ": `^\d{5}$`,
+ "AD": `^AD\d{3}$`,
+ "AR": `^([A-HJ-NP-Z])?\d{4}([A-Z]{3})?$`,
+ "AM": `^(37)?\d{4}$`,
+ "AZ": `^\d{4}$`,
+ "BH": `^((1[0-2]|[2-9])\d{2})?$`,
+ "BD": `^\d{4}$`,
+ "BB": `^(BB\d{5})?$`,
+ "BY": `^\d{6}$`,
+ "BM": `^[A-Z]{2}[ ]?[A-Z0-9]{2}$`,
+ "BA": `^\d{5}$`,
+ "IO": `^BBND 1ZZ$`,
+ "BN": `^[A-Z]{2}[ ]?\d{4}$`,
+ "BG": `^\d{4}$`,
+ "KH": `^\d{5}$`,
+ "CV": `^\d{4}$`,
+ "CL": `^\d{7}$`,
+ "CR": `^\d{4,5}|\d{3}-\d{4}$`,
+ "HR": `^\d{5}$`,
+ "CY": `^\d{4}$`,
+ "CZ": `^\d{3}[ ]?\d{2}$`,
+ "DO": `^\d{5}$`,
+ "EC": `^([A-Z]\d{4}[A-Z]|(?:[A-Z]{2})?\d{6})?$`,
+ "EG": `^\d{5}$`,
+ "EE": `^\d{5}$`,
+ "FO": `^\d{3}$`,
+ "GE": `^\d{4}$`,
+ "GR": `^\d{3}[ ]?\d{2}$`,
+ "GL": `^39\d{2}$`,
+ "GT": `^\d{5}$`,
+ "HT": `^\d{4}$`,
+ "HN": `^(?:\d{5})?$`,
+ "HU": `^\d{4}$`,
+ "IS": `^\d{3}$`,
+ "IN": `^\d{6}$`,
+ "ID": `^\d{5}$`,
+ "IL": `^\d{5}$`,
+ "JO": `^\d{5}$`,
+ "KZ": `^\d{6}$`,
+ "KE": `^\d{5}$`,
+ "KW": `^\d{5}$`,
+ "LA": `^\d{5}$`,
+ "LV": `^\d{4}$`,
+ "LB": `^(\d{4}([ ]?\d{4})?)?$`,
+ "LI": `^(948[5-9])|(949[0-7])$`,
+ "LT": `^\d{5}$`,
+ "LU": `^\d{4}$`,
+ "MK": `^\d{4}$`,
+ "MY": `^\d{5}$`,
+ "MV": `^\d{5}$`,
+ "MT": `^[A-Z]{3}[ ]?\d{2,4}$`,
+ "MU": `^(\d{3}[A-Z]{2}\d{3})?$`,
+ "MX": `^\d{5}$`,
+ "MD": `^\d{4}$`,
+ "MC": `^980\d{2}$`,
+ "MA": `^\d{5}$`,
+ "NP": `^\d{5}$`,
+ "NZ": `^\d{4}$`,
+ "NI": `^((\d{4}-)?\d{3}-\d{3}(-\d{1})?)?$`,
+ "NG": `^(\d{6})?$`,
+ "OM": `^(PC )?\d{3}$`,
+ "PK": `^\d{5}$`,
+ "PY": `^\d{4}$`,
+ "PH": `^\d{4}$`,
+ "PL": `^\d{2}-\d{3}$`,
+ "PR": `^00[679]\d{2}([ \-]\d{4})?$`,
+ "RO": `^\d{6}$`,
+ "RU": `^\d{6}$`,
+ "SM": `^4789\d$`,
+ "SA": `^\d{5}$`,
+ "SN": `^\d{5}$`,
+ "SK": `^\d{3}[ ]?\d{2}$`,
+ "SI": `^\d{4}$`,
+ "ZA": `^\d{4}$`,
+ "LK": `^\d{5}$`,
+ "TJ": `^\d{6}$`,
+ "TH": `^\d{5}$`,
+ "TN": `^\d{4}$`,
+ "TR": `^\d{5}$`,
+ "TM": `^\d{6}$`,
+ "UA": `^\d{5}$`,
+ "UY": `^\d{5}$`,
+ "UZ": `^\d{6}$`,
+ "VA": `^00120$`,
+ "VE": `^\d{4}$`,
+ "ZM": `^\d{5}$`,
+ "AS": `^96799$`,
+ "CC": `^6799$`,
+ "CK": `^\d{4}$`,
+ "RS": `^\d{6}$`,
+ "ME": `^8\d{4}$`,
+ "CS": `^\d{5}$`,
+ "YU": `^\d{5}$`,
+ "CX": `^6798$`,
+ "ET": `^\d{4}$`,
+ "FK": `^FIQQ 1ZZ$`,
+ "NF": `^2899$`,
+ "FM": `^(9694[1-4])([ \-]\d{4})?$`,
+ "GF": `^9[78]3\d{2}$`,
+ "GN": `^\d{3}$`,
+ "GP": `^9[78][01]\d{2}$`,
+ "GS": `^SIQQ 1ZZ$`,
+ "GU": `^969[123]\d([ \-]\d{4})?$`,
+ "GW": `^\d{4}$`,
+ "HM": `^\d{4}$`,
+ "IQ": `^\d{5}$`,
+ "KG": `^\d{6}$`,
+ "LR": `^\d{4}$`,
+ "LS": `^\d{3}$`,
+ "MG": `^\d{3}$`,
+ "MH": `^969[67]\d([ \-]\d{4})?$`,
+ "MN": `^\d{6}$`,
+ "MP": `^9695[012]([ \-]\d{4})?$`,
+ "MQ": `^9[78]2\d{2}$`,
+ "NC": `^988\d{2}$`,
+ "NE": `^\d{4}$`,
+ "VI": `^008(([0-4]\d)|(5[01]))([ \-]\d{4})?$`,
+ "VN": `^[0-9]{1,6}$`,
+ "PF": `^987\d{2}$`,
+ "PG": `^\d{3}$`,
+ "PM": `^9[78]5\d{2}$`,
+ "PN": `^PCRN 1ZZ$`,
+ "PW": `^96940$`,
+ "RE": `^9[78]4\d{2}$`,
+ "SH": `^(ASCN|STHL) 1ZZ$`,
+ "SJ": `^\d{4}$`,
+ "SO": `^\d{5}$`,
+ "SZ": `^[HLMS]\d{3}$`,
+ "TC": `^TKCA 1ZZ$`,
+ "WF": `^986\d{2}$`,
+ "XK": `^\d{5}$`,
+ "YT": `^976\d{2}$`,
+}
+
+var (
+ postcodeRegexInit sync.Once
+ postCodeRegexDict = map[string]*regexp.Regexp{}
+)
+
+func initPostcodes() {
+ for countryCode, pattern := range postCodePatternDict {
+ postCodeRegexDict[countryCode] = regexp.MustCompile(pattern)
+ }
+}
diff --git a/vendor/github.com/go-playground/validator/v10/regexes.go b/vendor/github.com/go-playground/validator/v10/regexes.go
new file mode 100644
index 00000000..93909b2e
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/regexes.go
@@ -0,0 +1,165 @@
+package validator
+
+import (
+ "regexp"
+ "sync"
+)
+
+const (
+ alphaRegexString = "^[a-zA-Z]+$"
+ alphaNumericRegexString = "^[a-zA-Z0-9]+$"
+ alphaUnicodeRegexString = "^[\\p{L}]+$"
+ alphaUnicodeNumericRegexString = "^[\\p{L}\\p{N}]+$"
+ numericRegexString = "^[-+]?[0-9]+(?:\\.[0-9]+)?$"
+ numberRegexString = "^[0-9]+$"
+ hexadecimalRegexString = "^(0[xX])?[0-9a-fA-F]+$"
+ hexColorRegexString = "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
+ rgbRegexString = "^rgb\\(\\s*(?:(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])|(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%)\\s*\\)$"
+ rgbaRegexString = "^rgba\\(\\s*(?:(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])|(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%)\\s*,\\s*(?:(?:0.[1-9]*)|[01])\\s*\\)$"
+ hslRegexString = "^hsl\\(\\s*(?:0|[1-9]\\d?|[12]\\d\\d|3[0-5]\\d|360)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*\\)$"
+ hslaRegexString = "^hsla\\(\\s*(?:0|[1-9]\\d?|[12]\\d\\d|3[0-5]\\d|360)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*,\\s*(?:(?:0.[1-9]*)|[01])\\s*\\)$"
+ emailRegexString = "^(?:(?:(?:(?:[a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(?:\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|(?:(?:\\x22)(?:(?:(?:(?:\\x20|\\x09)*(?:\\x0d\\x0a))?(?:\\x20|\\x09)+)?(?:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(?:(?:(?:\\x20|\\x09)*(?:\\x0d\\x0a))?(\\x20|\\x09)+)?(?:\\x22))))@(?:(?:(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])(?:[a-zA-Z]|\\d|-|\\.|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(?:(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])(?:[a-zA-Z]|\\d|-|\\.|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$"
+ e164RegexString = "^\\+[1-9]?[0-9]{7,14}$"
+ base32RegexString = "^(?:[A-Z2-7]{8})*(?:[A-Z2-7]{2}={6}|[A-Z2-7]{4}={4}|[A-Z2-7]{5}={3}|[A-Z2-7]{7}=|[A-Z2-7]{8})$"
+ base64RegexString = "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$"
+ base64URLRegexString = "^(?:[A-Za-z0-9-_]{4})*(?:[A-Za-z0-9-_]{2}==|[A-Za-z0-9-_]{3}=|[A-Za-z0-9-_]{4})$"
+ base64RawURLRegexString = "^(?:[A-Za-z0-9-_]{4})*(?:[A-Za-z0-9-_]{2,4})$"
+ iSBN10RegexString = "^(?:[0-9]{9}X|[0-9]{10})$"
+ iSBN13RegexString = "^(?:(?:97(?:8|9))[0-9]{10})$"
+ iSSNRegexString = "^(?:[0-9]{4}-[0-9]{3}[0-9X])$"
+ uUID3RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$"
+ uUID4RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
+ uUID5RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"
+ uUIDRegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
+ uUID3RFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-3[0-9a-fA-F]{3}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
+ uUID4RFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"
+ uUID5RFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-5[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$"
+ uUIDRFC4122RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"
+ uLIDRegexString = "^(?i)[A-HJKMNP-TV-Z0-9]{26}$"
+ md4RegexString = "^[0-9a-f]{32}$"
+ md5RegexString = "^[0-9a-f]{32}$"
+ sha256RegexString = "^[0-9a-f]{64}$"
+ sha384RegexString = "^[0-9a-f]{96}$"
+ sha512RegexString = "^[0-9a-f]{128}$"
+ ripemd128RegexString = "^[0-9a-f]{32}$"
+ ripemd160RegexString = "^[0-9a-f]{40}$"
+ tiger128RegexString = "^[0-9a-f]{32}$"
+ tiger160RegexString = "^[0-9a-f]{40}$"
+ tiger192RegexString = "^[0-9a-f]{48}$"
+ aSCIIRegexString = "^[\x00-\x7F]*$"
+ printableASCIIRegexString = "^[\x20-\x7E]*$"
+ multibyteRegexString = "[^\x00-\x7F]"
+ dataURIRegexString = `^data:((?:\w+\/(?:([^;]|;[^;]).)+)?)`
+ latitudeRegexString = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$"
+ longitudeRegexString = "^[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)$"
+ sSNRegexString = `^[0-9]{3}[ -]?(0[1-9]|[1-9][0-9])[ -]?([1-9][0-9]{3}|[0-9][1-9][0-9]{2}|[0-9]{2}[1-9][0-9]|[0-9]{3}[1-9])$`
+ hostnameRegexStringRFC952 = `^[a-zA-Z]([a-zA-Z0-9\-]+[\.]?)*[a-zA-Z0-9]$` // https://tools.ietf.org/html/rfc952
+ hostnameRegexStringRFC1123 = `^([a-zA-Z0-9]{1}[a-zA-Z0-9-]{0,62}){1}(\.[a-zA-Z0-9]{1}[a-zA-Z0-9-]{0,62})*?$` // accepts hostname starting with a digit https://tools.ietf.org/html/rfc1123
+ fqdnRegexStringRFC1123 = `^([a-zA-Z0-9]{1}[a-zA-Z0-9-]{0,62})(\.[a-zA-Z0-9]{1}[a-zA-Z0-9-]{0,62})*?(\.[a-zA-Z]{1}[a-zA-Z0-9]{0,62})\.?$` // same as hostnameRegexStringRFC1123 but must contain a non numerical TLD (possibly ending with '.')
+ btcAddressRegexString = `^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$` // bitcoin address
+ btcAddressUpperRegexStringBech32 = `^BC1[02-9AC-HJ-NP-Z]{7,76}$` // bitcoin bech32 address https://en.bitcoin.it/wiki/Bech32
+ btcAddressLowerRegexStringBech32 = `^bc1[02-9ac-hj-np-z]{7,76}$` // bitcoin bech32 address https://en.bitcoin.it/wiki/Bech32
+ ethAddressRegexString = `^0x[0-9a-fA-F]{40}$`
+ ethAddressUpperRegexString = `^0x[0-9A-F]{40}$`
+ ethAddressLowerRegexString = `^0x[0-9a-f]{40}$`
+ uRLEncodedRegexString = `^(?:[^%]|%[0-9A-Fa-f]{2})*$`
+ hTMLEncodedRegexString = `[x]?([0-9a-fA-F]{2})|(>)|(<)|(")|(&)+[;]?`
+ hTMLRegexString = `<[/]?([a-zA-Z]+).*?>`
+ jWTRegexString = "^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$"
+ splitParamsRegexString = `'[^']*'|\S+`
+ bicRegexString = `^[A-Za-z]{6}[A-Za-z0-9]{2}([A-Za-z0-9]{3})?$`
+ semverRegexString = `^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$` // numbered capture groups https://semver.org/
+ dnsRegexStringRFC1035Label = "^[a-z]([-a-z0-9]*[a-z0-9])?$"
+ cveRegexString = `^CVE-(1999|2\d{3})-(0[^0]\d{2}|0\d[^0]\d{1}|0\d{2}[^0]|[1-9]{1}\d{3,})$` // CVE Format Id https://cve.mitre.org/cve/identifiers/syntaxchange.html
+ mongodbIdRegexString = "^[a-f\\d]{24}$"
+ mongodbConnStringRegexString = "^mongodb(\\+srv)?:\\/\\/(([a-zA-Z\\d]+):([a-zA-Z\\d$:\\/?#\\[\\]@]+)@)?(([a-z\\d.-]+)(:[\\d]+)?)((,(([a-z\\d.-]+)(:(\\d+))?))*)?(\\/[a-zA-Z-_]{1,64})?(\\?(([a-zA-Z]+)=([a-zA-Z\\d]+))(&(([a-zA-Z\\d]+)=([a-zA-Z\\d]+))?)*)?$"
+ cronRegexString = `(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every (\d+(ns|us|µs|ms|s|m|h))+)|((((\d+,)+\d+|((\*|\d+)(\/|-)\d+)|\d+|\*) ?){5,7})`
+ spicedbIDRegexString = `^(([a-zA-Z0-9/_|\-=+]{1,})|\*)$`
+ spicedbPermissionRegexString = "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
+ spicedbTypeRegexString = "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)?[a-z][a-z0-9_]{1,62}[a-z0-9]$"
+ einRegexString = "^(\\d{2}-\\d{7})$"
+)
+
+func lazyRegexCompile(str string) func() *regexp.Regexp {
+ var regex *regexp.Regexp
+ var once sync.Once
+ return func() *regexp.Regexp {
+ once.Do(func() {
+ regex = regexp.MustCompile(str)
+ })
+ return regex
+ }
+}
+
+var (
+ alphaRegex = lazyRegexCompile(alphaRegexString)
+ alphaNumericRegex = lazyRegexCompile(alphaNumericRegexString)
+ alphaUnicodeRegex = lazyRegexCompile(alphaUnicodeRegexString)
+ alphaUnicodeNumericRegex = lazyRegexCompile(alphaUnicodeNumericRegexString)
+ numericRegex = lazyRegexCompile(numericRegexString)
+ numberRegex = lazyRegexCompile(numberRegexString)
+ hexadecimalRegex = lazyRegexCompile(hexadecimalRegexString)
+ hexColorRegex = lazyRegexCompile(hexColorRegexString)
+ rgbRegex = lazyRegexCompile(rgbRegexString)
+ rgbaRegex = lazyRegexCompile(rgbaRegexString)
+ hslRegex = lazyRegexCompile(hslRegexString)
+ hslaRegex = lazyRegexCompile(hslaRegexString)
+ e164Regex = lazyRegexCompile(e164RegexString)
+ emailRegex = lazyRegexCompile(emailRegexString)
+ base32Regex = lazyRegexCompile(base32RegexString)
+ base64Regex = lazyRegexCompile(base64RegexString)
+ base64URLRegex = lazyRegexCompile(base64URLRegexString)
+ base64RawURLRegex = lazyRegexCompile(base64RawURLRegexString)
+ iSBN10Regex = lazyRegexCompile(iSBN10RegexString)
+ iSBN13Regex = lazyRegexCompile(iSBN13RegexString)
+ iSSNRegex = lazyRegexCompile(iSSNRegexString)
+ uUID3Regex = lazyRegexCompile(uUID3RegexString)
+ uUID4Regex = lazyRegexCompile(uUID4RegexString)
+ uUID5Regex = lazyRegexCompile(uUID5RegexString)
+ uUIDRegex = lazyRegexCompile(uUIDRegexString)
+ uUID3RFC4122Regex = lazyRegexCompile(uUID3RFC4122RegexString)
+ uUID4RFC4122Regex = lazyRegexCompile(uUID4RFC4122RegexString)
+ uUID5RFC4122Regex = lazyRegexCompile(uUID5RFC4122RegexString)
+ uUIDRFC4122Regex = lazyRegexCompile(uUIDRFC4122RegexString)
+ uLIDRegex = lazyRegexCompile(uLIDRegexString)
+ md4Regex = lazyRegexCompile(md4RegexString)
+ md5Regex = lazyRegexCompile(md5RegexString)
+ sha256Regex = lazyRegexCompile(sha256RegexString)
+ sha384Regex = lazyRegexCompile(sha384RegexString)
+ sha512Regex = lazyRegexCompile(sha512RegexString)
+ ripemd128Regex = lazyRegexCompile(ripemd128RegexString)
+ ripemd160Regex = lazyRegexCompile(ripemd160RegexString)
+ tiger128Regex = lazyRegexCompile(tiger128RegexString)
+ tiger160Regex = lazyRegexCompile(tiger160RegexString)
+ tiger192Regex = lazyRegexCompile(tiger192RegexString)
+ aSCIIRegex = lazyRegexCompile(aSCIIRegexString)
+ printableASCIIRegex = lazyRegexCompile(printableASCIIRegexString)
+ multibyteRegex = lazyRegexCompile(multibyteRegexString)
+ dataURIRegex = lazyRegexCompile(dataURIRegexString)
+ latitudeRegex = lazyRegexCompile(latitudeRegexString)
+ longitudeRegex = lazyRegexCompile(longitudeRegexString)
+ sSNRegex = lazyRegexCompile(sSNRegexString)
+ hostnameRegexRFC952 = lazyRegexCompile(hostnameRegexStringRFC952)
+ hostnameRegexRFC1123 = lazyRegexCompile(hostnameRegexStringRFC1123)
+ fqdnRegexRFC1123 = lazyRegexCompile(fqdnRegexStringRFC1123)
+ btcAddressRegex = lazyRegexCompile(btcAddressRegexString)
+ btcUpperAddressRegexBech32 = lazyRegexCompile(btcAddressUpperRegexStringBech32)
+ btcLowerAddressRegexBech32 = lazyRegexCompile(btcAddressLowerRegexStringBech32)
+ ethAddressRegex = lazyRegexCompile(ethAddressRegexString)
+ uRLEncodedRegex = lazyRegexCompile(uRLEncodedRegexString)
+ hTMLEncodedRegex = lazyRegexCompile(hTMLEncodedRegexString)
+ hTMLRegex = lazyRegexCompile(hTMLRegexString)
+ jWTRegex = lazyRegexCompile(jWTRegexString)
+ splitParamsRegex = lazyRegexCompile(splitParamsRegexString)
+ bicRegex = lazyRegexCompile(bicRegexString)
+ semverRegex = lazyRegexCompile(semverRegexString)
+ dnsRegexRFC1035Label = lazyRegexCompile(dnsRegexStringRFC1035Label)
+ cveRegex = lazyRegexCompile(cveRegexString)
+ mongodbIdRegex = lazyRegexCompile(mongodbIdRegexString)
+ mongodbConnectionRegex = lazyRegexCompile(mongodbConnStringRegexString)
+ cronRegex = lazyRegexCompile(cronRegexString)
+ spicedbIDRegex = lazyRegexCompile(spicedbIDRegexString)
+ spicedbPermissionRegex = lazyRegexCompile(spicedbPermissionRegexString)
+ spicedbTypeRegex = lazyRegexCompile(spicedbTypeRegexString)
+ einRegex = lazyRegexCompile(einRegexString)
+)
diff --git a/vendor/github.com/go-playground/validator/v10/struct_level.go b/vendor/github.com/go-playground/validator/v10/struct_level.go
new file mode 100644
index 00000000..129b2872
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/struct_level.go
@@ -0,0 +1,171 @@
+package validator
+
+import (
+ "context"
+ "reflect"
+)
+
+// StructLevelFunc accepts all values needed for struct level validation
+type StructLevelFunc func(sl StructLevel)
+
+// StructLevelFuncCtx accepts all values needed for struct level validation
+// but also allows passing of contextual validation information via context.Context.
+type StructLevelFuncCtx func(ctx context.Context, sl StructLevel)
+
+// wrapStructLevelFunc wraps normal StructLevelFunc makes it compatible with StructLevelFuncCtx
+func wrapStructLevelFunc(fn StructLevelFunc) StructLevelFuncCtx {
+ return func(ctx context.Context, sl StructLevel) {
+ fn(sl)
+ }
+}
+
+// StructLevel contains all the information and helper functions
+// to validate a struct
+type StructLevel interface {
+
+ // Validator returns the main validation object, in case one wants to call validations internally.
+ // this is so you don't have to use anonymous functions to get access to the validate
+ // instance.
+ Validator() *Validate
+
+ // Top returns the top level struct, if any
+ Top() reflect.Value
+
+ // Parent returns the current fields parent struct, if any
+ Parent() reflect.Value
+
+ // Current returns the current struct.
+ Current() reflect.Value
+
+ // ExtractType gets the actual underlying type of field value.
+ // It will dive into pointers, customTypes and return you the
+ // underlying value and its kind.
+ ExtractType(field reflect.Value) (value reflect.Value, kind reflect.Kind, nullable bool)
+
+ // ReportError reports an error just by passing the field and tag information
+ //
+ // NOTES:
+ //
+ // fieldName and structFieldName get appended to the existing
+ // namespace that validator is on. e.g. pass 'FirstName' or
+ // 'Names[0]' depending on the nesting
+ //
+ // tag can be an existing validation tag or just something you make up
+ // and process on the flip side it's up to you.
+ ReportError(field interface{}, fieldName, structFieldName string, tag, param string)
+
+ // ReportValidationErrors reports an error just by passing ValidationErrors
+ //
+ // NOTES:
+ //
+ // relativeNamespace and relativeActualNamespace get appended to the
+ // existing namespace that validator is on.
+ // e.g. pass 'User.FirstName' or 'Users[0].FirstName' depending
+ // on the nesting. most of the time they will be blank, unless you validate
+ // at a level lower the current field depth
+ ReportValidationErrors(relativeNamespace, relativeActualNamespace string, errs ValidationErrors)
+}
+
+var _ StructLevel = new(validate)
+
+// Top returns the top level struct
+//
+// NOTE: this can be the same as the current struct being validated
+// if not is a nested struct.
+//
+// this is only called when within Struct and Field Level validation and
+// should not be relied upon for an accurate value otherwise.
+func (v *validate) Top() reflect.Value {
+ return v.top
+}
+
+// Parent returns the current structs parent
+//
+// NOTE: this can be the same as the current struct being validated
+// if not is a nested struct.
+//
+// this is only called when within Struct and Field Level validation and
+// should not be relied upon for an accurate value otherwise.
+func (v *validate) Parent() reflect.Value {
+ return v.slflParent
+}
+
+// Current returns the current struct.
+func (v *validate) Current() reflect.Value {
+ return v.slCurrent
+}
+
+// Validator returns the main validation object, in case one want to call validations internally.
+func (v *validate) Validator() *Validate {
+ return v.v
+}
+
+// ExtractType gets the actual underlying type of field value.
+func (v *validate) ExtractType(field reflect.Value) (reflect.Value, reflect.Kind, bool) {
+ return v.extractTypeInternal(field, false)
+}
+
+// ReportError reports an error just by passing the field and tag information
+func (v *validate) ReportError(field interface{}, fieldName, structFieldName, tag, param string) {
+ fv, kind, _ := v.extractTypeInternal(reflect.ValueOf(field), false)
+
+ if len(structFieldName) == 0 {
+ structFieldName = fieldName
+ }
+
+ v.str1 = string(append(v.ns, fieldName...))
+
+ if v.v.hasTagNameFunc || fieldName != structFieldName {
+ v.str2 = string(append(v.actualNs, structFieldName...))
+ } else {
+ v.str2 = v.str1
+ }
+
+ if kind == reflect.Invalid {
+ v.errs = append(v.errs,
+ &fieldError{
+ v: v.v,
+ tag: tag,
+ actualTag: tag,
+ ns: v.str1,
+ structNs: v.str2,
+ fieldLen: uint8(len(fieldName)),
+ structfieldLen: uint8(len(structFieldName)),
+ param: param,
+ kind: kind,
+ },
+ )
+ return
+ }
+
+ v.errs = append(v.errs,
+ &fieldError{
+ v: v.v,
+ tag: tag,
+ actualTag: tag,
+ ns: v.str1,
+ structNs: v.str2,
+ fieldLen: uint8(len(fieldName)),
+ structfieldLen: uint8(len(structFieldName)),
+ value: getValue(fv),
+ param: param,
+ kind: kind,
+ typ: fv.Type(),
+ },
+ )
+}
+
+// ReportValidationErrors reports ValidationErrors obtained from running validations within the Struct Level validation.
+//
+// NOTE: this function prepends the current namespace to the relative ones.
+func (v *validate) ReportValidationErrors(relativeNamespace, relativeStructNamespace string, errs ValidationErrors) {
+ var err *fieldError
+
+ for i := 0; i < len(errs); i++ {
+ err = errs[i].(*fieldError)
+ err.ns = string(append(append(v.ns, relativeNamespace...), err.ns...))
+ err.structNs = string(append(append(v.actualNs, relativeStructNamespace...), err.structNs...))
+
+ v.errs = append(v.errs, err)
+ }
+}
diff --git a/vendor/github.com/go-playground/validator/v10/translations.go b/vendor/github.com/go-playground/validator/v10/translations.go
new file mode 100644
index 00000000..4d9d75c1
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/translations.go
@@ -0,0 +1,11 @@
+package validator
+
+import ut "github.com/go-playground/universal-translator"
+
+// TranslationFunc is the function type used to register or override
+// custom translations
+type TranslationFunc func(ut ut.Translator, fe FieldError) string
+
+// RegisterTranslationsFunc allows for registering of translations
+// for a 'ut.Translator' for use within the 'TranslationFunc'
+type RegisterTranslationsFunc func(ut ut.Translator) error
diff --git a/vendor/github.com/go-playground/validator/v10/util.go b/vendor/github.com/go-playground/validator/v10/util.go
new file mode 100644
index 00000000..b1fd8cc1
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/util.go
@@ -0,0 +1,305 @@
+package validator
+
+import (
+ "fmt"
+ "reflect"
+ "regexp"
+ "strconv"
+ "strings"
+ "time"
+)
+
+// extractTypeInternal gets the actual underlying type of field value.
+// It will dive into pointers, customTypes and return you the
+// underlying value and it's kind.
+func (v *validate) extractTypeInternal(current reflect.Value, nullable bool) (reflect.Value, reflect.Kind, bool) {
+BEGIN:
+ switch current.Kind() {
+ case reflect.Ptr:
+
+ nullable = true
+
+ if current.IsNil() {
+ return current, reflect.Ptr, nullable
+ }
+
+ current = current.Elem()
+ goto BEGIN
+
+ case reflect.Interface:
+
+ nullable = true
+
+ if current.IsNil() {
+ return current, reflect.Interface, nullable
+ }
+
+ current = current.Elem()
+ goto BEGIN
+
+ case reflect.Invalid:
+ return current, reflect.Invalid, nullable
+
+ default:
+
+ if v.v.hasCustomFuncs {
+ if fn, ok := v.v.customFuncs[current.Type()]; ok {
+ current = reflect.ValueOf(fn(current))
+ goto BEGIN
+ }
+ }
+
+ return current, current.Kind(), nullable
+ }
+}
+
+// getStructFieldOKInternal traverses a struct to retrieve a specific field denoted by the provided namespace and
+// returns the field, field kind and whether is was successful in retrieving the field at all.
+//
+// NOTE: when not successful ok will be false, this can happen when a nested struct is nil and so the field
+// could not be retrieved because it didn't exist.
+func (v *validate) getStructFieldOKInternal(val reflect.Value, namespace string) (current reflect.Value, kind reflect.Kind, nullable bool, found bool) {
+BEGIN:
+ current, kind, nullable = v.ExtractType(val)
+ if kind == reflect.Invalid {
+ return
+ }
+
+ if namespace == "" {
+ found = true
+ return
+ }
+
+ switch kind {
+ case reflect.Ptr, reflect.Interface:
+ return
+
+ case reflect.Struct:
+
+ typ := current.Type()
+ fld := namespace
+ var ns string
+
+ if !typ.ConvertibleTo(timeType) {
+ idx := strings.Index(namespace, namespaceSeparator)
+
+ if idx != -1 {
+ fld = namespace[:idx]
+ ns = namespace[idx+1:]
+ } else {
+ ns = ""
+ }
+
+ bracketIdx := strings.Index(fld, leftBracket)
+ if bracketIdx != -1 {
+ fld = fld[:bracketIdx]
+
+ ns = namespace[bracketIdx:]
+ }
+
+ val = current.FieldByName(fld)
+ namespace = ns
+ goto BEGIN
+ }
+
+ case reflect.Array, reflect.Slice:
+ idx := strings.Index(namespace, leftBracket)
+ idx2 := strings.Index(namespace, rightBracket)
+
+ arrIdx, _ := strconv.Atoi(namespace[idx+1 : idx2])
+
+ if arrIdx >= current.Len() {
+ return
+ }
+
+ startIdx := idx2 + 1
+
+ if startIdx < len(namespace) {
+ if namespace[startIdx:startIdx+1] == namespaceSeparator {
+ startIdx++
+ }
+ }
+
+ val = current.Index(arrIdx)
+ namespace = namespace[startIdx:]
+ goto BEGIN
+
+ case reflect.Map:
+ idx := strings.Index(namespace, leftBracket) + 1
+ idx2 := strings.Index(namespace, rightBracket)
+
+ endIdx := idx2
+
+ if endIdx+1 < len(namespace) {
+ if namespace[endIdx+1:endIdx+2] == namespaceSeparator {
+ endIdx++
+ }
+ }
+
+ key := namespace[idx:idx2]
+
+ switch current.Type().Key().Kind() {
+ case reflect.Int:
+ i, _ := strconv.Atoi(key)
+ val = current.MapIndex(reflect.ValueOf(i))
+ namespace = namespace[endIdx+1:]
+
+ case reflect.Int8:
+ i, _ := strconv.ParseInt(key, 10, 8)
+ val = current.MapIndex(reflect.ValueOf(int8(i)))
+ namespace = namespace[endIdx+1:]
+
+ case reflect.Int16:
+ i, _ := strconv.ParseInt(key, 10, 16)
+ val = current.MapIndex(reflect.ValueOf(int16(i)))
+ namespace = namespace[endIdx+1:]
+
+ case reflect.Int32:
+ i, _ := strconv.ParseInt(key, 10, 32)
+ val = current.MapIndex(reflect.ValueOf(int32(i)))
+ namespace = namespace[endIdx+1:]
+
+ case reflect.Int64:
+ i, _ := strconv.ParseInt(key, 10, 64)
+ val = current.MapIndex(reflect.ValueOf(i))
+ namespace = namespace[endIdx+1:]
+
+ case reflect.Uint:
+ i, _ := strconv.ParseUint(key, 10, 0)
+ val = current.MapIndex(reflect.ValueOf(uint(i)))
+ namespace = namespace[endIdx+1:]
+
+ case reflect.Uint8:
+ i, _ := strconv.ParseUint(key, 10, 8)
+ val = current.MapIndex(reflect.ValueOf(uint8(i)))
+ namespace = namespace[endIdx+1:]
+
+ case reflect.Uint16:
+ i, _ := strconv.ParseUint(key, 10, 16)
+ val = current.MapIndex(reflect.ValueOf(uint16(i)))
+ namespace = namespace[endIdx+1:]
+
+ case reflect.Uint32:
+ i, _ := strconv.ParseUint(key, 10, 32)
+ val = current.MapIndex(reflect.ValueOf(uint32(i)))
+ namespace = namespace[endIdx+1:]
+
+ case reflect.Uint64:
+ i, _ := strconv.ParseUint(key, 10, 64)
+ val = current.MapIndex(reflect.ValueOf(i))
+ namespace = namespace[endIdx+1:]
+
+ case reflect.Float32:
+ f, _ := strconv.ParseFloat(key, 32)
+ val = current.MapIndex(reflect.ValueOf(float32(f)))
+ namespace = namespace[endIdx+1:]
+
+ case reflect.Float64:
+ f, _ := strconv.ParseFloat(key, 64)
+ val = current.MapIndex(reflect.ValueOf(f))
+ namespace = namespace[endIdx+1:]
+
+ case reflect.Bool:
+ b, _ := strconv.ParseBool(key)
+ val = current.MapIndex(reflect.ValueOf(b))
+ namespace = namespace[endIdx+1:]
+
+ // reflect.Type = string
+ default:
+ val = current.MapIndex(reflect.ValueOf(key))
+ namespace = namespace[endIdx+1:]
+ }
+
+ goto BEGIN
+ }
+
+ // if got here there was more namespace, cannot go any deeper
+ panic("Invalid field namespace")
+}
+
+// asInt returns the parameter as an int64
+// or panics if it can't convert
+func asInt(param string) int64 {
+ i, err := strconv.ParseInt(param, 0, 64)
+ panicIf(err)
+
+ return i
+}
+
+// asIntFromTimeDuration parses param as time.Duration and returns it as int64
+// or panics on error.
+func asIntFromTimeDuration(param string) int64 {
+ d, err := time.ParseDuration(param)
+ if err != nil {
+ // attempt parsing as an integer assuming nanosecond precision
+ return asInt(param)
+ }
+ return int64(d)
+}
+
+// asIntFromType calls the proper function to parse param as int64,
+// given a field's Type t.
+func asIntFromType(t reflect.Type, param string) int64 {
+ switch t {
+ case timeDurationType:
+ return asIntFromTimeDuration(param)
+ default:
+ return asInt(param)
+ }
+}
+
+// asUint returns the parameter as a uint64
+// or panics if it can't convert
+func asUint(param string) uint64 {
+ i, err := strconv.ParseUint(param, 0, 64)
+ panicIf(err)
+
+ return i
+}
+
+// asFloat64 returns the parameter as a float64
+// or panics if it can't convert
+func asFloat64(param string) float64 {
+ i, err := strconv.ParseFloat(param, 64)
+ panicIf(err)
+ return i
+}
+
+// asFloat32 returns the parameter as a float32
+// or panics if it can't convert
+func asFloat32(param string) float64 {
+ i, err := strconv.ParseFloat(param, 32)
+ panicIf(err)
+ return i
+}
+
+// asBool returns the parameter as a bool
+// or panics if it can't convert
+func asBool(param string) bool {
+ i, err := strconv.ParseBool(param)
+ panicIf(err)
+
+ return i
+}
+
+func panicIf(err error) {
+ if err != nil {
+ panic(err.Error())
+ }
+}
+
+// Checks if field value matches regex. If fl.Field can be cast to Stringer, it uses the Stringer interfaces
+// String() return value. Otherwise, it uses fl.Field's String() value.
+func fieldMatchesRegexByStringerValOrString(regexFn func() *regexp.Regexp, fl FieldLevel) bool {
+ regex := regexFn()
+ switch fl.Field().Kind() {
+ case reflect.String:
+ return regex.MatchString(fl.Field().String())
+ default:
+ if stringer, ok := getValue(fl.Field()).(fmt.Stringer); ok {
+ return regex.MatchString(stringer.String())
+ } else {
+ return regex.MatchString(fl.Field().String())
+ }
+ }
+}
diff --git a/vendor/github.com/go-playground/validator/v10/validator.go b/vendor/github.com/go-playground/validator/v10/validator.go
new file mode 100644
index 00000000..995b0e19
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/validator.go
@@ -0,0 +1,523 @@
+package validator
+
+import (
+ "context"
+ "fmt"
+ "reflect"
+ "strconv"
+ "unsafe"
+)
+
+// per validate construct
+type validate struct {
+ v *Validate
+ top reflect.Value
+ ns []byte
+ actualNs []byte
+ errs ValidationErrors
+ includeExclude map[string]struct{} // reset only if StructPartial or StructExcept are called, no need otherwise
+ ffn FilterFunc
+ slflParent reflect.Value // StructLevel & FieldLevel
+ slCurrent reflect.Value // StructLevel & FieldLevel
+ flField reflect.Value // StructLevel & FieldLevel
+ cf *cField // StructLevel & FieldLevel
+ ct *cTag // StructLevel & FieldLevel
+ misc []byte // misc reusable
+ str1 string // misc reusable
+ str2 string // misc reusable
+ fldIsPointer bool // StructLevel & FieldLevel
+ isPartial bool
+ hasExcludes bool
+}
+
+// parent and current will be the same the first run of validateStruct
+func (v *validate) validateStruct(ctx context.Context, parent reflect.Value, current reflect.Value, typ reflect.Type, ns []byte, structNs []byte, ct *cTag) {
+ cs, ok := v.v.structCache.Get(typ)
+ if !ok {
+ cs = v.v.extractStructCache(current, typ.Name())
+ }
+
+ if len(ns) == 0 && len(cs.name) != 0 {
+ ns = append(ns, cs.name...)
+ ns = append(ns, '.')
+
+ structNs = append(structNs, cs.name...)
+ structNs = append(structNs, '.')
+ }
+
+ // ct is nil on top level struct, and structs as fields that have no tag info
+ // so if nil or if not nil and the structonly tag isn't present
+ if ct == nil || ct.typeof != typeStructOnly {
+ var f *cField
+
+ for i := 0; i < len(cs.fields); i++ {
+ f = cs.fields[i]
+
+ if v.isPartial {
+ if v.ffn != nil {
+ // used with StructFiltered
+ if v.ffn(append(structNs, f.name...)) {
+ continue
+ }
+ } else {
+ // used with StructPartial & StructExcept
+ _, ok = v.includeExclude[string(append(structNs, f.name...))]
+
+ if (ok && v.hasExcludes) || (!ok && !v.hasExcludes) {
+ continue
+ }
+ }
+ }
+
+ v.traverseField(ctx, current, current.Field(f.idx), ns, structNs, f, f.cTags)
+ }
+ }
+
+ // check if any struct level validations, after all field validations already checked.
+ // first iteration will have no info about nostructlevel tag, and is checked prior to
+ // calling the next iteration of validateStruct called from traverseField.
+ if cs.fn != nil {
+ v.slflParent = parent
+ v.slCurrent = current
+ v.ns = ns
+ v.actualNs = structNs
+
+ cs.fn(ctx, v)
+ }
+}
+
+// traverseField validates any field, be it a struct or single field, ensures it's validity and passes it along to be validated via it's tag options
+func (v *validate) traverseField(ctx context.Context, parent reflect.Value, current reflect.Value, ns []byte, structNs []byte, cf *cField, ct *cTag) {
+ var typ reflect.Type
+ var kind reflect.Kind
+
+ current, kind, v.fldIsPointer = v.extractTypeInternal(current, false)
+
+ var isNestedStruct bool
+
+ switch kind {
+ case reflect.Ptr, reflect.Interface, reflect.Invalid:
+
+ if ct == nil {
+ return
+ }
+
+ if ct.typeof == typeOmitEmpty || ct.typeof == typeIsDefault {
+ return
+ }
+
+ if ct.typeof == typeOmitNil && (kind != reflect.Invalid && current.IsNil()) {
+ return
+ }
+
+ if ct.typeof == typeOmitZero {
+ return
+ }
+
+ if ct.hasTag {
+ if kind == reflect.Invalid {
+ v.str1 = string(append(ns, cf.altName...))
+ if v.v.hasTagNameFunc {
+ v.str2 = string(append(structNs, cf.name...))
+ } else {
+ v.str2 = v.str1
+ }
+ v.errs = append(v.errs,
+ &fieldError{
+ v: v.v,
+ tag: ct.aliasTag,
+ actualTag: ct.tag,
+ ns: v.str1,
+ structNs: v.str2,
+ fieldLen: uint8(len(cf.altName)),
+ structfieldLen: uint8(len(cf.name)),
+ param: ct.param,
+ kind: kind,
+ },
+ )
+ return
+ }
+
+ v.str1 = string(append(ns, cf.altName...))
+ if v.v.hasTagNameFunc {
+ v.str2 = string(append(structNs, cf.name...))
+ } else {
+ v.str2 = v.str1
+ }
+ if !ct.runValidationWhenNil {
+ v.errs = append(v.errs,
+ &fieldError{
+ v: v.v,
+ tag: ct.aliasTag,
+ actualTag: ct.tag,
+ ns: v.str1,
+ structNs: v.str2,
+ fieldLen: uint8(len(cf.altName)),
+ structfieldLen: uint8(len(cf.name)),
+ value: getValue(current),
+ param: ct.param,
+ kind: kind,
+ typ: current.Type(),
+ },
+ )
+ return
+ }
+ }
+
+ if kind == reflect.Invalid {
+ return
+ }
+
+ case reflect.Struct:
+ isNestedStruct = !current.Type().ConvertibleTo(timeType)
+ // For backward compatibility before struct level validation tags were supported
+ // as there were a number of projects relying on `required` not failing on non-pointer
+ // structs. Since it's basically nonsensical to use `required` with a non-pointer struct
+ // are explicitly skipping the required validation for it. This WILL be removed in the
+ // next major version.
+ if isNestedStruct && !v.v.requiredStructEnabled && ct != nil && ct.tag == requiredTag {
+ ct = ct.next
+ }
+ }
+
+ typ = current.Type()
+
+OUTER:
+ for {
+ if ct == nil || !ct.hasTag || (isNestedStruct && len(cf.name) == 0) {
+ // isNestedStruct check here
+ if isNestedStruct {
+ // if len == 0 then validating using 'Var' or 'VarWithValue'
+ // Var - doesn't make much sense to do it that way, should call 'Struct', but no harm...
+ // VarWithField - this allows for validating against each field within the struct against a specific value
+ // pretty handy in certain situations
+ if len(cf.name) > 0 {
+ ns = append(append(ns, cf.altName...), '.')
+ structNs = append(append(structNs, cf.name...), '.')
+ }
+
+ v.validateStruct(ctx, parent, current, typ, ns, structNs, ct)
+ }
+ return
+ }
+
+ switch ct.typeof {
+ case typeNoStructLevel:
+ return
+
+ case typeStructOnly:
+ if isNestedStruct {
+ // if len == 0 then validating using 'Var' or 'VarWithValue'
+ // Var - doesn't make much sense to do it that way, should call 'Struct', but no harm...
+ // VarWithField - this allows for validating against each field within the struct against a specific value
+ // pretty handy in certain situations
+ if len(cf.name) > 0 {
+ ns = append(append(ns, cf.altName...), '.')
+ structNs = append(append(structNs, cf.name...), '.')
+ }
+
+ v.validateStruct(ctx, parent, current, typ, ns, structNs, ct)
+ }
+ return
+
+ case typeOmitEmpty:
+
+ // set Field Level fields
+ v.slflParent = parent
+ v.flField = current
+ v.cf = cf
+ v.ct = ct
+
+ if !hasValue(v) {
+ return
+ }
+
+ ct = ct.next
+ continue
+
+ case typeOmitZero:
+ v.slflParent = parent
+ v.flField = current
+ v.cf = cf
+ v.ct = ct
+
+ if !hasNotZeroValue(v) {
+ return
+ }
+
+ ct = ct.next
+ continue
+
+ case typeOmitNil:
+ v.slflParent = parent
+ v.flField = current
+ v.cf = cf
+ v.ct = ct
+
+ switch field := v.Field(); field.Kind() {
+ case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func:
+ if field.IsNil() {
+ return
+ }
+ default:
+ if v.fldIsPointer && getValue(field) == nil {
+ return
+ }
+ }
+
+ ct = ct.next
+ continue
+
+ case typeEndKeys:
+ return
+
+ case typeDive:
+
+ ct = ct.next
+
+ // traverse slice or map here
+ // or panic ;)
+ switch kind {
+ case reflect.Slice, reflect.Array:
+
+ var i64 int64
+ reusableCF := &cField{}
+
+ for i := 0; i < current.Len(); i++ {
+ i64 = int64(i)
+
+ v.misc = append(v.misc[0:0], cf.name...)
+ v.misc = append(v.misc, '[')
+ v.misc = strconv.AppendInt(v.misc, i64, 10)
+ v.misc = append(v.misc, ']')
+
+ reusableCF.name = string(v.misc)
+
+ if cf.namesEqual {
+ reusableCF.altName = reusableCF.name
+ } else {
+ v.misc = append(v.misc[0:0], cf.altName...)
+ v.misc = append(v.misc, '[')
+ v.misc = strconv.AppendInt(v.misc, i64, 10)
+ v.misc = append(v.misc, ']')
+
+ reusableCF.altName = string(v.misc)
+ }
+ v.traverseField(ctx, parent, current.Index(i), ns, structNs, reusableCF, ct)
+ }
+
+ case reflect.Map:
+
+ var pv string
+ reusableCF := &cField{}
+
+ for _, key := range current.MapKeys() {
+ pv = fmt.Sprintf("%v", key)
+
+ v.misc = append(v.misc[0:0], cf.name...)
+ v.misc = append(v.misc, '[')
+ v.misc = append(v.misc, pv...)
+ v.misc = append(v.misc, ']')
+
+ reusableCF.name = string(v.misc)
+
+ if cf.namesEqual {
+ reusableCF.altName = reusableCF.name
+ } else {
+ v.misc = append(v.misc[0:0], cf.altName...)
+ v.misc = append(v.misc, '[')
+ v.misc = append(v.misc, pv...)
+ v.misc = append(v.misc, ']')
+
+ reusableCF.altName = string(v.misc)
+ }
+
+ if ct != nil && ct.typeof == typeKeys && ct.keys != nil {
+ v.traverseField(ctx, parent, key, ns, structNs, reusableCF, ct.keys)
+ // can be nil when just keys being validated
+ if ct.next != nil {
+ v.traverseField(ctx, parent, current.MapIndex(key), ns, structNs, reusableCF, ct.next)
+ } else {
+ // Struct fallback when map values are structs
+ val := current.MapIndex(key)
+ switch val.Kind() {
+ case reflect.Ptr:
+ if val.Elem().Kind() == reflect.Struct {
+ // Dive into the struct so its own tags run
+ v.traverseField(ctx, parent, val, ns, structNs, reusableCF, nil)
+ }
+ case reflect.Struct:
+ v.traverseField(ctx, parent, val, ns, structNs, reusableCF, nil)
+ }
+ }
+ } else {
+ v.traverseField(ctx, parent, current.MapIndex(key), ns, structNs, reusableCF, ct)
+ }
+ }
+
+ default:
+ // throw error, if not a slice or map then should not have gotten here
+ // bad dive tag
+ panic("dive error! can't dive on a non slice or map")
+ }
+
+ return
+
+ case typeOr:
+
+ v.misc = v.misc[0:0]
+
+ for {
+ // set Field Level fields
+ v.slflParent = parent
+ v.flField = current
+ v.cf = cf
+ v.ct = ct
+
+ if ct.fn(ctx, v) {
+ if ct.isBlockEnd {
+ ct = ct.next
+ continue OUTER
+ }
+
+ // drain rest of the 'or' values, then continue or leave
+ for {
+ ct = ct.next
+
+ if ct == nil {
+ continue OUTER
+ }
+
+ if ct.typeof != typeOr {
+ continue OUTER
+ }
+
+ if ct.isBlockEnd {
+ ct = ct.next
+ continue OUTER
+ }
+ }
+ }
+
+ v.misc = append(v.misc, '|')
+ v.misc = append(v.misc, ct.tag...)
+
+ if ct.hasParam {
+ v.misc = append(v.misc, '=')
+ v.misc = append(v.misc, ct.param...)
+ }
+
+ if ct.isBlockEnd || ct.next == nil {
+ // if we get here, no valid 'or' value and no more tags
+ v.str1 = string(append(ns, cf.altName...))
+
+ if v.v.hasTagNameFunc {
+ v.str2 = string(append(structNs, cf.name...))
+ } else {
+ v.str2 = v.str1
+ }
+
+ if ct.hasAlias {
+ v.errs = append(v.errs,
+ &fieldError{
+ v: v.v,
+ tag: ct.aliasTag,
+ actualTag: ct.actualAliasTag,
+ ns: v.str1,
+ structNs: v.str2,
+ fieldLen: uint8(len(cf.altName)),
+ structfieldLen: uint8(len(cf.name)),
+ value: getValue(current),
+ param: ct.param,
+ kind: kind,
+ typ: typ,
+ },
+ )
+ } else {
+ tVal := string(v.misc)[1:]
+
+ v.errs = append(v.errs,
+ &fieldError{
+ v: v.v,
+ tag: tVal,
+ actualTag: tVal,
+ ns: v.str1,
+ structNs: v.str2,
+ fieldLen: uint8(len(cf.altName)),
+ structfieldLen: uint8(len(cf.name)),
+ value: getValue(current),
+ param: ct.param,
+ kind: kind,
+ typ: typ,
+ },
+ )
+ }
+
+ return
+ }
+
+ ct = ct.next
+ }
+
+ default:
+
+ // set Field Level fields
+ v.slflParent = parent
+ v.flField = current
+ v.cf = cf
+ v.ct = ct
+
+ if !ct.fn(ctx, v) {
+ v.str1 = string(append(ns, cf.altName...))
+
+ if v.v.hasTagNameFunc {
+ v.str2 = string(append(structNs, cf.name...))
+ } else {
+ v.str2 = v.str1
+ }
+
+ v.errs = append(v.errs,
+ &fieldError{
+ v: v.v,
+ tag: ct.aliasTag,
+ actualTag: ct.tag,
+ ns: v.str1,
+ structNs: v.str2,
+ fieldLen: uint8(len(cf.altName)),
+ structfieldLen: uint8(len(cf.name)),
+ value: getValue(current),
+ param: ct.param,
+ kind: kind,
+ typ: typ,
+ },
+ )
+
+ return
+ }
+ ct = ct.next
+ }
+ }
+}
+
+func getValue(val reflect.Value) interface{} {
+ if val.CanInterface() {
+ return val.Interface()
+ }
+
+ if val.CanAddr() {
+ return reflect.NewAt(val.Type(), unsafe.Pointer(val.UnsafeAddr())).Elem().Interface()
+ }
+
+ switch val.Kind() {
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return val.Int()
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return val.Uint()
+ case reflect.Complex64, reflect.Complex128:
+ return val.Complex()
+ case reflect.Float32, reflect.Float64:
+ return val.Float()
+ default:
+ return val.String()
+ }
+}
diff --git a/vendor/github.com/go-playground/validator/v10/validator_instance.go b/vendor/github.com/go-playground/validator/v10/validator_instance.go
new file mode 100644
index 00000000..9362cd73
--- /dev/null
+++ b/vendor/github.com/go-playground/validator/v10/validator_instance.go
@@ -0,0 +1,699 @@
+package validator
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "reflect"
+ "strings"
+ "sync"
+ "time"
+
+ ut "github.com/go-playground/universal-translator"
+)
+
+const (
+ defaultTagName = "validate"
+ utf8HexComma = "0x2C"
+ utf8Pipe = "0x7C"
+ tagSeparator = ","
+ orSeparator = "|"
+ tagKeySeparator = "="
+ structOnlyTag = "structonly"
+ noStructLevelTag = "nostructlevel"
+ omitzero = "omitzero"
+ omitempty = "omitempty"
+ omitnil = "omitnil"
+ isdefault = "isdefault"
+ requiredWithoutAllTag = "required_without_all"
+ requiredWithoutTag = "required_without"
+ requiredWithTag = "required_with"
+ requiredWithAllTag = "required_with_all"
+ requiredIfTag = "required_if"
+ requiredUnlessTag = "required_unless"
+ skipUnlessTag = "skip_unless"
+ excludedWithoutAllTag = "excluded_without_all"
+ excludedWithoutTag = "excluded_without"
+ excludedWithTag = "excluded_with"
+ excludedWithAllTag = "excluded_with_all"
+ excludedIfTag = "excluded_if"
+ excludedUnlessTag = "excluded_unless"
+ skipValidationTag = "-"
+ diveTag = "dive"
+ keysTag = "keys"
+ endKeysTag = "endkeys"
+ requiredTag = "required"
+ namespaceSeparator = "."
+ leftBracket = "["
+ rightBracket = "]"
+ restrictedTagChars = ".[],|=+()`~!@#$%^&*\\\"/?<>{}"
+ restrictedAliasErr = "Alias '%s' either contains restricted characters or is the same as a restricted tag needed for normal operation"
+ restrictedTagErr = "Tag '%s' either contains restricted characters or is the same as a restricted tag needed for normal operation"
+)
+
+var (
+ timeDurationType = reflect.TypeOf(time.Duration(0))
+ timeType = reflect.TypeOf(time.Time{})
+
+ byteSliceType = reflect.TypeOf([]byte{})
+
+ defaultCField = &cField{namesEqual: true}
+)
+
+// FilterFunc is the type used to filter fields using
+// StructFiltered(...) function.
+// returning true results in the field being filtered/skipped from
+// validation
+type FilterFunc func(ns []byte) bool
+
+// CustomTypeFunc allows for overriding or adding custom field type handler functions
+// field = field value of the type to return a value to be validated
+// example Valuer from sql drive see https://golang.org/src/database/sql/driver/types.go?s=1210:1293#L29
+type CustomTypeFunc func(field reflect.Value) interface{}
+
+// TagNameFunc allows for adding of a custom tag name parser
+type TagNameFunc func(field reflect.StructField) string
+
+type internalValidationFuncWrapper struct {
+ fn FuncCtx
+ runValidationOnNil bool
+}
+
+// Validate contains the validator settings and cache
+type Validate struct {
+ tagName string
+ pool *sync.Pool
+ tagNameFunc TagNameFunc
+ structLevelFuncs map[reflect.Type]StructLevelFuncCtx
+ customFuncs map[reflect.Type]CustomTypeFunc
+ aliases map[string]string
+ validations map[string]internalValidationFuncWrapper
+ transTagFunc map[ut.Translator]map[string]TranslationFunc // map[]map[]TranslationFunc
+ rules map[reflect.Type]map[string]string
+ tagCache *tagCache
+ structCache *structCache
+ hasCustomFuncs bool
+ hasTagNameFunc bool
+ requiredStructEnabled bool
+ privateFieldValidation bool
+}
+
+// New returns a new instance of 'validate' with sane defaults.
+// Validate is designed to be thread-safe and used as a singleton instance.
+// It caches information about your struct and validations,
+// in essence only parsing your validation tags once per struct type.
+// Using multiple instances neglects the benefit of caching.
+func New(options ...Option) *Validate {
+ tc := new(tagCache)
+ tc.m.Store(make(map[string]*cTag))
+
+ sc := new(structCache)
+ sc.m.Store(make(map[reflect.Type]*cStruct))
+
+ v := &Validate{
+ tagName: defaultTagName,
+ aliases: make(map[string]string, len(bakedInAliases)),
+ validations: make(map[string]internalValidationFuncWrapper, len(bakedInValidators)),
+ tagCache: tc,
+ structCache: sc,
+ }
+
+ // must copy alias validators for separate validations to be used in each validator instance
+ for k, val := range bakedInAliases {
+ v.RegisterAlias(k, val)
+ }
+
+ // must copy validators for separate validations to be used in each instance
+ for k, val := range bakedInValidators {
+ switch k {
+ // these require that even if the value is nil that the validation should run, omitempty still overrides this behaviour
+ case requiredIfTag, requiredUnlessTag, requiredWithTag, requiredWithAllTag, requiredWithoutTag, requiredWithoutAllTag,
+ excludedIfTag, excludedUnlessTag, excludedWithTag, excludedWithAllTag, excludedWithoutTag, excludedWithoutAllTag,
+ skipUnlessTag:
+ _ = v.registerValidation(k, wrapFunc(val), true, true)
+ default:
+ // no need to error check here, baked in will always be valid
+ _ = v.registerValidation(k, wrapFunc(val), true, false)
+ }
+ }
+
+ v.pool = &sync.Pool{
+ New: func() interface{} {
+ return &validate{
+ v: v,
+ ns: make([]byte, 0, 64),
+ actualNs: make([]byte, 0, 64),
+ misc: make([]byte, 32),
+ }
+ },
+ }
+
+ for _, o := range options {
+ o(v)
+ }
+ return v
+}
+
+// SetTagName allows for changing of the default tag name of 'validate'
+func (v *Validate) SetTagName(name string) {
+ v.tagName = name
+}
+
+// ValidateMapCtx validates a map using a map of validation rules and allows passing of contextual
+// validation information via context.Context.
+func (v Validate) ValidateMapCtx(ctx context.Context, data map[string]interface{}, rules map[string]interface{}) map[string]interface{} {
+ errs := make(map[string]interface{})
+ for field, rule := range rules {
+ if ruleObj, ok := rule.(map[string]interface{}); ok {
+ if dataObj, ok := data[field].(map[string]interface{}); ok {
+ err := v.ValidateMapCtx(ctx, dataObj, ruleObj)
+ if len(err) > 0 {
+ errs[field] = err
+ }
+ } else if dataObjs, ok := data[field].([]map[string]interface{}); ok {
+ for _, obj := range dataObjs {
+ err := v.ValidateMapCtx(ctx, obj, ruleObj)
+ if len(err) > 0 {
+ errs[field] = err
+ }
+ }
+ } else {
+ errs[field] = errors.New("The field: '" + field + "' is not a map to dive")
+ }
+ } else if ruleStr, ok := rule.(string); ok {
+ err := v.VarCtx(ctx, data[field], ruleStr)
+ if err != nil {
+ errs[field] = err
+ }
+ }
+ }
+ return errs
+}
+
+// ValidateMap validates map data from a map of tags
+func (v *Validate) ValidateMap(data map[string]interface{}, rules map[string]interface{}) map[string]interface{} {
+ return v.ValidateMapCtx(context.Background(), data, rules)
+}
+
+// RegisterTagNameFunc registers a function to get alternate names for StructFields.
+//
+// eg. to use the names which have been specified for JSON representations of structs, rather than normal Go field names:
+//
+// validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
+// name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
+// // skip if tag key says it should be ignored
+// if name == "-" {
+// return ""
+// }
+// return name
+// })
+func (v *Validate) RegisterTagNameFunc(fn TagNameFunc) {
+ v.tagNameFunc = fn
+ v.hasTagNameFunc = true
+}
+
+// RegisterValidation adds a validation with the given tag
+//
+// NOTES:
+// - if the key already exists, the previous validation function will be replaced.
+// - this method is not thread-safe it is intended that these all be registered prior to any validation
+func (v *Validate) RegisterValidation(tag string, fn Func, callValidationEvenIfNull ...bool) error {
+ return v.RegisterValidationCtx(tag, wrapFunc(fn), callValidationEvenIfNull...)
+}
+
+// RegisterValidationCtx does the same as RegisterValidation on accepts a FuncCtx validation
+// allowing context.Context validation support.
+func (v *Validate) RegisterValidationCtx(tag string, fn FuncCtx, callValidationEvenIfNull ...bool) error {
+ var nilCheckable bool
+ if len(callValidationEvenIfNull) > 0 {
+ nilCheckable = callValidationEvenIfNull[0]
+ }
+ return v.registerValidation(tag, fn, false, nilCheckable)
+}
+
+// RegisterAlias registers a mapping of a single validation tag that
+// defines a common or complex set of validation(s) to simplify adding validation
+// to structs.
+//
+// NOTE: this function is not thread-safe it is intended that these all be registered prior to any validation
+func (v *Validate) RegisterAlias(alias, tags string) {
+ _, ok := restrictedTags[alias]
+
+ if ok || strings.ContainsAny(alias, restrictedTagChars) {
+ panic(fmt.Sprintf(restrictedAliasErr, alias))
+ }
+
+ v.aliases[alias] = tags
+}
+
+// RegisterStructValidation registers a StructLevelFunc against a number of types.
+//
+// NOTE:
+// - this method is not thread-safe it is intended that these all be registered prior to any validation
+func (v *Validate) RegisterStructValidation(fn StructLevelFunc, types ...interface{}) {
+ v.RegisterStructValidationCtx(wrapStructLevelFunc(fn), types...)
+}
+
+// RegisterStructValidationCtx registers a StructLevelFuncCtx against a number of types and allows passing
+// of contextual validation information via context.Context.
+//
+// NOTE:
+// - this method is not thread-safe it is intended that these all be registered prior to any validation
+func (v *Validate) RegisterStructValidationCtx(fn StructLevelFuncCtx, types ...interface{}) {
+ if v.structLevelFuncs == nil {
+ v.structLevelFuncs = make(map[reflect.Type]StructLevelFuncCtx)
+ }
+
+ for _, t := range types {
+ tv := reflect.ValueOf(t)
+ if tv.Kind() == reflect.Ptr {
+ t = reflect.Indirect(tv).Interface()
+ }
+
+ v.structLevelFuncs[reflect.TypeOf(t)] = fn
+ }
+}
+
+// RegisterStructValidationMapRules registers validate map rules.
+// Be aware that map validation rules supersede those defined on a/the struct if present.
+//
+// NOTE: this method is not thread-safe it is intended that these all be registered prior to any validation
+func (v *Validate) RegisterStructValidationMapRules(rules map[string]string, types ...interface{}) {
+ if v.rules == nil {
+ v.rules = make(map[reflect.Type]map[string]string)
+ }
+
+ deepCopyRules := make(map[string]string)
+ for i, rule := range rules {
+ deepCopyRules[i] = rule
+ }
+
+ for _, t := range types {
+ typ := reflect.TypeOf(t)
+
+ if typ.Kind() == reflect.Ptr {
+ typ = typ.Elem()
+ }
+
+ if typ.Kind() != reflect.Struct {
+ continue
+ }
+ v.rules[typ] = deepCopyRules
+ }
+}
+
+// RegisterCustomTypeFunc registers a CustomTypeFunc against a number of types
+//
+// NOTE: this method is not thread-safe it is intended that these all be registered prior to any validation
+func (v *Validate) RegisterCustomTypeFunc(fn CustomTypeFunc, types ...interface{}) {
+ if v.customFuncs == nil {
+ v.customFuncs = make(map[reflect.Type]CustomTypeFunc)
+ }
+
+ for _, t := range types {
+ v.customFuncs[reflect.TypeOf(t)] = fn
+ }
+
+ v.hasCustomFuncs = true
+}
+
+// RegisterTranslation registers translations against the provided tag.
+func (v *Validate) RegisterTranslation(tag string, trans ut.Translator, registerFn RegisterTranslationsFunc, translationFn TranslationFunc) (err error) {
+ if v.transTagFunc == nil {
+ v.transTagFunc = make(map[ut.Translator]map[string]TranslationFunc)
+ }
+
+ if err = registerFn(trans); err != nil {
+ return
+ }
+
+ m, ok := v.transTagFunc[trans]
+ if !ok {
+ m = make(map[string]TranslationFunc)
+ v.transTagFunc[trans] = m
+ }
+
+ m[tag] = translationFn
+
+ return
+}
+
+// Struct validates a structs exposed fields, and automatically validates nested structs, unless otherwise specified.
+//
+// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
+// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
+func (v *Validate) Struct(s interface{}) error {
+ return v.StructCtx(context.Background(), s)
+}
+
+// StructCtx validates a structs exposed fields, and automatically validates nested structs, unless otherwise specified
+// and also allows passing of context.Context for contextual validation information.
+//
+// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
+// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
+func (v *Validate) StructCtx(ctx context.Context, s interface{}) (err error) {
+ val := reflect.ValueOf(s)
+ top := val
+
+ if val.Kind() == reflect.Ptr && !val.IsNil() {
+ val = val.Elem()
+ }
+
+ if val.Kind() != reflect.Struct || val.Type().ConvertibleTo(timeType) {
+ return &InvalidValidationError{Type: reflect.TypeOf(s)}
+ }
+
+ // good to validate
+ vd := v.pool.Get().(*validate)
+ vd.top = top
+ vd.isPartial = false
+ // vd.hasExcludes = false // only need to reset in StructPartial and StructExcept
+
+ vd.validateStruct(ctx, top, val, val.Type(), vd.ns[0:0], vd.actualNs[0:0], nil)
+
+ if len(vd.errs) > 0 {
+ err = vd.errs
+ vd.errs = nil
+ }
+
+ v.pool.Put(vd)
+
+ return
+}
+
+// StructFiltered validates a structs exposed fields, that pass the FilterFunc check and automatically validates
+// nested structs, unless otherwise specified.
+//
+// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
+// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
+func (v *Validate) StructFiltered(s interface{}, fn FilterFunc) error {
+ return v.StructFilteredCtx(context.Background(), s, fn)
+}
+
+// StructFilteredCtx validates a structs exposed fields, that pass the FilterFunc check and automatically validates
+// nested structs, unless otherwise specified and also allows passing of contextual validation information via
+// context.Context
+//
+// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
+// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
+func (v *Validate) StructFilteredCtx(ctx context.Context, s interface{}, fn FilterFunc) (err error) {
+ val := reflect.ValueOf(s)
+ top := val
+
+ if val.Kind() == reflect.Ptr && !val.IsNil() {
+ val = val.Elem()
+ }
+
+ if val.Kind() != reflect.Struct || val.Type().ConvertibleTo(timeType) {
+ return &InvalidValidationError{Type: reflect.TypeOf(s)}
+ }
+
+ // good to validate
+ vd := v.pool.Get().(*validate)
+ vd.top = top
+ vd.isPartial = true
+ vd.ffn = fn
+ // vd.hasExcludes = false // only need to reset in StructPartial and StructExcept
+
+ vd.validateStruct(ctx, top, val, val.Type(), vd.ns[0:0], vd.actualNs[0:0], nil)
+
+ if len(vd.errs) > 0 {
+ err = vd.errs
+ vd.errs = nil
+ }
+
+ v.pool.Put(vd)
+
+ return
+}
+
+// StructPartial validates the fields passed in only, ignoring all others.
+// Fields may be provided in a namespaced fashion relative to the struct provided
+// eg. NestedStruct.Field or NestedArrayField[0].Struct.Name
+//
+// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
+// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
+func (v *Validate) StructPartial(s interface{}, fields ...string) error {
+ return v.StructPartialCtx(context.Background(), s, fields...)
+}
+
+// StructPartialCtx validates the fields passed in only, ignoring all others and allows passing of contextual
+// validation information via context.Context
+// Fields may be provided in a namespaced fashion relative to the struct provided
+// eg. NestedStruct.Field or NestedArrayField[0].Struct.Name
+//
+// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
+// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
+func (v *Validate) StructPartialCtx(ctx context.Context, s interface{}, fields ...string) (err error) {
+ val := reflect.ValueOf(s)
+ top := val
+
+ if val.Kind() == reflect.Ptr && !val.IsNil() {
+ val = val.Elem()
+ }
+
+ if val.Kind() != reflect.Struct || val.Type().ConvertibleTo(timeType) {
+ return &InvalidValidationError{Type: reflect.TypeOf(s)}
+ }
+
+ // good to validate
+ vd := v.pool.Get().(*validate)
+ vd.top = top
+ vd.isPartial = true
+ vd.ffn = nil
+ vd.hasExcludes = false
+ vd.includeExclude = make(map[string]struct{})
+
+ typ := val.Type()
+ name := typ.Name()
+
+ for _, k := range fields {
+ flds := strings.Split(k, namespaceSeparator)
+ if len(flds) > 0 {
+ vd.misc = append(vd.misc[0:0], name...)
+ // Don't append empty name for unnamed structs
+ if len(vd.misc) != 0 {
+ vd.misc = append(vd.misc, '.')
+ }
+
+ for _, s := range flds {
+ idx := strings.Index(s, leftBracket)
+
+ if idx != -1 {
+ for idx != -1 {
+ vd.misc = append(vd.misc, s[:idx]...)
+ vd.includeExclude[string(vd.misc)] = struct{}{}
+
+ idx2 := strings.Index(s, rightBracket)
+ idx2++
+ vd.misc = append(vd.misc, s[idx:idx2]...)
+ vd.includeExclude[string(vd.misc)] = struct{}{}
+ s = s[idx2:]
+ idx = strings.Index(s, leftBracket)
+ }
+ } else {
+ vd.misc = append(vd.misc, s...)
+ vd.includeExclude[string(vd.misc)] = struct{}{}
+ }
+
+ vd.misc = append(vd.misc, '.')
+ }
+ }
+ }
+
+ vd.validateStruct(ctx, top, val, typ, vd.ns[0:0], vd.actualNs[0:0], nil)
+
+ if len(vd.errs) > 0 {
+ err = vd.errs
+ vd.errs = nil
+ }
+
+ v.pool.Put(vd)
+
+ return
+}
+
+// StructExcept validates all fields except the ones passed in.
+// Fields may be provided in a namespaced fashion relative to the struct provided
+// i.e. NestedStruct.Field or NestedArrayField[0].Struct.Name
+//
+// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
+// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
+func (v *Validate) StructExcept(s interface{}, fields ...string) error {
+ return v.StructExceptCtx(context.Background(), s, fields...)
+}
+
+// StructExceptCtx validates all fields except the ones passed in and allows passing of contextual
+// validation information via context.Context
+// Fields may be provided in a namespaced fashion relative to the struct provided
+// i.e. NestedStruct.Field or NestedArrayField[0].Struct.Name
+//
+// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
+// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
+func (v *Validate) StructExceptCtx(ctx context.Context, s interface{}, fields ...string) (err error) {
+ val := reflect.ValueOf(s)
+ top := val
+
+ if val.Kind() == reflect.Ptr && !val.IsNil() {
+ val = val.Elem()
+ }
+
+ if val.Kind() != reflect.Struct || val.Type().ConvertibleTo(timeType) {
+ return &InvalidValidationError{Type: reflect.TypeOf(s)}
+ }
+
+ // good to validate
+ vd := v.pool.Get().(*validate)
+ vd.top = top
+ vd.isPartial = true
+ vd.ffn = nil
+ vd.hasExcludes = true
+ vd.includeExclude = make(map[string]struct{})
+
+ typ := val.Type()
+ name := typ.Name()
+
+ for _, key := range fields {
+ vd.misc = vd.misc[0:0]
+
+ if len(name) > 0 {
+ vd.misc = append(vd.misc, name...)
+ vd.misc = append(vd.misc, '.')
+ }
+
+ vd.misc = append(vd.misc, key...)
+ vd.includeExclude[string(vd.misc)] = struct{}{}
+ }
+
+ vd.validateStruct(ctx, top, val, typ, vd.ns[0:0], vd.actualNs[0:0], nil)
+
+ if len(vd.errs) > 0 {
+ err = vd.errs
+ vd.errs = nil
+ }
+
+ v.pool.Put(vd)
+
+ return
+}
+
+// Var validates a single variable using tag style validation.
+// eg.
+// var i int
+// validate.Var(i, "gt=1,lt=10")
+//
+// WARNING: a struct can be passed for validation eg. time.Time is a struct or
+// if you have a custom type and have registered a custom type handler, so must
+// allow it; however unforeseen validations will occur if trying to validate a
+// struct that is meant to be passed to 'validate.Struct'
+//
+// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
+// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
+// validate Array, Slice and maps fields which may contain more than one error
+func (v *Validate) Var(field interface{}, tag string) error {
+ return v.VarCtx(context.Background(), field, tag)
+}
+
+// VarCtx validates a single variable using tag style validation and allows passing of contextual
+// validation information via context.Context.
+// eg.
+// var i int
+// validate.Var(i, "gt=1,lt=10")
+//
+// WARNING: a struct can be passed for validation eg. time.Time is a struct or
+// if you have a custom type and have registered a custom type handler, so must
+// allow it; however unforeseen validations will occur if trying to validate a
+// struct that is meant to be passed to 'validate.Struct'
+//
+// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
+// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
+// validate Array, Slice and maps fields which may contain more than one error
+func (v *Validate) VarCtx(ctx context.Context, field interface{}, tag string) (err error) {
+ if len(tag) == 0 || tag == skipValidationTag {
+ return nil
+ }
+
+ ctag := v.fetchCacheTag(tag)
+
+ val := reflect.ValueOf(field)
+ vd := v.pool.Get().(*validate)
+ vd.top = val
+ vd.isPartial = false
+ vd.traverseField(ctx, val, val, vd.ns[0:0], vd.actualNs[0:0], defaultCField, ctag)
+
+ if len(vd.errs) > 0 {
+ err = vd.errs
+ vd.errs = nil
+ }
+ v.pool.Put(vd)
+ return
+}
+
+// VarWithValue validates a single variable, against another variable/field's value using tag style validation
+// eg.
+// s1 := "abcd"
+// s2 := "abcd"
+// validate.VarWithValue(s1, s2, "eqcsfield") // returns true
+//
+// WARNING: a struct can be passed for validation eg. time.Time is a struct or
+// if you have a custom type and have registered a custom type handler, so must
+// allow it; however unforeseen validations will occur if trying to validate a
+// struct that is meant to be passed to 'validate.Struct'
+//
+// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
+// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
+// validate Array, Slice and maps fields which may contain more than one error
+func (v *Validate) VarWithValue(field interface{}, other interface{}, tag string) error {
+ return v.VarWithValueCtx(context.Background(), field, other, tag)
+}
+
+// VarWithValueCtx validates a single variable, against another variable/field's value using tag style validation and
+// allows passing of contextual validation information via context.Context.
+// eg.
+// s1 := "abcd"
+// s2 := "abcd"
+// validate.VarWithValue(s1, s2, "eqcsfield") // returns true
+//
+// WARNING: a struct can be passed for validation eg. time.Time is a struct or
+// if you have a custom type and have registered a custom type handler, so must
+// allow it; however unforeseen validations will occur if trying to validate a
+// struct that is meant to be passed to 'validate.Struct'
+//
+// It returns InvalidValidationError for bad values passed in and nil or ValidationErrors as error otherwise.
+// You will need to assert the error if it's not nil eg. err.(validator.ValidationErrors) to access the array of errors.
+// validate Array, Slice and maps fields which may contain more than one error
+func (v *Validate) VarWithValueCtx(ctx context.Context, field interface{}, other interface{}, tag string) (err error) {
+ if len(tag) == 0 || tag == skipValidationTag {
+ return nil
+ }
+ ctag := v.fetchCacheTag(tag)
+ otherVal := reflect.ValueOf(other)
+ vd := v.pool.Get().(*validate)
+ vd.top = otherVal
+ vd.isPartial = false
+ vd.traverseField(ctx, otherVal, reflect.ValueOf(field), vd.ns[0:0], vd.actualNs[0:0], defaultCField, ctag)
+
+ if len(vd.errs) > 0 {
+ err = vd.errs
+ vd.errs = nil
+ }
+ v.pool.Put(vd)
+ return
+}
+
+func (v *Validate) registerValidation(tag string, fn FuncCtx, bakedIn bool, nilCheckable bool) error {
+ if len(tag) == 0 {
+ return errors.New("function Key cannot be empty")
+ }
+
+ if fn == nil {
+ return errors.New("function cannot be empty")
+ }
+
+ _, ok := restrictedTags[tag]
+ if !bakedIn && (ok || strings.ContainsAny(tag, restrictedTagChars)) {
+ panic(fmt.Sprintf(restrictedTagErr, tag))
+ }
+ v.validations[tag] = internalValidationFuncWrapper{fn: fn, runValidationOnNil: nilCheckable}
+ return nil
+}
diff --git a/vendor/github.com/leodido/go-urn/.gitignore b/vendor/github.com/leodido/go-urn/.gitignore
new file mode 100644
index 00000000..427454f8
--- /dev/null
+++ b/vendor/github.com/leodido/go-urn/.gitignore
@@ -0,0 +1,13 @@
+*.exe
+*.dll
+*.so
+*.dylib
+
+*.test
+
+*.out
+*.txt
+
+vendor/
+/removecomments
+/snake2camel
\ No newline at end of file
diff --git a/vendor/github.com/leodido/go-urn/LICENSE b/vendor/github.com/leodido/go-urn/LICENSE
new file mode 100644
index 00000000..8c3504a5
--- /dev/null
+++ b/vendor/github.com/leodido/go-urn/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 Leonardo Di Donato
+
+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/leodido/go-urn/README.md b/vendor/github.com/leodido/go-urn/README.md
new file mode 100644
index 00000000..619475bf
--- /dev/null
+++ b/vendor/github.com/leodido/go-urn/README.md
@@ -0,0 +1,153 @@
+[](https://app.circleci.com/pipelines/github/leodido/go-urn) [](https://codecov.io/gh/leodido/go-urn) [](https://godoc.org/github.com/leodido/go-urn)
+
+**A parser for URNs**.
+
+> As seen on [RFC 2141](https://datatracker.ietf.org/doc/html/rfc2141), [RFC 7643](https://datatracker.ietf.org/doc/html/rfc7643#section-10), and on [RFC 8141](https://datatracker.ietf.org/doc/html/rfc8141).
+
+[API documentation](https://godoc.org/github.com/leodido/go-urn).
+
+Starting with version 1.3 this library also supports [RFC 7643 SCIM URNs](https://datatracker.ietf.org/doc/html/rfc7643#section-10).
+
+Starting with version 1.4 this library also supports [RFC 8141 URNs (2017)](https://datatracker.ietf.org/doc/html/rfc8141).
+
+## Installation
+
+```
+go get github.com/leodido/go-urn
+```
+
+## Features
+
+1. RFC 2141 URNs parsing (default)
+2. RFC 8141 URNs parsing (supersedes RFC 2141)
+3. RFC 7643 SCIM URNs parsing
+4. Normalization as per RFCs
+5. Lexical equivalence as per RFCs
+6. Precise, fine-grained errors
+
+## Performances
+
+This implementation results to be really fast.
+
+Usually below 400 ns on my machine[1](#mymachine) .
+
+Notice it also performs, while parsing:
+
+1. fine-grained and informative erroring
+2. specific-string normalization
+
+```
+ok/00/urn:a:b______________________________________/-10 51372006 109.0 ns/op 275 B/op 3 allocs/op
+ok/01/URN:foo:a123,456_____________________________/-10 36024072 160.8 ns/op 296 B/op 6 allocs/op
+ok/02/urn:foo:a123%2C456___________________________/-10 31901007 188.4 ns/op 320 B/op 7 allocs/op
+ok/03/urn:ietf:params:scim:schemas:core:2.0:User___/-10 22736756 266.6 ns/op 376 B/op 6 allocs/op
+ok/04/urn:ietf:params:scim:schemas:extension:enterp/-10 18291859 335.2 ns/op 408 B/op 6 allocs/op
+ok/05/urn:ietf:params:scim:schemas:extension:enterp/-10 15283087 379.4 ns/op 440 B/op 6 allocs/op
+ok/06/urn:burnout:nss______________________________/-10 39407593 155.1 ns/op 288 B/op 6 allocs/op
+ok/07/urn:abcdefghilmnopqrstuvzabcdefghilm:x_______/-10 27832718 211.4 ns/op 307 B/op 4 allocs/op
+ok/08/urn:urnurnurn:urn____________________________/-10 33269596 168.1 ns/op 293 B/op 6 allocs/op
+ok/09/urn:ciao:!!*_________________________________/-10 41100675 148.8 ns/op 288 B/op 6 allocs/op
+ok/10/urn:ciao:=@__________________________________/-10 37214253 149.7 ns/op 284 B/op 6 allocs/op
+ok/11/urn:ciao:@!=%2C(xyz)+a,b.*@g=$_'_____________/-10 26534240 229.8 ns/op 336 B/op 7 allocs/op
+ok/12/URN:x:abc%1Dz%2F%3az_________________________/-10 28166396 211.8 ns/op 336 B/op 7 allocs/op
+no/13/URN:---xxx:x_________________________________/-10 23635159 255.6 ns/op 419 B/op 5 allocs/op
+no/14/urn::colon:nss_______________________________/-10 23594779 258.4 ns/op 419 B/op 5 allocs/op
+no/15/URN:@,:x_____________________________________/-10 23742535 261.5 ns/op 419 B/op 5 allocs/op
+no/16/URN:URN:NSS__________________________________/-10 27432714 223.3 ns/op 371 B/op 5 allocs/op
+no/17/urn:UrN:NSS__________________________________/-10 26922117 224.9 ns/op 371 B/op 5 allocs/op
+no/18/urn:a:%______________________________________/-10 24926733 224.6 ns/op 371 B/op 5 allocs/op
+no/19/urn:urn:NSS__________________________________/-10 27652641 220.7 ns/op 371 B/op 5 allocs/op
+```
+
+* [1] : Apple M1 Pro
+
+
+## Example
+
+For more examples take a look at the [examples file](examples_test.go).
+
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/leodido/go-urn"
+)
+
+func main() {
+ var uid = "URN:foo:a123,456"
+
+ // Parse the input string as a RFC 2141 URN only
+ u, e := urn.NewMachine().Parse(uid)
+ if e != nil {
+ fmt.Errorf(err)
+
+ return
+ }
+
+ fmt.Println(u.ID)
+ fmt.Println(u.SS)
+
+ // Output:
+ // foo
+ // a123,456
+}
+```
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/leodido/go-urn"
+)
+
+func main() {
+ var uid = "URN:foo:a123,456"
+
+ // Parse the input string as a RFC 2141 URN only
+ u, ok := urn.Parse([]byte(uid))
+ if !ok {
+ panic("error parsing urn")
+ }
+
+ fmt.Println(u.ID)
+ fmt.Println(u.SS)
+
+ // Output:
+ // foo
+ // a123,456
+}
+```
+
+```go
+package main
+
+import (
+ "fmt"
+ "github.com/leodido/go-urn"
+)
+
+func main() {
+ input := "urn:ietf:params:scim:api:messages:2.0:ListResponse"
+
+ // Parsing the input string as a RFC 7643 SCIM URN
+ u, ok := urn.Parse([]byte(input), urn.WithParsingMode(urn.RFC7643Only))
+ if !ok {
+ panic("error parsing urn")
+ }
+
+ fmt.Println(u.IsSCIM())
+ scim := u.SCIM()
+ fmt.Println(scim.Type.String())
+ fmt.Println(scim.Name)
+ fmt.Println(scim.Other)
+
+ // Output:
+ // true
+ // api
+ // messages
+ // 2.0:ListResponse
+}
+```
\ No newline at end of file
diff --git a/vendor/github.com/leodido/go-urn/kind.go b/vendor/github.com/leodido/go-urn/kind.go
new file mode 100644
index 00000000..f5e140f0
--- /dev/null
+++ b/vendor/github.com/leodido/go-urn/kind.go
@@ -0,0 +1,10 @@
+package urn
+
+type Kind int
+
+const (
+ NONE Kind = iota
+ RFC2141
+ RFC7643
+ RFC8141
+)
diff --git a/vendor/github.com/leodido/go-urn/machine.go b/vendor/github.com/leodido/go-urn/machine.go
new file mode 100644
index 00000000..aec1ba69
--- /dev/null
+++ b/vendor/github.com/leodido/go-urn/machine.go
@@ -0,0 +1,5046 @@
+package urn
+
+import (
+ "fmt"
+
+ scimschema "github.com/leodido/go-urn/scim/schema"
+)
+
+var (
+ errPrefix = "expecting the prefix to be the \"urn\" string (whatever case) [col %d]"
+ errIdentifier = "expecting the identifier to be string (1..31 alnum chars, also containing dashes but not at its beginning) [col %d]"
+ errSpecificString = "expecting the specific string to be a string containing alnum, hex, or others ([()+,-.:=@;$_!*']) chars [col %d]"
+ errNoUrnWithinID = "expecting the identifier to not contain the \"urn\" reserved string [col %d]"
+ errHex = "expecting the percent encoded chars to be well-formed (%%alnum{2}) [col %d]"
+ errSCIMNamespace = "expecing the SCIM namespace identifier (ietf:params:scim) [col %d]"
+ errSCIMType = "expecting a correct SCIM type (schemas, api, param) [col %d]"
+ errSCIMName = "expecting one or more alnum char in the SCIM name part [col %d]"
+ errSCIMOther = "expecting a well-formed other SCIM part [col %d]"
+ errSCIMOtherIncomplete = "expecting a not empty SCIM other part after colon [col %d]"
+ err8141InformalID = "informal URN namespace must be in the form urn-[1-9][0-9] [col %d]"
+ err8141SpecificString = "expecting the specific string to contain alnum, hex, or others ([~&()+,-.:=@;$_!*'] or [/?] not in first position) chars [col %d]"
+ err8141Identifier = "expecting the indentifier to be a string with (length 2 to 32 chars) containing alnum (or dashes) not starting or ending with a dash [col %d]"
+ err8141RComponentStart = "expecting only one r-component (starting with the ?+ sequence) [col %d]"
+ err8141QComponentStart = "expecting only one q-component (starting with the ?= sequence) [col %d]"
+ err8141MalformedRComp = "expecting a non-empty r-component containing alnum, hex, or others ([~&()+,-.:=@;$_!*'] or [/?] but not at its beginning) [col %d]"
+ err8141MalformedQComp = "expecting a non-empty q-component containing alnum, hex, or others ([~&()+,-.:=@;$_!*'] or [/?] but not at its beginning) [col %d]"
+)
+var _toStateActions []byte = []byte{
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 33, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0,
+}
+
+var _eofActions []byte = []byte{
+ 0, 1, 1, 1, 1, 4, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 8, 9,
+ 9, 4, 4, 11, 1, 1, 1, 1,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 14, 14, 14, 14, 16, 18, 20,
+ 20, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 1, 1, 1, 1, 21,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 23, 24, 24, 25, 25, 0, 26, 28,
+ 28, 29, 29, 30, 30, 26, 26, 31,
+ 31, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 21,
+ 21, 22, 22, 22, 34, 34, 35, 37,
+ 37, 38, 40, 41, 41, 38, 42, 42,
+ 42, 44, 42, 48, 48, 48, 50, 44,
+ 50, 0,
+}
+
+const start int = 1
+const firstFinal int = 172
+
+const enScimOnly int = 44
+const enRfc8141Only int = 83
+const enFail int = 193
+const enMain int = 1
+
+// Machine is the interface representing the FSM
+type Machine interface {
+ Error() error
+ Parse(input []byte) (*URN, error)
+ WithParsingMode(ParsingMode)
+}
+
+type machine struct {
+ data []byte
+ cs int
+ p, pe, eof, pb int
+ err error
+ startParsingAt int
+ parsingMode ParsingMode
+ parsingModeSet bool
+}
+
+// NewMachine creates a new FSM able to parse RFC 2141 strings.
+func NewMachine(options ...Option) Machine {
+ m := &machine{
+ parsingModeSet: false,
+ }
+
+ for _, o := range options {
+ o(m)
+ }
+ // Set default parsing mode
+ if !m.parsingModeSet {
+ m.WithParsingMode(DefaultParsingMode)
+ }
+
+ return m
+}
+
+// Err returns the error that occurred on the last call to Parse.
+//
+// If the result is nil, then the line was parsed successfully.
+func (m *machine) Error() error {
+ return m.err
+}
+
+func (m *machine) text() []byte {
+ return m.data[m.pb:m.p]
+}
+
+// Parse parses the input byte array as a RFC 2141 or RFC7643 string.
+func (m *machine) Parse(input []byte) (*URN, error) {
+ m.data = input
+ m.p = 0
+ m.pb = 0
+ m.pe = len(input)
+ m.eof = len(input)
+ m.err = nil
+ m.cs = m.startParsingAt
+ output := &URN{
+ tolower: []int{},
+ }
+ {
+ if (m.p) == (m.pe) {
+ goto _testEof
+ }
+ if m.cs == 0 {
+ goto _out
+ }
+ _resume:
+ switch m.cs {
+ case 1:
+ switch (m.data)[(m.p)] {
+ case 85:
+ goto tr1
+ case 117:
+ goto tr1
+ }
+ goto tr0
+ case 0:
+ goto _out
+ case 2:
+ switch (m.data)[(m.p)] {
+ case 82:
+ goto tr2
+ case 114:
+ goto tr2
+ }
+ goto tr0
+ case 3:
+ switch (m.data)[(m.p)] {
+ case 78:
+ goto tr3
+ case 110:
+ goto tr3
+ }
+ goto tr0
+ case 4:
+ if (m.data)[(m.p)] == 58 {
+ goto tr4
+ }
+ goto tr0
+ case 5:
+ switch (m.data)[(m.p)] {
+ case 85:
+ goto tr7
+ case 117:
+ goto tr7
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr6
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr6
+ }
+ default:
+ goto tr6
+ }
+ goto tr5
+ case 6:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr9
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr9
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr9
+ }
+ default:
+ goto tr9
+ }
+ goto tr8
+ case 7:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr11
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr11
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr11
+ }
+ default:
+ goto tr11
+ }
+ goto tr8
+ case 8:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr12
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr12
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr12
+ }
+ default:
+ goto tr12
+ }
+ goto tr8
+ case 9:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr13
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr13
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr13
+ }
+ default:
+ goto tr13
+ }
+ goto tr8
+ case 10:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr14
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr14
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr14
+ }
+ default:
+ goto tr14
+ }
+ goto tr8
+ case 11:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr15
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr15
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr15
+ }
+ default:
+ goto tr15
+ }
+ goto tr8
+ case 12:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr16
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr16
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr16
+ }
+ default:
+ goto tr16
+ }
+ goto tr8
+ case 13:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr17
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr17
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr17
+ }
+ default:
+ goto tr17
+ }
+ goto tr8
+ case 14:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr18
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr18
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr18
+ }
+ default:
+ goto tr18
+ }
+ goto tr8
+ case 15:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr19
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr19
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr19
+ }
+ default:
+ goto tr19
+ }
+ goto tr8
+ case 16:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr20
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr20
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr20
+ }
+ default:
+ goto tr20
+ }
+ goto tr8
+ case 17:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr21
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr21
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr21
+ }
+ default:
+ goto tr21
+ }
+ goto tr8
+ case 18:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr22
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr22
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr22
+ }
+ default:
+ goto tr22
+ }
+ goto tr8
+ case 19:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr23
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr23
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr23
+ }
+ default:
+ goto tr23
+ }
+ goto tr8
+ case 20:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr24
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr24
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr24
+ }
+ default:
+ goto tr24
+ }
+ goto tr8
+ case 21:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr25
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr25
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr25
+ }
+ default:
+ goto tr25
+ }
+ goto tr8
+ case 22:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr26
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr26
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr26
+ }
+ default:
+ goto tr26
+ }
+ goto tr8
+ case 23:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr27
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr27
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr27
+ }
+ default:
+ goto tr27
+ }
+ goto tr8
+ case 24:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr28
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr28
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr28
+ }
+ default:
+ goto tr28
+ }
+ goto tr8
+ case 25:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr29
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr29
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr29
+ }
+ default:
+ goto tr29
+ }
+ goto tr8
+ case 26:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr30
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr30
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr30
+ }
+ default:
+ goto tr30
+ }
+ goto tr8
+ case 27:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr31
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr31
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr31
+ }
+ default:
+ goto tr31
+ }
+ goto tr8
+ case 28:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr32
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr32
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr32
+ }
+ default:
+ goto tr32
+ }
+ goto tr8
+ case 29:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr33
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr33
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr33
+ }
+ default:
+ goto tr33
+ }
+ goto tr8
+ case 30:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr34
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr34
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr34
+ }
+ default:
+ goto tr34
+ }
+ goto tr8
+ case 31:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr35
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr35
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr35
+ }
+ default:
+ goto tr35
+ }
+ goto tr8
+ case 32:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr36
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr36
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr36
+ }
+ default:
+ goto tr36
+ }
+ goto tr8
+ case 33:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr37
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr37
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr37
+ }
+ default:
+ goto tr37
+ }
+ goto tr8
+ case 34:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr38
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr38
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr38
+ }
+ default:
+ goto tr38
+ }
+ goto tr8
+ case 35:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr39
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr39
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr39
+ }
+ default:
+ goto tr39
+ }
+ goto tr8
+ case 36:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr40
+ case 58:
+ goto tr10
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr40
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr40
+ }
+ default:
+ goto tr40
+ }
+ goto tr8
+ case 37:
+ if (m.data)[(m.p)] == 58 {
+ goto tr10
+ }
+ goto tr8
+ case 38:
+ switch (m.data)[(m.p)] {
+ case 33:
+ goto tr42
+ case 36:
+ goto tr42
+ case 37:
+ goto tr43
+ case 61:
+ goto tr42
+ case 95:
+ goto tr42
+ }
+ switch {
+ case (m.data)[(m.p)] < 48:
+ if 39 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 46 {
+ goto tr42
+ }
+ case (m.data)[(m.p)] > 59:
+ switch {
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr42
+ }
+ case (m.data)[(m.p)] >= 64:
+ goto tr42
+ }
+ default:
+ goto tr42
+ }
+ goto tr41
+ case 172:
+ switch (m.data)[(m.p)] {
+ case 33:
+ goto tr212
+ case 36:
+ goto tr212
+ case 37:
+ goto tr213
+ case 61:
+ goto tr212
+ case 95:
+ goto tr212
+ }
+ switch {
+ case (m.data)[(m.p)] < 48:
+ if 39 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 46 {
+ goto tr212
+ }
+ case (m.data)[(m.p)] > 59:
+ switch {
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr212
+ }
+ case (m.data)[(m.p)] >= 64:
+ goto tr212
+ }
+ default:
+ goto tr212
+ }
+ goto tr41
+ case 39:
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr45
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr45
+ }
+ default:
+ goto tr46
+ }
+ goto tr44
+ case 40:
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr47
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr47
+ }
+ default:
+ goto tr48
+ }
+ goto tr44
+ case 173:
+ switch (m.data)[(m.p)] {
+ case 33:
+ goto tr212
+ case 36:
+ goto tr212
+ case 37:
+ goto tr213
+ case 61:
+ goto tr212
+ case 95:
+ goto tr212
+ }
+ switch {
+ case (m.data)[(m.p)] < 48:
+ if 39 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 46 {
+ goto tr212
+ }
+ case (m.data)[(m.p)] > 59:
+ switch {
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr212
+ }
+ case (m.data)[(m.p)] >= 64:
+ goto tr212
+ }
+ default:
+ goto tr212
+ }
+ goto tr44
+ case 41:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr9
+ case 58:
+ goto tr10
+ case 82:
+ goto tr49
+ case 114:
+ goto tr49
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr9
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr9
+ }
+ default:
+ goto tr9
+ }
+ goto tr5
+ case 42:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr11
+ case 58:
+ goto tr10
+ case 78:
+ goto tr50
+ case 110:
+ goto tr50
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr11
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr11
+ }
+ default:
+ goto tr11
+ }
+ goto tr5
+ case 43:
+ if (m.data)[(m.p)] == 45 {
+ goto tr12
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr12
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr12
+ }
+ default:
+ goto tr12
+ }
+ goto tr51
+ case 44:
+ switch (m.data)[(m.p)] {
+ case 85:
+ goto tr52
+ case 117:
+ goto tr52
+ }
+ goto tr0
+ case 45:
+ switch (m.data)[(m.p)] {
+ case 82:
+ goto tr53
+ case 114:
+ goto tr53
+ }
+ goto tr0
+ case 46:
+ switch (m.data)[(m.p)] {
+ case 78:
+ goto tr54
+ case 110:
+ goto tr54
+ }
+ goto tr0
+ case 47:
+ if (m.data)[(m.p)] == 58 {
+ goto tr55
+ }
+ goto tr0
+ case 48:
+ if (m.data)[(m.p)] == 105 {
+ goto tr57
+ }
+ goto tr56
+ case 49:
+ if (m.data)[(m.p)] == 101 {
+ goto tr58
+ }
+ goto tr56
+ case 50:
+ if (m.data)[(m.p)] == 116 {
+ goto tr59
+ }
+ goto tr56
+ case 51:
+ if (m.data)[(m.p)] == 102 {
+ goto tr60
+ }
+ goto tr56
+ case 52:
+ if (m.data)[(m.p)] == 58 {
+ goto tr61
+ }
+ goto tr56
+ case 53:
+ if (m.data)[(m.p)] == 112 {
+ goto tr62
+ }
+ goto tr56
+ case 54:
+ if (m.data)[(m.p)] == 97 {
+ goto tr63
+ }
+ goto tr56
+ case 55:
+ if (m.data)[(m.p)] == 114 {
+ goto tr64
+ }
+ goto tr56
+ case 56:
+ if (m.data)[(m.p)] == 97 {
+ goto tr65
+ }
+ goto tr56
+ case 57:
+ if (m.data)[(m.p)] == 109 {
+ goto tr66
+ }
+ goto tr56
+ case 58:
+ if (m.data)[(m.p)] == 115 {
+ goto tr67
+ }
+ goto tr56
+ case 59:
+ if (m.data)[(m.p)] == 58 {
+ goto tr68
+ }
+ goto tr56
+ case 60:
+ if (m.data)[(m.p)] == 115 {
+ goto tr69
+ }
+ goto tr56
+ case 61:
+ if (m.data)[(m.p)] == 99 {
+ goto tr70
+ }
+ goto tr56
+ case 62:
+ if (m.data)[(m.p)] == 105 {
+ goto tr71
+ }
+ goto tr56
+ case 63:
+ if (m.data)[(m.p)] == 109 {
+ goto tr72
+ }
+ goto tr56
+ case 64:
+ if (m.data)[(m.p)] == 58 {
+ goto tr73
+ }
+ goto tr56
+ case 65:
+ switch (m.data)[(m.p)] {
+ case 97:
+ goto tr75
+ case 112:
+ goto tr76
+ case 115:
+ goto tr77
+ }
+ goto tr74
+ case 66:
+ if (m.data)[(m.p)] == 112 {
+ goto tr78
+ }
+ goto tr74
+ case 67:
+ if (m.data)[(m.p)] == 105 {
+ goto tr79
+ }
+ goto tr74
+ case 68:
+ if (m.data)[(m.p)] == 58 {
+ goto tr80
+ }
+ goto tr74
+ case 69:
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr82
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr82
+ }
+ default:
+ goto tr82
+ }
+ goto tr81
+ case 174:
+ if (m.data)[(m.p)] == 58 {
+ goto tr215
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr214
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr214
+ }
+ default:
+ goto tr214
+ }
+ goto tr81
+ case 70:
+ switch (m.data)[(m.p)] {
+ case 33:
+ goto tr84
+ case 36:
+ goto tr84
+ case 37:
+ goto tr85
+ case 61:
+ goto tr84
+ case 95:
+ goto tr84
+ }
+ switch {
+ case (m.data)[(m.p)] < 48:
+ if 39 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 46 {
+ goto tr84
+ }
+ case (m.data)[(m.p)] > 59:
+ switch {
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr84
+ }
+ case (m.data)[(m.p)] >= 64:
+ goto tr84
+ }
+ default:
+ goto tr84
+ }
+ goto tr83
+ case 175:
+ switch (m.data)[(m.p)] {
+ case 33:
+ goto tr216
+ case 36:
+ goto tr216
+ case 37:
+ goto tr217
+ case 61:
+ goto tr216
+ case 95:
+ goto tr216
+ }
+ switch {
+ case (m.data)[(m.p)] < 48:
+ if 39 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 46 {
+ goto tr216
+ }
+ case (m.data)[(m.p)] > 59:
+ switch {
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr216
+ }
+ case (m.data)[(m.p)] >= 64:
+ goto tr216
+ }
+ default:
+ goto tr216
+ }
+ goto tr83
+ case 71:
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr87
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr87
+ }
+ default:
+ goto tr88
+ }
+ goto tr86
+ case 72:
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr89
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr89
+ }
+ default:
+ goto tr90
+ }
+ goto tr86
+ case 176:
+ switch (m.data)[(m.p)] {
+ case 33:
+ goto tr216
+ case 36:
+ goto tr216
+ case 37:
+ goto tr217
+ case 61:
+ goto tr216
+ case 95:
+ goto tr216
+ }
+ switch {
+ case (m.data)[(m.p)] < 48:
+ if 39 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 46 {
+ goto tr216
+ }
+ case (m.data)[(m.p)] > 59:
+ switch {
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr216
+ }
+ case (m.data)[(m.p)] >= 64:
+ goto tr216
+ }
+ default:
+ goto tr216
+ }
+ goto tr86
+ case 73:
+ if (m.data)[(m.p)] == 97 {
+ goto tr91
+ }
+ goto tr74
+ case 74:
+ if (m.data)[(m.p)] == 114 {
+ goto tr92
+ }
+ goto tr74
+ case 75:
+ if (m.data)[(m.p)] == 97 {
+ goto tr93
+ }
+ goto tr74
+ case 76:
+ if (m.data)[(m.p)] == 109 {
+ goto tr79
+ }
+ goto tr74
+ case 77:
+ if (m.data)[(m.p)] == 99 {
+ goto tr94
+ }
+ goto tr74
+ case 78:
+ if (m.data)[(m.p)] == 104 {
+ goto tr95
+ }
+ goto tr74
+ case 79:
+ if (m.data)[(m.p)] == 101 {
+ goto tr96
+ }
+ goto tr74
+ case 80:
+ if (m.data)[(m.p)] == 109 {
+ goto tr97
+ }
+ goto tr74
+ case 81:
+ if (m.data)[(m.p)] == 97 {
+ goto tr98
+ }
+ goto tr74
+ case 82:
+ if (m.data)[(m.p)] == 115 {
+ goto tr79
+ }
+ goto tr74
+ case 83:
+ switch (m.data)[(m.p)] {
+ case 85:
+ goto tr99
+ case 117:
+ goto tr99
+ }
+ goto tr0
+ case 84:
+ switch (m.data)[(m.p)] {
+ case 82:
+ goto tr100
+ case 114:
+ goto tr100
+ }
+ goto tr0
+ case 85:
+ switch (m.data)[(m.p)] {
+ case 78:
+ goto tr101
+ case 110:
+ goto tr101
+ }
+ goto tr0
+ case 86:
+ if (m.data)[(m.p)] == 58 {
+ goto tr102
+ }
+ goto tr0
+ case 87:
+ switch (m.data)[(m.p)] {
+ case 85:
+ goto tr105
+ case 117:
+ goto tr105
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr104
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr104
+ }
+ default:
+ goto tr104
+ }
+ goto tr103
+ case 88:
+ if (m.data)[(m.p)] == 45 {
+ goto tr107
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr108
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr108
+ }
+ default:
+ goto tr108
+ }
+ goto tr106
+ case 89:
+ if (m.data)[(m.p)] == 45 {
+ goto tr109
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr110
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr110
+ }
+ default:
+ goto tr110
+ }
+ goto tr106
+ case 90:
+ if (m.data)[(m.p)] == 45 {
+ goto tr111
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr112
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr112
+ }
+ default:
+ goto tr112
+ }
+ goto tr106
+ case 91:
+ if (m.data)[(m.p)] == 45 {
+ goto tr113
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr114
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr114
+ }
+ default:
+ goto tr114
+ }
+ goto tr106
+ case 92:
+ if (m.data)[(m.p)] == 45 {
+ goto tr115
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr116
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr116
+ }
+ default:
+ goto tr116
+ }
+ goto tr106
+ case 93:
+ if (m.data)[(m.p)] == 45 {
+ goto tr117
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr118
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr118
+ }
+ default:
+ goto tr118
+ }
+ goto tr106
+ case 94:
+ if (m.data)[(m.p)] == 45 {
+ goto tr119
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr120
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr120
+ }
+ default:
+ goto tr120
+ }
+ goto tr106
+ case 95:
+ if (m.data)[(m.p)] == 45 {
+ goto tr121
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr122
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr122
+ }
+ default:
+ goto tr122
+ }
+ goto tr106
+ case 96:
+ if (m.data)[(m.p)] == 45 {
+ goto tr123
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr124
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr124
+ }
+ default:
+ goto tr124
+ }
+ goto tr106
+ case 97:
+ if (m.data)[(m.p)] == 45 {
+ goto tr125
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr126
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr126
+ }
+ default:
+ goto tr126
+ }
+ goto tr106
+ case 98:
+ if (m.data)[(m.p)] == 45 {
+ goto tr127
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr128
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr128
+ }
+ default:
+ goto tr128
+ }
+ goto tr106
+ case 99:
+ if (m.data)[(m.p)] == 45 {
+ goto tr129
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr130
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr130
+ }
+ default:
+ goto tr130
+ }
+ goto tr106
+ case 100:
+ if (m.data)[(m.p)] == 45 {
+ goto tr131
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr132
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr132
+ }
+ default:
+ goto tr132
+ }
+ goto tr106
+ case 101:
+ if (m.data)[(m.p)] == 45 {
+ goto tr133
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr134
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr134
+ }
+ default:
+ goto tr134
+ }
+ goto tr106
+ case 102:
+ if (m.data)[(m.p)] == 45 {
+ goto tr135
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr136
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr136
+ }
+ default:
+ goto tr136
+ }
+ goto tr106
+ case 103:
+ if (m.data)[(m.p)] == 45 {
+ goto tr137
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr138
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr138
+ }
+ default:
+ goto tr138
+ }
+ goto tr106
+ case 104:
+ if (m.data)[(m.p)] == 45 {
+ goto tr139
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr140
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr140
+ }
+ default:
+ goto tr140
+ }
+ goto tr106
+ case 105:
+ if (m.data)[(m.p)] == 45 {
+ goto tr141
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr142
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr142
+ }
+ default:
+ goto tr142
+ }
+ goto tr106
+ case 106:
+ if (m.data)[(m.p)] == 45 {
+ goto tr143
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr144
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr144
+ }
+ default:
+ goto tr144
+ }
+ goto tr106
+ case 107:
+ if (m.data)[(m.p)] == 45 {
+ goto tr145
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr146
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr146
+ }
+ default:
+ goto tr146
+ }
+ goto tr106
+ case 108:
+ if (m.data)[(m.p)] == 45 {
+ goto tr147
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr148
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr148
+ }
+ default:
+ goto tr148
+ }
+ goto tr106
+ case 109:
+ if (m.data)[(m.p)] == 45 {
+ goto tr149
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr150
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr150
+ }
+ default:
+ goto tr150
+ }
+ goto tr106
+ case 110:
+ if (m.data)[(m.p)] == 45 {
+ goto tr151
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr152
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr152
+ }
+ default:
+ goto tr152
+ }
+ goto tr106
+ case 111:
+ if (m.data)[(m.p)] == 45 {
+ goto tr153
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr154
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr154
+ }
+ default:
+ goto tr154
+ }
+ goto tr106
+ case 112:
+ if (m.data)[(m.p)] == 45 {
+ goto tr155
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr156
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr156
+ }
+ default:
+ goto tr156
+ }
+ goto tr106
+ case 113:
+ if (m.data)[(m.p)] == 45 {
+ goto tr157
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr158
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr158
+ }
+ default:
+ goto tr158
+ }
+ goto tr106
+ case 114:
+ if (m.data)[(m.p)] == 45 {
+ goto tr159
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr160
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr160
+ }
+ default:
+ goto tr160
+ }
+ goto tr106
+ case 115:
+ if (m.data)[(m.p)] == 45 {
+ goto tr161
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr162
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr162
+ }
+ default:
+ goto tr162
+ }
+ goto tr106
+ case 116:
+ if (m.data)[(m.p)] == 45 {
+ goto tr163
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr164
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr164
+ }
+ default:
+ goto tr164
+ }
+ goto tr106
+ case 117:
+ if (m.data)[(m.p)] == 45 {
+ goto tr165
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr166
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr166
+ }
+ default:
+ goto tr166
+ }
+ goto tr106
+ case 118:
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr167
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr167
+ }
+ default:
+ goto tr167
+ }
+ goto tr106
+ case 119:
+ if (m.data)[(m.p)] == 58 {
+ goto tr168
+ }
+ goto tr106
+ case 120:
+ switch (m.data)[(m.p)] {
+ case 33:
+ goto tr170
+ case 37:
+ goto tr171
+ case 61:
+ goto tr170
+ case 95:
+ goto tr170
+ case 126:
+ goto tr170
+ }
+ switch {
+ case (m.data)[(m.p)] < 48:
+ if 36 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 46 {
+ goto tr170
+ }
+ case (m.data)[(m.p)] > 59:
+ switch {
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr170
+ }
+ case (m.data)[(m.p)] >= 64:
+ goto tr170
+ }
+ default:
+ goto tr170
+ }
+ goto tr169
+ case 177:
+ switch (m.data)[(m.p)] {
+ case 33:
+ goto tr218
+ case 35:
+ goto tr219
+ case 37:
+ goto tr220
+ case 61:
+ goto tr218
+ case 63:
+ goto tr221
+ case 95:
+ goto tr218
+ case 126:
+ goto tr218
+ }
+ switch {
+ case (m.data)[(m.p)] < 64:
+ if 36 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 59 {
+ goto tr218
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr218
+ }
+ default:
+ goto tr218
+ }
+ goto tr169
+ case 178:
+ switch (m.data)[(m.p)] {
+ case 33:
+ goto tr222
+ case 37:
+ goto tr223
+ case 61:
+ goto tr222
+ case 95:
+ goto tr222
+ case 126:
+ goto tr222
+ }
+ switch {
+ case (m.data)[(m.p)] < 63:
+ if 36 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 59 {
+ goto tr222
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr222
+ }
+ default:
+ goto tr222
+ }
+ goto tr183
+ case 179:
+ switch (m.data)[(m.p)] {
+ case 33:
+ goto tr224
+ case 37:
+ goto tr225
+ case 61:
+ goto tr224
+ case 95:
+ goto tr224
+ case 126:
+ goto tr224
+ }
+ switch {
+ case (m.data)[(m.p)] < 63:
+ if 36 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 59 {
+ goto tr224
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr224
+ }
+ default:
+ goto tr224
+ }
+ goto tr183
+ case 121:
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr173
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr173
+ }
+ default:
+ goto tr174
+ }
+ goto tr172
+ case 122:
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr175
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr175
+ }
+ default:
+ goto tr176
+ }
+ goto tr172
+ case 180:
+ switch (m.data)[(m.p)] {
+ case 33:
+ goto tr224
+ case 37:
+ goto tr225
+ case 61:
+ goto tr224
+ case 95:
+ goto tr224
+ case 126:
+ goto tr224
+ }
+ switch {
+ case (m.data)[(m.p)] < 63:
+ if 36 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 59 {
+ goto tr224
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr224
+ }
+ default:
+ goto tr224
+ }
+ goto tr172
+ case 123:
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr178
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr178
+ }
+ default:
+ goto tr179
+ }
+ goto tr177
+ case 124:
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr180
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr180
+ }
+ default:
+ goto tr181
+ }
+ goto tr177
+ case 181:
+ switch (m.data)[(m.p)] {
+ case 33:
+ goto tr218
+ case 35:
+ goto tr219
+ case 37:
+ goto tr220
+ case 61:
+ goto tr218
+ case 63:
+ goto tr221
+ case 95:
+ goto tr218
+ case 126:
+ goto tr218
+ }
+ switch {
+ case (m.data)[(m.p)] < 64:
+ if 36 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 59 {
+ goto tr218
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr218
+ }
+ default:
+ goto tr218
+ }
+ goto tr177
+ case 125:
+ switch (m.data)[(m.p)] {
+ case 43:
+ goto tr182
+ case 61:
+ goto tr184
+ }
+ goto tr183
+ case 126:
+ switch (m.data)[(m.p)] {
+ case 33:
+ goto tr186
+ case 37:
+ goto tr187
+ case 61:
+ goto tr186
+ case 63:
+ goto tr188
+ case 95:
+ goto tr186
+ case 126:
+ goto tr186
+ }
+ switch {
+ case (m.data)[(m.p)] < 48:
+ if 36 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 46 {
+ goto tr186
+ }
+ case (m.data)[(m.p)] > 59:
+ switch {
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr186
+ }
+ case (m.data)[(m.p)] >= 64:
+ goto tr186
+ }
+ default:
+ goto tr186
+ }
+ goto tr185
+ case 182:
+ switch (m.data)[(m.p)] {
+ case 33:
+ goto tr226
+ case 35:
+ goto tr227
+ case 37:
+ goto tr228
+ case 61:
+ goto tr226
+ case 63:
+ goto tr229
+ case 95:
+ goto tr226
+ case 126:
+ goto tr226
+ }
+ switch {
+ case (m.data)[(m.p)] < 64:
+ if 36 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 59 {
+ goto tr226
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr226
+ }
+ default:
+ goto tr226
+ }
+ goto tr185
+ case 127:
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr190
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr190
+ }
+ default:
+ goto tr191
+ }
+ goto tr189
+ case 128:
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr192
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr192
+ }
+ default:
+ goto tr193
+ }
+ goto tr189
+ case 183:
+ switch (m.data)[(m.p)] {
+ case 33:
+ goto tr226
+ case 35:
+ goto tr227
+ case 37:
+ goto tr228
+ case 61:
+ goto tr226
+ case 63:
+ goto tr229
+ case 95:
+ goto tr226
+ case 126:
+ goto tr226
+ }
+ switch {
+ case (m.data)[(m.p)] < 64:
+ if 36 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 59 {
+ goto tr226
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr226
+ }
+ default:
+ goto tr226
+ }
+ goto tr189
+ case 184:
+ switch (m.data)[(m.p)] {
+ case 33:
+ goto tr226
+ case 35:
+ goto tr227
+ case 37:
+ goto tr228
+ case 43:
+ goto tr230
+ case 61:
+ goto tr231
+ case 63:
+ goto tr229
+ case 95:
+ goto tr226
+ case 126:
+ goto tr226
+ }
+ switch {
+ case (m.data)[(m.p)] < 64:
+ if 36 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 59 {
+ goto tr226
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr226
+ }
+ default:
+ goto tr226
+ }
+ goto tr185
+ case 185:
+ switch (m.data)[(m.p)] {
+ case 33:
+ goto tr232
+ case 35:
+ goto tr233
+ case 37:
+ goto tr234
+ case 47:
+ goto tr226
+ case 61:
+ goto tr232
+ case 63:
+ goto tr235
+ case 95:
+ goto tr232
+ case 126:
+ goto tr232
+ }
+ switch {
+ case (m.data)[(m.p)] < 64:
+ if 36 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 59 {
+ goto tr232
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr232
+ }
+ default:
+ goto tr232
+ }
+ goto tr185
+ case 186:
+ switch (m.data)[(m.p)] {
+ case 33:
+ goto tr204
+ case 35:
+ goto tr227
+ case 37:
+ goto tr237
+ case 47:
+ goto tr226
+ case 61:
+ goto tr204
+ case 63:
+ goto tr229
+ case 95:
+ goto tr204
+ case 126:
+ goto tr204
+ }
+ switch {
+ case (m.data)[(m.p)] < 64:
+ if 36 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 59 {
+ goto tr204
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr204
+ }
+ default:
+ goto tr204
+ }
+ goto tr236
+ case 187:
+ switch (m.data)[(m.p)] {
+ case 33:
+ goto tr238
+ case 35:
+ goto tr239
+ case 37:
+ goto tr240
+ case 61:
+ goto tr238
+ case 63:
+ goto tr241
+ case 95:
+ goto tr238
+ case 126:
+ goto tr238
+ }
+ switch {
+ case (m.data)[(m.p)] < 64:
+ if 36 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 59 {
+ goto tr238
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr238
+ }
+ default:
+ goto tr238
+ }
+ goto tr203
+ case 129:
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr195
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr195
+ }
+ default:
+ goto tr196
+ }
+ goto tr194
+ case 130:
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr197
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr197
+ }
+ default:
+ goto tr198
+ }
+ goto tr194
+ case 188:
+ switch (m.data)[(m.p)] {
+ case 33:
+ goto tr238
+ case 35:
+ goto tr239
+ case 37:
+ goto tr240
+ case 61:
+ goto tr238
+ case 63:
+ goto tr241
+ case 95:
+ goto tr238
+ case 126:
+ goto tr238
+ }
+ switch {
+ case (m.data)[(m.p)] < 64:
+ if 36 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 59 {
+ goto tr238
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr238
+ }
+ default:
+ goto tr238
+ }
+ goto tr194
+ case 189:
+ switch (m.data)[(m.p)] {
+ case 33:
+ goto tr238
+ case 35:
+ goto tr239
+ case 37:
+ goto tr240
+ case 61:
+ goto tr242
+ case 63:
+ goto tr241
+ case 95:
+ goto tr238
+ case 126:
+ goto tr238
+ }
+ switch {
+ case (m.data)[(m.p)] < 64:
+ if 36 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 59 {
+ goto tr238
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr238
+ }
+ default:
+ goto tr238
+ }
+ goto tr203
+ case 190:
+ switch (m.data)[(m.p)] {
+ case 33:
+ goto tr243
+ case 35:
+ goto tr244
+ case 37:
+ goto tr245
+ case 47:
+ goto tr238
+ case 61:
+ goto tr243
+ case 63:
+ goto tr246
+ case 95:
+ goto tr243
+ case 126:
+ goto tr243
+ }
+ switch {
+ case (m.data)[(m.p)] < 64:
+ if 36 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 59 {
+ goto tr243
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr243
+ }
+ default:
+ goto tr243
+ }
+ goto tr203
+ case 131:
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr200
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr200
+ }
+ default:
+ goto tr201
+ }
+ goto tr199
+ case 132:
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr197
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr197
+ }
+ default:
+ goto tr198
+ }
+ goto tr199
+ case 133:
+ if (m.data)[(m.p)] == 43 {
+ goto tr202
+ }
+ goto tr185
+ case 191:
+ switch (m.data)[(m.p)] {
+ case 33:
+ goto tr232
+ case 35:
+ goto tr233
+ case 37:
+ goto tr234
+ case 61:
+ goto tr232
+ case 63:
+ goto tr247
+ case 95:
+ goto tr232
+ case 126:
+ goto tr232
+ }
+ switch {
+ case (m.data)[(m.p)] < 48:
+ if 36 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 46 {
+ goto tr232
+ }
+ case (m.data)[(m.p)] > 59:
+ switch {
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr232
+ }
+ case (m.data)[(m.p)] >= 64:
+ goto tr232
+ }
+ default:
+ goto tr232
+ }
+ goto tr185
+ case 134:
+ switch (m.data)[(m.p)] {
+ case 43:
+ goto tr202
+ case 61:
+ goto tr184
+ }
+ goto tr185
+ case 135:
+ switch (m.data)[(m.p)] {
+ case 33:
+ goto tr204
+ case 37:
+ goto tr205
+ case 61:
+ goto tr204
+ case 63:
+ goto tr206
+ case 95:
+ goto tr204
+ case 126:
+ goto tr204
+ }
+ switch {
+ case (m.data)[(m.p)] < 48:
+ if 36 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 46 {
+ goto tr204
+ }
+ case (m.data)[(m.p)] > 59:
+ switch {
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr204
+ }
+ case (m.data)[(m.p)] >= 64:
+ goto tr204
+ }
+ default:
+ goto tr204
+ }
+ goto tr203
+ case 136:
+ if (m.data)[(m.p)] == 61 {
+ goto tr207
+ }
+ goto tr203
+ case 192:
+ switch (m.data)[(m.p)] {
+ case 33:
+ goto tr243
+ case 35:
+ goto tr244
+ case 37:
+ goto tr245
+ case 61:
+ goto tr243
+ case 63:
+ goto tr248
+ case 95:
+ goto tr243
+ case 126:
+ goto tr243
+ }
+ switch {
+ case (m.data)[(m.p)] < 48:
+ if 36 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 46 {
+ goto tr243
+ }
+ case (m.data)[(m.p)] > 59:
+ switch {
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr243
+ }
+ case (m.data)[(m.p)] >= 64:
+ goto tr243
+ }
+ default:
+ goto tr243
+ }
+ goto tr203
+ case 137:
+ if (m.data)[(m.p)] == 58 {
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr167
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr167
+ }
+ default:
+ goto tr167
+ }
+ goto tr106
+ case 138:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr165
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr166
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr166
+ }
+ default:
+ goto tr166
+ }
+ goto tr106
+ case 139:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr163
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr164
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr164
+ }
+ default:
+ goto tr164
+ }
+ goto tr106
+ case 140:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr161
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr162
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr162
+ }
+ default:
+ goto tr162
+ }
+ goto tr106
+ case 141:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr159
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr160
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr160
+ }
+ default:
+ goto tr160
+ }
+ goto tr106
+ case 142:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr157
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr158
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr158
+ }
+ default:
+ goto tr158
+ }
+ goto tr106
+ case 143:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr155
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr156
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr156
+ }
+ default:
+ goto tr156
+ }
+ goto tr106
+ case 144:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr153
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr154
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr154
+ }
+ default:
+ goto tr154
+ }
+ goto tr106
+ case 145:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr151
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr152
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr152
+ }
+ default:
+ goto tr152
+ }
+ goto tr106
+ case 146:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr149
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr150
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr150
+ }
+ default:
+ goto tr150
+ }
+ goto tr106
+ case 147:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr147
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr148
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr148
+ }
+ default:
+ goto tr148
+ }
+ goto tr106
+ case 148:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr145
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr146
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr146
+ }
+ default:
+ goto tr146
+ }
+ goto tr106
+ case 149:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr143
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr144
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr144
+ }
+ default:
+ goto tr144
+ }
+ goto tr106
+ case 150:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr141
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr142
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr142
+ }
+ default:
+ goto tr142
+ }
+ goto tr106
+ case 151:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr139
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr140
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr140
+ }
+ default:
+ goto tr140
+ }
+ goto tr106
+ case 152:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr137
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr138
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr138
+ }
+ default:
+ goto tr138
+ }
+ goto tr106
+ case 153:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr135
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr136
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr136
+ }
+ default:
+ goto tr136
+ }
+ goto tr106
+ case 154:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr133
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr134
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr134
+ }
+ default:
+ goto tr134
+ }
+ goto tr106
+ case 155:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr131
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr132
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr132
+ }
+ default:
+ goto tr132
+ }
+ goto tr106
+ case 156:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr129
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr130
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr130
+ }
+ default:
+ goto tr130
+ }
+ goto tr106
+ case 157:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr127
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr128
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr128
+ }
+ default:
+ goto tr128
+ }
+ goto tr106
+ case 158:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr125
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr126
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr126
+ }
+ default:
+ goto tr126
+ }
+ goto tr106
+ case 159:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr123
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr124
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr124
+ }
+ default:
+ goto tr124
+ }
+ goto tr106
+ case 160:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr121
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr122
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr122
+ }
+ default:
+ goto tr122
+ }
+ goto tr106
+ case 161:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr119
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr120
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr120
+ }
+ default:
+ goto tr120
+ }
+ goto tr106
+ case 162:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr117
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr118
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr118
+ }
+ default:
+ goto tr118
+ }
+ goto tr106
+ case 163:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr115
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr116
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr116
+ }
+ default:
+ goto tr116
+ }
+ goto tr106
+ case 164:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr113
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr114
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr114
+ }
+ default:
+ goto tr114
+ }
+ goto tr106
+ case 165:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr111
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr112
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr112
+ }
+ default:
+ goto tr112
+ }
+ goto tr106
+ case 166:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr109
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr110
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr110
+ }
+ default:
+ goto tr110
+ }
+ goto tr106
+ case 167:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr107
+ case 82:
+ goto tr208
+ case 114:
+ goto tr208
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr108
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr108
+ }
+ default:
+ goto tr108
+ }
+ goto tr103
+ case 168:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr109
+ case 58:
+ goto tr168
+ case 78:
+ goto tr209
+ case 110:
+ goto tr209
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr110
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr110
+ }
+ default:
+ goto tr110
+ }
+ goto tr103
+ case 169:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr210
+ case 58:
+ goto tr168
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr112
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr112
+ }
+ default:
+ goto tr112
+ }
+ goto tr106
+ case 170:
+ switch (m.data)[(m.p)] {
+ case 45:
+ goto tr113
+ case 48:
+ goto tr211
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 49 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr114
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr211
+ }
+ default:
+ goto tr211
+ }
+ goto tr106
+ case 171:
+ if (m.data)[(m.p)] == 45 {
+ goto tr115
+ }
+ switch {
+ case (m.data)[(m.p)] < 65:
+ if 48 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 57 {
+ goto tr116
+ }
+ case (m.data)[(m.p)] > 90:
+ if 97 <= (m.data)[(m.p)] && (m.data)[(m.p)] <= 122 {
+ goto tr116
+ }
+ default:
+ goto tr116
+ }
+ goto tr106
+ case 193:
+ switch (m.data)[(m.p)] {
+ case 10:
+ goto tr183
+ case 13:
+ goto tr183
+ }
+ goto tr249
+ }
+
+ tr183:
+ m.cs = 0
+ goto _again
+ tr0:
+ m.cs = 0
+ goto f0
+ tr5:
+ m.cs = 0
+ goto f3
+ tr8:
+ m.cs = 0
+ goto f5
+ tr41:
+ m.cs = 0
+ goto f7
+ tr44:
+ m.cs = 0
+ goto f8
+ tr51:
+ m.cs = 0
+ goto f10
+ tr56:
+ m.cs = 0
+ goto f11
+ tr74:
+ m.cs = 0
+ goto f13
+ tr81:
+ m.cs = 0
+ goto f15
+ tr83:
+ m.cs = 0
+ goto f17
+ tr86:
+ m.cs = 0
+ goto f19
+ tr103:
+ m.cs = 0
+ goto f20
+ tr106:
+ m.cs = 0
+ goto f21
+ tr169:
+ m.cs = 0
+ goto f22
+ tr172:
+ m.cs = 0
+ goto f23
+ tr177:
+ m.cs = 0
+ goto f24
+ tr185:
+ m.cs = 0
+ goto f25
+ tr189:
+ m.cs = 0
+ goto f27
+ tr194:
+ m.cs = 0
+ goto f28
+ tr199:
+ m.cs = 0
+ goto f29
+ tr203:
+ m.cs = 0
+ goto f30
+ tr236:
+ m.cs = 0
+ goto f46
+ tr1:
+ m.cs = 2
+ goto f1
+ tr2:
+ m.cs = 3
+ goto _again
+ tr3:
+ m.cs = 4
+ goto _again
+ tr4:
+ m.cs = 5
+ goto f2
+ tr6:
+ m.cs = 6
+ goto f4
+ tr9:
+ m.cs = 7
+ goto _again
+ tr11:
+ m.cs = 8
+ goto _again
+ tr12:
+ m.cs = 9
+ goto _again
+ tr13:
+ m.cs = 10
+ goto _again
+ tr14:
+ m.cs = 11
+ goto _again
+ tr15:
+ m.cs = 12
+ goto _again
+ tr16:
+ m.cs = 13
+ goto _again
+ tr17:
+ m.cs = 14
+ goto _again
+ tr18:
+ m.cs = 15
+ goto _again
+ tr19:
+ m.cs = 16
+ goto _again
+ tr20:
+ m.cs = 17
+ goto _again
+ tr21:
+ m.cs = 18
+ goto _again
+ tr22:
+ m.cs = 19
+ goto _again
+ tr23:
+ m.cs = 20
+ goto _again
+ tr24:
+ m.cs = 21
+ goto _again
+ tr25:
+ m.cs = 22
+ goto _again
+ tr26:
+ m.cs = 23
+ goto _again
+ tr27:
+ m.cs = 24
+ goto _again
+ tr28:
+ m.cs = 25
+ goto _again
+ tr29:
+ m.cs = 26
+ goto _again
+ tr30:
+ m.cs = 27
+ goto _again
+ tr31:
+ m.cs = 28
+ goto _again
+ tr32:
+ m.cs = 29
+ goto _again
+ tr33:
+ m.cs = 30
+ goto _again
+ tr34:
+ m.cs = 31
+ goto _again
+ tr35:
+ m.cs = 32
+ goto _again
+ tr36:
+ m.cs = 33
+ goto _again
+ tr37:
+ m.cs = 34
+ goto _again
+ tr38:
+ m.cs = 35
+ goto _again
+ tr39:
+ m.cs = 36
+ goto _again
+ tr40:
+ m.cs = 37
+ goto _again
+ tr10:
+ m.cs = 38
+ goto f6
+ tr213:
+ m.cs = 39
+ goto _again
+ tr43:
+ m.cs = 39
+ goto f4
+ tr45:
+ m.cs = 40
+ goto _again
+ tr46:
+ m.cs = 40
+ goto f9
+ tr7:
+ m.cs = 41
+ goto f1
+ tr49:
+ m.cs = 42
+ goto _again
+ tr50:
+ m.cs = 43
+ goto _again
+ tr52:
+ m.cs = 45
+ goto f1
+ tr53:
+ m.cs = 46
+ goto _again
+ tr54:
+ m.cs = 47
+ goto _again
+ tr55:
+ m.cs = 48
+ goto f2
+ tr57:
+ m.cs = 49
+ goto f4
+ tr58:
+ m.cs = 50
+ goto _again
+ tr59:
+ m.cs = 51
+ goto _again
+ tr60:
+ m.cs = 52
+ goto _again
+ tr61:
+ m.cs = 53
+ goto _again
+ tr62:
+ m.cs = 54
+ goto _again
+ tr63:
+ m.cs = 55
+ goto _again
+ tr64:
+ m.cs = 56
+ goto _again
+ tr65:
+ m.cs = 57
+ goto _again
+ tr66:
+ m.cs = 58
+ goto _again
+ tr67:
+ m.cs = 59
+ goto _again
+ tr68:
+ m.cs = 60
+ goto _again
+ tr69:
+ m.cs = 61
+ goto _again
+ tr70:
+ m.cs = 62
+ goto _again
+ tr71:
+ m.cs = 63
+ goto _again
+ tr72:
+ m.cs = 64
+ goto _again
+ tr73:
+ m.cs = 65
+ goto f12
+ tr75:
+ m.cs = 66
+ goto f4
+ tr78:
+ m.cs = 67
+ goto _again
+ tr79:
+ m.cs = 68
+ goto _again
+ tr80:
+ m.cs = 69
+ goto f14
+ tr215:
+ m.cs = 70
+ goto f35
+ tr217:
+ m.cs = 71
+ goto _again
+ tr85:
+ m.cs = 71
+ goto f18
+ tr87:
+ m.cs = 72
+ goto _again
+ tr88:
+ m.cs = 72
+ goto f9
+ tr76:
+ m.cs = 73
+ goto f4
+ tr91:
+ m.cs = 74
+ goto _again
+ tr92:
+ m.cs = 75
+ goto _again
+ tr93:
+ m.cs = 76
+ goto _again
+ tr77:
+ m.cs = 77
+ goto f4
+ tr94:
+ m.cs = 78
+ goto _again
+ tr95:
+ m.cs = 79
+ goto _again
+ tr96:
+ m.cs = 80
+ goto _again
+ tr97:
+ m.cs = 81
+ goto _again
+ tr98:
+ m.cs = 82
+ goto _again
+ tr99:
+ m.cs = 84
+ goto f1
+ tr100:
+ m.cs = 85
+ goto _again
+ tr101:
+ m.cs = 86
+ goto _again
+ tr102:
+ m.cs = 87
+ goto f2
+ tr104:
+ m.cs = 88
+ goto f4
+ tr107:
+ m.cs = 89
+ goto _again
+ tr109:
+ m.cs = 90
+ goto _again
+ tr111:
+ m.cs = 91
+ goto _again
+ tr113:
+ m.cs = 92
+ goto _again
+ tr115:
+ m.cs = 93
+ goto _again
+ tr117:
+ m.cs = 94
+ goto _again
+ tr119:
+ m.cs = 95
+ goto _again
+ tr121:
+ m.cs = 96
+ goto _again
+ tr123:
+ m.cs = 97
+ goto _again
+ tr125:
+ m.cs = 98
+ goto _again
+ tr127:
+ m.cs = 99
+ goto _again
+ tr129:
+ m.cs = 100
+ goto _again
+ tr131:
+ m.cs = 101
+ goto _again
+ tr133:
+ m.cs = 102
+ goto _again
+ tr135:
+ m.cs = 103
+ goto _again
+ tr137:
+ m.cs = 104
+ goto _again
+ tr139:
+ m.cs = 105
+ goto _again
+ tr141:
+ m.cs = 106
+ goto _again
+ tr143:
+ m.cs = 107
+ goto _again
+ tr145:
+ m.cs = 108
+ goto _again
+ tr147:
+ m.cs = 109
+ goto _again
+ tr149:
+ m.cs = 110
+ goto _again
+ tr151:
+ m.cs = 111
+ goto _again
+ tr153:
+ m.cs = 112
+ goto _again
+ tr155:
+ m.cs = 113
+ goto _again
+ tr157:
+ m.cs = 114
+ goto _again
+ tr159:
+ m.cs = 115
+ goto _again
+ tr161:
+ m.cs = 116
+ goto _again
+ tr163:
+ m.cs = 117
+ goto _again
+ tr165:
+ m.cs = 118
+ goto _again
+ tr167:
+ m.cs = 119
+ goto _again
+ tr168:
+ m.cs = 120
+ goto f6
+ tr225:
+ m.cs = 121
+ goto _again
+ tr223:
+ m.cs = 121
+ goto f4
+ tr173:
+ m.cs = 122
+ goto _again
+ tr174:
+ m.cs = 122
+ goto f9
+ tr220:
+ m.cs = 123
+ goto _again
+ tr171:
+ m.cs = 123
+ goto f4
+ tr178:
+ m.cs = 124
+ goto _again
+ tr179:
+ m.cs = 124
+ goto f9
+ tr221:
+ m.cs = 125
+ goto f38
+ tr182:
+ m.cs = 126
+ goto _again
+ tr228:
+ m.cs = 127
+ goto _again
+ tr187:
+ m.cs = 127
+ goto f26
+ tr234:
+ m.cs = 127
+ goto f44
+ tr190:
+ m.cs = 128
+ goto _again
+ tr191:
+ m.cs = 128
+ goto f9
+ tr240:
+ m.cs = 129
+ goto _again
+ tr205:
+ m.cs = 129
+ goto f31
+ tr245:
+ m.cs = 129
+ goto f50
+ tr195:
+ m.cs = 130
+ goto _again
+ tr196:
+ m.cs = 130
+ goto f9
+ tr237:
+ m.cs = 131
+ goto f31
+ tr200:
+ m.cs = 132
+ goto _again
+ tr201:
+ m.cs = 132
+ goto f9
+ tr188:
+ m.cs = 133
+ goto f26
+ tr247:
+ m.cs = 134
+ goto f45
+ tr184:
+ m.cs = 135
+ goto _again
+ tr206:
+ m.cs = 136
+ goto f31
+ tr248:
+ m.cs = 136
+ goto f50
+ tr166:
+ m.cs = 137
+ goto _again
+ tr164:
+ m.cs = 138
+ goto _again
+ tr162:
+ m.cs = 139
+ goto _again
+ tr160:
+ m.cs = 140
+ goto _again
+ tr158:
+ m.cs = 141
+ goto _again
+ tr156:
+ m.cs = 142
+ goto _again
+ tr154:
+ m.cs = 143
+ goto _again
+ tr152:
+ m.cs = 144
+ goto _again
+ tr150:
+ m.cs = 145
+ goto _again
+ tr148:
+ m.cs = 146
+ goto _again
+ tr146:
+ m.cs = 147
+ goto _again
+ tr144:
+ m.cs = 148
+ goto _again
+ tr142:
+ m.cs = 149
+ goto _again
+ tr140:
+ m.cs = 150
+ goto _again
+ tr138:
+ m.cs = 151
+ goto _again
+ tr136:
+ m.cs = 152
+ goto _again
+ tr134:
+ m.cs = 153
+ goto _again
+ tr132:
+ m.cs = 154
+ goto _again
+ tr130:
+ m.cs = 155
+ goto _again
+ tr128:
+ m.cs = 156
+ goto _again
+ tr126:
+ m.cs = 157
+ goto _again
+ tr124:
+ m.cs = 158
+ goto _again
+ tr122:
+ m.cs = 159
+ goto _again
+ tr120:
+ m.cs = 160
+ goto _again
+ tr118:
+ m.cs = 161
+ goto _again
+ tr116:
+ m.cs = 162
+ goto _again
+ tr114:
+ m.cs = 163
+ goto _again
+ tr112:
+ m.cs = 164
+ goto _again
+ tr110:
+ m.cs = 165
+ goto _again
+ tr108:
+ m.cs = 166
+ goto _again
+ tr105:
+ m.cs = 167
+ goto f1
+ tr208:
+ m.cs = 168
+ goto _again
+ tr209:
+ m.cs = 169
+ goto _again
+ tr210:
+ m.cs = 170
+ goto f2
+ tr211:
+ m.cs = 171
+ goto _again
+ tr212:
+ m.cs = 172
+ goto _again
+ tr42:
+ m.cs = 172
+ goto f4
+ tr47:
+ m.cs = 173
+ goto _again
+ tr48:
+ m.cs = 173
+ goto f9
+ tr214:
+ m.cs = 174
+ goto _again
+ tr82:
+ m.cs = 174
+ goto f16
+ tr216:
+ m.cs = 175
+ goto _again
+ tr84:
+ m.cs = 175
+ goto f18
+ tr89:
+ m.cs = 176
+ goto _again
+ tr90:
+ m.cs = 176
+ goto f9
+ tr218:
+ m.cs = 177
+ goto _again
+ tr170:
+ m.cs = 177
+ goto f4
+ tr219:
+ m.cs = 178
+ goto f38
+ tr227:
+ m.cs = 178
+ goto f42
+ tr233:
+ m.cs = 178
+ goto f45
+ tr239:
+ m.cs = 178
+ goto f48
+ tr244:
+ m.cs = 178
+ goto f51
+ tr224:
+ m.cs = 179
+ goto _again
+ tr222:
+ m.cs = 179
+ goto f4
+ tr175:
+ m.cs = 180
+ goto _again
+ tr176:
+ m.cs = 180
+ goto f9
+ tr180:
+ m.cs = 181
+ goto _again
+ tr181:
+ m.cs = 181
+ goto f9
+ tr226:
+ m.cs = 182
+ goto _again
+ tr186:
+ m.cs = 182
+ goto f26
+ tr232:
+ m.cs = 182
+ goto f44
+ tr192:
+ m.cs = 183
+ goto _again
+ tr193:
+ m.cs = 183
+ goto f9
+ tr229:
+ m.cs = 184
+ goto f42
+ tr235:
+ m.cs = 184
+ goto f45
+ tr230:
+ m.cs = 185
+ goto _again
+ tr231:
+ m.cs = 186
+ goto _again
+ tr238:
+ m.cs = 187
+ goto _again
+ tr204:
+ m.cs = 187
+ goto f31
+ tr243:
+ m.cs = 187
+ goto f50
+ tr197:
+ m.cs = 188
+ goto _again
+ tr198:
+ m.cs = 188
+ goto f9
+ tr241:
+ m.cs = 189
+ goto _again
+ tr246:
+ m.cs = 189
+ goto f50
+ tr242:
+ m.cs = 190
+ goto _again
+ tr202:
+ m.cs = 191
+ goto _again
+ tr207:
+ m.cs = 192
+ goto _again
+ tr249:
+ m.cs = 193
+ goto _again
+
+ f4:
+
+ m.pb = m.p
+
+ goto _again
+ f9:
+
+ // List of positions in the buffer to later lowercase
+ output.tolower = append(output.tolower, m.p-m.pb)
+
+ goto _again
+ f2:
+
+ output.prefix = string(m.text())
+
+ goto _again
+ f6:
+
+ output.ID = string(m.text())
+
+ goto _again
+ f38:
+
+ output.SS = string(m.text())
+ // Iterate upper letters lowering them
+ for _, i := range output.tolower {
+ m.data[m.pb+i] = m.data[m.pb+i] + 32
+ }
+ output.norm = string(m.text())
+ // Revert the buffer to the original
+ for _, i := range output.tolower {
+ m.data[m.pb+i] = m.data[m.pb+i] - 32
+ }
+
+ goto _again
+ f0:
+
+ m.err = fmt.Errorf(errPrefix, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ goto _again
+ f5:
+
+ m.err = fmt.Errorf(errIdentifier, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ goto _again
+ f7:
+
+ m.err = fmt.Errorf(errSpecificString, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ goto _again
+ f23:
+
+ if m.parsingMode == RFC2141Only || m.parsingMode == RFC8141Only {
+ m.err = fmt.Errorf(errHex, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ }
+
+ goto _again
+ f11:
+
+ m.err = fmt.Errorf(errSCIMNamespace, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ goto _again
+ f13:
+
+ m.err = fmt.Errorf(errSCIMType, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ goto _again
+ f15:
+
+ m.err = fmt.Errorf(errSCIMName, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ goto _again
+ f17:
+
+ if m.p == m.pe {
+ m.err = fmt.Errorf(errSCIMOtherIncomplete, m.p-1)
+ } else {
+ m.err = fmt.Errorf(errSCIMOther, m.p)
+ }
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ goto _again
+ f14:
+
+ output.scim.Type = scimschema.TypeFromString(string(m.text()))
+
+ goto _again
+ f16:
+
+ output.scim.pos = m.p
+
+ goto _again
+ f35:
+
+ output.scim.Name = string(m.data[output.scim.pos:m.p])
+
+ goto _again
+ f18:
+
+ output.scim.pos = m.p
+
+ goto _again
+ f22:
+
+ m.err = fmt.Errorf(err8141SpecificString, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ goto _again
+ f21:
+
+ m.err = fmt.Errorf(err8141Identifier, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ goto _again
+ f42:
+
+ output.rComponent = string(m.text())
+
+ goto _again
+ f48:
+
+ output.qComponent = string(m.text())
+
+ goto _again
+ f44:
+
+ if output.rStart {
+ m.err = fmt.Errorf(err8141RComponentStart, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ }
+ output.rStart = true
+
+ goto _again
+ f50:
+
+ if output.qStart {
+ m.err = fmt.Errorf(err8141QComponentStart, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ }
+ output.qStart = true
+
+ goto _again
+ f25:
+
+ m.err = fmt.Errorf(err8141MalformedRComp, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ goto _again
+ f30:
+
+ m.err = fmt.Errorf(err8141MalformedQComp, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ goto _again
+ f1:
+
+ m.pb = m.p
+
+ if m.parsingMode != RFC8141Only {
+ // Throw an error when:
+ // - we are entering here matching the the prefix in the namespace identifier part
+ // - looking ahead (3 chars) we find a colon
+ if pos := m.p + 3; pos < m.pe && m.data[pos] == 58 && output.prefix != "" {
+ m.err = fmt.Errorf(errNoUrnWithinID, pos)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ }
+ }
+
+ goto _again
+ f12:
+
+ output.ID = string(m.text())
+
+ output.scim = &SCIM{}
+
+ goto _again
+ f3:
+
+ m.err = fmt.Errorf(errIdentifier, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ m.err = fmt.Errorf(errPrefix, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ goto _again
+ f10:
+
+ m.err = fmt.Errorf(errIdentifier, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ m.err = fmt.Errorf(errNoUrnWithinID, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ goto _again
+ f8:
+
+ if m.parsingMode == RFC2141Only || m.parsingMode == RFC8141Only {
+ m.err = fmt.Errorf(errHex, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ }
+
+ m.err = fmt.Errorf(errSpecificString, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ goto _again
+ f19:
+
+ if m.parsingMode == RFC2141Only || m.parsingMode == RFC8141Only {
+ m.err = fmt.Errorf(errHex, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ }
+
+ if m.p == m.pe {
+ m.err = fmt.Errorf(errSCIMOtherIncomplete, m.p-1)
+ } else {
+ m.err = fmt.Errorf(errSCIMOther, m.p)
+ }
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ goto _again
+ f24:
+
+ if m.parsingMode == RFC2141Only || m.parsingMode == RFC8141Only {
+ m.err = fmt.Errorf(errHex, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ }
+
+ m.err = fmt.Errorf(err8141SpecificString, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ goto _again
+ f27:
+
+ if m.parsingMode == RFC2141Only || m.parsingMode == RFC8141Only {
+ m.err = fmt.Errorf(errHex, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ }
+
+ m.err = fmt.Errorf(err8141MalformedRComp, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ goto _again
+ f28:
+
+ if m.parsingMode == RFC2141Only || m.parsingMode == RFC8141Only {
+ m.err = fmt.Errorf(errHex, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ }
+
+ m.err = fmt.Errorf(err8141MalformedQComp, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ goto _again
+ f20:
+
+ m.err = fmt.Errorf(err8141Identifier, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ m.err = fmt.Errorf(errPrefix, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ goto _again
+ f26:
+
+ if output.rStart {
+ m.err = fmt.Errorf(err8141RComponentStart, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ }
+ output.rStart = true
+
+ m.pb = m.p
+
+ goto _again
+ f45:
+
+ if output.rStart {
+ m.err = fmt.Errorf(err8141RComponentStart, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ }
+ output.rStart = true
+
+ output.rComponent = string(m.text())
+
+ goto _again
+ f31:
+
+ if output.qStart {
+ m.err = fmt.Errorf(err8141QComponentStart, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ }
+ output.qStart = true
+
+ m.pb = m.p
+
+ goto _again
+ f51:
+
+ if output.qStart {
+ m.err = fmt.Errorf(err8141QComponentStart, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ }
+ output.qStart = true
+
+ output.qComponent = string(m.text())
+
+ goto _again
+ f46:
+
+ m.err = fmt.Errorf(err8141MalformedRComp, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ m.err = fmt.Errorf(err8141MalformedQComp, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ goto _again
+ f29:
+
+ if m.parsingMode == RFC2141Only || m.parsingMode == RFC8141Only {
+ m.err = fmt.Errorf(errHex, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ }
+
+ m.err = fmt.Errorf(err8141MalformedRComp, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ m.err = fmt.Errorf(err8141MalformedQComp, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ goto _again
+
+ _again:
+ switch _toStateActions[m.cs] {
+ case 33:
+
+ (m.p)--
+
+ m.err = fmt.Errorf(err8141InformalID, m.p)
+ m.cs = 193
+ goto _again
+ }
+
+ if m.cs == 0 {
+ goto _out
+ }
+ if (m.p)++; (m.p) != (m.pe) {
+ goto _resume
+ }
+ _testEof:
+ {
+ }
+ if (m.p) == (m.eof) {
+ switch _eofActions[m.cs] {
+ case 1:
+
+ m.err = fmt.Errorf(errPrefix, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ case 6:
+
+ m.err = fmt.Errorf(errIdentifier, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ case 8:
+
+ m.err = fmt.Errorf(errSpecificString, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ case 24:
+
+ if m.parsingMode == RFC2141Only || m.parsingMode == RFC8141Only {
+ m.err = fmt.Errorf(errHex, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ }
+
+ case 12:
+
+ m.err = fmt.Errorf(errSCIMNamespace, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ case 14:
+
+ m.err = fmt.Errorf(errSCIMType, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ case 16:
+
+ m.err = fmt.Errorf(errSCIMName, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ case 18:
+
+ if m.p == m.pe {
+ m.err = fmt.Errorf(errSCIMOtherIncomplete, m.p-1)
+ } else {
+ m.err = fmt.Errorf(errSCIMOther, m.p)
+ }
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ case 23:
+
+ m.err = fmt.Errorf(err8141SpecificString, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ case 22:
+
+ m.err = fmt.Errorf(err8141Identifier, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ case 26:
+
+ m.err = fmt.Errorf(err8141MalformedRComp, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ case 31:
+
+ m.err = fmt.Errorf(err8141MalformedQComp, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ case 34:
+
+ output.SS = string(m.text())
+ // Iterate upper letters lowering them
+ for _, i := range output.tolower {
+ m.data[m.pb+i] = m.data[m.pb+i] + 32
+ }
+ output.norm = string(m.text())
+ // Revert the buffer to the original
+ for _, i := range output.tolower {
+ m.data[m.pb+i] = m.data[m.pb+i] - 32
+ }
+
+ output.kind = RFC2141
+
+ case 38:
+
+ output.SS = string(m.text())
+ // Iterate upper letters lowering them
+ for _, i := range output.tolower {
+ m.data[m.pb+i] = m.data[m.pb+i] + 32
+ }
+ output.norm = string(m.text())
+ // Revert the buffer to the original
+ for _, i := range output.tolower {
+ m.data[m.pb+i] = m.data[m.pb+i] - 32
+ }
+
+ output.kind = RFC8141
+
+ case 4:
+
+ m.err = fmt.Errorf(errIdentifier, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ m.err = fmt.Errorf(errPrefix, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ case 11:
+
+ m.err = fmt.Errorf(errIdentifier, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ m.err = fmt.Errorf(errNoUrnWithinID, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ case 9:
+
+ if m.parsingMode == RFC2141Only || m.parsingMode == RFC8141Only {
+ m.err = fmt.Errorf(errHex, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ }
+
+ m.err = fmt.Errorf(errSpecificString, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ case 20:
+
+ if m.parsingMode == RFC2141Only || m.parsingMode == RFC8141Only {
+ m.err = fmt.Errorf(errHex, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ }
+
+ if m.p == m.pe {
+ m.err = fmt.Errorf(errSCIMOtherIncomplete, m.p-1)
+ } else {
+ m.err = fmt.Errorf(errSCIMOther, m.p)
+ }
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ case 25:
+
+ if m.parsingMode == RFC2141Only || m.parsingMode == RFC8141Only {
+ m.err = fmt.Errorf(errHex, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ }
+
+ m.err = fmt.Errorf(err8141SpecificString, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ case 28:
+
+ if m.parsingMode == RFC2141Only || m.parsingMode == RFC8141Only {
+ m.err = fmt.Errorf(errHex, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ }
+
+ m.err = fmt.Errorf(err8141MalformedRComp, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ case 29:
+
+ if m.parsingMode == RFC2141Only || m.parsingMode == RFC8141Only {
+ m.err = fmt.Errorf(errHex, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ }
+
+ m.err = fmt.Errorf(err8141MalformedQComp, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ case 21:
+
+ m.err = fmt.Errorf(err8141Identifier, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ m.err = fmt.Errorf(errPrefix, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ case 42:
+
+ output.rComponent = string(m.text())
+
+ output.kind = RFC8141
+
+ case 48:
+
+ output.qComponent = string(m.text())
+
+ output.kind = RFC8141
+
+ case 41:
+
+ output.fComponent = string(m.text())
+
+ output.kind = RFC8141
+
+ case 40:
+
+ m.pb = m.p
+
+ output.fComponent = string(m.text())
+
+ output.kind = RFC8141
+
+ case 30:
+
+ if m.parsingMode == RFC2141Only || m.parsingMode == RFC8141Only {
+ m.err = fmt.Errorf(errHex, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ }
+
+ m.err = fmt.Errorf(err8141MalformedRComp, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ m.err = fmt.Errorf(err8141MalformedQComp, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ case 35:
+
+ output.scim.Name = string(m.data[output.scim.pos:m.p])
+
+ output.SS = string(m.text())
+ // Iterate upper letters lowering them
+ for _, i := range output.tolower {
+ m.data[m.pb+i] = m.data[m.pb+i] + 32
+ }
+ output.norm = string(m.text())
+ // Revert the buffer to the original
+ for _, i := range output.tolower {
+ m.data[m.pb+i] = m.data[m.pb+i] - 32
+ }
+
+ output.kind = RFC7643
+
+ case 37:
+
+ output.scim.Other = string(m.data[output.scim.pos:m.p])
+
+ output.SS = string(m.text())
+ // Iterate upper letters lowering them
+ for _, i := range output.tolower {
+ m.data[m.pb+i] = m.data[m.pb+i] + 32
+ }
+ output.norm = string(m.text())
+ // Revert the buffer to the original
+ for _, i := range output.tolower {
+ m.data[m.pb+i] = m.data[m.pb+i] - 32
+ }
+
+ output.kind = RFC7643
+
+ case 44:
+
+ if output.rStart {
+ m.err = fmt.Errorf(err8141RComponentStart, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ }
+ output.rStart = true
+
+ output.rComponent = string(m.text())
+
+ output.kind = RFC8141
+
+ case 50:
+
+ if output.qStart {
+ m.err = fmt.Errorf(err8141QComponentStart, m.p)
+ (m.p)--
+
+ m.cs = 193
+ goto _again
+
+ }
+ output.qStart = true
+
+ output.qComponent = string(m.text())
+
+ output.kind = RFC8141
+ }
+ }
+
+ _out:
+ {
+ }
+ }
+
+ if m.cs < firstFinal || m.cs == enFail {
+ return nil, m.err
+ }
+
+ return output, nil
+}
+
+func (m *machine) WithParsingMode(x ParsingMode) {
+ m.parsingMode = x
+ switch m.parsingMode {
+ case RFC2141Only:
+ m.startParsingAt = enMain
+ case RFC8141Only:
+ m.startParsingAt = enRfc8141Only
+ case RFC7643Only:
+ m.startParsingAt = enScimOnly
+ }
+ m.parsingModeSet = true
+}
diff --git a/vendor/github.com/leodido/go-urn/machine.go.rl b/vendor/github.com/leodido/go-urn/machine.go.rl
new file mode 100644
index 00000000..0a174219
--- /dev/null
+++ b/vendor/github.com/leodido/go-urn/machine.go.rl
@@ -0,0 +1,386 @@
+package urn
+
+import (
+ "fmt"
+
+ scimschema "github.com/leodido/go-urn/scim/schema"
+)
+
+var (
+ errPrefix = "expecting the prefix to be the \"urn\" string (whatever case) [col %d]"
+ errIdentifier = "expecting the identifier to be string (1..31 alnum chars, also containing dashes but not at its beginning) [col %d]"
+ errSpecificString = "expecting the specific string to be a string containing alnum, hex, or others ([()+,-.:=@;$_!*']) chars [col %d]"
+ errNoUrnWithinID = "expecting the identifier to not contain the \"urn\" reserved string [col %d]"
+ errHex = "expecting the percent encoded chars to be well-formed (%%alnum{2}) [col %d]"
+ errSCIMNamespace = "expecing the SCIM namespace identifier (ietf:params:scim) [col %d]"
+ errSCIMType = "expecting a correct SCIM type (schemas, api, param) [col %d]"
+ errSCIMName = "expecting one or more alnum char in the SCIM name part [col %d]"
+ errSCIMOther = "expecting a well-formed other SCIM part [col %d]"
+ errSCIMOtherIncomplete = "expecting a not empty SCIM other part after colon [col %d]"
+ err8141InformalID = "informal URN namespace must be in the form urn-[1-9][0-9] [col %d]"
+ err8141SpecificString = "expecting the specific string to contain alnum, hex, or others ([~&()+,-.:=@;$_!*'] or [/?] not in first position) chars [col %d]"
+ err8141Identifier = "expecting the indentifier to be a string with (length 2 to 32 chars) containing alnum (or dashes) not starting or ending with a dash [col %d]"
+ err8141RComponentStart = "expecting only one r-component (starting with the ?+ sequence) [col %d]"
+ err8141QComponentStart = "expecting only one q-component (starting with the ?= sequence) [col %d]"
+ err8141MalformedRComp = "expecting a non-empty r-component containing alnum, hex, or others ([~&()+,-.:=@;$_!*'] or [/?] but not at its beginning) [col %d]"
+ err8141MalformedQComp = "expecting a non-empty q-component containing alnum, hex, or others ([~&()+,-.:=@;$_!*'] or [/?] but not at its beginning) [col %d]"
+)
+
+%%{
+machine urn;
+
+# unsigned alphabet
+alphtype uint8;
+
+action mark {
+ m.pb = m.p
+}
+
+action tolower {
+ // List of positions in the buffer to later lowercase
+ output.tolower = append(output.tolower, m.p - m.pb)
+}
+
+action set_pre {
+ output.prefix = string(m.text())
+}
+
+action throw_pre_urn_err {
+ if m.parsingMode != RFC8141Only {
+ // Throw an error when:
+ // - we are entering here matching the the prefix in the namespace identifier part
+ // - looking ahead (3 chars) we find a colon
+ if pos := m.p + 3; pos < m.pe && m.data[pos] == 58 && output.prefix != "" {
+ m.err = fmt.Errorf(errNoUrnWithinID, pos)
+ fhold;
+ fgoto fail;
+ }
+ }
+}
+
+action set_nid {
+ output.ID = string(m.text())
+}
+
+action set_nss {
+ output.SS = string(m.text())
+ // Iterate upper letters lowering them
+ for _, i := range output.tolower {
+ m.data[m.pb+i] = m.data[m.pb+i] + 32
+ }
+ output.norm = string(m.text())
+ // Revert the buffer to the original
+ for _, i := range output.tolower {
+ m.data[m.pb+i] = m.data[m.pb+i] - 32
+ }
+}
+
+action err_pre {
+ m.err = fmt.Errorf(errPrefix, m.p)
+ fhold;
+ fgoto fail;
+}
+
+action err_nid {
+ m.err = fmt.Errorf(errIdentifier, m.p)
+ fhold;
+ fgoto fail;
+}
+
+action err_nss {
+ m.err = fmt.Errorf(errSpecificString, m.p)
+ fhold;
+ fgoto fail;
+}
+
+action err_urn {
+ m.err = fmt.Errorf(errNoUrnWithinID, m.p)
+ fhold;
+ fgoto fail;
+}
+
+action err_hex {
+ if m.parsingMode == RFC2141Only || m.parsingMode == RFC8141Only {
+ m.err = fmt.Errorf(errHex, m.p)
+ fhold;
+ fgoto fail;
+ }
+}
+
+action base_type {
+ output.kind = RFC2141;
+}
+
+pre = ([uU] @err(err_pre) [rR] @err(err_pre) [nN] @err(err_pre)) >mark >throw_pre_urn_err %set_pre;
+
+nid = (alnum >mark (alnum | '-'){0,31}) $err(err_nid) %set_nid;
+
+hex = '%' (digit | lower | upper >tolower){2} $err(err_hex);
+
+sss = (alnum | [()+,\-.:=@;$_!*']);
+
+nss = (sss | hex)+ $err(err_nss);
+
+nid_not_urn = (nid - pre %err(err_urn));
+
+urn = pre ':' @err(err_pre) (nid_not_urn ':' nss >mark %set_nss) %eof(base_type);
+
+### SCIM BEG
+
+action err_scim_nid {
+ m.err = fmt.Errorf(errSCIMNamespace, m.p)
+ fhold;
+ fgoto fail;
+}
+
+action err_scim_type {
+ m.err = fmt.Errorf(errSCIMType, m.p)
+ fhold;
+ fgoto fail;
+}
+
+action err_scim_name {
+ m.err = fmt.Errorf(errSCIMName, m.p)
+ fhold;
+ fgoto fail;
+}
+
+action err_scim_other {
+ if m.p == m.pe {
+ m.err = fmt.Errorf(errSCIMOtherIncomplete, m.p-1)
+ } else {
+ m.err = fmt.Errorf(errSCIMOther, m.p)
+ }
+ fhold;
+ fgoto fail;
+}
+
+action scim_type {
+ output.kind = RFC7643;
+}
+
+action create_scim {
+ output.scim = &SCIM{};
+}
+
+action set_scim_type {
+ output.scim.Type = scimschema.TypeFromString(string(m.text()))
+}
+
+action mark_scim_name {
+ output.scim.pos = m.p
+}
+
+action set_scim_name {
+ output.scim.Name = string(m.data[output.scim.pos:m.p])
+}
+
+action mark_scim_other {
+ output.scim.pos = m.p
+}
+
+action set_scim_other {
+ output.scim.Other = string(m.data[output.scim.pos:m.p])
+}
+
+scim_nid = 'ietf:params:scim' >mark %set_nid %create_scim $err(err_scim_nid);
+
+scim_other = ':' (sss | hex)+ >mark_scim_other %set_scim_other $err(err_scim_other);
+
+scim_name = (alnum)+ >mark_scim_name %set_scim_name $err(err_scim_name);
+
+scim_type = ('schemas' | 'api' | 'param') >mark %set_scim_type $err(err_scim_type);
+
+scim_only := pre ':' @err(err_pre) (scim_nid ':' scim_type ':' scim_name scim_other? %set_nss) %eof(scim_type);
+
+### SCIM END
+
+### 8141 BEG
+
+action err_nss_8141 {
+ m.err = fmt.Errorf(err8141SpecificString, m.p)
+ fhold;
+ fgoto fail;
+}
+
+action err_nid_8141 {
+ m.err = fmt.Errorf(err8141Identifier, m.p)
+ fhold;
+ fgoto fail;
+}
+
+action rfc8141_type {
+ output.kind = RFC8141;
+}
+
+action set_r_component {
+ output.rComponent = string(m.text())
+}
+
+action set_q_component {
+ output.qComponent = string(m.text())
+}
+
+action set_f_component {
+ output.fComponent = string(m.text())
+}
+
+action informal_nid_match {
+ fhold;
+ m.err = fmt.Errorf(err8141InformalID, m.p);
+ fgoto fail;
+}
+
+action mark_r_start {
+ if output.rStart {
+ m.err = fmt.Errorf(err8141RComponentStart, m.p)
+ fhold;
+ fgoto fail;
+ }
+ output.rStart = true
+}
+
+action mark_q_start {
+ if output.qStart {
+ m.err = fmt.Errorf(err8141QComponentStart, m.p)
+ fhold;
+ fgoto fail;
+ }
+ output.qStart = true
+}
+
+action err_malformed_r_component {
+ m.err = fmt.Errorf(err8141MalformedRComp, m.p)
+ fhold;
+ fgoto fail;
+}
+
+action err_malformed_q_component {
+ m.err = fmt.Errorf(err8141MalformedQComp, m.p)
+ fhold;
+ fgoto fail;
+}
+
+pchar = (sss | '~' | '&' | hex);
+
+component = pchar (pchar | '/' | '?')*;
+
+r_start = ('?+') %mark_r_start;
+
+r_component = r_start <: (r_start | component)+ $err(err_malformed_r_component) >mark %set_r_component;
+
+q_start = ('?=') %mark_q_start;
+
+q_component = q_start <: (q_start | component)+ $err(err_malformed_q_component) >mark %set_q_component;
+
+rq_components = (r_component :>> q_component? | q_component);
+
+fragment = (pchar | '/' | '?')*;
+
+f_component = '#' fragment >mark %set_f_component;
+
+nss_rfc8141 = (pchar >mark (pchar | '/')*) $err(err_nss_8141) %set_nss;
+
+nid_rfc8141 = (alnum >mark (alnum | '-'){0,30} alnum) $err(err_nid_8141) %set_nid;
+
+informal_id = pre ('-' [a-zA-z0] %to(informal_nid_match));
+
+nid_rfc8141_not_urn = (nid_rfc8141 - informal_id?);
+
+rfc8141_only := pre ':' @err(err_pre) nid_rfc8141_not_urn ':' nss_rfc8141 rq_components? f_component? %eof(rfc8141_type);
+
+### 8141 END
+
+fail := (any - [\n\r])* @err{ fgoto main; };
+
+main := urn;
+
+}%%
+
+%% write data noerror noprefix;
+
+// Machine is the interface representing the FSM
+type Machine interface {
+ Error() error
+ Parse(input []byte) (*URN, error)
+ WithParsingMode(ParsingMode)
+}
+
+type machine struct {
+ data []byte
+ cs int
+ p, pe, eof, pb int
+ err error
+ startParsingAt int
+ parsingMode ParsingMode
+ parsingModeSet bool
+}
+
+// NewMachine creates a new FSM able to parse RFC 2141 strings.
+func NewMachine(options ...Option) Machine {
+ m := &machine{
+ parsingModeSet: false,
+ }
+
+ for _, o := range options {
+ o(m)
+ }
+ // Set default parsing mode
+ if !m.parsingModeSet {
+ m.WithParsingMode(DefaultParsingMode)
+ }
+
+ %% access m.;
+ %% variable p m.p;
+ %% variable pe m.pe;
+ %% variable eof m.eof;
+ %% variable data m.data;
+
+ return m
+}
+
+// Err returns the error that occurred on the last call to Parse.
+//
+// If the result is nil, then the line was parsed successfully.
+func (m *machine) Error() error {
+ return m.err
+}
+
+func (m *machine) text() []byte {
+ return m.data[m.pb:m.p]
+}
+
+// Parse parses the input byte array as a RFC 2141 or RFC7643 string.
+func (m *machine) Parse(input []byte) (*URN, error) {
+ m.data = input
+ m.p = 0
+ m.pb = 0
+ m.pe = len(input)
+ m.eof = len(input)
+ m.err = nil
+ m.cs = m.startParsingAt
+ output := &URN{
+ tolower: []int{},
+ }
+
+ %% write exec;
+
+ if m.cs < first_final || m.cs == en_fail {
+ return nil, m.err
+ }
+
+ return output, nil
+}
+
+func (m *machine) WithParsingMode(x ParsingMode) {
+ m.parsingMode = x
+ switch m.parsingMode {
+ case RFC2141Only:
+ m.startParsingAt = en_main
+ case RFC8141Only:
+ m.startParsingAt = en_rfc8141_only
+ case RFC7643Only:
+ m.startParsingAt = en_scim_only
+ }
+ m.parsingModeSet = true
+}
\ No newline at end of file
diff --git a/vendor/github.com/leodido/go-urn/makefile b/vendor/github.com/leodido/go-urn/makefile
new file mode 100644
index 00000000..68d5dd0f
--- /dev/null
+++ b/vendor/github.com/leodido/go-urn/makefile
@@ -0,0 +1,51 @@
+SHELL := /bin/bash
+RAGEL := ragel
+GOFMT := go fmt
+
+export GO_TEST=env GOTRACEBACK=all go test $(GO_ARGS)
+
+.PHONY: build
+build: machine.go
+
+.PHONY: clean
+clean:
+ @rm -rf docs
+ @rm -f machine.go
+
+.PHONY: images
+images: docs/urn.png
+
+.PHONY: snake2camel
+snake2camel:
+ @cd ./tools/snake2camel; go build -o ../../snake2camel .
+
+.PHONY: removecomments
+removecomments:
+ @cd ./tools/removecomments; go build -o ../../removecomments .
+
+machine.go: machine.go.rl
+
+machine.go: snake2camel
+
+machine.go: removecomments
+
+machine.go:
+ $(RAGEL) -Z -G1 -e -o $@ $<
+ @./removecomments $@
+ @./snake2camel $@
+ $(GOFMT) $@
+
+docs/urn.dot: machine.go.rl
+ @mkdir -p docs
+ $(RAGEL) -Z -e -Vp $< -o $@
+
+docs/urn.png: docs/urn.dot
+ dot $< -Tpng -o $@
+
+.PHONY: bench
+bench: *_test.go machine.go
+ go test -bench=. -benchmem -benchtime=5s ./...
+
+.PHONY: tests
+tests: *_test.go
+ $(GO_TEST) ./...
diff --git a/vendor/github.com/leodido/go-urn/options.go b/vendor/github.com/leodido/go-urn/options.go
new file mode 100644
index 00000000..c543835a
--- /dev/null
+++ b/vendor/github.com/leodido/go-urn/options.go
@@ -0,0 +1,9 @@
+package urn
+
+type Option func(Machine)
+
+func WithParsingMode(mode ParsingMode) Option {
+ return func(m Machine) {
+ m.WithParsingMode(mode)
+ }
+}
diff --git a/vendor/github.com/leodido/go-urn/parsing_mode.go b/vendor/github.com/leodido/go-urn/parsing_mode.go
new file mode 100644
index 00000000..fce5aadc
--- /dev/null
+++ b/vendor/github.com/leodido/go-urn/parsing_mode.go
@@ -0,0 +1,12 @@
+package urn
+
+type ParsingMode int
+
+const (
+ Default ParsingMode = iota
+ RFC2141Only
+ RFC7643Only
+ RFC8141Only
+)
+
+const DefaultParsingMode = RFC2141Only
diff --git a/vendor/github.com/leodido/go-urn/scim.go b/vendor/github.com/leodido/go-urn/scim.go
new file mode 100644
index 00000000..f6b7aefb
--- /dev/null
+++ b/vendor/github.com/leodido/go-urn/scim.go
@@ -0,0 +1,48 @@
+package urn
+
+import (
+ "encoding/json"
+ "fmt"
+
+ scimschema "github.com/leodido/go-urn/scim/schema"
+)
+
+const errInvalidSCIMURN = "invalid SCIM URN: %s"
+
+type SCIM struct {
+ Type scimschema.Type
+ Name string
+ Other string
+ pos int
+}
+
+func (s SCIM) MarshalJSON() ([]byte, error) {
+ return json.Marshal(s.String())
+}
+
+func (s *SCIM) UnmarshalJSON(bytes []byte) error {
+ var str string
+ if err := json.Unmarshal(bytes, &str); err != nil {
+ return err
+ }
+ // Parse as SCIM
+ value, ok := Parse([]byte(str), WithParsingMode(RFC7643Only))
+ if !ok {
+ return fmt.Errorf(errInvalidSCIMURN, str)
+ }
+ if value.RFC() != RFC7643 {
+ return fmt.Errorf(errInvalidSCIMURN, str)
+ }
+ *s = *value.SCIM()
+
+ return nil
+}
+
+func (s *SCIM) String() string {
+ ret := fmt.Sprintf("urn:ietf:params:scim:%s:%s", s.Type.String(), s.Name)
+ if s.Other != "" {
+ ret += fmt.Sprintf(":%s", s.Other)
+ }
+
+ return ret
+}
diff --git a/vendor/github.com/leodido/go-urn/scim/schema/type.go b/vendor/github.com/leodido/go-urn/scim/schema/type.go
new file mode 100644
index 00000000..13491823
--- /dev/null
+++ b/vendor/github.com/leodido/go-urn/scim/schema/type.go
@@ -0,0 +1,36 @@
+package scimschema
+
+type Type int
+
+const (
+ Unsupported Type = iota
+ Schemas
+ API
+ Param
+)
+
+func (t Type) String() string {
+ switch t {
+ case Schemas:
+ return "schemas"
+ case API:
+ return "api"
+ case Param:
+ return "param"
+ }
+
+ return ""
+}
+
+func TypeFromString(input string) Type {
+ switch input {
+ case "schemas":
+ return Schemas
+ case "api":
+ return API
+ case "param":
+ return Param
+ }
+
+ return Unsupported
+}
diff --git a/vendor/github.com/leodido/go-urn/urn.go b/vendor/github.com/leodido/go-urn/urn.go
new file mode 100644
index 00000000..894d6258
--- /dev/null
+++ b/vendor/github.com/leodido/go-urn/urn.go
@@ -0,0 +1,141 @@
+package urn
+
+import (
+ "encoding/json"
+ "fmt"
+ "strings"
+)
+
+const errInvalidURN = "invalid URN: %s"
+
+// URN represents an Uniform Resource Name.
+//
+// The general form represented is:
+//
+// urn::
+//
+// Details at https://tools.ietf.org/html/rfc2141.
+type URN struct {
+ prefix string // Static prefix. Equal to "urn" when empty.
+ ID string // Namespace identifier (NID)
+ SS string // Namespace specific string (NSS)
+ norm string // Normalized namespace specific string
+ kind Kind
+ scim *SCIM
+ rComponent string // RFC8141
+ qComponent string // RFC8141
+ fComponent string // RFC8141
+ rStart bool // RFC8141
+ qStart bool // RFC8141
+ tolower []int
+}
+
+// Normalize turns the receiving URN into its norm version.
+//
+// Which means: lowercase prefix, lowercase namespace identifier, and immutate namespace specific string chars (except tokens which are lowercased).
+func (u *URN) Normalize() *URN {
+ return &URN{
+ prefix: "urn",
+ ID: strings.ToLower(u.ID),
+ SS: u.norm,
+ // rComponent: u.rComponent,
+ // qComponent: u.qComponent,
+ // fComponent: u.fComponent,
+ }
+}
+
+// Equal checks the lexical equivalence of the current URN with another one.
+func (u *URN) Equal(x *URN) bool {
+ if x == nil {
+ return false
+ }
+ nu := u.Normalize()
+ nx := x.Normalize()
+
+ return nu.prefix == nx.prefix && nu.ID == nx.ID && nu.SS == nx.SS
+}
+
+// String reassembles the URN into a valid URN string.
+//
+// This requires both ID and SS fields to be non-empty.
+// Otherwise it returns an empty string.
+//
+// Default URN prefix is "urn".
+func (u *URN) String() string {
+ var res string
+ if u.ID != "" && u.SS != "" {
+ if u.prefix == "" {
+ res += "urn"
+ }
+ res += u.prefix + ":" + u.ID + ":" + u.SS
+ if u.rComponent != "" {
+ res += "?+" + u.rComponent
+ }
+ if u.qComponent != "" {
+ res += "?=" + u.qComponent
+ }
+ if u.fComponent != "" {
+ res += "#" + u.fComponent
+ }
+ }
+
+ return res
+}
+
+// Parse is responsible to create an URN instance from a byte array matching the correct URN syntax (RFC 2141).
+func Parse(u []byte, options ...Option) (*URN, bool) {
+ urn, err := NewMachine(options...).Parse(u)
+ if err != nil {
+ return nil, false
+ }
+
+ return urn, true
+}
+
+// MarshalJSON marshals the URN to JSON string form (e.g. `"urn:oid:1.2.3.4"`).
+func (u URN) MarshalJSON() ([]byte, error) {
+ return json.Marshal(u.String())
+}
+
+// UnmarshalJSON unmarshals a URN from JSON string form (e.g. `"urn:oid:1.2.3.4"`).
+func (u *URN) UnmarshalJSON(bytes []byte) error {
+ var str string
+ if err := json.Unmarshal(bytes, &str); err != nil {
+ return err
+ }
+ if value, ok := Parse([]byte(str)); !ok {
+ return fmt.Errorf(errInvalidURN, str)
+ } else {
+ *u = *value
+ }
+
+ return nil
+}
+
+func (u *URN) IsSCIM() bool {
+ return u.kind == RFC7643
+}
+
+func (u *URN) SCIM() *SCIM {
+ if u.kind != RFC7643 {
+ return nil
+ }
+
+ return u.scim
+}
+
+func (u *URN) RFC() Kind {
+ return u.kind
+}
+
+func (u *URN) FComponent() string {
+ return u.fComponent
+}
+
+func (u *URN) QComponent() string {
+ return u.qComponent
+}
+
+func (u *URN) RComponent() string {
+ return u.rComponent
+}
diff --git a/vendor/github.com/leodido/go-urn/urn8141.go b/vendor/github.com/leodido/go-urn/urn8141.go
new file mode 100644
index 00000000..da4dd062
--- /dev/null
+++ b/vendor/github.com/leodido/go-urn/urn8141.go
@@ -0,0 +1,30 @@
+package urn
+
+import (
+ "encoding/json"
+ "fmt"
+)
+
+const errInvalidURN8141 = "invalid URN per RFC 8141: %s"
+
+type URN8141 struct {
+ *URN
+}
+
+func (u URN8141) MarshalJSON() ([]byte, error) {
+ return json.Marshal(u.String())
+}
+
+func (u *URN8141) UnmarshalJSON(bytes []byte) error {
+ var str string
+ if err := json.Unmarshal(bytes, &str); err != nil {
+ return err
+ }
+ if value, ok := Parse([]byte(str), WithParsingMode(RFC8141Only)); !ok {
+ return fmt.Errorf(errInvalidURN8141, str)
+ } else {
+ *u = URN8141{value}
+ }
+
+ return nil
+}
diff --git a/vendor/golang.org/x/crypto/LICENSE b/vendor/golang.org/x/crypto/LICENSE
new file mode 100644
index 00000000..2a7cf70d
--- /dev/null
+++ b/vendor/golang.org/x/crypto/LICENSE
@@ -0,0 +1,27 @@
+Copyright 2009 The Go Authors.
+
+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 LLC 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.
diff --git a/vendor/golang.org/x/crypto/PATENTS b/vendor/golang.org/x/crypto/PATENTS
new file mode 100644
index 00000000..73309904
--- /dev/null
+++ b/vendor/golang.org/x/crypto/PATENTS
@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Go project.
+
+Google 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,
+transfer and otherwise run, modify and propagate the contents of this
+implementation of Go, where such license applies only to those patent
+claims, both currently owned or controlled by Google and acquired in
+the future, licensable by Google that are necessarily infringed by this
+implementation of Go. This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation. If you or your agent or exclusive licensee institute or
+order or agree to the institution of patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that this implementation of Go or any code incorporated within this
+implementation of Go constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of Go
+shall terminate as of the date such litigation is filed.
diff --git a/vendor/golang.org/x/crypto/sha3/doc.go b/vendor/golang.org/x/crypto/sha3/doc.go
new file mode 100644
index 00000000..bbf391fe
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/doc.go
@@ -0,0 +1,66 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package sha3 implements the SHA-3 fixed-output-length hash functions and
+// the SHAKE variable-output-length hash functions defined by FIPS-202.
+//
+// All types in this package also implement [encoding.BinaryMarshaler],
+// [encoding.BinaryAppender] and [encoding.BinaryUnmarshaler] to marshal and
+// unmarshal the internal state of the hash.
+//
+// Both types of hash function use the "sponge" construction and the Keccak
+// permutation. For a detailed specification see http://keccak.noekeon.org/
+//
+// # Guidance
+//
+// If you aren't sure what function you need, use SHAKE256 with at least 64
+// bytes of output. The SHAKE instances are faster than the SHA3 instances;
+// the latter have to allocate memory to conform to the hash.Hash interface.
+//
+// If you need a secret-key MAC (message authentication code), prepend the
+// secret key to the input, hash with SHAKE256 and read at least 32 bytes of
+// output.
+//
+// # Security strengths
+//
+// The SHA3-x (x equals 224, 256, 384, or 512) functions have a security
+// strength against preimage attacks of x bits. Since they only produce "x"
+// bits of output, their collision-resistance is only "x/2" bits.
+//
+// The SHAKE-256 and -128 functions have a generic security strength of 256 and
+// 128 bits against all attacks, provided that at least 2x bits of their output
+// is used. Requesting more than 64 or 32 bytes of output, respectively, does
+// not increase the collision-resistance of the SHAKE functions.
+//
+// # The sponge construction
+//
+// A sponge builds a pseudo-random function from a public pseudo-random
+// permutation, by applying the permutation to a state of "rate + capacity"
+// bytes, but hiding "capacity" of the bytes.
+//
+// A sponge starts out with a zero state. To hash an input using a sponge, up
+// to "rate" bytes of the input are XORed into the sponge's state. The sponge
+// is then "full" and the permutation is applied to "empty" it. This process is
+// repeated until all the input has been "absorbed". The input is then padded.
+// The digest is "squeezed" from the sponge in the same way, except that output
+// is copied out instead of input being XORed in.
+//
+// A sponge is parameterized by its generic security strength, which is equal
+// to half its capacity; capacity + rate is equal to the permutation's width.
+// Since the KeccakF-1600 permutation is 1600 bits (200 bytes) wide, this means
+// that the security strength of a sponge instance is equal to (1600 - bitrate) / 2.
+//
+// # Recommendations
+//
+// The SHAKE functions are recommended for most new uses. They can produce
+// output of arbitrary length. SHAKE256, with an output length of at least
+// 64 bytes, provides 256-bit security against all attacks. The Keccak team
+// recommends it for most applications upgrading from SHA2-512. (NIST chose a
+// much stronger, but much slower, sponge instance for SHA3-512.)
+//
+// The SHA-3 functions are "drop-in" replacements for the SHA-2 functions.
+// They produce output of the same length, with the same security strengths
+// against all attacks. This means, in particular, that SHA3-256 only has
+// 128-bit collision resistance, because its output length is 32 bytes.
+package sha3
diff --git a/vendor/golang.org/x/crypto/sha3/hashes.go b/vendor/golang.org/x/crypto/sha3/hashes.go
new file mode 100644
index 00000000..31fffbe0
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/hashes.go
@@ -0,0 +1,128 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha3
+
+// This file provides functions for creating instances of the SHA-3
+// and SHAKE hash functions, as well as utility functions for hashing
+// bytes.
+
+import (
+ "crypto"
+ "hash"
+)
+
+// New224 creates a new SHA3-224 hash.
+// Its generic security strength is 224 bits against preimage attacks,
+// and 112 bits against collision attacks.
+func New224() hash.Hash {
+ return new224()
+}
+
+// New256 creates a new SHA3-256 hash.
+// Its generic security strength is 256 bits against preimage attacks,
+// and 128 bits against collision attacks.
+func New256() hash.Hash {
+ return new256()
+}
+
+// New384 creates a new SHA3-384 hash.
+// Its generic security strength is 384 bits against preimage attacks,
+// and 192 bits against collision attacks.
+func New384() hash.Hash {
+ return new384()
+}
+
+// New512 creates a new SHA3-512 hash.
+// Its generic security strength is 512 bits against preimage attacks,
+// and 256 bits against collision attacks.
+func New512() hash.Hash {
+ return new512()
+}
+
+func init() {
+ crypto.RegisterHash(crypto.SHA3_224, New224)
+ crypto.RegisterHash(crypto.SHA3_256, New256)
+ crypto.RegisterHash(crypto.SHA3_384, New384)
+ crypto.RegisterHash(crypto.SHA3_512, New512)
+}
+
+const (
+ dsbyteSHA3 = 0b00000110
+ dsbyteKeccak = 0b00000001
+ dsbyteShake = 0b00011111
+ dsbyteCShake = 0b00000100
+
+ // rateK[c] is the rate in bytes for Keccak[c] where c is the capacity in
+ // bits. Given the sponge size is 1600 bits, the rate is 1600 - c bits.
+ rateK256 = (1600 - 256) / 8
+ rateK448 = (1600 - 448) / 8
+ rateK512 = (1600 - 512) / 8
+ rateK768 = (1600 - 768) / 8
+ rateK1024 = (1600 - 1024) / 8
+)
+
+func new224Generic() *state {
+ return &state{rate: rateK448, outputLen: 28, dsbyte: dsbyteSHA3}
+}
+
+func new256Generic() *state {
+ return &state{rate: rateK512, outputLen: 32, dsbyte: dsbyteSHA3}
+}
+
+func new384Generic() *state {
+ return &state{rate: rateK768, outputLen: 48, dsbyte: dsbyteSHA3}
+}
+
+func new512Generic() *state {
+ return &state{rate: rateK1024, outputLen: 64, dsbyte: dsbyteSHA3}
+}
+
+// NewLegacyKeccak256 creates a new Keccak-256 hash.
+//
+// Only use this function if you require compatibility with an existing cryptosystem
+// that uses non-standard padding. All other users should use New256 instead.
+func NewLegacyKeccak256() hash.Hash {
+ return &state{rate: rateK512, outputLen: 32, dsbyte: dsbyteKeccak}
+}
+
+// NewLegacyKeccak512 creates a new Keccak-512 hash.
+//
+// Only use this function if you require compatibility with an existing cryptosystem
+// that uses non-standard padding. All other users should use New512 instead.
+func NewLegacyKeccak512() hash.Hash {
+ return &state{rate: rateK1024, outputLen: 64, dsbyte: dsbyteKeccak}
+}
+
+// Sum224 returns the SHA3-224 digest of the data.
+func Sum224(data []byte) (digest [28]byte) {
+ h := New224()
+ h.Write(data)
+ h.Sum(digest[:0])
+ return
+}
+
+// Sum256 returns the SHA3-256 digest of the data.
+func Sum256(data []byte) (digest [32]byte) {
+ h := New256()
+ h.Write(data)
+ h.Sum(digest[:0])
+ return
+}
+
+// Sum384 returns the SHA3-384 digest of the data.
+func Sum384(data []byte) (digest [48]byte) {
+ h := New384()
+ h.Write(data)
+ h.Sum(digest[:0])
+ return
+}
+
+// Sum512 returns the SHA3-512 digest of the data.
+func Sum512(data []byte) (digest [64]byte) {
+ h := New512()
+ h.Write(data)
+ h.Sum(digest[:0])
+ return
+}
diff --git a/vendor/golang.org/x/crypto/sha3/hashes_noasm.go b/vendor/golang.org/x/crypto/sha3/hashes_noasm.go
new file mode 100644
index 00000000..9d85fb62
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/hashes_noasm.go
@@ -0,0 +1,23 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !gc || purego || !s390x
+
+package sha3
+
+func new224() *state {
+ return new224Generic()
+}
+
+func new256() *state {
+ return new256Generic()
+}
+
+func new384() *state {
+ return new384Generic()
+}
+
+func new512() *state {
+ return new512Generic()
+}
diff --git a/vendor/golang.org/x/crypto/sha3/keccakf.go b/vendor/golang.org/x/crypto/sha3/keccakf.go
new file mode 100644
index 00000000..ce48b1dd
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/keccakf.go
@@ -0,0 +1,414 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !amd64 || purego || !gc
+
+package sha3
+
+import "math/bits"
+
+// rc stores the round constants for use in the ι step.
+var rc = [24]uint64{
+ 0x0000000000000001,
+ 0x0000000000008082,
+ 0x800000000000808A,
+ 0x8000000080008000,
+ 0x000000000000808B,
+ 0x0000000080000001,
+ 0x8000000080008081,
+ 0x8000000000008009,
+ 0x000000000000008A,
+ 0x0000000000000088,
+ 0x0000000080008009,
+ 0x000000008000000A,
+ 0x000000008000808B,
+ 0x800000000000008B,
+ 0x8000000000008089,
+ 0x8000000000008003,
+ 0x8000000000008002,
+ 0x8000000000000080,
+ 0x000000000000800A,
+ 0x800000008000000A,
+ 0x8000000080008081,
+ 0x8000000000008080,
+ 0x0000000080000001,
+ 0x8000000080008008,
+}
+
+// keccakF1600 applies the Keccak permutation to a 1600b-wide
+// state represented as a slice of 25 uint64s.
+func keccakF1600(a *[25]uint64) {
+ // Implementation translated from Keccak-inplace.c
+ // in the keccak reference code.
+ var t, bc0, bc1, bc2, bc3, bc4, d0, d1, d2, d3, d4 uint64
+
+ for i := 0; i < 24; i += 4 {
+ // Combines the 5 steps in each round into 2 steps.
+ // Unrolls 4 rounds per loop and spreads some steps across rounds.
+
+ // Round 1
+ bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
+ bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
+ bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
+ bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
+ bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
+ d0 = bc4 ^ (bc1<<1 | bc1>>63)
+ d1 = bc0 ^ (bc2<<1 | bc2>>63)
+ d2 = bc1 ^ (bc3<<1 | bc3>>63)
+ d3 = bc2 ^ (bc4<<1 | bc4>>63)
+ d4 = bc3 ^ (bc0<<1 | bc0>>63)
+
+ bc0 = a[0] ^ d0
+ t = a[6] ^ d1
+ bc1 = bits.RotateLeft64(t, 44)
+ t = a[12] ^ d2
+ bc2 = bits.RotateLeft64(t, 43)
+ t = a[18] ^ d3
+ bc3 = bits.RotateLeft64(t, 21)
+ t = a[24] ^ d4
+ bc4 = bits.RotateLeft64(t, 14)
+ a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i]
+ a[6] = bc1 ^ (bc3 &^ bc2)
+ a[12] = bc2 ^ (bc4 &^ bc3)
+ a[18] = bc3 ^ (bc0 &^ bc4)
+ a[24] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[10] ^ d0
+ bc2 = bits.RotateLeft64(t, 3)
+ t = a[16] ^ d1
+ bc3 = bits.RotateLeft64(t, 45)
+ t = a[22] ^ d2
+ bc4 = bits.RotateLeft64(t, 61)
+ t = a[3] ^ d3
+ bc0 = bits.RotateLeft64(t, 28)
+ t = a[9] ^ d4
+ bc1 = bits.RotateLeft64(t, 20)
+ a[10] = bc0 ^ (bc2 &^ bc1)
+ a[16] = bc1 ^ (bc3 &^ bc2)
+ a[22] = bc2 ^ (bc4 &^ bc3)
+ a[3] = bc3 ^ (bc0 &^ bc4)
+ a[9] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[20] ^ d0
+ bc4 = bits.RotateLeft64(t, 18)
+ t = a[1] ^ d1
+ bc0 = bits.RotateLeft64(t, 1)
+ t = a[7] ^ d2
+ bc1 = bits.RotateLeft64(t, 6)
+ t = a[13] ^ d3
+ bc2 = bits.RotateLeft64(t, 25)
+ t = a[19] ^ d4
+ bc3 = bits.RotateLeft64(t, 8)
+ a[20] = bc0 ^ (bc2 &^ bc1)
+ a[1] = bc1 ^ (bc3 &^ bc2)
+ a[7] = bc2 ^ (bc4 &^ bc3)
+ a[13] = bc3 ^ (bc0 &^ bc4)
+ a[19] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[5] ^ d0
+ bc1 = bits.RotateLeft64(t, 36)
+ t = a[11] ^ d1
+ bc2 = bits.RotateLeft64(t, 10)
+ t = a[17] ^ d2
+ bc3 = bits.RotateLeft64(t, 15)
+ t = a[23] ^ d3
+ bc4 = bits.RotateLeft64(t, 56)
+ t = a[4] ^ d4
+ bc0 = bits.RotateLeft64(t, 27)
+ a[5] = bc0 ^ (bc2 &^ bc1)
+ a[11] = bc1 ^ (bc3 &^ bc2)
+ a[17] = bc2 ^ (bc4 &^ bc3)
+ a[23] = bc3 ^ (bc0 &^ bc4)
+ a[4] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[15] ^ d0
+ bc3 = bits.RotateLeft64(t, 41)
+ t = a[21] ^ d1
+ bc4 = bits.RotateLeft64(t, 2)
+ t = a[2] ^ d2
+ bc0 = bits.RotateLeft64(t, 62)
+ t = a[8] ^ d3
+ bc1 = bits.RotateLeft64(t, 55)
+ t = a[14] ^ d4
+ bc2 = bits.RotateLeft64(t, 39)
+ a[15] = bc0 ^ (bc2 &^ bc1)
+ a[21] = bc1 ^ (bc3 &^ bc2)
+ a[2] = bc2 ^ (bc4 &^ bc3)
+ a[8] = bc3 ^ (bc0 &^ bc4)
+ a[14] = bc4 ^ (bc1 &^ bc0)
+
+ // Round 2
+ bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
+ bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
+ bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
+ bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
+ bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
+ d0 = bc4 ^ (bc1<<1 | bc1>>63)
+ d1 = bc0 ^ (bc2<<1 | bc2>>63)
+ d2 = bc1 ^ (bc3<<1 | bc3>>63)
+ d3 = bc2 ^ (bc4<<1 | bc4>>63)
+ d4 = bc3 ^ (bc0<<1 | bc0>>63)
+
+ bc0 = a[0] ^ d0
+ t = a[16] ^ d1
+ bc1 = bits.RotateLeft64(t, 44)
+ t = a[7] ^ d2
+ bc2 = bits.RotateLeft64(t, 43)
+ t = a[23] ^ d3
+ bc3 = bits.RotateLeft64(t, 21)
+ t = a[14] ^ d4
+ bc4 = bits.RotateLeft64(t, 14)
+ a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+1]
+ a[16] = bc1 ^ (bc3 &^ bc2)
+ a[7] = bc2 ^ (bc4 &^ bc3)
+ a[23] = bc3 ^ (bc0 &^ bc4)
+ a[14] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[20] ^ d0
+ bc2 = bits.RotateLeft64(t, 3)
+ t = a[11] ^ d1
+ bc3 = bits.RotateLeft64(t, 45)
+ t = a[2] ^ d2
+ bc4 = bits.RotateLeft64(t, 61)
+ t = a[18] ^ d3
+ bc0 = bits.RotateLeft64(t, 28)
+ t = a[9] ^ d4
+ bc1 = bits.RotateLeft64(t, 20)
+ a[20] = bc0 ^ (bc2 &^ bc1)
+ a[11] = bc1 ^ (bc3 &^ bc2)
+ a[2] = bc2 ^ (bc4 &^ bc3)
+ a[18] = bc3 ^ (bc0 &^ bc4)
+ a[9] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[15] ^ d0
+ bc4 = bits.RotateLeft64(t, 18)
+ t = a[6] ^ d1
+ bc0 = bits.RotateLeft64(t, 1)
+ t = a[22] ^ d2
+ bc1 = bits.RotateLeft64(t, 6)
+ t = a[13] ^ d3
+ bc2 = bits.RotateLeft64(t, 25)
+ t = a[4] ^ d4
+ bc3 = bits.RotateLeft64(t, 8)
+ a[15] = bc0 ^ (bc2 &^ bc1)
+ a[6] = bc1 ^ (bc3 &^ bc2)
+ a[22] = bc2 ^ (bc4 &^ bc3)
+ a[13] = bc3 ^ (bc0 &^ bc4)
+ a[4] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[10] ^ d0
+ bc1 = bits.RotateLeft64(t, 36)
+ t = a[1] ^ d1
+ bc2 = bits.RotateLeft64(t, 10)
+ t = a[17] ^ d2
+ bc3 = bits.RotateLeft64(t, 15)
+ t = a[8] ^ d3
+ bc4 = bits.RotateLeft64(t, 56)
+ t = a[24] ^ d4
+ bc0 = bits.RotateLeft64(t, 27)
+ a[10] = bc0 ^ (bc2 &^ bc1)
+ a[1] = bc1 ^ (bc3 &^ bc2)
+ a[17] = bc2 ^ (bc4 &^ bc3)
+ a[8] = bc3 ^ (bc0 &^ bc4)
+ a[24] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[5] ^ d0
+ bc3 = bits.RotateLeft64(t, 41)
+ t = a[21] ^ d1
+ bc4 = bits.RotateLeft64(t, 2)
+ t = a[12] ^ d2
+ bc0 = bits.RotateLeft64(t, 62)
+ t = a[3] ^ d3
+ bc1 = bits.RotateLeft64(t, 55)
+ t = a[19] ^ d4
+ bc2 = bits.RotateLeft64(t, 39)
+ a[5] = bc0 ^ (bc2 &^ bc1)
+ a[21] = bc1 ^ (bc3 &^ bc2)
+ a[12] = bc2 ^ (bc4 &^ bc3)
+ a[3] = bc3 ^ (bc0 &^ bc4)
+ a[19] = bc4 ^ (bc1 &^ bc0)
+
+ // Round 3
+ bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
+ bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
+ bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
+ bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
+ bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
+ d0 = bc4 ^ (bc1<<1 | bc1>>63)
+ d1 = bc0 ^ (bc2<<1 | bc2>>63)
+ d2 = bc1 ^ (bc3<<1 | bc3>>63)
+ d3 = bc2 ^ (bc4<<1 | bc4>>63)
+ d4 = bc3 ^ (bc0<<1 | bc0>>63)
+
+ bc0 = a[0] ^ d0
+ t = a[11] ^ d1
+ bc1 = bits.RotateLeft64(t, 44)
+ t = a[22] ^ d2
+ bc2 = bits.RotateLeft64(t, 43)
+ t = a[8] ^ d3
+ bc3 = bits.RotateLeft64(t, 21)
+ t = a[19] ^ d4
+ bc4 = bits.RotateLeft64(t, 14)
+ a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+2]
+ a[11] = bc1 ^ (bc3 &^ bc2)
+ a[22] = bc2 ^ (bc4 &^ bc3)
+ a[8] = bc3 ^ (bc0 &^ bc4)
+ a[19] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[15] ^ d0
+ bc2 = bits.RotateLeft64(t, 3)
+ t = a[1] ^ d1
+ bc3 = bits.RotateLeft64(t, 45)
+ t = a[12] ^ d2
+ bc4 = bits.RotateLeft64(t, 61)
+ t = a[23] ^ d3
+ bc0 = bits.RotateLeft64(t, 28)
+ t = a[9] ^ d4
+ bc1 = bits.RotateLeft64(t, 20)
+ a[15] = bc0 ^ (bc2 &^ bc1)
+ a[1] = bc1 ^ (bc3 &^ bc2)
+ a[12] = bc2 ^ (bc4 &^ bc3)
+ a[23] = bc3 ^ (bc0 &^ bc4)
+ a[9] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[5] ^ d0
+ bc4 = bits.RotateLeft64(t, 18)
+ t = a[16] ^ d1
+ bc0 = bits.RotateLeft64(t, 1)
+ t = a[2] ^ d2
+ bc1 = bits.RotateLeft64(t, 6)
+ t = a[13] ^ d3
+ bc2 = bits.RotateLeft64(t, 25)
+ t = a[24] ^ d4
+ bc3 = bits.RotateLeft64(t, 8)
+ a[5] = bc0 ^ (bc2 &^ bc1)
+ a[16] = bc1 ^ (bc3 &^ bc2)
+ a[2] = bc2 ^ (bc4 &^ bc3)
+ a[13] = bc3 ^ (bc0 &^ bc4)
+ a[24] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[20] ^ d0
+ bc1 = bits.RotateLeft64(t, 36)
+ t = a[6] ^ d1
+ bc2 = bits.RotateLeft64(t, 10)
+ t = a[17] ^ d2
+ bc3 = bits.RotateLeft64(t, 15)
+ t = a[3] ^ d3
+ bc4 = bits.RotateLeft64(t, 56)
+ t = a[14] ^ d4
+ bc0 = bits.RotateLeft64(t, 27)
+ a[20] = bc0 ^ (bc2 &^ bc1)
+ a[6] = bc1 ^ (bc3 &^ bc2)
+ a[17] = bc2 ^ (bc4 &^ bc3)
+ a[3] = bc3 ^ (bc0 &^ bc4)
+ a[14] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[10] ^ d0
+ bc3 = bits.RotateLeft64(t, 41)
+ t = a[21] ^ d1
+ bc4 = bits.RotateLeft64(t, 2)
+ t = a[7] ^ d2
+ bc0 = bits.RotateLeft64(t, 62)
+ t = a[18] ^ d3
+ bc1 = bits.RotateLeft64(t, 55)
+ t = a[4] ^ d4
+ bc2 = bits.RotateLeft64(t, 39)
+ a[10] = bc0 ^ (bc2 &^ bc1)
+ a[21] = bc1 ^ (bc3 &^ bc2)
+ a[7] = bc2 ^ (bc4 &^ bc3)
+ a[18] = bc3 ^ (bc0 &^ bc4)
+ a[4] = bc4 ^ (bc1 &^ bc0)
+
+ // Round 4
+ bc0 = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20]
+ bc1 = a[1] ^ a[6] ^ a[11] ^ a[16] ^ a[21]
+ bc2 = a[2] ^ a[7] ^ a[12] ^ a[17] ^ a[22]
+ bc3 = a[3] ^ a[8] ^ a[13] ^ a[18] ^ a[23]
+ bc4 = a[4] ^ a[9] ^ a[14] ^ a[19] ^ a[24]
+ d0 = bc4 ^ (bc1<<1 | bc1>>63)
+ d1 = bc0 ^ (bc2<<1 | bc2>>63)
+ d2 = bc1 ^ (bc3<<1 | bc3>>63)
+ d3 = bc2 ^ (bc4<<1 | bc4>>63)
+ d4 = bc3 ^ (bc0<<1 | bc0>>63)
+
+ bc0 = a[0] ^ d0
+ t = a[1] ^ d1
+ bc1 = bits.RotateLeft64(t, 44)
+ t = a[2] ^ d2
+ bc2 = bits.RotateLeft64(t, 43)
+ t = a[3] ^ d3
+ bc3 = bits.RotateLeft64(t, 21)
+ t = a[4] ^ d4
+ bc4 = bits.RotateLeft64(t, 14)
+ a[0] = bc0 ^ (bc2 &^ bc1) ^ rc[i+3]
+ a[1] = bc1 ^ (bc3 &^ bc2)
+ a[2] = bc2 ^ (bc4 &^ bc3)
+ a[3] = bc3 ^ (bc0 &^ bc4)
+ a[4] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[5] ^ d0
+ bc2 = bits.RotateLeft64(t, 3)
+ t = a[6] ^ d1
+ bc3 = bits.RotateLeft64(t, 45)
+ t = a[7] ^ d2
+ bc4 = bits.RotateLeft64(t, 61)
+ t = a[8] ^ d3
+ bc0 = bits.RotateLeft64(t, 28)
+ t = a[9] ^ d4
+ bc1 = bits.RotateLeft64(t, 20)
+ a[5] = bc0 ^ (bc2 &^ bc1)
+ a[6] = bc1 ^ (bc3 &^ bc2)
+ a[7] = bc2 ^ (bc4 &^ bc3)
+ a[8] = bc3 ^ (bc0 &^ bc4)
+ a[9] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[10] ^ d0
+ bc4 = bits.RotateLeft64(t, 18)
+ t = a[11] ^ d1
+ bc0 = bits.RotateLeft64(t, 1)
+ t = a[12] ^ d2
+ bc1 = bits.RotateLeft64(t, 6)
+ t = a[13] ^ d3
+ bc2 = bits.RotateLeft64(t, 25)
+ t = a[14] ^ d4
+ bc3 = bits.RotateLeft64(t, 8)
+ a[10] = bc0 ^ (bc2 &^ bc1)
+ a[11] = bc1 ^ (bc3 &^ bc2)
+ a[12] = bc2 ^ (bc4 &^ bc3)
+ a[13] = bc3 ^ (bc0 &^ bc4)
+ a[14] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[15] ^ d0
+ bc1 = bits.RotateLeft64(t, 36)
+ t = a[16] ^ d1
+ bc2 = bits.RotateLeft64(t, 10)
+ t = a[17] ^ d2
+ bc3 = bits.RotateLeft64(t, 15)
+ t = a[18] ^ d3
+ bc4 = bits.RotateLeft64(t, 56)
+ t = a[19] ^ d4
+ bc0 = bits.RotateLeft64(t, 27)
+ a[15] = bc0 ^ (bc2 &^ bc1)
+ a[16] = bc1 ^ (bc3 &^ bc2)
+ a[17] = bc2 ^ (bc4 &^ bc3)
+ a[18] = bc3 ^ (bc0 &^ bc4)
+ a[19] = bc4 ^ (bc1 &^ bc0)
+
+ t = a[20] ^ d0
+ bc3 = bits.RotateLeft64(t, 41)
+ t = a[21] ^ d1
+ bc4 = bits.RotateLeft64(t, 2)
+ t = a[22] ^ d2
+ bc0 = bits.RotateLeft64(t, 62)
+ t = a[23] ^ d3
+ bc1 = bits.RotateLeft64(t, 55)
+ t = a[24] ^ d4
+ bc2 = bits.RotateLeft64(t, 39)
+ a[20] = bc0 ^ (bc2 &^ bc1)
+ a[21] = bc1 ^ (bc3 &^ bc2)
+ a[22] = bc2 ^ (bc4 &^ bc3)
+ a[23] = bc3 ^ (bc0 &^ bc4)
+ a[24] = bc4 ^ (bc1 &^ bc0)
+ }
+}
diff --git a/vendor/golang.org/x/crypto/sha3/keccakf_amd64.go b/vendor/golang.org/x/crypto/sha3/keccakf_amd64.go
new file mode 100644
index 00000000..b908696b
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/keccakf_amd64.go
@@ -0,0 +1,13 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build amd64 && !purego && gc
+
+package sha3
+
+// This function is implemented in keccakf_amd64.s.
+
+//go:noescape
+
+func keccakF1600(a *[25]uint64)
diff --git a/vendor/golang.org/x/crypto/sha3/keccakf_amd64.s b/vendor/golang.org/x/crypto/sha3/keccakf_amd64.s
new file mode 100644
index 00000000..99e2f16e
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/keccakf_amd64.s
@@ -0,0 +1,5419 @@
+// Code generated by command: go run keccakf_amd64_asm.go -out ../keccakf_amd64.s -pkg sha3. DO NOT EDIT.
+
+//go:build amd64 && !purego && gc
+
+// func keccakF1600(a *[25]uint64)
+TEXT ·keccakF1600(SB), $200-8
+ MOVQ a+0(FP), DI
+
+ // Convert the user state into an internal state
+ NOTQ 8(DI)
+ NOTQ 16(DI)
+ NOTQ 64(DI)
+ NOTQ 96(DI)
+ NOTQ 136(DI)
+ NOTQ 160(DI)
+
+ // Execute the KeccakF permutation
+ MOVQ (DI), SI
+ MOVQ 8(DI), BP
+ MOVQ 32(DI), R15
+ XORQ 40(DI), SI
+ XORQ 48(DI), BP
+ XORQ 72(DI), R15
+ XORQ 80(DI), SI
+ XORQ 88(DI), BP
+ XORQ 112(DI), R15
+ XORQ 120(DI), SI
+ XORQ 128(DI), BP
+ XORQ 152(DI), R15
+ XORQ 160(DI), SI
+ XORQ 168(DI), BP
+ MOVQ 176(DI), DX
+ MOVQ 184(DI), R8
+ XORQ 192(DI), R15
+
+ // Prepare round
+ MOVQ BP, BX
+ ROLQ $0x01, BX
+ MOVQ 16(DI), R12
+ XORQ 56(DI), DX
+ XORQ R15, BX
+ XORQ 96(DI), R12
+ XORQ 136(DI), DX
+ XORQ DX, R12
+ MOVQ R12, CX
+ ROLQ $0x01, CX
+ MOVQ 24(DI), R13
+ XORQ 64(DI), R8
+ XORQ SI, CX
+ XORQ 104(DI), R13
+ XORQ 144(DI), R8
+ XORQ R8, R13
+ MOVQ R13, DX
+ ROLQ $0x01, DX
+ MOVQ R15, R8
+ XORQ BP, DX
+ ROLQ $0x01, R8
+ MOVQ SI, R9
+ XORQ R12, R8
+ ROLQ $0x01, R9
+
+ // Result b
+ MOVQ (DI), R10
+ MOVQ 48(DI), R11
+ XORQ R13, R9
+ MOVQ 96(DI), R12
+ MOVQ 144(DI), R13
+ MOVQ 192(DI), R14
+ XORQ CX, R11
+ ROLQ $0x2c, R11
+ XORQ DX, R12
+ XORQ BX, R10
+ ROLQ $0x2b, R12
+ MOVQ R11, SI
+ MOVQ $0x0000000000000001, AX
+ ORQ R12, SI
+ XORQ R10, AX
+ XORQ AX, SI
+ MOVQ SI, (SP)
+ XORQ R9, R14
+ ROLQ $0x0e, R14
+ MOVQ R10, R15
+ ANDQ R11, R15
+ XORQ R14, R15
+ MOVQ R15, 32(SP)
+ XORQ R8, R13
+ ROLQ $0x15, R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 16(SP)
+ NOTQ R12
+ ORQ R10, R14
+ ORQ R13, R12
+ XORQ R13, R14
+ XORQ R11, R12
+ MOVQ R14, 24(SP)
+ MOVQ R12, 8(SP)
+ MOVQ R12, BP
+
+ // Result g
+ MOVQ 72(DI), R11
+ XORQ R9, R11
+ MOVQ 80(DI), R12
+ ROLQ $0x14, R11
+ XORQ BX, R12
+ ROLQ $0x03, R12
+ MOVQ 24(DI), R10
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ R8, R10
+ MOVQ 128(DI), R13
+ MOVQ 176(DI), R14
+ ROLQ $0x1c, R10
+ XORQ R10, AX
+ MOVQ AX, 40(SP)
+ XORQ AX, SI
+ XORQ CX, R13
+ ROLQ $0x2d, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 48(SP)
+ XORQ AX, BP
+ XORQ DX, R14
+ ROLQ $0x3d, R14
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 64(SP)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 72(SP)
+ NOTQ R14
+ XORQ R10, R15
+ ORQ R14, R13
+ XORQ R12, R13
+ MOVQ R13, 56(SP)
+
+ // Result k
+ MOVQ 8(DI), R10
+ MOVQ 56(DI), R11
+ MOVQ 104(DI), R12
+ MOVQ 152(DI), R13
+ MOVQ 160(DI), R14
+ XORQ DX, R11
+ ROLQ $0x06, R11
+ XORQ R8, R12
+ ROLQ $0x19, R12
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ CX, R10
+ ROLQ $0x01, R10
+ XORQ R10, AX
+ MOVQ AX, 80(SP)
+ XORQ AX, SI
+ XORQ R9, R13
+ ROLQ $0x08, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 88(SP)
+ XORQ AX, BP
+ XORQ BX, R14
+ ROLQ $0x12, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 96(SP)
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 104(SP)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 112(SP)
+ XORQ R10, R15
+
+ // Result m
+ MOVQ 40(DI), R11
+ XORQ BX, R11
+ MOVQ 88(DI), R12
+ ROLQ $0x24, R11
+ XORQ CX, R12
+ MOVQ 32(DI), R10
+ ROLQ $0x0a, R12
+ MOVQ R11, AX
+ MOVQ 136(DI), R13
+ ANDQ R12, AX
+ XORQ R9, R10
+ MOVQ 184(DI), R14
+ ROLQ $0x1b, R10
+ XORQ R10, AX
+ MOVQ AX, 120(SP)
+ XORQ AX, SI
+ XORQ DX, R13
+ ROLQ $0x0f, R13
+ MOVQ R12, AX
+ ORQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 128(SP)
+ XORQ AX, BP
+ XORQ R8, R14
+ ROLQ $0x38, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ORQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 136(SP)
+ ORQ R10, R11
+ XORQ R14, R11
+ MOVQ R11, 152(SP)
+ ANDQ R10, R14
+ XORQ R13, R14
+ MOVQ R14, 144(SP)
+ XORQ R11, R15
+
+ // Result s
+ MOVQ 16(DI), R10
+ MOVQ 64(DI), R11
+ MOVQ 112(DI), R12
+ XORQ DX, R10
+ MOVQ 120(DI), R13
+ ROLQ $0x3e, R10
+ XORQ R8, R11
+ MOVQ 168(DI), R14
+ ROLQ $0x37, R11
+ XORQ R9, R12
+ MOVQ R10, R9
+ XORQ CX, R14
+ ROLQ $0x02, R14
+ ANDQ R11, R9
+ XORQ R14, R9
+ MOVQ R9, 192(SP)
+ ROLQ $0x27, R12
+ XORQ R9, R15
+ NOTQ R11
+ XORQ BX, R13
+ MOVQ R11, BX
+ ANDQ R12, BX
+ XORQ R10, BX
+ MOVQ BX, 160(SP)
+ XORQ BX, SI
+ ROLQ $0x29, R13
+ MOVQ R12, CX
+ ORQ R13, CX
+ XORQ R11, CX
+ MOVQ CX, 168(SP)
+ XORQ CX, BP
+ MOVQ R13, DX
+ MOVQ R14, R8
+ ANDQ R14, DX
+ ORQ R10, R8
+ XORQ R12, DX
+ XORQ R13, R8
+ MOVQ DX, 176(SP)
+ MOVQ R8, 184(SP)
+
+ // Prepare round
+ MOVQ BP, BX
+ ROLQ $0x01, BX
+ MOVQ 16(SP), R12
+ XORQ 56(SP), DX
+ XORQ R15, BX
+ XORQ 96(SP), R12
+ XORQ 136(SP), DX
+ XORQ DX, R12
+ MOVQ R12, CX
+ ROLQ $0x01, CX
+ MOVQ 24(SP), R13
+ XORQ 64(SP), R8
+ XORQ SI, CX
+ XORQ 104(SP), R13
+ XORQ 144(SP), R8
+ XORQ R8, R13
+ MOVQ R13, DX
+ ROLQ $0x01, DX
+ MOVQ R15, R8
+ XORQ BP, DX
+ ROLQ $0x01, R8
+ MOVQ SI, R9
+ XORQ R12, R8
+ ROLQ $0x01, R9
+
+ // Result b
+ MOVQ (SP), R10
+ MOVQ 48(SP), R11
+ XORQ R13, R9
+ MOVQ 96(SP), R12
+ MOVQ 144(SP), R13
+ MOVQ 192(SP), R14
+ XORQ CX, R11
+ ROLQ $0x2c, R11
+ XORQ DX, R12
+ XORQ BX, R10
+ ROLQ $0x2b, R12
+ MOVQ R11, SI
+ MOVQ $0x0000000000008082, AX
+ ORQ R12, SI
+ XORQ R10, AX
+ XORQ AX, SI
+ MOVQ SI, (DI)
+ XORQ R9, R14
+ ROLQ $0x0e, R14
+ MOVQ R10, R15
+ ANDQ R11, R15
+ XORQ R14, R15
+ MOVQ R15, 32(DI)
+ XORQ R8, R13
+ ROLQ $0x15, R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 16(DI)
+ NOTQ R12
+ ORQ R10, R14
+ ORQ R13, R12
+ XORQ R13, R14
+ XORQ R11, R12
+ MOVQ R14, 24(DI)
+ MOVQ R12, 8(DI)
+ MOVQ R12, BP
+
+ // Result g
+ MOVQ 72(SP), R11
+ XORQ R9, R11
+ MOVQ 80(SP), R12
+ ROLQ $0x14, R11
+ XORQ BX, R12
+ ROLQ $0x03, R12
+ MOVQ 24(SP), R10
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ R8, R10
+ MOVQ 128(SP), R13
+ MOVQ 176(SP), R14
+ ROLQ $0x1c, R10
+ XORQ R10, AX
+ MOVQ AX, 40(DI)
+ XORQ AX, SI
+ XORQ CX, R13
+ ROLQ $0x2d, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 48(DI)
+ XORQ AX, BP
+ XORQ DX, R14
+ ROLQ $0x3d, R14
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 64(DI)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 72(DI)
+ NOTQ R14
+ XORQ R10, R15
+ ORQ R14, R13
+ XORQ R12, R13
+ MOVQ R13, 56(DI)
+
+ // Result k
+ MOVQ 8(SP), R10
+ MOVQ 56(SP), R11
+ MOVQ 104(SP), R12
+ MOVQ 152(SP), R13
+ MOVQ 160(SP), R14
+ XORQ DX, R11
+ ROLQ $0x06, R11
+ XORQ R8, R12
+ ROLQ $0x19, R12
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ CX, R10
+ ROLQ $0x01, R10
+ XORQ R10, AX
+ MOVQ AX, 80(DI)
+ XORQ AX, SI
+ XORQ R9, R13
+ ROLQ $0x08, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 88(DI)
+ XORQ AX, BP
+ XORQ BX, R14
+ ROLQ $0x12, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 96(DI)
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 104(DI)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 112(DI)
+ XORQ R10, R15
+
+ // Result m
+ MOVQ 40(SP), R11
+ XORQ BX, R11
+ MOVQ 88(SP), R12
+ ROLQ $0x24, R11
+ XORQ CX, R12
+ MOVQ 32(SP), R10
+ ROLQ $0x0a, R12
+ MOVQ R11, AX
+ MOVQ 136(SP), R13
+ ANDQ R12, AX
+ XORQ R9, R10
+ MOVQ 184(SP), R14
+ ROLQ $0x1b, R10
+ XORQ R10, AX
+ MOVQ AX, 120(DI)
+ XORQ AX, SI
+ XORQ DX, R13
+ ROLQ $0x0f, R13
+ MOVQ R12, AX
+ ORQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 128(DI)
+ XORQ AX, BP
+ XORQ R8, R14
+ ROLQ $0x38, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ORQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 136(DI)
+ ORQ R10, R11
+ XORQ R14, R11
+ MOVQ R11, 152(DI)
+ ANDQ R10, R14
+ XORQ R13, R14
+ MOVQ R14, 144(DI)
+ XORQ R11, R15
+
+ // Result s
+ MOVQ 16(SP), R10
+ MOVQ 64(SP), R11
+ MOVQ 112(SP), R12
+ XORQ DX, R10
+ MOVQ 120(SP), R13
+ ROLQ $0x3e, R10
+ XORQ R8, R11
+ MOVQ 168(SP), R14
+ ROLQ $0x37, R11
+ XORQ R9, R12
+ MOVQ R10, R9
+ XORQ CX, R14
+ ROLQ $0x02, R14
+ ANDQ R11, R9
+ XORQ R14, R9
+ MOVQ R9, 192(DI)
+ ROLQ $0x27, R12
+ XORQ R9, R15
+ NOTQ R11
+ XORQ BX, R13
+ MOVQ R11, BX
+ ANDQ R12, BX
+ XORQ R10, BX
+ MOVQ BX, 160(DI)
+ XORQ BX, SI
+ ROLQ $0x29, R13
+ MOVQ R12, CX
+ ORQ R13, CX
+ XORQ R11, CX
+ MOVQ CX, 168(DI)
+ XORQ CX, BP
+ MOVQ R13, DX
+ MOVQ R14, R8
+ ANDQ R14, DX
+ ORQ R10, R8
+ XORQ R12, DX
+ XORQ R13, R8
+ MOVQ DX, 176(DI)
+ MOVQ R8, 184(DI)
+
+ // Prepare round
+ MOVQ BP, BX
+ ROLQ $0x01, BX
+ MOVQ 16(DI), R12
+ XORQ 56(DI), DX
+ XORQ R15, BX
+ XORQ 96(DI), R12
+ XORQ 136(DI), DX
+ XORQ DX, R12
+ MOVQ R12, CX
+ ROLQ $0x01, CX
+ MOVQ 24(DI), R13
+ XORQ 64(DI), R8
+ XORQ SI, CX
+ XORQ 104(DI), R13
+ XORQ 144(DI), R8
+ XORQ R8, R13
+ MOVQ R13, DX
+ ROLQ $0x01, DX
+ MOVQ R15, R8
+ XORQ BP, DX
+ ROLQ $0x01, R8
+ MOVQ SI, R9
+ XORQ R12, R8
+ ROLQ $0x01, R9
+
+ // Result b
+ MOVQ (DI), R10
+ MOVQ 48(DI), R11
+ XORQ R13, R9
+ MOVQ 96(DI), R12
+ MOVQ 144(DI), R13
+ MOVQ 192(DI), R14
+ XORQ CX, R11
+ ROLQ $0x2c, R11
+ XORQ DX, R12
+ XORQ BX, R10
+ ROLQ $0x2b, R12
+ MOVQ R11, SI
+ MOVQ $0x800000000000808a, AX
+ ORQ R12, SI
+ XORQ R10, AX
+ XORQ AX, SI
+ MOVQ SI, (SP)
+ XORQ R9, R14
+ ROLQ $0x0e, R14
+ MOVQ R10, R15
+ ANDQ R11, R15
+ XORQ R14, R15
+ MOVQ R15, 32(SP)
+ XORQ R8, R13
+ ROLQ $0x15, R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 16(SP)
+ NOTQ R12
+ ORQ R10, R14
+ ORQ R13, R12
+ XORQ R13, R14
+ XORQ R11, R12
+ MOVQ R14, 24(SP)
+ MOVQ R12, 8(SP)
+ MOVQ R12, BP
+
+ // Result g
+ MOVQ 72(DI), R11
+ XORQ R9, R11
+ MOVQ 80(DI), R12
+ ROLQ $0x14, R11
+ XORQ BX, R12
+ ROLQ $0x03, R12
+ MOVQ 24(DI), R10
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ R8, R10
+ MOVQ 128(DI), R13
+ MOVQ 176(DI), R14
+ ROLQ $0x1c, R10
+ XORQ R10, AX
+ MOVQ AX, 40(SP)
+ XORQ AX, SI
+ XORQ CX, R13
+ ROLQ $0x2d, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 48(SP)
+ XORQ AX, BP
+ XORQ DX, R14
+ ROLQ $0x3d, R14
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 64(SP)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 72(SP)
+ NOTQ R14
+ XORQ R10, R15
+ ORQ R14, R13
+ XORQ R12, R13
+ MOVQ R13, 56(SP)
+
+ // Result k
+ MOVQ 8(DI), R10
+ MOVQ 56(DI), R11
+ MOVQ 104(DI), R12
+ MOVQ 152(DI), R13
+ MOVQ 160(DI), R14
+ XORQ DX, R11
+ ROLQ $0x06, R11
+ XORQ R8, R12
+ ROLQ $0x19, R12
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ CX, R10
+ ROLQ $0x01, R10
+ XORQ R10, AX
+ MOVQ AX, 80(SP)
+ XORQ AX, SI
+ XORQ R9, R13
+ ROLQ $0x08, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 88(SP)
+ XORQ AX, BP
+ XORQ BX, R14
+ ROLQ $0x12, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 96(SP)
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 104(SP)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 112(SP)
+ XORQ R10, R15
+
+ // Result m
+ MOVQ 40(DI), R11
+ XORQ BX, R11
+ MOVQ 88(DI), R12
+ ROLQ $0x24, R11
+ XORQ CX, R12
+ MOVQ 32(DI), R10
+ ROLQ $0x0a, R12
+ MOVQ R11, AX
+ MOVQ 136(DI), R13
+ ANDQ R12, AX
+ XORQ R9, R10
+ MOVQ 184(DI), R14
+ ROLQ $0x1b, R10
+ XORQ R10, AX
+ MOVQ AX, 120(SP)
+ XORQ AX, SI
+ XORQ DX, R13
+ ROLQ $0x0f, R13
+ MOVQ R12, AX
+ ORQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 128(SP)
+ XORQ AX, BP
+ XORQ R8, R14
+ ROLQ $0x38, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ORQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 136(SP)
+ ORQ R10, R11
+ XORQ R14, R11
+ MOVQ R11, 152(SP)
+ ANDQ R10, R14
+ XORQ R13, R14
+ MOVQ R14, 144(SP)
+ XORQ R11, R15
+
+ // Result s
+ MOVQ 16(DI), R10
+ MOVQ 64(DI), R11
+ MOVQ 112(DI), R12
+ XORQ DX, R10
+ MOVQ 120(DI), R13
+ ROLQ $0x3e, R10
+ XORQ R8, R11
+ MOVQ 168(DI), R14
+ ROLQ $0x37, R11
+ XORQ R9, R12
+ MOVQ R10, R9
+ XORQ CX, R14
+ ROLQ $0x02, R14
+ ANDQ R11, R9
+ XORQ R14, R9
+ MOVQ R9, 192(SP)
+ ROLQ $0x27, R12
+ XORQ R9, R15
+ NOTQ R11
+ XORQ BX, R13
+ MOVQ R11, BX
+ ANDQ R12, BX
+ XORQ R10, BX
+ MOVQ BX, 160(SP)
+ XORQ BX, SI
+ ROLQ $0x29, R13
+ MOVQ R12, CX
+ ORQ R13, CX
+ XORQ R11, CX
+ MOVQ CX, 168(SP)
+ XORQ CX, BP
+ MOVQ R13, DX
+ MOVQ R14, R8
+ ANDQ R14, DX
+ ORQ R10, R8
+ XORQ R12, DX
+ XORQ R13, R8
+ MOVQ DX, 176(SP)
+ MOVQ R8, 184(SP)
+
+ // Prepare round
+ MOVQ BP, BX
+ ROLQ $0x01, BX
+ MOVQ 16(SP), R12
+ XORQ 56(SP), DX
+ XORQ R15, BX
+ XORQ 96(SP), R12
+ XORQ 136(SP), DX
+ XORQ DX, R12
+ MOVQ R12, CX
+ ROLQ $0x01, CX
+ MOVQ 24(SP), R13
+ XORQ 64(SP), R8
+ XORQ SI, CX
+ XORQ 104(SP), R13
+ XORQ 144(SP), R8
+ XORQ R8, R13
+ MOVQ R13, DX
+ ROLQ $0x01, DX
+ MOVQ R15, R8
+ XORQ BP, DX
+ ROLQ $0x01, R8
+ MOVQ SI, R9
+ XORQ R12, R8
+ ROLQ $0x01, R9
+
+ // Result b
+ MOVQ (SP), R10
+ MOVQ 48(SP), R11
+ XORQ R13, R9
+ MOVQ 96(SP), R12
+ MOVQ 144(SP), R13
+ MOVQ 192(SP), R14
+ XORQ CX, R11
+ ROLQ $0x2c, R11
+ XORQ DX, R12
+ XORQ BX, R10
+ ROLQ $0x2b, R12
+ MOVQ R11, SI
+ MOVQ $0x8000000080008000, AX
+ ORQ R12, SI
+ XORQ R10, AX
+ XORQ AX, SI
+ MOVQ SI, (DI)
+ XORQ R9, R14
+ ROLQ $0x0e, R14
+ MOVQ R10, R15
+ ANDQ R11, R15
+ XORQ R14, R15
+ MOVQ R15, 32(DI)
+ XORQ R8, R13
+ ROLQ $0x15, R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 16(DI)
+ NOTQ R12
+ ORQ R10, R14
+ ORQ R13, R12
+ XORQ R13, R14
+ XORQ R11, R12
+ MOVQ R14, 24(DI)
+ MOVQ R12, 8(DI)
+ MOVQ R12, BP
+
+ // Result g
+ MOVQ 72(SP), R11
+ XORQ R9, R11
+ MOVQ 80(SP), R12
+ ROLQ $0x14, R11
+ XORQ BX, R12
+ ROLQ $0x03, R12
+ MOVQ 24(SP), R10
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ R8, R10
+ MOVQ 128(SP), R13
+ MOVQ 176(SP), R14
+ ROLQ $0x1c, R10
+ XORQ R10, AX
+ MOVQ AX, 40(DI)
+ XORQ AX, SI
+ XORQ CX, R13
+ ROLQ $0x2d, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 48(DI)
+ XORQ AX, BP
+ XORQ DX, R14
+ ROLQ $0x3d, R14
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 64(DI)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 72(DI)
+ NOTQ R14
+ XORQ R10, R15
+ ORQ R14, R13
+ XORQ R12, R13
+ MOVQ R13, 56(DI)
+
+ // Result k
+ MOVQ 8(SP), R10
+ MOVQ 56(SP), R11
+ MOVQ 104(SP), R12
+ MOVQ 152(SP), R13
+ MOVQ 160(SP), R14
+ XORQ DX, R11
+ ROLQ $0x06, R11
+ XORQ R8, R12
+ ROLQ $0x19, R12
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ CX, R10
+ ROLQ $0x01, R10
+ XORQ R10, AX
+ MOVQ AX, 80(DI)
+ XORQ AX, SI
+ XORQ R9, R13
+ ROLQ $0x08, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 88(DI)
+ XORQ AX, BP
+ XORQ BX, R14
+ ROLQ $0x12, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 96(DI)
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 104(DI)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 112(DI)
+ XORQ R10, R15
+
+ // Result m
+ MOVQ 40(SP), R11
+ XORQ BX, R11
+ MOVQ 88(SP), R12
+ ROLQ $0x24, R11
+ XORQ CX, R12
+ MOVQ 32(SP), R10
+ ROLQ $0x0a, R12
+ MOVQ R11, AX
+ MOVQ 136(SP), R13
+ ANDQ R12, AX
+ XORQ R9, R10
+ MOVQ 184(SP), R14
+ ROLQ $0x1b, R10
+ XORQ R10, AX
+ MOVQ AX, 120(DI)
+ XORQ AX, SI
+ XORQ DX, R13
+ ROLQ $0x0f, R13
+ MOVQ R12, AX
+ ORQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 128(DI)
+ XORQ AX, BP
+ XORQ R8, R14
+ ROLQ $0x38, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ORQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 136(DI)
+ ORQ R10, R11
+ XORQ R14, R11
+ MOVQ R11, 152(DI)
+ ANDQ R10, R14
+ XORQ R13, R14
+ MOVQ R14, 144(DI)
+ XORQ R11, R15
+
+ // Result s
+ MOVQ 16(SP), R10
+ MOVQ 64(SP), R11
+ MOVQ 112(SP), R12
+ XORQ DX, R10
+ MOVQ 120(SP), R13
+ ROLQ $0x3e, R10
+ XORQ R8, R11
+ MOVQ 168(SP), R14
+ ROLQ $0x37, R11
+ XORQ R9, R12
+ MOVQ R10, R9
+ XORQ CX, R14
+ ROLQ $0x02, R14
+ ANDQ R11, R9
+ XORQ R14, R9
+ MOVQ R9, 192(DI)
+ ROLQ $0x27, R12
+ XORQ R9, R15
+ NOTQ R11
+ XORQ BX, R13
+ MOVQ R11, BX
+ ANDQ R12, BX
+ XORQ R10, BX
+ MOVQ BX, 160(DI)
+ XORQ BX, SI
+ ROLQ $0x29, R13
+ MOVQ R12, CX
+ ORQ R13, CX
+ XORQ R11, CX
+ MOVQ CX, 168(DI)
+ XORQ CX, BP
+ MOVQ R13, DX
+ MOVQ R14, R8
+ ANDQ R14, DX
+ ORQ R10, R8
+ XORQ R12, DX
+ XORQ R13, R8
+ MOVQ DX, 176(DI)
+ MOVQ R8, 184(DI)
+
+ // Prepare round
+ MOVQ BP, BX
+ ROLQ $0x01, BX
+ MOVQ 16(DI), R12
+ XORQ 56(DI), DX
+ XORQ R15, BX
+ XORQ 96(DI), R12
+ XORQ 136(DI), DX
+ XORQ DX, R12
+ MOVQ R12, CX
+ ROLQ $0x01, CX
+ MOVQ 24(DI), R13
+ XORQ 64(DI), R8
+ XORQ SI, CX
+ XORQ 104(DI), R13
+ XORQ 144(DI), R8
+ XORQ R8, R13
+ MOVQ R13, DX
+ ROLQ $0x01, DX
+ MOVQ R15, R8
+ XORQ BP, DX
+ ROLQ $0x01, R8
+ MOVQ SI, R9
+ XORQ R12, R8
+ ROLQ $0x01, R9
+
+ // Result b
+ MOVQ (DI), R10
+ MOVQ 48(DI), R11
+ XORQ R13, R9
+ MOVQ 96(DI), R12
+ MOVQ 144(DI), R13
+ MOVQ 192(DI), R14
+ XORQ CX, R11
+ ROLQ $0x2c, R11
+ XORQ DX, R12
+ XORQ BX, R10
+ ROLQ $0x2b, R12
+ MOVQ R11, SI
+ MOVQ $0x000000000000808b, AX
+ ORQ R12, SI
+ XORQ R10, AX
+ XORQ AX, SI
+ MOVQ SI, (SP)
+ XORQ R9, R14
+ ROLQ $0x0e, R14
+ MOVQ R10, R15
+ ANDQ R11, R15
+ XORQ R14, R15
+ MOVQ R15, 32(SP)
+ XORQ R8, R13
+ ROLQ $0x15, R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 16(SP)
+ NOTQ R12
+ ORQ R10, R14
+ ORQ R13, R12
+ XORQ R13, R14
+ XORQ R11, R12
+ MOVQ R14, 24(SP)
+ MOVQ R12, 8(SP)
+ MOVQ R12, BP
+
+ // Result g
+ MOVQ 72(DI), R11
+ XORQ R9, R11
+ MOVQ 80(DI), R12
+ ROLQ $0x14, R11
+ XORQ BX, R12
+ ROLQ $0x03, R12
+ MOVQ 24(DI), R10
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ R8, R10
+ MOVQ 128(DI), R13
+ MOVQ 176(DI), R14
+ ROLQ $0x1c, R10
+ XORQ R10, AX
+ MOVQ AX, 40(SP)
+ XORQ AX, SI
+ XORQ CX, R13
+ ROLQ $0x2d, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 48(SP)
+ XORQ AX, BP
+ XORQ DX, R14
+ ROLQ $0x3d, R14
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 64(SP)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 72(SP)
+ NOTQ R14
+ XORQ R10, R15
+ ORQ R14, R13
+ XORQ R12, R13
+ MOVQ R13, 56(SP)
+
+ // Result k
+ MOVQ 8(DI), R10
+ MOVQ 56(DI), R11
+ MOVQ 104(DI), R12
+ MOVQ 152(DI), R13
+ MOVQ 160(DI), R14
+ XORQ DX, R11
+ ROLQ $0x06, R11
+ XORQ R8, R12
+ ROLQ $0x19, R12
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ CX, R10
+ ROLQ $0x01, R10
+ XORQ R10, AX
+ MOVQ AX, 80(SP)
+ XORQ AX, SI
+ XORQ R9, R13
+ ROLQ $0x08, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 88(SP)
+ XORQ AX, BP
+ XORQ BX, R14
+ ROLQ $0x12, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 96(SP)
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 104(SP)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 112(SP)
+ XORQ R10, R15
+
+ // Result m
+ MOVQ 40(DI), R11
+ XORQ BX, R11
+ MOVQ 88(DI), R12
+ ROLQ $0x24, R11
+ XORQ CX, R12
+ MOVQ 32(DI), R10
+ ROLQ $0x0a, R12
+ MOVQ R11, AX
+ MOVQ 136(DI), R13
+ ANDQ R12, AX
+ XORQ R9, R10
+ MOVQ 184(DI), R14
+ ROLQ $0x1b, R10
+ XORQ R10, AX
+ MOVQ AX, 120(SP)
+ XORQ AX, SI
+ XORQ DX, R13
+ ROLQ $0x0f, R13
+ MOVQ R12, AX
+ ORQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 128(SP)
+ XORQ AX, BP
+ XORQ R8, R14
+ ROLQ $0x38, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ORQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 136(SP)
+ ORQ R10, R11
+ XORQ R14, R11
+ MOVQ R11, 152(SP)
+ ANDQ R10, R14
+ XORQ R13, R14
+ MOVQ R14, 144(SP)
+ XORQ R11, R15
+
+ // Result s
+ MOVQ 16(DI), R10
+ MOVQ 64(DI), R11
+ MOVQ 112(DI), R12
+ XORQ DX, R10
+ MOVQ 120(DI), R13
+ ROLQ $0x3e, R10
+ XORQ R8, R11
+ MOVQ 168(DI), R14
+ ROLQ $0x37, R11
+ XORQ R9, R12
+ MOVQ R10, R9
+ XORQ CX, R14
+ ROLQ $0x02, R14
+ ANDQ R11, R9
+ XORQ R14, R9
+ MOVQ R9, 192(SP)
+ ROLQ $0x27, R12
+ XORQ R9, R15
+ NOTQ R11
+ XORQ BX, R13
+ MOVQ R11, BX
+ ANDQ R12, BX
+ XORQ R10, BX
+ MOVQ BX, 160(SP)
+ XORQ BX, SI
+ ROLQ $0x29, R13
+ MOVQ R12, CX
+ ORQ R13, CX
+ XORQ R11, CX
+ MOVQ CX, 168(SP)
+ XORQ CX, BP
+ MOVQ R13, DX
+ MOVQ R14, R8
+ ANDQ R14, DX
+ ORQ R10, R8
+ XORQ R12, DX
+ XORQ R13, R8
+ MOVQ DX, 176(SP)
+ MOVQ R8, 184(SP)
+
+ // Prepare round
+ MOVQ BP, BX
+ ROLQ $0x01, BX
+ MOVQ 16(SP), R12
+ XORQ 56(SP), DX
+ XORQ R15, BX
+ XORQ 96(SP), R12
+ XORQ 136(SP), DX
+ XORQ DX, R12
+ MOVQ R12, CX
+ ROLQ $0x01, CX
+ MOVQ 24(SP), R13
+ XORQ 64(SP), R8
+ XORQ SI, CX
+ XORQ 104(SP), R13
+ XORQ 144(SP), R8
+ XORQ R8, R13
+ MOVQ R13, DX
+ ROLQ $0x01, DX
+ MOVQ R15, R8
+ XORQ BP, DX
+ ROLQ $0x01, R8
+ MOVQ SI, R9
+ XORQ R12, R8
+ ROLQ $0x01, R9
+
+ // Result b
+ MOVQ (SP), R10
+ MOVQ 48(SP), R11
+ XORQ R13, R9
+ MOVQ 96(SP), R12
+ MOVQ 144(SP), R13
+ MOVQ 192(SP), R14
+ XORQ CX, R11
+ ROLQ $0x2c, R11
+ XORQ DX, R12
+ XORQ BX, R10
+ ROLQ $0x2b, R12
+ MOVQ R11, SI
+ MOVQ $0x0000000080000001, AX
+ ORQ R12, SI
+ XORQ R10, AX
+ XORQ AX, SI
+ MOVQ SI, (DI)
+ XORQ R9, R14
+ ROLQ $0x0e, R14
+ MOVQ R10, R15
+ ANDQ R11, R15
+ XORQ R14, R15
+ MOVQ R15, 32(DI)
+ XORQ R8, R13
+ ROLQ $0x15, R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 16(DI)
+ NOTQ R12
+ ORQ R10, R14
+ ORQ R13, R12
+ XORQ R13, R14
+ XORQ R11, R12
+ MOVQ R14, 24(DI)
+ MOVQ R12, 8(DI)
+ MOVQ R12, BP
+
+ // Result g
+ MOVQ 72(SP), R11
+ XORQ R9, R11
+ MOVQ 80(SP), R12
+ ROLQ $0x14, R11
+ XORQ BX, R12
+ ROLQ $0x03, R12
+ MOVQ 24(SP), R10
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ R8, R10
+ MOVQ 128(SP), R13
+ MOVQ 176(SP), R14
+ ROLQ $0x1c, R10
+ XORQ R10, AX
+ MOVQ AX, 40(DI)
+ XORQ AX, SI
+ XORQ CX, R13
+ ROLQ $0x2d, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 48(DI)
+ XORQ AX, BP
+ XORQ DX, R14
+ ROLQ $0x3d, R14
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 64(DI)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 72(DI)
+ NOTQ R14
+ XORQ R10, R15
+ ORQ R14, R13
+ XORQ R12, R13
+ MOVQ R13, 56(DI)
+
+ // Result k
+ MOVQ 8(SP), R10
+ MOVQ 56(SP), R11
+ MOVQ 104(SP), R12
+ MOVQ 152(SP), R13
+ MOVQ 160(SP), R14
+ XORQ DX, R11
+ ROLQ $0x06, R11
+ XORQ R8, R12
+ ROLQ $0x19, R12
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ CX, R10
+ ROLQ $0x01, R10
+ XORQ R10, AX
+ MOVQ AX, 80(DI)
+ XORQ AX, SI
+ XORQ R9, R13
+ ROLQ $0x08, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 88(DI)
+ XORQ AX, BP
+ XORQ BX, R14
+ ROLQ $0x12, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 96(DI)
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 104(DI)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 112(DI)
+ XORQ R10, R15
+
+ // Result m
+ MOVQ 40(SP), R11
+ XORQ BX, R11
+ MOVQ 88(SP), R12
+ ROLQ $0x24, R11
+ XORQ CX, R12
+ MOVQ 32(SP), R10
+ ROLQ $0x0a, R12
+ MOVQ R11, AX
+ MOVQ 136(SP), R13
+ ANDQ R12, AX
+ XORQ R9, R10
+ MOVQ 184(SP), R14
+ ROLQ $0x1b, R10
+ XORQ R10, AX
+ MOVQ AX, 120(DI)
+ XORQ AX, SI
+ XORQ DX, R13
+ ROLQ $0x0f, R13
+ MOVQ R12, AX
+ ORQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 128(DI)
+ XORQ AX, BP
+ XORQ R8, R14
+ ROLQ $0x38, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ORQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 136(DI)
+ ORQ R10, R11
+ XORQ R14, R11
+ MOVQ R11, 152(DI)
+ ANDQ R10, R14
+ XORQ R13, R14
+ MOVQ R14, 144(DI)
+ XORQ R11, R15
+
+ // Result s
+ MOVQ 16(SP), R10
+ MOVQ 64(SP), R11
+ MOVQ 112(SP), R12
+ XORQ DX, R10
+ MOVQ 120(SP), R13
+ ROLQ $0x3e, R10
+ XORQ R8, R11
+ MOVQ 168(SP), R14
+ ROLQ $0x37, R11
+ XORQ R9, R12
+ MOVQ R10, R9
+ XORQ CX, R14
+ ROLQ $0x02, R14
+ ANDQ R11, R9
+ XORQ R14, R9
+ MOVQ R9, 192(DI)
+ ROLQ $0x27, R12
+ XORQ R9, R15
+ NOTQ R11
+ XORQ BX, R13
+ MOVQ R11, BX
+ ANDQ R12, BX
+ XORQ R10, BX
+ MOVQ BX, 160(DI)
+ XORQ BX, SI
+ ROLQ $0x29, R13
+ MOVQ R12, CX
+ ORQ R13, CX
+ XORQ R11, CX
+ MOVQ CX, 168(DI)
+ XORQ CX, BP
+ MOVQ R13, DX
+ MOVQ R14, R8
+ ANDQ R14, DX
+ ORQ R10, R8
+ XORQ R12, DX
+ XORQ R13, R8
+ MOVQ DX, 176(DI)
+ MOVQ R8, 184(DI)
+
+ // Prepare round
+ MOVQ BP, BX
+ ROLQ $0x01, BX
+ MOVQ 16(DI), R12
+ XORQ 56(DI), DX
+ XORQ R15, BX
+ XORQ 96(DI), R12
+ XORQ 136(DI), DX
+ XORQ DX, R12
+ MOVQ R12, CX
+ ROLQ $0x01, CX
+ MOVQ 24(DI), R13
+ XORQ 64(DI), R8
+ XORQ SI, CX
+ XORQ 104(DI), R13
+ XORQ 144(DI), R8
+ XORQ R8, R13
+ MOVQ R13, DX
+ ROLQ $0x01, DX
+ MOVQ R15, R8
+ XORQ BP, DX
+ ROLQ $0x01, R8
+ MOVQ SI, R9
+ XORQ R12, R8
+ ROLQ $0x01, R9
+
+ // Result b
+ MOVQ (DI), R10
+ MOVQ 48(DI), R11
+ XORQ R13, R9
+ MOVQ 96(DI), R12
+ MOVQ 144(DI), R13
+ MOVQ 192(DI), R14
+ XORQ CX, R11
+ ROLQ $0x2c, R11
+ XORQ DX, R12
+ XORQ BX, R10
+ ROLQ $0x2b, R12
+ MOVQ R11, SI
+ MOVQ $0x8000000080008081, AX
+ ORQ R12, SI
+ XORQ R10, AX
+ XORQ AX, SI
+ MOVQ SI, (SP)
+ XORQ R9, R14
+ ROLQ $0x0e, R14
+ MOVQ R10, R15
+ ANDQ R11, R15
+ XORQ R14, R15
+ MOVQ R15, 32(SP)
+ XORQ R8, R13
+ ROLQ $0x15, R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 16(SP)
+ NOTQ R12
+ ORQ R10, R14
+ ORQ R13, R12
+ XORQ R13, R14
+ XORQ R11, R12
+ MOVQ R14, 24(SP)
+ MOVQ R12, 8(SP)
+ MOVQ R12, BP
+
+ // Result g
+ MOVQ 72(DI), R11
+ XORQ R9, R11
+ MOVQ 80(DI), R12
+ ROLQ $0x14, R11
+ XORQ BX, R12
+ ROLQ $0x03, R12
+ MOVQ 24(DI), R10
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ R8, R10
+ MOVQ 128(DI), R13
+ MOVQ 176(DI), R14
+ ROLQ $0x1c, R10
+ XORQ R10, AX
+ MOVQ AX, 40(SP)
+ XORQ AX, SI
+ XORQ CX, R13
+ ROLQ $0x2d, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 48(SP)
+ XORQ AX, BP
+ XORQ DX, R14
+ ROLQ $0x3d, R14
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 64(SP)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 72(SP)
+ NOTQ R14
+ XORQ R10, R15
+ ORQ R14, R13
+ XORQ R12, R13
+ MOVQ R13, 56(SP)
+
+ // Result k
+ MOVQ 8(DI), R10
+ MOVQ 56(DI), R11
+ MOVQ 104(DI), R12
+ MOVQ 152(DI), R13
+ MOVQ 160(DI), R14
+ XORQ DX, R11
+ ROLQ $0x06, R11
+ XORQ R8, R12
+ ROLQ $0x19, R12
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ CX, R10
+ ROLQ $0x01, R10
+ XORQ R10, AX
+ MOVQ AX, 80(SP)
+ XORQ AX, SI
+ XORQ R9, R13
+ ROLQ $0x08, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 88(SP)
+ XORQ AX, BP
+ XORQ BX, R14
+ ROLQ $0x12, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 96(SP)
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 104(SP)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 112(SP)
+ XORQ R10, R15
+
+ // Result m
+ MOVQ 40(DI), R11
+ XORQ BX, R11
+ MOVQ 88(DI), R12
+ ROLQ $0x24, R11
+ XORQ CX, R12
+ MOVQ 32(DI), R10
+ ROLQ $0x0a, R12
+ MOVQ R11, AX
+ MOVQ 136(DI), R13
+ ANDQ R12, AX
+ XORQ R9, R10
+ MOVQ 184(DI), R14
+ ROLQ $0x1b, R10
+ XORQ R10, AX
+ MOVQ AX, 120(SP)
+ XORQ AX, SI
+ XORQ DX, R13
+ ROLQ $0x0f, R13
+ MOVQ R12, AX
+ ORQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 128(SP)
+ XORQ AX, BP
+ XORQ R8, R14
+ ROLQ $0x38, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ORQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 136(SP)
+ ORQ R10, R11
+ XORQ R14, R11
+ MOVQ R11, 152(SP)
+ ANDQ R10, R14
+ XORQ R13, R14
+ MOVQ R14, 144(SP)
+ XORQ R11, R15
+
+ // Result s
+ MOVQ 16(DI), R10
+ MOVQ 64(DI), R11
+ MOVQ 112(DI), R12
+ XORQ DX, R10
+ MOVQ 120(DI), R13
+ ROLQ $0x3e, R10
+ XORQ R8, R11
+ MOVQ 168(DI), R14
+ ROLQ $0x37, R11
+ XORQ R9, R12
+ MOVQ R10, R9
+ XORQ CX, R14
+ ROLQ $0x02, R14
+ ANDQ R11, R9
+ XORQ R14, R9
+ MOVQ R9, 192(SP)
+ ROLQ $0x27, R12
+ XORQ R9, R15
+ NOTQ R11
+ XORQ BX, R13
+ MOVQ R11, BX
+ ANDQ R12, BX
+ XORQ R10, BX
+ MOVQ BX, 160(SP)
+ XORQ BX, SI
+ ROLQ $0x29, R13
+ MOVQ R12, CX
+ ORQ R13, CX
+ XORQ R11, CX
+ MOVQ CX, 168(SP)
+ XORQ CX, BP
+ MOVQ R13, DX
+ MOVQ R14, R8
+ ANDQ R14, DX
+ ORQ R10, R8
+ XORQ R12, DX
+ XORQ R13, R8
+ MOVQ DX, 176(SP)
+ MOVQ R8, 184(SP)
+
+ // Prepare round
+ MOVQ BP, BX
+ ROLQ $0x01, BX
+ MOVQ 16(SP), R12
+ XORQ 56(SP), DX
+ XORQ R15, BX
+ XORQ 96(SP), R12
+ XORQ 136(SP), DX
+ XORQ DX, R12
+ MOVQ R12, CX
+ ROLQ $0x01, CX
+ MOVQ 24(SP), R13
+ XORQ 64(SP), R8
+ XORQ SI, CX
+ XORQ 104(SP), R13
+ XORQ 144(SP), R8
+ XORQ R8, R13
+ MOVQ R13, DX
+ ROLQ $0x01, DX
+ MOVQ R15, R8
+ XORQ BP, DX
+ ROLQ $0x01, R8
+ MOVQ SI, R9
+ XORQ R12, R8
+ ROLQ $0x01, R9
+
+ // Result b
+ MOVQ (SP), R10
+ MOVQ 48(SP), R11
+ XORQ R13, R9
+ MOVQ 96(SP), R12
+ MOVQ 144(SP), R13
+ MOVQ 192(SP), R14
+ XORQ CX, R11
+ ROLQ $0x2c, R11
+ XORQ DX, R12
+ XORQ BX, R10
+ ROLQ $0x2b, R12
+ MOVQ R11, SI
+ MOVQ $0x8000000000008009, AX
+ ORQ R12, SI
+ XORQ R10, AX
+ XORQ AX, SI
+ MOVQ SI, (DI)
+ XORQ R9, R14
+ ROLQ $0x0e, R14
+ MOVQ R10, R15
+ ANDQ R11, R15
+ XORQ R14, R15
+ MOVQ R15, 32(DI)
+ XORQ R8, R13
+ ROLQ $0x15, R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 16(DI)
+ NOTQ R12
+ ORQ R10, R14
+ ORQ R13, R12
+ XORQ R13, R14
+ XORQ R11, R12
+ MOVQ R14, 24(DI)
+ MOVQ R12, 8(DI)
+ MOVQ R12, BP
+
+ // Result g
+ MOVQ 72(SP), R11
+ XORQ R9, R11
+ MOVQ 80(SP), R12
+ ROLQ $0x14, R11
+ XORQ BX, R12
+ ROLQ $0x03, R12
+ MOVQ 24(SP), R10
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ R8, R10
+ MOVQ 128(SP), R13
+ MOVQ 176(SP), R14
+ ROLQ $0x1c, R10
+ XORQ R10, AX
+ MOVQ AX, 40(DI)
+ XORQ AX, SI
+ XORQ CX, R13
+ ROLQ $0x2d, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 48(DI)
+ XORQ AX, BP
+ XORQ DX, R14
+ ROLQ $0x3d, R14
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 64(DI)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 72(DI)
+ NOTQ R14
+ XORQ R10, R15
+ ORQ R14, R13
+ XORQ R12, R13
+ MOVQ R13, 56(DI)
+
+ // Result k
+ MOVQ 8(SP), R10
+ MOVQ 56(SP), R11
+ MOVQ 104(SP), R12
+ MOVQ 152(SP), R13
+ MOVQ 160(SP), R14
+ XORQ DX, R11
+ ROLQ $0x06, R11
+ XORQ R8, R12
+ ROLQ $0x19, R12
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ CX, R10
+ ROLQ $0x01, R10
+ XORQ R10, AX
+ MOVQ AX, 80(DI)
+ XORQ AX, SI
+ XORQ R9, R13
+ ROLQ $0x08, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 88(DI)
+ XORQ AX, BP
+ XORQ BX, R14
+ ROLQ $0x12, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 96(DI)
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 104(DI)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 112(DI)
+ XORQ R10, R15
+
+ // Result m
+ MOVQ 40(SP), R11
+ XORQ BX, R11
+ MOVQ 88(SP), R12
+ ROLQ $0x24, R11
+ XORQ CX, R12
+ MOVQ 32(SP), R10
+ ROLQ $0x0a, R12
+ MOVQ R11, AX
+ MOVQ 136(SP), R13
+ ANDQ R12, AX
+ XORQ R9, R10
+ MOVQ 184(SP), R14
+ ROLQ $0x1b, R10
+ XORQ R10, AX
+ MOVQ AX, 120(DI)
+ XORQ AX, SI
+ XORQ DX, R13
+ ROLQ $0x0f, R13
+ MOVQ R12, AX
+ ORQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 128(DI)
+ XORQ AX, BP
+ XORQ R8, R14
+ ROLQ $0x38, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ORQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 136(DI)
+ ORQ R10, R11
+ XORQ R14, R11
+ MOVQ R11, 152(DI)
+ ANDQ R10, R14
+ XORQ R13, R14
+ MOVQ R14, 144(DI)
+ XORQ R11, R15
+
+ // Result s
+ MOVQ 16(SP), R10
+ MOVQ 64(SP), R11
+ MOVQ 112(SP), R12
+ XORQ DX, R10
+ MOVQ 120(SP), R13
+ ROLQ $0x3e, R10
+ XORQ R8, R11
+ MOVQ 168(SP), R14
+ ROLQ $0x37, R11
+ XORQ R9, R12
+ MOVQ R10, R9
+ XORQ CX, R14
+ ROLQ $0x02, R14
+ ANDQ R11, R9
+ XORQ R14, R9
+ MOVQ R9, 192(DI)
+ ROLQ $0x27, R12
+ XORQ R9, R15
+ NOTQ R11
+ XORQ BX, R13
+ MOVQ R11, BX
+ ANDQ R12, BX
+ XORQ R10, BX
+ MOVQ BX, 160(DI)
+ XORQ BX, SI
+ ROLQ $0x29, R13
+ MOVQ R12, CX
+ ORQ R13, CX
+ XORQ R11, CX
+ MOVQ CX, 168(DI)
+ XORQ CX, BP
+ MOVQ R13, DX
+ MOVQ R14, R8
+ ANDQ R14, DX
+ ORQ R10, R8
+ XORQ R12, DX
+ XORQ R13, R8
+ MOVQ DX, 176(DI)
+ MOVQ R8, 184(DI)
+
+ // Prepare round
+ MOVQ BP, BX
+ ROLQ $0x01, BX
+ MOVQ 16(DI), R12
+ XORQ 56(DI), DX
+ XORQ R15, BX
+ XORQ 96(DI), R12
+ XORQ 136(DI), DX
+ XORQ DX, R12
+ MOVQ R12, CX
+ ROLQ $0x01, CX
+ MOVQ 24(DI), R13
+ XORQ 64(DI), R8
+ XORQ SI, CX
+ XORQ 104(DI), R13
+ XORQ 144(DI), R8
+ XORQ R8, R13
+ MOVQ R13, DX
+ ROLQ $0x01, DX
+ MOVQ R15, R8
+ XORQ BP, DX
+ ROLQ $0x01, R8
+ MOVQ SI, R9
+ XORQ R12, R8
+ ROLQ $0x01, R9
+
+ // Result b
+ MOVQ (DI), R10
+ MOVQ 48(DI), R11
+ XORQ R13, R9
+ MOVQ 96(DI), R12
+ MOVQ 144(DI), R13
+ MOVQ 192(DI), R14
+ XORQ CX, R11
+ ROLQ $0x2c, R11
+ XORQ DX, R12
+ XORQ BX, R10
+ ROLQ $0x2b, R12
+ MOVQ R11, SI
+ MOVQ $0x000000000000008a, AX
+ ORQ R12, SI
+ XORQ R10, AX
+ XORQ AX, SI
+ MOVQ SI, (SP)
+ XORQ R9, R14
+ ROLQ $0x0e, R14
+ MOVQ R10, R15
+ ANDQ R11, R15
+ XORQ R14, R15
+ MOVQ R15, 32(SP)
+ XORQ R8, R13
+ ROLQ $0x15, R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 16(SP)
+ NOTQ R12
+ ORQ R10, R14
+ ORQ R13, R12
+ XORQ R13, R14
+ XORQ R11, R12
+ MOVQ R14, 24(SP)
+ MOVQ R12, 8(SP)
+ MOVQ R12, BP
+
+ // Result g
+ MOVQ 72(DI), R11
+ XORQ R9, R11
+ MOVQ 80(DI), R12
+ ROLQ $0x14, R11
+ XORQ BX, R12
+ ROLQ $0x03, R12
+ MOVQ 24(DI), R10
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ R8, R10
+ MOVQ 128(DI), R13
+ MOVQ 176(DI), R14
+ ROLQ $0x1c, R10
+ XORQ R10, AX
+ MOVQ AX, 40(SP)
+ XORQ AX, SI
+ XORQ CX, R13
+ ROLQ $0x2d, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 48(SP)
+ XORQ AX, BP
+ XORQ DX, R14
+ ROLQ $0x3d, R14
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 64(SP)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 72(SP)
+ NOTQ R14
+ XORQ R10, R15
+ ORQ R14, R13
+ XORQ R12, R13
+ MOVQ R13, 56(SP)
+
+ // Result k
+ MOVQ 8(DI), R10
+ MOVQ 56(DI), R11
+ MOVQ 104(DI), R12
+ MOVQ 152(DI), R13
+ MOVQ 160(DI), R14
+ XORQ DX, R11
+ ROLQ $0x06, R11
+ XORQ R8, R12
+ ROLQ $0x19, R12
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ CX, R10
+ ROLQ $0x01, R10
+ XORQ R10, AX
+ MOVQ AX, 80(SP)
+ XORQ AX, SI
+ XORQ R9, R13
+ ROLQ $0x08, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 88(SP)
+ XORQ AX, BP
+ XORQ BX, R14
+ ROLQ $0x12, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 96(SP)
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 104(SP)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 112(SP)
+ XORQ R10, R15
+
+ // Result m
+ MOVQ 40(DI), R11
+ XORQ BX, R11
+ MOVQ 88(DI), R12
+ ROLQ $0x24, R11
+ XORQ CX, R12
+ MOVQ 32(DI), R10
+ ROLQ $0x0a, R12
+ MOVQ R11, AX
+ MOVQ 136(DI), R13
+ ANDQ R12, AX
+ XORQ R9, R10
+ MOVQ 184(DI), R14
+ ROLQ $0x1b, R10
+ XORQ R10, AX
+ MOVQ AX, 120(SP)
+ XORQ AX, SI
+ XORQ DX, R13
+ ROLQ $0x0f, R13
+ MOVQ R12, AX
+ ORQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 128(SP)
+ XORQ AX, BP
+ XORQ R8, R14
+ ROLQ $0x38, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ORQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 136(SP)
+ ORQ R10, R11
+ XORQ R14, R11
+ MOVQ R11, 152(SP)
+ ANDQ R10, R14
+ XORQ R13, R14
+ MOVQ R14, 144(SP)
+ XORQ R11, R15
+
+ // Result s
+ MOVQ 16(DI), R10
+ MOVQ 64(DI), R11
+ MOVQ 112(DI), R12
+ XORQ DX, R10
+ MOVQ 120(DI), R13
+ ROLQ $0x3e, R10
+ XORQ R8, R11
+ MOVQ 168(DI), R14
+ ROLQ $0x37, R11
+ XORQ R9, R12
+ MOVQ R10, R9
+ XORQ CX, R14
+ ROLQ $0x02, R14
+ ANDQ R11, R9
+ XORQ R14, R9
+ MOVQ R9, 192(SP)
+ ROLQ $0x27, R12
+ XORQ R9, R15
+ NOTQ R11
+ XORQ BX, R13
+ MOVQ R11, BX
+ ANDQ R12, BX
+ XORQ R10, BX
+ MOVQ BX, 160(SP)
+ XORQ BX, SI
+ ROLQ $0x29, R13
+ MOVQ R12, CX
+ ORQ R13, CX
+ XORQ R11, CX
+ MOVQ CX, 168(SP)
+ XORQ CX, BP
+ MOVQ R13, DX
+ MOVQ R14, R8
+ ANDQ R14, DX
+ ORQ R10, R8
+ XORQ R12, DX
+ XORQ R13, R8
+ MOVQ DX, 176(SP)
+ MOVQ R8, 184(SP)
+
+ // Prepare round
+ MOVQ BP, BX
+ ROLQ $0x01, BX
+ MOVQ 16(SP), R12
+ XORQ 56(SP), DX
+ XORQ R15, BX
+ XORQ 96(SP), R12
+ XORQ 136(SP), DX
+ XORQ DX, R12
+ MOVQ R12, CX
+ ROLQ $0x01, CX
+ MOVQ 24(SP), R13
+ XORQ 64(SP), R8
+ XORQ SI, CX
+ XORQ 104(SP), R13
+ XORQ 144(SP), R8
+ XORQ R8, R13
+ MOVQ R13, DX
+ ROLQ $0x01, DX
+ MOVQ R15, R8
+ XORQ BP, DX
+ ROLQ $0x01, R8
+ MOVQ SI, R9
+ XORQ R12, R8
+ ROLQ $0x01, R9
+
+ // Result b
+ MOVQ (SP), R10
+ MOVQ 48(SP), R11
+ XORQ R13, R9
+ MOVQ 96(SP), R12
+ MOVQ 144(SP), R13
+ MOVQ 192(SP), R14
+ XORQ CX, R11
+ ROLQ $0x2c, R11
+ XORQ DX, R12
+ XORQ BX, R10
+ ROLQ $0x2b, R12
+ MOVQ R11, SI
+ MOVQ $0x0000000000000088, AX
+ ORQ R12, SI
+ XORQ R10, AX
+ XORQ AX, SI
+ MOVQ SI, (DI)
+ XORQ R9, R14
+ ROLQ $0x0e, R14
+ MOVQ R10, R15
+ ANDQ R11, R15
+ XORQ R14, R15
+ MOVQ R15, 32(DI)
+ XORQ R8, R13
+ ROLQ $0x15, R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 16(DI)
+ NOTQ R12
+ ORQ R10, R14
+ ORQ R13, R12
+ XORQ R13, R14
+ XORQ R11, R12
+ MOVQ R14, 24(DI)
+ MOVQ R12, 8(DI)
+ MOVQ R12, BP
+
+ // Result g
+ MOVQ 72(SP), R11
+ XORQ R9, R11
+ MOVQ 80(SP), R12
+ ROLQ $0x14, R11
+ XORQ BX, R12
+ ROLQ $0x03, R12
+ MOVQ 24(SP), R10
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ R8, R10
+ MOVQ 128(SP), R13
+ MOVQ 176(SP), R14
+ ROLQ $0x1c, R10
+ XORQ R10, AX
+ MOVQ AX, 40(DI)
+ XORQ AX, SI
+ XORQ CX, R13
+ ROLQ $0x2d, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 48(DI)
+ XORQ AX, BP
+ XORQ DX, R14
+ ROLQ $0x3d, R14
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 64(DI)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 72(DI)
+ NOTQ R14
+ XORQ R10, R15
+ ORQ R14, R13
+ XORQ R12, R13
+ MOVQ R13, 56(DI)
+
+ // Result k
+ MOVQ 8(SP), R10
+ MOVQ 56(SP), R11
+ MOVQ 104(SP), R12
+ MOVQ 152(SP), R13
+ MOVQ 160(SP), R14
+ XORQ DX, R11
+ ROLQ $0x06, R11
+ XORQ R8, R12
+ ROLQ $0x19, R12
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ CX, R10
+ ROLQ $0x01, R10
+ XORQ R10, AX
+ MOVQ AX, 80(DI)
+ XORQ AX, SI
+ XORQ R9, R13
+ ROLQ $0x08, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 88(DI)
+ XORQ AX, BP
+ XORQ BX, R14
+ ROLQ $0x12, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 96(DI)
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 104(DI)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 112(DI)
+ XORQ R10, R15
+
+ // Result m
+ MOVQ 40(SP), R11
+ XORQ BX, R11
+ MOVQ 88(SP), R12
+ ROLQ $0x24, R11
+ XORQ CX, R12
+ MOVQ 32(SP), R10
+ ROLQ $0x0a, R12
+ MOVQ R11, AX
+ MOVQ 136(SP), R13
+ ANDQ R12, AX
+ XORQ R9, R10
+ MOVQ 184(SP), R14
+ ROLQ $0x1b, R10
+ XORQ R10, AX
+ MOVQ AX, 120(DI)
+ XORQ AX, SI
+ XORQ DX, R13
+ ROLQ $0x0f, R13
+ MOVQ R12, AX
+ ORQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 128(DI)
+ XORQ AX, BP
+ XORQ R8, R14
+ ROLQ $0x38, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ORQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 136(DI)
+ ORQ R10, R11
+ XORQ R14, R11
+ MOVQ R11, 152(DI)
+ ANDQ R10, R14
+ XORQ R13, R14
+ MOVQ R14, 144(DI)
+ XORQ R11, R15
+
+ // Result s
+ MOVQ 16(SP), R10
+ MOVQ 64(SP), R11
+ MOVQ 112(SP), R12
+ XORQ DX, R10
+ MOVQ 120(SP), R13
+ ROLQ $0x3e, R10
+ XORQ R8, R11
+ MOVQ 168(SP), R14
+ ROLQ $0x37, R11
+ XORQ R9, R12
+ MOVQ R10, R9
+ XORQ CX, R14
+ ROLQ $0x02, R14
+ ANDQ R11, R9
+ XORQ R14, R9
+ MOVQ R9, 192(DI)
+ ROLQ $0x27, R12
+ XORQ R9, R15
+ NOTQ R11
+ XORQ BX, R13
+ MOVQ R11, BX
+ ANDQ R12, BX
+ XORQ R10, BX
+ MOVQ BX, 160(DI)
+ XORQ BX, SI
+ ROLQ $0x29, R13
+ MOVQ R12, CX
+ ORQ R13, CX
+ XORQ R11, CX
+ MOVQ CX, 168(DI)
+ XORQ CX, BP
+ MOVQ R13, DX
+ MOVQ R14, R8
+ ANDQ R14, DX
+ ORQ R10, R8
+ XORQ R12, DX
+ XORQ R13, R8
+ MOVQ DX, 176(DI)
+ MOVQ R8, 184(DI)
+
+ // Prepare round
+ MOVQ BP, BX
+ ROLQ $0x01, BX
+ MOVQ 16(DI), R12
+ XORQ 56(DI), DX
+ XORQ R15, BX
+ XORQ 96(DI), R12
+ XORQ 136(DI), DX
+ XORQ DX, R12
+ MOVQ R12, CX
+ ROLQ $0x01, CX
+ MOVQ 24(DI), R13
+ XORQ 64(DI), R8
+ XORQ SI, CX
+ XORQ 104(DI), R13
+ XORQ 144(DI), R8
+ XORQ R8, R13
+ MOVQ R13, DX
+ ROLQ $0x01, DX
+ MOVQ R15, R8
+ XORQ BP, DX
+ ROLQ $0x01, R8
+ MOVQ SI, R9
+ XORQ R12, R8
+ ROLQ $0x01, R9
+
+ // Result b
+ MOVQ (DI), R10
+ MOVQ 48(DI), R11
+ XORQ R13, R9
+ MOVQ 96(DI), R12
+ MOVQ 144(DI), R13
+ MOVQ 192(DI), R14
+ XORQ CX, R11
+ ROLQ $0x2c, R11
+ XORQ DX, R12
+ XORQ BX, R10
+ ROLQ $0x2b, R12
+ MOVQ R11, SI
+ MOVQ $0x0000000080008009, AX
+ ORQ R12, SI
+ XORQ R10, AX
+ XORQ AX, SI
+ MOVQ SI, (SP)
+ XORQ R9, R14
+ ROLQ $0x0e, R14
+ MOVQ R10, R15
+ ANDQ R11, R15
+ XORQ R14, R15
+ MOVQ R15, 32(SP)
+ XORQ R8, R13
+ ROLQ $0x15, R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 16(SP)
+ NOTQ R12
+ ORQ R10, R14
+ ORQ R13, R12
+ XORQ R13, R14
+ XORQ R11, R12
+ MOVQ R14, 24(SP)
+ MOVQ R12, 8(SP)
+ MOVQ R12, BP
+
+ // Result g
+ MOVQ 72(DI), R11
+ XORQ R9, R11
+ MOVQ 80(DI), R12
+ ROLQ $0x14, R11
+ XORQ BX, R12
+ ROLQ $0x03, R12
+ MOVQ 24(DI), R10
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ R8, R10
+ MOVQ 128(DI), R13
+ MOVQ 176(DI), R14
+ ROLQ $0x1c, R10
+ XORQ R10, AX
+ MOVQ AX, 40(SP)
+ XORQ AX, SI
+ XORQ CX, R13
+ ROLQ $0x2d, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 48(SP)
+ XORQ AX, BP
+ XORQ DX, R14
+ ROLQ $0x3d, R14
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 64(SP)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 72(SP)
+ NOTQ R14
+ XORQ R10, R15
+ ORQ R14, R13
+ XORQ R12, R13
+ MOVQ R13, 56(SP)
+
+ // Result k
+ MOVQ 8(DI), R10
+ MOVQ 56(DI), R11
+ MOVQ 104(DI), R12
+ MOVQ 152(DI), R13
+ MOVQ 160(DI), R14
+ XORQ DX, R11
+ ROLQ $0x06, R11
+ XORQ R8, R12
+ ROLQ $0x19, R12
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ CX, R10
+ ROLQ $0x01, R10
+ XORQ R10, AX
+ MOVQ AX, 80(SP)
+ XORQ AX, SI
+ XORQ R9, R13
+ ROLQ $0x08, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 88(SP)
+ XORQ AX, BP
+ XORQ BX, R14
+ ROLQ $0x12, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 96(SP)
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 104(SP)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 112(SP)
+ XORQ R10, R15
+
+ // Result m
+ MOVQ 40(DI), R11
+ XORQ BX, R11
+ MOVQ 88(DI), R12
+ ROLQ $0x24, R11
+ XORQ CX, R12
+ MOVQ 32(DI), R10
+ ROLQ $0x0a, R12
+ MOVQ R11, AX
+ MOVQ 136(DI), R13
+ ANDQ R12, AX
+ XORQ R9, R10
+ MOVQ 184(DI), R14
+ ROLQ $0x1b, R10
+ XORQ R10, AX
+ MOVQ AX, 120(SP)
+ XORQ AX, SI
+ XORQ DX, R13
+ ROLQ $0x0f, R13
+ MOVQ R12, AX
+ ORQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 128(SP)
+ XORQ AX, BP
+ XORQ R8, R14
+ ROLQ $0x38, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ORQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 136(SP)
+ ORQ R10, R11
+ XORQ R14, R11
+ MOVQ R11, 152(SP)
+ ANDQ R10, R14
+ XORQ R13, R14
+ MOVQ R14, 144(SP)
+ XORQ R11, R15
+
+ // Result s
+ MOVQ 16(DI), R10
+ MOVQ 64(DI), R11
+ MOVQ 112(DI), R12
+ XORQ DX, R10
+ MOVQ 120(DI), R13
+ ROLQ $0x3e, R10
+ XORQ R8, R11
+ MOVQ 168(DI), R14
+ ROLQ $0x37, R11
+ XORQ R9, R12
+ MOVQ R10, R9
+ XORQ CX, R14
+ ROLQ $0x02, R14
+ ANDQ R11, R9
+ XORQ R14, R9
+ MOVQ R9, 192(SP)
+ ROLQ $0x27, R12
+ XORQ R9, R15
+ NOTQ R11
+ XORQ BX, R13
+ MOVQ R11, BX
+ ANDQ R12, BX
+ XORQ R10, BX
+ MOVQ BX, 160(SP)
+ XORQ BX, SI
+ ROLQ $0x29, R13
+ MOVQ R12, CX
+ ORQ R13, CX
+ XORQ R11, CX
+ MOVQ CX, 168(SP)
+ XORQ CX, BP
+ MOVQ R13, DX
+ MOVQ R14, R8
+ ANDQ R14, DX
+ ORQ R10, R8
+ XORQ R12, DX
+ XORQ R13, R8
+ MOVQ DX, 176(SP)
+ MOVQ R8, 184(SP)
+
+ // Prepare round
+ MOVQ BP, BX
+ ROLQ $0x01, BX
+ MOVQ 16(SP), R12
+ XORQ 56(SP), DX
+ XORQ R15, BX
+ XORQ 96(SP), R12
+ XORQ 136(SP), DX
+ XORQ DX, R12
+ MOVQ R12, CX
+ ROLQ $0x01, CX
+ MOVQ 24(SP), R13
+ XORQ 64(SP), R8
+ XORQ SI, CX
+ XORQ 104(SP), R13
+ XORQ 144(SP), R8
+ XORQ R8, R13
+ MOVQ R13, DX
+ ROLQ $0x01, DX
+ MOVQ R15, R8
+ XORQ BP, DX
+ ROLQ $0x01, R8
+ MOVQ SI, R9
+ XORQ R12, R8
+ ROLQ $0x01, R9
+
+ // Result b
+ MOVQ (SP), R10
+ MOVQ 48(SP), R11
+ XORQ R13, R9
+ MOVQ 96(SP), R12
+ MOVQ 144(SP), R13
+ MOVQ 192(SP), R14
+ XORQ CX, R11
+ ROLQ $0x2c, R11
+ XORQ DX, R12
+ XORQ BX, R10
+ ROLQ $0x2b, R12
+ MOVQ R11, SI
+ MOVQ $0x000000008000000a, AX
+ ORQ R12, SI
+ XORQ R10, AX
+ XORQ AX, SI
+ MOVQ SI, (DI)
+ XORQ R9, R14
+ ROLQ $0x0e, R14
+ MOVQ R10, R15
+ ANDQ R11, R15
+ XORQ R14, R15
+ MOVQ R15, 32(DI)
+ XORQ R8, R13
+ ROLQ $0x15, R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 16(DI)
+ NOTQ R12
+ ORQ R10, R14
+ ORQ R13, R12
+ XORQ R13, R14
+ XORQ R11, R12
+ MOVQ R14, 24(DI)
+ MOVQ R12, 8(DI)
+ MOVQ R12, BP
+
+ // Result g
+ MOVQ 72(SP), R11
+ XORQ R9, R11
+ MOVQ 80(SP), R12
+ ROLQ $0x14, R11
+ XORQ BX, R12
+ ROLQ $0x03, R12
+ MOVQ 24(SP), R10
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ R8, R10
+ MOVQ 128(SP), R13
+ MOVQ 176(SP), R14
+ ROLQ $0x1c, R10
+ XORQ R10, AX
+ MOVQ AX, 40(DI)
+ XORQ AX, SI
+ XORQ CX, R13
+ ROLQ $0x2d, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 48(DI)
+ XORQ AX, BP
+ XORQ DX, R14
+ ROLQ $0x3d, R14
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 64(DI)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 72(DI)
+ NOTQ R14
+ XORQ R10, R15
+ ORQ R14, R13
+ XORQ R12, R13
+ MOVQ R13, 56(DI)
+
+ // Result k
+ MOVQ 8(SP), R10
+ MOVQ 56(SP), R11
+ MOVQ 104(SP), R12
+ MOVQ 152(SP), R13
+ MOVQ 160(SP), R14
+ XORQ DX, R11
+ ROLQ $0x06, R11
+ XORQ R8, R12
+ ROLQ $0x19, R12
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ CX, R10
+ ROLQ $0x01, R10
+ XORQ R10, AX
+ MOVQ AX, 80(DI)
+ XORQ AX, SI
+ XORQ R9, R13
+ ROLQ $0x08, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 88(DI)
+ XORQ AX, BP
+ XORQ BX, R14
+ ROLQ $0x12, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 96(DI)
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 104(DI)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 112(DI)
+ XORQ R10, R15
+
+ // Result m
+ MOVQ 40(SP), R11
+ XORQ BX, R11
+ MOVQ 88(SP), R12
+ ROLQ $0x24, R11
+ XORQ CX, R12
+ MOVQ 32(SP), R10
+ ROLQ $0x0a, R12
+ MOVQ R11, AX
+ MOVQ 136(SP), R13
+ ANDQ R12, AX
+ XORQ R9, R10
+ MOVQ 184(SP), R14
+ ROLQ $0x1b, R10
+ XORQ R10, AX
+ MOVQ AX, 120(DI)
+ XORQ AX, SI
+ XORQ DX, R13
+ ROLQ $0x0f, R13
+ MOVQ R12, AX
+ ORQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 128(DI)
+ XORQ AX, BP
+ XORQ R8, R14
+ ROLQ $0x38, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ORQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 136(DI)
+ ORQ R10, R11
+ XORQ R14, R11
+ MOVQ R11, 152(DI)
+ ANDQ R10, R14
+ XORQ R13, R14
+ MOVQ R14, 144(DI)
+ XORQ R11, R15
+
+ // Result s
+ MOVQ 16(SP), R10
+ MOVQ 64(SP), R11
+ MOVQ 112(SP), R12
+ XORQ DX, R10
+ MOVQ 120(SP), R13
+ ROLQ $0x3e, R10
+ XORQ R8, R11
+ MOVQ 168(SP), R14
+ ROLQ $0x37, R11
+ XORQ R9, R12
+ MOVQ R10, R9
+ XORQ CX, R14
+ ROLQ $0x02, R14
+ ANDQ R11, R9
+ XORQ R14, R9
+ MOVQ R9, 192(DI)
+ ROLQ $0x27, R12
+ XORQ R9, R15
+ NOTQ R11
+ XORQ BX, R13
+ MOVQ R11, BX
+ ANDQ R12, BX
+ XORQ R10, BX
+ MOVQ BX, 160(DI)
+ XORQ BX, SI
+ ROLQ $0x29, R13
+ MOVQ R12, CX
+ ORQ R13, CX
+ XORQ R11, CX
+ MOVQ CX, 168(DI)
+ XORQ CX, BP
+ MOVQ R13, DX
+ MOVQ R14, R8
+ ANDQ R14, DX
+ ORQ R10, R8
+ XORQ R12, DX
+ XORQ R13, R8
+ MOVQ DX, 176(DI)
+ MOVQ R8, 184(DI)
+
+ // Prepare round
+ MOVQ BP, BX
+ ROLQ $0x01, BX
+ MOVQ 16(DI), R12
+ XORQ 56(DI), DX
+ XORQ R15, BX
+ XORQ 96(DI), R12
+ XORQ 136(DI), DX
+ XORQ DX, R12
+ MOVQ R12, CX
+ ROLQ $0x01, CX
+ MOVQ 24(DI), R13
+ XORQ 64(DI), R8
+ XORQ SI, CX
+ XORQ 104(DI), R13
+ XORQ 144(DI), R8
+ XORQ R8, R13
+ MOVQ R13, DX
+ ROLQ $0x01, DX
+ MOVQ R15, R8
+ XORQ BP, DX
+ ROLQ $0x01, R8
+ MOVQ SI, R9
+ XORQ R12, R8
+ ROLQ $0x01, R9
+
+ // Result b
+ MOVQ (DI), R10
+ MOVQ 48(DI), R11
+ XORQ R13, R9
+ MOVQ 96(DI), R12
+ MOVQ 144(DI), R13
+ MOVQ 192(DI), R14
+ XORQ CX, R11
+ ROLQ $0x2c, R11
+ XORQ DX, R12
+ XORQ BX, R10
+ ROLQ $0x2b, R12
+ MOVQ R11, SI
+ MOVQ $0x000000008000808b, AX
+ ORQ R12, SI
+ XORQ R10, AX
+ XORQ AX, SI
+ MOVQ SI, (SP)
+ XORQ R9, R14
+ ROLQ $0x0e, R14
+ MOVQ R10, R15
+ ANDQ R11, R15
+ XORQ R14, R15
+ MOVQ R15, 32(SP)
+ XORQ R8, R13
+ ROLQ $0x15, R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 16(SP)
+ NOTQ R12
+ ORQ R10, R14
+ ORQ R13, R12
+ XORQ R13, R14
+ XORQ R11, R12
+ MOVQ R14, 24(SP)
+ MOVQ R12, 8(SP)
+ MOVQ R12, BP
+
+ // Result g
+ MOVQ 72(DI), R11
+ XORQ R9, R11
+ MOVQ 80(DI), R12
+ ROLQ $0x14, R11
+ XORQ BX, R12
+ ROLQ $0x03, R12
+ MOVQ 24(DI), R10
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ R8, R10
+ MOVQ 128(DI), R13
+ MOVQ 176(DI), R14
+ ROLQ $0x1c, R10
+ XORQ R10, AX
+ MOVQ AX, 40(SP)
+ XORQ AX, SI
+ XORQ CX, R13
+ ROLQ $0x2d, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 48(SP)
+ XORQ AX, BP
+ XORQ DX, R14
+ ROLQ $0x3d, R14
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 64(SP)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 72(SP)
+ NOTQ R14
+ XORQ R10, R15
+ ORQ R14, R13
+ XORQ R12, R13
+ MOVQ R13, 56(SP)
+
+ // Result k
+ MOVQ 8(DI), R10
+ MOVQ 56(DI), R11
+ MOVQ 104(DI), R12
+ MOVQ 152(DI), R13
+ MOVQ 160(DI), R14
+ XORQ DX, R11
+ ROLQ $0x06, R11
+ XORQ R8, R12
+ ROLQ $0x19, R12
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ CX, R10
+ ROLQ $0x01, R10
+ XORQ R10, AX
+ MOVQ AX, 80(SP)
+ XORQ AX, SI
+ XORQ R9, R13
+ ROLQ $0x08, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 88(SP)
+ XORQ AX, BP
+ XORQ BX, R14
+ ROLQ $0x12, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 96(SP)
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 104(SP)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 112(SP)
+ XORQ R10, R15
+
+ // Result m
+ MOVQ 40(DI), R11
+ XORQ BX, R11
+ MOVQ 88(DI), R12
+ ROLQ $0x24, R11
+ XORQ CX, R12
+ MOVQ 32(DI), R10
+ ROLQ $0x0a, R12
+ MOVQ R11, AX
+ MOVQ 136(DI), R13
+ ANDQ R12, AX
+ XORQ R9, R10
+ MOVQ 184(DI), R14
+ ROLQ $0x1b, R10
+ XORQ R10, AX
+ MOVQ AX, 120(SP)
+ XORQ AX, SI
+ XORQ DX, R13
+ ROLQ $0x0f, R13
+ MOVQ R12, AX
+ ORQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 128(SP)
+ XORQ AX, BP
+ XORQ R8, R14
+ ROLQ $0x38, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ORQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 136(SP)
+ ORQ R10, R11
+ XORQ R14, R11
+ MOVQ R11, 152(SP)
+ ANDQ R10, R14
+ XORQ R13, R14
+ MOVQ R14, 144(SP)
+ XORQ R11, R15
+
+ // Result s
+ MOVQ 16(DI), R10
+ MOVQ 64(DI), R11
+ MOVQ 112(DI), R12
+ XORQ DX, R10
+ MOVQ 120(DI), R13
+ ROLQ $0x3e, R10
+ XORQ R8, R11
+ MOVQ 168(DI), R14
+ ROLQ $0x37, R11
+ XORQ R9, R12
+ MOVQ R10, R9
+ XORQ CX, R14
+ ROLQ $0x02, R14
+ ANDQ R11, R9
+ XORQ R14, R9
+ MOVQ R9, 192(SP)
+ ROLQ $0x27, R12
+ XORQ R9, R15
+ NOTQ R11
+ XORQ BX, R13
+ MOVQ R11, BX
+ ANDQ R12, BX
+ XORQ R10, BX
+ MOVQ BX, 160(SP)
+ XORQ BX, SI
+ ROLQ $0x29, R13
+ MOVQ R12, CX
+ ORQ R13, CX
+ XORQ R11, CX
+ MOVQ CX, 168(SP)
+ XORQ CX, BP
+ MOVQ R13, DX
+ MOVQ R14, R8
+ ANDQ R14, DX
+ ORQ R10, R8
+ XORQ R12, DX
+ XORQ R13, R8
+ MOVQ DX, 176(SP)
+ MOVQ R8, 184(SP)
+
+ // Prepare round
+ MOVQ BP, BX
+ ROLQ $0x01, BX
+ MOVQ 16(SP), R12
+ XORQ 56(SP), DX
+ XORQ R15, BX
+ XORQ 96(SP), R12
+ XORQ 136(SP), DX
+ XORQ DX, R12
+ MOVQ R12, CX
+ ROLQ $0x01, CX
+ MOVQ 24(SP), R13
+ XORQ 64(SP), R8
+ XORQ SI, CX
+ XORQ 104(SP), R13
+ XORQ 144(SP), R8
+ XORQ R8, R13
+ MOVQ R13, DX
+ ROLQ $0x01, DX
+ MOVQ R15, R8
+ XORQ BP, DX
+ ROLQ $0x01, R8
+ MOVQ SI, R9
+ XORQ R12, R8
+ ROLQ $0x01, R9
+
+ // Result b
+ MOVQ (SP), R10
+ MOVQ 48(SP), R11
+ XORQ R13, R9
+ MOVQ 96(SP), R12
+ MOVQ 144(SP), R13
+ MOVQ 192(SP), R14
+ XORQ CX, R11
+ ROLQ $0x2c, R11
+ XORQ DX, R12
+ XORQ BX, R10
+ ROLQ $0x2b, R12
+ MOVQ R11, SI
+ MOVQ $0x800000000000008b, AX
+ ORQ R12, SI
+ XORQ R10, AX
+ XORQ AX, SI
+ MOVQ SI, (DI)
+ XORQ R9, R14
+ ROLQ $0x0e, R14
+ MOVQ R10, R15
+ ANDQ R11, R15
+ XORQ R14, R15
+ MOVQ R15, 32(DI)
+ XORQ R8, R13
+ ROLQ $0x15, R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 16(DI)
+ NOTQ R12
+ ORQ R10, R14
+ ORQ R13, R12
+ XORQ R13, R14
+ XORQ R11, R12
+ MOVQ R14, 24(DI)
+ MOVQ R12, 8(DI)
+ MOVQ R12, BP
+
+ // Result g
+ MOVQ 72(SP), R11
+ XORQ R9, R11
+ MOVQ 80(SP), R12
+ ROLQ $0x14, R11
+ XORQ BX, R12
+ ROLQ $0x03, R12
+ MOVQ 24(SP), R10
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ R8, R10
+ MOVQ 128(SP), R13
+ MOVQ 176(SP), R14
+ ROLQ $0x1c, R10
+ XORQ R10, AX
+ MOVQ AX, 40(DI)
+ XORQ AX, SI
+ XORQ CX, R13
+ ROLQ $0x2d, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 48(DI)
+ XORQ AX, BP
+ XORQ DX, R14
+ ROLQ $0x3d, R14
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 64(DI)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 72(DI)
+ NOTQ R14
+ XORQ R10, R15
+ ORQ R14, R13
+ XORQ R12, R13
+ MOVQ R13, 56(DI)
+
+ // Result k
+ MOVQ 8(SP), R10
+ MOVQ 56(SP), R11
+ MOVQ 104(SP), R12
+ MOVQ 152(SP), R13
+ MOVQ 160(SP), R14
+ XORQ DX, R11
+ ROLQ $0x06, R11
+ XORQ R8, R12
+ ROLQ $0x19, R12
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ CX, R10
+ ROLQ $0x01, R10
+ XORQ R10, AX
+ MOVQ AX, 80(DI)
+ XORQ AX, SI
+ XORQ R9, R13
+ ROLQ $0x08, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 88(DI)
+ XORQ AX, BP
+ XORQ BX, R14
+ ROLQ $0x12, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 96(DI)
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 104(DI)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 112(DI)
+ XORQ R10, R15
+
+ // Result m
+ MOVQ 40(SP), R11
+ XORQ BX, R11
+ MOVQ 88(SP), R12
+ ROLQ $0x24, R11
+ XORQ CX, R12
+ MOVQ 32(SP), R10
+ ROLQ $0x0a, R12
+ MOVQ R11, AX
+ MOVQ 136(SP), R13
+ ANDQ R12, AX
+ XORQ R9, R10
+ MOVQ 184(SP), R14
+ ROLQ $0x1b, R10
+ XORQ R10, AX
+ MOVQ AX, 120(DI)
+ XORQ AX, SI
+ XORQ DX, R13
+ ROLQ $0x0f, R13
+ MOVQ R12, AX
+ ORQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 128(DI)
+ XORQ AX, BP
+ XORQ R8, R14
+ ROLQ $0x38, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ORQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 136(DI)
+ ORQ R10, R11
+ XORQ R14, R11
+ MOVQ R11, 152(DI)
+ ANDQ R10, R14
+ XORQ R13, R14
+ MOVQ R14, 144(DI)
+ XORQ R11, R15
+
+ // Result s
+ MOVQ 16(SP), R10
+ MOVQ 64(SP), R11
+ MOVQ 112(SP), R12
+ XORQ DX, R10
+ MOVQ 120(SP), R13
+ ROLQ $0x3e, R10
+ XORQ R8, R11
+ MOVQ 168(SP), R14
+ ROLQ $0x37, R11
+ XORQ R9, R12
+ MOVQ R10, R9
+ XORQ CX, R14
+ ROLQ $0x02, R14
+ ANDQ R11, R9
+ XORQ R14, R9
+ MOVQ R9, 192(DI)
+ ROLQ $0x27, R12
+ XORQ R9, R15
+ NOTQ R11
+ XORQ BX, R13
+ MOVQ R11, BX
+ ANDQ R12, BX
+ XORQ R10, BX
+ MOVQ BX, 160(DI)
+ XORQ BX, SI
+ ROLQ $0x29, R13
+ MOVQ R12, CX
+ ORQ R13, CX
+ XORQ R11, CX
+ MOVQ CX, 168(DI)
+ XORQ CX, BP
+ MOVQ R13, DX
+ MOVQ R14, R8
+ ANDQ R14, DX
+ ORQ R10, R8
+ XORQ R12, DX
+ XORQ R13, R8
+ MOVQ DX, 176(DI)
+ MOVQ R8, 184(DI)
+
+ // Prepare round
+ MOVQ BP, BX
+ ROLQ $0x01, BX
+ MOVQ 16(DI), R12
+ XORQ 56(DI), DX
+ XORQ R15, BX
+ XORQ 96(DI), R12
+ XORQ 136(DI), DX
+ XORQ DX, R12
+ MOVQ R12, CX
+ ROLQ $0x01, CX
+ MOVQ 24(DI), R13
+ XORQ 64(DI), R8
+ XORQ SI, CX
+ XORQ 104(DI), R13
+ XORQ 144(DI), R8
+ XORQ R8, R13
+ MOVQ R13, DX
+ ROLQ $0x01, DX
+ MOVQ R15, R8
+ XORQ BP, DX
+ ROLQ $0x01, R8
+ MOVQ SI, R9
+ XORQ R12, R8
+ ROLQ $0x01, R9
+
+ // Result b
+ MOVQ (DI), R10
+ MOVQ 48(DI), R11
+ XORQ R13, R9
+ MOVQ 96(DI), R12
+ MOVQ 144(DI), R13
+ MOVQ 192(DI), R14
+ XORQ CX, R11
+ ROLQ $0x2c, R11
+ XORQ DX, R12
+ XORQ BX, R10
+ ROLQ $0x2b, R12
+ MOVQ R11, SI
+ MOVQ $0x8000000000008089, AX
+ ORQ R12, SI
+ XORQ R10, AX
+ XORQ AX, SI
+ MOVQ SI, (SP)
+ XORQ R9, R14
+ ROLQ $0x0e, R14
+ MOVQ R10, R15
+ ANDQ R11, R15
+ XORQ R14, R15
+ MOVQ R15, 32(SP)
+ XORQ R8, R13
+ ROLQ $0x15, R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 16(SP)
+ NOTQ R12
+ ORQ R10, R14
+ ORQ R13, R12
+ XORQ R13, R14
+ XORQ R11, R12
+ MOVQ R14, 24(SP)
+ MOVQ R12, 8(SP)
+ MOVQ R12, BP
+
+ // Result g
+ MOVQ 72(DI), R11
+ XORQ R9, R11
+ MOVQ 80(DI), R12
+ ROLQ $0x14, R11
+ XORQ BX, R12
+ ROLQ $0x03, R12
+ MOVQ 24(DI), R10
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ R8, R10
+ MOVQ 128(DI), R13
+ MOVQ 176(DI), R14
+ ROLQ $0x1c, R10
+ XORQ R10, AX
+ MOVQ AX, 40(SP)
+ XORQ AX, SI
+ XORQ CX, R13
+ ROLQ $0x2d, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 48(SP)
+ XORQ AX, BP
+ XORQ DX, R14
+ ROLQ $0x3d, R14
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 64(SP)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 72(SP)
+ NOTQ R14
+ XORQ R10, R15
+ ORQ R14, R13
+ XORQ R12, R13
+ MOVQ R13, 56(SP)
+
+ // Result k
+ MOVQ 8(DI), R10
+ MOVQ 56(DI), R11
+ MOVQ 104(DI), R12
+ MOVQ 152(DI), R13
+ MOVQ 160(DI), R14
+ XORQ DX, R11
+ ROLQ $0x06, R11
+ XORQ R8, R12
+ ROLQ $0x19, R12
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ CX, R10
+ ROLQ $0x01, R10
+ XORQ R10, AX
+ MOVQ AX, 80(SP)
+ XORQ AX, SI
+ XORQ R9, R13
+ ROLQ $0x08, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 88(SP)
+ XORQ AX, BP
+ XORQ BX, R14
+ ROLQ $0x12, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 96(SP)
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 104(SP)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 112(SP)
+ XORQ R10, R15
+
+ // Result m
+ MOVQ 40(DI), R11
+ XORQ BX, R11
+ MOVQ 88(DI), R12
+ ROLQ $0x24, R11
+ XORQ CX, R12
+ MOVQ 32(DI), R10
+ ROLQ $0x0a, R12
+ MOVQ R11, AX
+ MOVQ 136(DI), R13
+ ANDQ R12, AX
+ XORQ R9, R10
+ MOVQ 184(DI), R14
+ ROLQ $0x1b, R10
+ XORQ R10, AX
+ MOVQ AX, 120(SP)
+ XORQ AX, SI
+ XORQ DX, R13
+ ROLQ $0x0f, R13
+ MOVQ R12, AX
+ ORQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 128(SP)
+ XORQ AX, BP
+ XORQ R8, R14
+ ROLQ $0x38, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ORQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 136(SP)
+ ORQ R10, R11
+ XORQ R14, R11
+ MOVQ R11, 152(SP)
+ ANDQ R10, R14
+ XORQ R13, R14
+ MOVQ R14, 144(SP)
+ XORQ R11, R15
+
+ // Result s
+ MOVQ 16(DI), R10
+ MOVQ 64(DI), R11
+ MOVQ 112(DI), R12
+ XORQ DX, R10
+ MOVQ 120(DI), R13
+ ROLQ $0x3e, R10
+ XORQ R8, R11
+ MOVQ 168(DI), R14
+ ROLQ $0x37, R11
+ XORQ R9, R12
+ MOVQ R10, R9
+ XORQ CX, R14
+ ROLQ $0x02, R14
+ ANDQ R11, R9
+ XORQ R14, R9
+ MOVQ R9, 192(SP)
+ ROLQ $0x27, R12
+ XORQ R9, R15
+ NOTQ R11
+ XORQ BX, R13
+ MOVQ R11, BX
+ ANDQ R12, BX
+ XORQ R10, BX
+ MOVQ BX, 160(SP)
+ XORQ BX, SI
+ ROLQ $0x29, R13
+ MOVQ R12, CX
+ ORQ R13, CX
+ XORQ R11, CX
+ MOVQ CX, 168(SP)
+ XORQ CX, BP
+ MOVQ R13, DX
+ MOVQ R14, R8
+ ANDQ R14, DX
+ ORQ R10, R8
+ XORQ R12, DX
+ XORQ R13, R8
+ MOVQ DX, 176(SP)
+ MOVQ R8, 184(SP)
+
+ // Prepare round
+ MOVQ BP, BX
+ ROLQ $0x01, BX
+ MOVQ 16(SP), R12
+ XORQ 56(SP), DX
+ XORQ R15, BX
+ XORQ 96(SP), R12
+ XORQ 136(SP), DX
+ XORQ DX, R12
+ MOVQ R12, CX
+ ROLQ $0x01, CX
+ MOVQ 24(SP), R13
+ XORQ 64(SP), R8
+ XORQ SI, CX
+ XORQ 104(SP), R13
+ XORQ 144(SP), R8
+ XORQ R8, R13
+ MOVQ R13, DX
+ ROLQ $0x01, DX
+ MOVQ R15, R8
+ XORQ BP, DX
+ ROLQ $0x01, R8
+ MOVQ SI, R9
+ XORQ R12, R8
+ ROLQ $0x01, R9
+
+ // Result b
+ MOVQ (SP), R10
+ MOVQ 48(SP), R11
+ XORQ R13, R9
+ MOVQ 96(SP), R12
+ MOVQ 144(SP), R13
+ MOVQ 192(SP), R14
+ XORQ CX, R11
+ ROLQ $0x2c, R11
+ XORQ DX, R12
+ XORQ BX, R10
+ ROLQ $0x2b, R12
+ MOVQ R11, SI
+ MOVQ $0x8000000000008003, AX
+ ORQ R12, SI
+ XORQ R10, AX
+ XORQ AX, SI
+ MOVQ SI, (DI)
+ XORQ R9, R14
+ ROLQ $0x0e, R14
+ MOVQ R10, R15
+ ANDQ R11, R15
+ XORQ R14, R15
+ MOVQ R15, 32(DI)
+ XORQ R8, R13
+ ROLQ $0x15, R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 16(DI)
+ NOTQ R12
+ ORQ R10, R14
+ ORQ R13, R12
+ XORQ R13, R14
+ XORQ R11, R12
+ MOVQ R14, 24(DI)
+ MOVQ R12, 8(DI)
+ MOVQ R12, BP
+
+ // Result g
+ MOVQ 72(SP), R11
+ XORQ R9, R11
+ MOVQ 80(SP), R12
+ ROLQ $0x14, R11
+ XORQ BX, R12
+ ROLQ $0x03, R12
+ MOVQ 24(SP), R10
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ R8, R10
+ MOVQ 128(SP), R13
+ MOVQ 176(SP), R14
+ ROLQ $0x1c, R10
+ XORQ R10, AX
+ MOVQ AX, 40(DI)
+ XORQ AX, SI
+ XORQ CX, R13
+ ROLQ $0x2d, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 48(DI)
+ XORQ AX, BP
+ XORQ DX, R14
+ ROLQ $0x3d, R14
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 64(DI)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 72(DI)
+ NOTQ R14
+ XORQ R10, R15
+ ORQ R14, R13
+ XORQ R12, R13
+ MOVQ R13, 56(DI)
+
+ // Result k
+ MOVQ 8(SP), R10
+ MOVQ 56(SP), R11
+ MOVQ 104(SP), R12
+ MOVQ 152(SP), R13
+ MOVQ 160(SP), R14
+ XORQ DX, R11
+ ROLQ $0x06, R11
+ XORQ R8, R12
+ ROLQ $0x19, R12
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ CX, R10
+ ROLQ $0x01, R10
+ XORQ R10, AX
+ MOVQ AX, 80(DI)
+ XORQ AX, SI
+ XORQ R9, R13
+ ROLQ $0x08, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 88(DI)
+ XORQ AX, BP
+ XORQ BX, R14
+ ROLQ $0x12, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 96(DI)
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 104(DI)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 112(DI)
+ XORQ R10, R15
+
+ // Result m
+ MOVQ 40(SP), R11
+ XORQ BX, R11
+ MOVQ 88(SP), R12
+ ROLQ $0x24, R11
+ XORQ CX, R12
+ MOVQ 32(SP), R10
+ ROLQ $0x0a, R12
+ MOVQ R11, AX
+ MOVQ 136(SP), R13
+ ANDQ R12, AX
+ XORQ R9, R10
+ MOVQ 184(SP), R14
+ ROLQ $0x1b, R10
+ XORQ R10, AX
+ MOVQ AX, 120(DI)
+ XORQ AX, SI
+ XORQ DX, R13
+ ROLQ $0x0f, R13
+ MOVQ R12, AX
+ ORQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 128(DI)
+ XORQ AX, BP
+ XORQ R8, R14
+ ROLQ $0x38, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ORQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 136(DI)
+ ORQ R10, R11
+ XORQ R14, R11
+ MOVQ R11, 152(DI)
+ ANDQ R10, R14
+ XORQ R13, R14
+ MOVQ R14, 144(DI)
+ XORQ R11, R15
+
+ // Result s
+ MOVQ 16(SP), R10
+ MOVQ 64(SP), R11
+ MOVQ 112(SP), R12
+ XORQ DX, R10
+ MOVQ 120(SP), R13
+ ROLQ $0x3e, R10
+ XORQ R8, R11
+ MOVQ 168(SP), R14
+ ROLQ $0x37, R11
+ XORQ R9, R12
+ MOVQ R10, R9
+ XORQ CX, R14
+ ROLQ $0x02, R14
+ ANDQ R11, R9
+ XORQ R14, R9
+ MOVQ R9, 192(DI)
+ ROLQ $0x27, R12
+ XORQ R9, R15
+ NOTQ R11
+ XORQ BX, R13
+ MOVQ R11, BX
+ ANDQ R12, BX
+ XORQ R10, BX
+ MOVQ BX, 160(DI)
+ XORQ BX, SI
+ ROLQ $0x29, R13
+ MOVQ R12, CX
+ ORQ R13, CX
+ XORQ R11, CX
+ MOVQ CX, 168(DI)
+ XORQ CX, BP
+ MOVQ R13, DX
+ MOVQ R14, R8
+ ANDQ R14, DX
+ ORQ R10, R8
+ XORQ R12, DX
+ XORQ R13, R8
+ MOVQ DX, 176(DI)
+ MOVQ R8, 184(DI)
+
+ // Prepare round
+ MOVQ BP, BX
+ ROLQ $0x01, BX
+ MOVQ 16(DI), R12
+ XORQ 56(DI), DX
+ XORQ R15, BX
+ XORQ 96(DI), R12
+ XORQ 136(DI), DX
+ XORQ DX, R12
+ MOVQ R12, CX
+ ROLQ $0x01, CX
+ MOVQ 24(DI), R13
+ XORQ 64(DI), R8
+ XORQ SI, CX
+ XORQ 104(DI), R13
+ XORQ 144(DI), R8
+ XORQ R8, R13
+ MOVQ R13, DX
+ ROLQ $0x01, DX
+ MOVQ R15, R8
+ XORQ BP, DX
+ ROLQ $0x01, R8
+ MOVQ SI, R9
+ XORQ R12, R8
+ ROLQ $0x01, R9
+
+ // Result b
+ MOVQ (DI), R10
+ MOVQ 48(DI), R11
+ XORQ R13, R9
+ MOVQ 96(DI), R12
+ MOVQ 144(DI), R13
+ MOVQ 192(DI), R14
+ XORQ CX, R11
+ ROLQ $0x2c, R11
+ XORQ DX, R12
+ XORQ BX, R10
+ ROLQ $0x2b, R12
+ MOVQ R11, SI
+ MOVQ $0x8000000000008002, AX
+ ORQ R12, SI
+ XORQ R10, AX
+ XORQ AX, SI
+ MOVQ SI, (SP)
+ XORQ R9, R14
+ ROLQ $0x0e, R14
+ MOVQ R10, R15
+ ANDQ R11, R15
+ XORQ R14, R15
+ MOVQ R15, 32(SP)
+ XORQ R8, R13
+ ROLQ $0x15, R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 16(SP)
+ NOTQ R12
+ ORQ R10, R14
+ ORQ R13, R12
+ XORQ R13, R14
+ XORQ R11, R12
+ MOVQ R14, 24(SP)
+ MOVQ R12, 8(SP)
+ MOVQ R12, BP
+
+ // Result g
+ MOVQ 72(DI), R11
+ XORQ R9, R11
+ MOVQ 80(DI), R12
+ ROLQ $0x14, R11
+ XORQ BX, R12
+ ROLQ $0x03, R12
+ MOVQ 24(DI), R10
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ R8, R10
+ MOVQ 128(DI), R13
+ MOVQ 176(DI), R14
+ ROLQ $0x1c, R10
+ XORQ R10, AX
+ MOVQ AX, 40(SP)
+ XORQ AX, SI
+ XORQ CX, R13
+ ROLQ $0x2d, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 48(SP)
+ XORQ AX, BP
+ XORQ DX, R14
+ ROLQ $0x3d, R14
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 64(SP)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 72(SP)
+ NOTQ R14
+ XORQ R10, R15
+ ORQ R14, R13
+ XORQ R12, R13
+ MOVQ R13, 56(SP)
+
+ // Result k
+ MOVQ 8(DI), R10
+ MOVQ 56(DI), R11
+ MOVQ 104(DI), R12
+ MOVQ 152(DI), R13
+ MOVQ 160(DI), R14
+ XORQ DX, R11
+ ROLQ $0x06, R11
+ XORQ R8, R12
+ ROLQ $0x19, R12
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ CX, R10
+ ROLQ $0x01, R10
+ XORQ R10, AX
+ MOVQ AX, 80(SP)
+ XORQ AX, SI
+ XORQ R9, R13
+ ROLQ $0x08, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 88(SP)
+ XORQ AX, BP
+ XORQ BX, R14
+ ROLQ $0x12, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 96(SP)
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 104(SP)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 112(SP)
+ XORQ R10, R15
+
+ // Result m
+ MOVQ 40(DI), R11
+ XORQ BX, R11
+ MOVQ 88(DI), R12
+ ROLQ $0x24, R11
+ XORQ CX, R12
+ MOVQ 32(DI), R10
+ ROLQ $0x0a, R12
+ MOVQ R11, AX
+ MOVQ 136(DI), R13
+ ANDQ R12, AX
+ XORQ R9, R10
+ MOVQ 184(DI), R14
+ ROLQ $0x1b, R10
+ XORQ R10, AX
+ MOVQ AX, 120(SP)
+ XORQ AX, SI
+ XORQ DX, R13
+ ROLQ $0x0f, R13
+ MOVQ R12, AX
+ ORQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 128(SP)
+ XORQ AX, BP
+ XORQ R8, R14
+ ROLQ $0x38, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ORQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 136(SP)
+ ORQ R10, R11
+ XORQ R14, R11
+ MOVQ R11, 152(SP)
+ ANDQ R10, R14
+ XORQ R13, R14
+ MOVQ R14, 144(SP)
+ XORQ R11, R15
+
+ // Result s
+ MOVQ 16(DI), R10
+ MOVQ 64(DI), R11
+ MOVQ 112(DI), R12
+ XORQ DX, R10
+ MOVQ 120(DI), R13
+ ROLQ $0x3e, R10
+ XORQ R8, R11
+ MOVQ 168(DI), R14
+ ROLQ $0x37, R11
+ XORQ R9, R12
+ MOVQ R10, R9
+ XORQ CX, R14
+ ROLQ $0x02, R14
+ ANDQ R11, R9
+ XORQ R14, R9
+ MOVQ R9, 192(SP)
+ ROLQ $0x27, R12
+ XORQ R9, R15
+ NOTQ R11
+ XORQ BX, R13
+ MOVQ R11, BX
+ ANDQ R12, BX
+ XORQ R10, BX
+ MOVQ BX, 160(SP)
+ XORQ BX, SI
+ ROLQ $0x29, R13
+ MOVQ R12, CX
+ ORQ R13, CX
+ XORQ R11, CX
+ MOVQ CX, 168(SP)
+ XORQ CX, BP
+ MOVQ R13, DX
+ MOVQ R14, R8
+ ANDQ R14, DX
+ ORQ R10, R8
+ XORQ R12, DX
+ XORQ R13, R8
+ MOVQ DX, 176(SP)
+ MOVQ R8, 184(SP)
+
+ // Prepare round
+ MOVQ BP, BX
+ ROLQ $0x01, BX
+ MOVQ 16(SP), R12
+ XORQ 56(SP), DX
+ XORQ R15, BX
+ XORQ 96(SP), R12
+ XORQ 136(SP), DX
+ XORQ DX, R12
+ MOVQ R12, CX
+ ROLQ $0x01, CX
+ MOVQ 24(SP), R13
+ XORQ 64(SP), R8
+ XORQ SI, CX
+ XORQ 104(SP), R13
+ XORQ 144(SP), R8
+ XORQ R8, R13
+ MOVQ R13, DX
+ ROLQ $0x01, DX
+ MOVQ R15, R8
+ XORQ BP, DX
+ ROLQ $0x01, R8
+ MOVQ SI, R9
+ XORQ R12, R8
+ ROLQ $0x01, R9
+
+ // Result b
+ MOVQ (SP), R10
+ MOVQ 48(SP), R11
+ XORQ R13, R9
+ MOVQ 96(SP), R12
+ MOVQ 144(SP), R13
+ MOVQ 192(SP), R14
+ XORQ CX, R11
+ ROLQ $0x2c, R11
+ XORQ DX, R12
+ XORQ BX, R10
+ ROLQ $0x2b, R12
+ MOVQ R11, SI
+ MOVQ $0x8000000000000080, AX
+ ORQ R12, SI
+ XORQ R10, AX
+ XORQ AX, SI
+ MOVQ SI, (DI)
+ XORQ R9, R14
+ ROLQ $0x0e, R14
+ MOVQ R10, R15
+ ANDQ R11, R15
+ XORQ R14, R15
+ MOVQ R15, 32(DI)
+ XORQ R8, R13
+ ROLQ $0x15, R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 16(DI)
+ NOTQ R12
+ ORQ R10, R14
+ ORQ R13, R12
+ XORQ R13, R14
+ XORQ R11, R12
+ MOVQ R14, 24(DI)
+ MOVQ R12, 8(DI)
+ MOVQ R12, BP
+
+ // Result g
+ MOVQ 72(SP), R11
+ XORQ R9, R11
+ MOVQ 80(SP), R12
+ ROLQ $0x14, R11
+ XORQ BX, R12
+ ROLQ $0x03, R12
+ MOVQ 24(SP), R10
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ R8, R10
+ MOVQ 128(SP), R13
+ MOVQ 176(SP), R14
+ ROLQ $0x1c, R10
+ XORQ R10, AX
+ MOVQ AX, 40(DI)
+ XORQ AX, SI
+ XORQ CX, R13
+ ROLQ $0x2d, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 48(DI)
+ XORQ AX, BP
+ XORQ DX, R14
+ ROLQ $0x3d, R14
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 64(DI)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 72(DI)
+ NOTQ R14
+ XORQ R10, R15
+ ORQ R14, R13
+ XORQ R12, R13
+ MOVQ R13, 56(DI)
+
+ // Result k
+ MOVQ 8(SP), R10
+ MOVQ 56(SP), R11
+ MOVQ 104(SP), R12
+ MOVQ 152(SP), R13
+ MOVQ 160(SP), R14
+ XORQ DX, R11
+ ROLQ $0x06, R11
+ XORQ R8, R12
+ ROLQ $0x19, R12
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ CX, R10
+ ROLQ $0x01, R10
+ XORQ R10, AX
+ MOVQ AX, 80(DI)
+ XORQ AX, SI
+ XORQ R9, R13
+ ROLQ $0x08, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 88(DI)
+ XORQ AX, BP
+ XORQ BX, R14
+ ROLQ $0x12, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 96(DI)
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 104(DI)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 112(DI)
+ XORQ R10, R15
+
+ // Result m
+ MOVQ 40(SP), R11
+ XORQ BX, R11
+ MOVQ 88(SP), R12
+ ROLQ $0x24, R11
+ XORQ CX, R12
+ MOVQ 32(SP), R10
+ ROLQ $0x0a, R12
+ MOVQ R11, AX
+ MOVQ 136(SP), R13
+ ANDQ R12, AX
+ XORQ R9, R10
+ MOVQ 184(SP), R14
+ ROLQ $0x1b, R10
+ XORQ R10, AX
+ MOVQ AX, 120(DI)
+ XORQ AX, SI
+ XORQ DX, R13
+ ROLQ $0x0f, R13
+ MOVQ R12, AX
+ ORQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 128(DI)
+ XORQ AX, BP
+ XORQ R8, R14
+ ROLQ $0x38, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ORQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 136(DI)
+ ORQ R10, R11
+ XORQ R14, R11
+ MOVQ R11, 152(DI)
+ ANDQ R10, R14
+ XORQ R13, R14
+ MOVQ R14, 144(DI)
+ XORQ R11, R15
+
+ // Result s
+ MOVQ 16(SP), R10
+ MOVQ 64(SP), R11
+ MOVQ 112(SP), R12
+ XORQ DX, R10
+ MOVQ 120(SP), R13
+ ROLQ $0x3e, R10
+ XORQ R8, R11
+ MOVQ 168(SP), R14
+ ROLQ $0x37, R11
+ XORQ R9, R12
+ MOVQ R10, R9
+ XORQ CX, R14
+ ROLQ $0x02, R14
+ ANDQ R11, R9
+ XORQ R14, R9
+ MOVQ R9, 192(DI)
+ ROLQ $0x27, R12
+ XORQ R9, R15
+ NOTQ R11
+ XORQ BX, R13
+ MOVQ R11, BX
+ ANDQ R12, BX
+ XORQ R10, BX
+ MOVQ BX, 160(DI)
+ XORQ BX, SI
+ ROLQ $0x29, R13
+ MOVQ R12, CX
+ ORQ R13, CX
+ XORQ R11, CX
+ MOVQ CX, 168(DI)
+ XORQ CX, BP
+ MOVQ R13, DX
+ MOVQ R14, R8
+ ANDQ R14, DX
+ ORQ R10, R8
+ XORQ R12, DX
+ XORQ R13, R8
+ MOVQ DX, 176(DI)
+ MOVQ R8, 184(DI)
+
+ // Prepare round
+ MOVQ BP, BX
+ ROLQ $0x01, BX
+ MOVQ 16(DI), R12
+ XORQ 56(DI), DX
+ XORQ R15, BX
+ XORQ 96(DI), R12
+ XORQ 136(DI), DX
+ XORQ DX, R12
+ MOVQ R12, CX
+ ROLQ $0x01, CX
+ MOVQ 24(DI), R13
+ XORQ 64(DI), R8
+ XORQ SI, CX
+ XORQ 104(DI), R13
+ XORQ 144(DI), R8
+ XORQ R8, R13
+ MOVQ R13, DX
+ ROLQ $0x01, DX
+ MOVQ R15, R8
+ XORQ BP, DX
+ ROLQ $0x01, R8
+ MOVQ SI, R9
+ XORQ R12, R8
+ ROLQ $0x01, R9
+
+ // Result b
+ MOVQ (DI), R10
+ MOVQ 48(DI), R11
+ XORQ R13, R9
+ MOVQ 96(DI), R12
+ MOVQ 144(DI), R13
+ MOVQ 192(DI), R14
+ XORQ CX, R11
+ ROLQ $0x2c, R11
+ XORQ DX, R12
+ XORQ BX, R10
+ ROLQ $0x2b, R12
+ MOVQ R11, SI
+ MOVQ $0x000000000000800a, AX
+ ORQ R12, SI
+ XORQ R10, AX
+ XORQ AX, SI
+ MOVQ SI, (SP)
+ XORQ R9, R14
+ ROLQ $0x0e, R14
+ MOVQ R10, R15
+ ANDQ R11, R15
+ XORQ R14, R15
+ MOVQ R15, 32(SP)
+ XORQ R8, R13
+ ROLQ $0x15, R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 16(SP)
+ NOTQ R12
+ ORQ R10, R14
+ ORQ R13, R12
+ XORQ R13, R14
+ XORQ R11, R12
+ MOVQ R14, 24(SP)
+ MOVQ R12, 8(SP)
+ MOVQ R12, BP
+
+ // Result g
+ MOVQ 72(DI), R11
+ XORQ R9, R11
+ MOVQ 80(DI), R12
+ ROLQ $0x14, R11
+ XORQ BX, R12
+ ROLQ $0x03, R12
+ MOVQ 24(DI), R10
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ R8, R10
+ MOVQ 128(DI), R13
+ MOVQ 176(DI), R14
+ ROLQ $0x1c, R10
+ XORQ R10, AX
+ MOVQ AX, 40(SP)
+ XORQ AX, SI
+ XORQ CX, R13
+ ROLQ $0x2d, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 48(SP)
+ XORQ AX, BP
+ XORQ DX, R14
+ ROLQ $0x3d, R14
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 64(SP)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 72(SP)
+ NOTQ R14
+ XORQ R10, R15
+ ORQ R14, R13
+ XORQ R12, R13
+ MOVQ R13, 56(SP)
+
+ // Result k
+ MOVQ 8(DI), R10
+ MOVQ 56(DI), R11
+ MOVQ 104(DI), R12
+ MOVQ 152(DI), R13
+ MOVQ 160(DI), R14
+ XORQ DX, R11
+ ROLQ $0x06, R11
+ XORQ R8, R12
+ ROLQ $0x19, R12
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ CX, R10
+ ROLQ $0x01, R10
+ XORQ R10, AX
+ MOVQ AX, 80(SP)
+ XORQ AX, SI
+ XORQ R9, R13
+ ROLQ $0x08, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 88(SP)
+ XORQ AX, BP
+ XORQ BX, R14
+ ROLQ $0x12, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 96(SP)
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 104(SP)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 112(SP)
+ XORQ R10, R15
+
+ // Result m
+ MOVQ 40(DI), R11
+ XORQ BX, R11
+ MOVQ 88(DI), R12
+ ROLQ $0x24, R11
+ XORQ CX, R12
+ MOVQ 32(DI), R10
+ ROLQ $0x0a, R12
+ MOVQ R11, AX
+ MOVQ 136(DI), R13
+ ANDQ R12, AX
+ XORQ R9, R10
+ MOVQ 184(DI), R14
+ ROLQ $0x1b, R10
+ XORQ R10, AX
+ MOVQ AX, 120(SP)
+ XORQ AX, SI
+ XORQ DX, R13
+ ROLQ $0x0f, R13
+ MOVQ R12, AX
+ ORQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 128(SP)
+ XORQ AX, BP
+ XORQ R8, R14
+ ROLQ $0x38, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ORQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 136(SP)
+ ORQ R10, R11
+ XORQ R14, R11
+ MOVQ R11, 152(SP)
+ ANDQ R10, R14
+ XORQ R13, R14
+ MOVQ R14, 144(SP)
+ XORQ R11, R15
+
+ // Result s
+ MOVQ 16(DI), R10
+ MOVQ 64(DI), R11
+ MOVQ 112(DI), R12
+ XORQ DX, R10
+ MOVQ 120(DI), R13
+ ROLQ $0x3e, R10
+ XORQ R8, R11
+ MOVQ 168(DI), R14
+ ROLQ $0x37, R11
+ XORQ R9, R12
+ MOVQ R10, R9
+ XORQ CX, R14
+ ROLQ $0x02, R14
+ ANDQ R11, R9
+ XORQ R14, R9
+ MOVQ R9, 192(SP)
+ ROLQ $0x27, R12
+ XORQ R9, R15
+ NOTQ R11
+ XORQ BX, R13
+ MOVQ R11, BX
+ ANDQ R12, BX
+ XORQ R10, BX
+ MOVQ BX, 160(SP)
+ XORQ BX, SI
+ ROLQ $0x29, R13
+ MOVQ R12, CX
+ ORQ R13, CX
+ XORQ R11, CX
+ MOVQ CX, 168(SP)
+ XORQ CX, BP
+ MOVQ R13, DX
+ MOVQ R14, R8
+ ANDQ R14, DX
+ ORQ R10, R8
+ XORQ R12, DX
+ XORQ R13, R8
+ MOVQ DX, 176(SP)
+ MOVQ R8, 184(SP)
+
+ // Prepare round
+ MOVQ BP, BX
+ ROLQ $0x01, BX
+ MOVQ 16(SP), R12
+ XORQ 56(SP), DX
+ XORQ R15, BX
+ XORQ 96(SP), R12
+ XORQ 136(SP), DX
+ XORQ DX, R12
+ MOVQ R12, CX
+ ROLQ $0x01, CX
+ MOVQ 24(SP), R13
+ XORQ 64(SP), R8
+ XORQ SI, CX
+ XORQ 104(SP), R13
+ XORQ 144(SP), R8
+ XORQ R8, R13
+ MOVQ R13, DX
+ ROLQ $0x01, DX
+ MOVQ R15, R8
+ XORQ BP, DX
+ ROLQ $0x01, R8
+ MOVQ SI, R9
+ XORQ R12, R8
+ ROLQ $0x01, R9
+
+ // Result b
+ MOVQ (SP), R10
+ MOVQ 48(SP), R11
+ XORQ R13, R9
+ MOVQ 96(SP), R12
+ MOVQ 144(SP), R13
+ MOVQ 192(SP), R14
+ XORQ CX, R11
+ ROLQ $0x2c, R11
+ XORQ DX, R12
+ XORQ BX, R10
+ ROLQ $0x2b, R12
+ MOVQ R11, SI
+ MOVQ $0x800000008000000a, AX
+ ORQ R12, SI
+ XORQ R10, AX
+ XORQ AX, SI
+ MOVQ SI, (DI)
+ XORQ R9, R14
+ ROLQ $0x0e, R14
+ MOVQ R10, R15
+ ANDQ R11, R15
+ XORQ R14, R15
+ MOVQ R15, 32(DI)
+ XORQ R8, R13
+ ROLQ $0x15, R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 16(DI)
+ NOTQ R12
+ ORQ R10, R14
+ ORQ R13, R12
+ XORQ R13, R14
+ XORQ R11, R12
+ MOVQ R14, 24(DI)
+ MOVQ R12, 8(DI)
+ MOVQ R12, BP
+
+ // Result g
+ MOVQ 72(SP), R11
+ XORQ R9, R11
+ MOVQ 80(SP), R12
+ ROLQ $0x14, R11
+ XORQ BX, R12
+ ROLQ $0x03, R12
+ MOVQ 24(SP), R10
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ R8, R10
+ MOVQ 128(SP), R13
+ MOVQ 176(SP), R14
+ ROLQ $0x1c, R10
+ XORQ R10, AX
+ MOVQ AX, 40(DI)
+ XORQ AX, SI
+ XORQ CX, R13
+ ROLQ $0x2d, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 48(DI)
+ XORQ AX, BP
+ XORQ DX, R14
+ ROLQ $0x3d, R14
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 64(DI)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 72(DI)
+ NOTQ R14
+ XORQ R10, R15
+ ORQ R14, R13
+ XORQ R12, R13
+ MOVQ R13, 56(DI)
+
+ // Result k
+ MOVQ 8(SP), R10
+ MOVQ 56(SP), R11
+ MOVQ 104(SP), R12
+ MOVQ 152(SP), R13
+ MOVQ 160(SP), R14
+ XORQ DX, R11
+ ROLQ $0x06, R11
+ XORQ R8, R12
+ ROLQ $0x19, R12
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ CX, R10
+ ROLQ $0x01, R10
+ XORQ R10, AX
+ MOVQ AX, 80(DI)
+ XORQ AX, SI
+ XORQ R9, R13
+ ROLQ $0x08, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 88(DI)
+ XORQ AX, BP
+ XORQ BX, R14
+ ROLQ $0x12, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 96(DI)
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 104(DI)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 112(DI)
+ XORQ R10, R15
+
+ // Result m
+ MOVQ 40(SP), R11
+ XORQ BX, R11
+ MOVQ 88(SP), R12
+ ROLQ $0x24, R11
+ XORQ CX, R12
+ MOVQ 32(SP), R10
+ ROLQ $0x0a, R12
+ MOVQ R11, AX
+ MOVQ 136(SP), R13
+ ANDQ R12, AX
+ XORQ R9, R10
+ MOVQ 184(SP), R14
+ ROLQ $0x1b, R10
+ XORQ R10, AX
+ MOVQ AX, 120(DI)
+ XORQ AX, SI
+ XORQ DX, R13
+ ROLQ $0x0f, R13
+ MOVQ R12, AX
+ ORQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 128(DI)
+ XORQ AX, BP
+ XORQ R8, R14
+ ROLQ $0x38, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ORQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 136(DI)
+ ORQ R10, R11
+ XORQ R14, R11
+ MOVQ R11, 152(DI)
+ ANDQ R10, R14
+ XORQ R13, R14
+ MOVQ R14, 144(DI)
+ XORQ R11, R15
+
+ // Result s
+ MOVQ 16(SP), R10
+ MOVQ 64(SP), R11
+ MOVQ 112(SP), R12
+ XORQ DX, R10
+ MOVQ 120(SP), R13
+ ROLQ $0x3e, R10
+ XORQ R8, R11
+ MOVQ 168(SP), R14
+ ROLQ $0x37, R11
+ XORQ R9, R12
+ MOVQ R10, R9
+ XORQ CX, R14
+ ROLQ $0x02, R14
+ ANDQ R11, R9
+ XORQ R14, R9
+ MOVQ R9, 192(DI)
+ ROLQ $0x27, R12
+ XORQ R9, R15
+ NOTQ R11
+ XORQ BX, R13
+ MOVQ R11, BX
+ ANDQ R12, BX
+ XORQ R10, BX
+ MOVQ BX, 160(DI)
+ XORQ BX, SI
+ ROLQ $0x29, R13
+ MOVQ R12, CX
+ ORQ R13, CX
+ XORQ R11, CX
+ MOVQ CX, 168(DI)
+ XORQ CX, BP
+ MOVQ R13, DX
+ MOVQ R14, R8
+ ANDQ R14, DX
+ ORQ R10, R8
+ XORQ R12, DX
+ XORQ R13, R8
+ MOVQ DX, 176(DI)
+ MOVQ R8, 184(DI)
+
+ // Prepare round
+ MOVQ BP, BX
+ ROLQ $0x01, BX
+ MOVQ 16(DI), R12
+ XORQ 56(DI), DX
+ XORQ R15, BX
+ XORQ 96(DI), R12
+ XORQ 136(DI), DX
+ XORQ DX, R12
+ MOVQ R12, CX
+ ROLQ $0x01, CX
+ MOVQ 24(DI), R13
+ XORQ 64(DI), R8
+ XORQ SI, CX
+ XORQ 104(DI), R13
+ XORQ 144(DI), R8
+ XORQ R8, R13
+ MOVQ R13, DX
+ ROLQ $0x01, DX
+ MOVQ R15, R8
+ XORQ BP, DX
+ ROLQ $0x01, R8
+ MOVQ SI, R9
+ XORQ R12, R8
+ ROLQ $0x01, R9
+
+ // Result b
+ MOVQ (DI), R10
+ MOVQ 48(DI), R11
+ XORQ R13, R9
+ MOVQ 96(DI), R12
+ MOVQ 144(DI), R13
+ MOVQ 192(DI), R14
+ XORQ CX, R11
+ ROLQ $0x2c, R11
+ XORQ DX, R12
+ XORQ BX, R10
+ ROLQ $0x2b, R12
+ MOVQ R11, SI
+ MOVQ $0x8000000080008081, AX
+ ORQ R12, SI
+ XORQ R10, AX
+ XORQ AX, SI
+ MOVQ SI, (SP)
+ XORQ R9, R14
+ ROLQ $0x0e, R14
+ MOVQ R10, R15
+ ANDQ R11, R15
+ XORQ R14, R15
+ MOVQ R15, 32(SP)
+ XORQ R8, R13
+ ROLQ $0x15, R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 16(SP)
+ NOTQ R12
+ ORQ R10, R14
+ ORQ R13, R12
+ XORQ R13, R14
+ XORQ R11, R12
+ MOVQ R14, 24(SP)
+ MOVQ R12, 8(SP)
+ MOVQ R12, BP
+
+ // Result g
+ MOVQ 72(DI), R11
+ XORQ R9, R11
+ MOVQ 80(DI), R12
+ ROLQ $0x14, R11
+ XORQ BX, R12
+ ROLQ $0x03, R12
+ MOVQ 24(DI), R10
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ R8, R10
+ MOVQ 128(DI), R13
+ MOVQ 176(DI), R14
+ ROLQ $0x1c, R10
+ XORQ R10, AX
+ MOVQ AX, 40(SP)
+ XORQ AX, SI
+ XORQ CX, R13
+ ROLQ $0x2d, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 48(SP)
+ XORQ AX, BP
+ XORQ DX, R14
+ ROLQ $0x3d, R14
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 64(SP)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 72(SP)
+ NOTQ R14
+ XORQ R10, R15
+ ORQ R14, R13
+ XORQ R12, R13
+ MOVQ R13, 56(SP)
+
+ // Result k
+ MOVQ 8(DI), R10
+ MOVQ 56(DI), R11
+ MOVQ 104(DI), R12
+ MOVQ 152(DI), R13
+ MOVQ 160(DI), R14
+ XORQ DX, R11
+ ROLQ $0x06, R11
+ XORQ R8, R12
+ ROLQ $0x19, R12
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ CX, R10
+ ROLQ $0x01, R10
+ XORQ R10, AX
+ MOVQ AX, 80(SP)
+ XORQ AX, SI
+ XORQ R9, R13
+ ROLQ $0x08, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 88(SP)
+ XORQ AX, BP
+ XORQ BX, R14
+ ROLQ $0x12, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 96(SP)
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 104(SP)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 112(SP)
+ XORQ R10, R15
+
+ // Result m
+ MOVQ 40(DI), R11
+ XORQ BX, R11
+ MOVQ 88(DI), R12
+ ROLQ $0x24, R11
+ XORQ CX, R12
+ MOVQ 32(DI), R10
+ ROLQ $0x0a, R12
+ MOVQ R11, AX
+ MOVQ 136(DI), R13
+ ANDQ R12, AX
+ XORQ R9, R10
+ MOVQ 184(DI), R14
+ ROLQ $0x1b, R10
+ XORQ R10, AX
+ MOVQ AX, 120(SP)
+ XORQ AX, SI
+ XORQ DX, R13
+ ROLQ $0x0f, R13
+ MOVQ R12, AX
+ ORQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 128(SP)
+ XORQ AX, BP
+ XORQ R8, R14
+ ROLQ $0x38, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ORQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 136(SP)
+ ORQ R10, R11
+ XORQ R14, R11
+ MOVQ R11, 152(SP)
+ ANDQ R10, R14
+ XORQ R13, R14
+ MOVQ R14, 144(SP)
+ XORQ R11, R15
+
+ // Result s
+ MOVQ 16(DI), R10
+ MOVQ 64(DI), R11
+ MOVQ 112(DI), R12
+ XORQ DX, R10
+ MOVQ 120(DI), R13
+ ROLQ $0x3e, R10
+ XORQ R8, R11
+ MOVQ 168(DI), R14
+ ROLQ $0x37, R11
+ XORQ R9, R12
+ MOVQ R10, R9
+ XORQ CX, R14
+ ROLQ $0x02, R14
+ ANDQ R11, R9
+ XORQ R14, R9
+ MOVQ R9, 192(SP)
+ ROLQ $0x27, R12
+ XORQ R9, R15
+ NOTQ R11
+ XORQ BX, R13
+ MOVQ R11, BX
+ ANDQ R12, BX
+ XORQ R10, BX
+ MOVQ BX, 160(SP)
+ XORQ BX, SI
+ ROLQ $0x29, R13
+ MOVQ R12, CX
+ ORQ R13, CX
+ XORQ R11, CX
+ MOVQ CX, 168(SP)
+ XORQ CX, BP
+ MOVQ R13, DX
+ MOVQ R14, R8
+ ANDQ R14, DX
+ ORQ R10, R8
+ XORQ R12, DX
+ XORQ R13, R8
+ MOVQ DX, 176(SP)
+ MOVQ R8, 184(SP)
+
+ // Prepare round
+ MOVQ BP, BX
+ ROLQ $0x01, BX
+ MOVQ 16(SP), R12
+ XORQ 56(SP), DX
+ XORQ R15, BX
+ XORQ 96(SP), R12
+ XORQ 136(SP), DX
+ XORQ DX, R12
+ MOVQ R12, CX
+ ROLQ $0x01, CX
+ MOVQ 24(SP), R13
+ XORQ 64(SP), R8
+ XORQ SI, CX
+ XORQ 104(SP), R13
+ XORQ 144(SP), R8
+ XORQ R8, R13
+ MOVQ R13, DX
+ ROLQ $0x01, DX
+ MOVQ R15, R8
+ XORQ BP, DX
+ ROLQ $0x01, R8
+ MOVQ SI, R9
+ XORQ R12, R8
+ ROLQ $0x01, R9
+
+ // Result b
+ MOVQ (SP), R10
+ MOVQ 48(SP), R11
+ XORQ R13, R9
+ MOVQ 96(SP), R12
+ MOVQ 144(SP), R13
+ MOVQ 192(SP), R14
+ XORQ CX, R11
+ ROLQ $0x2c, R11
+ XORQ DX, R12
+ XORQ BX, R10
+ ROLQ $0x2b, R12
+ MOVQ R11, SI
+ MOVQ $0x8000000000008080, AX
+ ORQ R12, SI
+ XORQ R10, AX
+ XORQ AX, SI
+ MOVQ SI, (DI)
+ XORQ R9, R14
+ ROLQ $0x0e, R14
+ MOVQ R10, R15
+ ANDQ R11, R15
+ XORQ R14, R15
+ MOVQ R15, 32(DI)
+ XORQ R8, R13
+ ROLQ $0x15, R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 16(DI)
+ NOTQ R12
+ ORQ R10, R14
+ ORQ R13, R12
+ XORQ R13, R14
+ XORQ R11, R12
+ MOVQ R14, 24(DI)
+ MOVQ R12, 8(DI)
+ MOVQ R12, BP
+
+ // Result g
+ MOVQ 72(SP), R11
+ XORQ R9, R11
+ MOVQ 80(SP), R12
+ ROLQ $0x14, R11
+ XORQ BX, R12
+ ROLQ $0x03, R12
+ MOVQ 24(SP), R10
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ R8, R10
+ MOVQ 128(SP), R13
+ MOVQ 176(SP), R14
+ ROLQ $0x1c, R10
+ XORQ R10, AX
+ MOVQ AX, 40(DI)
+ XORQ AX, SI
+ XORQ CX, R13
+ ROLQ $0x2d, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 48(DI)
+ XORQ AX, BP
+ XORQ DX, R14
+ ROLQ $0x3d, R14
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 64(DI)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 72(DI)
+ NOTQ R14
+ XORQ R10, R15
+ ORQ R14, R13
+ XORQ R12, R13
+ MOVQ R13, 56(DI)
+
+ // Result k
+ MOVQ 8(SP), R10
+ MOVQ 56(SP), R11
+ MOVQ 104(SP), R12
+ MOVQ 152(SP), R13
+ MOVQ 160(SP), R14
+ XORQ DX, R11
+ ROLQ $0x06, R11
+ XORQ R8, R12
+ ROLQ $0x19, R12
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ CX, R10
+ ROLQ $0x01, R10
+ XORQ R10, AX
+ MOVQ AX, 80(DI)
+ XORQ AX, SI
+ XORQ R9, R13
+ ROLQ $0x08, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 88(DI)
+ XORQ AX, BP
+ XORQ BX, R14
+ ROLQ $0x12, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 96(DI)
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 104(DI)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 112(DI)
+ XORQ R10, R15
+
+ // Result m
+ MOVQ 40(SP), R11
+ XORQ BX, R11
+ MOVQ 88(SP), R12
+ ROLQ $0x24, R11
+ XORQ CX, R12
+ MOVQ 32(SP), R10
+ ROLQ $0x0a, R12
+ MOVQ R11, AX
+ MOVQ 136(SP), R13
+ ANDQ R12, AX
+ XORQ R9, R10
+ MOVQ 184(SP), R14
+ ROLQ $0x1b, R10
+ XORQ R10, AX
+ MOVQ AX, 120(DI)
+ XORQ AX, SI
+ XORQ DX, R13
+ ROLQ $0x0f, R13
+ MOVQ R12, AX
+ ORQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 128(DI)
+ XORQ AX, BP
+ XORQ R8, R14
+ ROLQ $0x38, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ORQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 136(DI)
+ ORQ R10, R11
+ XORQ R14, R11
+ MOVQ R11, 152(DI)
+ ANDQ R10, R14
+ XORQ R13, R14
+ MOVQ R14, 144(DI)
+ XORQ R11, R15
+
+ // Result s
+ MOVQ 16(SP), R10
+ MOVQ 64(SP), R11
+ MOVQ 112(SP), R12
+ XORQ DX, R10
+ MOVQ 120(SP), R13
+ ROLQ $0x3e, R10
+ XORQ R8, R11
+ MOVQ 168(SP), R14
+ ROLQ $0x37, R11
+ XORQ R9, R12
+ MOVQ R10, R9
+ XORQ CX, R14
+ ROLQ $0x02, R14
+ ANDQ R11, R9
+ XORQ R14, R9
+ MOVQ R9, 192(DI)
+ ROLQ $0x27, R12
+ XORQ R9, R15
+ NOTQ R11
+ XORQ BX, R13
+ MOVQ R11, BX
+ ANDQ R12, BX
+ XORQ R10, BX
+ MOVQ BX, 160(DI)
+ XORQ BX, SI
+ ROLQ $0x29, R13
+ MOVQ R12, CX
+ ORQ R13, CX
+ XORQ R11, CX
+ MOVQ CX, 168(DI)
+ XORQ CX, BP
+ MOVQ R13, DX
+ MOVQ R14, R8
+ ANDQ R14, DX
+ ORQ R10, R8
+ XORQ R12, DX
+ XORQ R13, R8
+ MOVQ DX, 176(DI)
+ MOVQ R8, 184(DI)
+
+ // Prepare round
+ MOVQ BP, BX
+ ROLQ $0x01, BX
+ MOVQ 16(DI), R12
+ XORQ 56(DI), DX
+ XORQ R15, BX
+ XORQ 96(DI), R12
+ XORQ 136(DI), DX
+ XORQ DX, R12
+ MOVQ R12, CX
+ ROLQ $0x01, CX
+ MOVQ 24(DI), R13
+ XORQ 64(DI), R8
+ XORQ SI, CX
+ XORQ 104(DI), R13
+ XORQ 144(DI), R8
+ XORQ R8, R13
+ MOVQ R13, DX
+ ROLQ $0x01, DX
+ MOVQ R15, R8
+ XORQ BP, DX
+ ROLQ $0x01, R8
+ MOVQ SI, R9
+ XORQ R12, R8
+ ROLQ $0x01, R9
+
+ // Result b
+ MOVQ (DI), R10
+ MOVQ 48(DI), R11
+ XORQ R13, R9
+ MOVQ 96(DI), R12
+ MOVQ 144(DI), R13
+ MOVQ 192(DI), R14
+ XORQ CX, R11
+ ROLQ $0x2c, R11
+ XORQ DX, R12
+ XORQ BX, R10
+ ROLQ $0x2b, R12
+ MOVQ R11, SI
+ MOVQ $0x0000000080000001, AX
+ ORQ R12, SI
+ XORQ R10, AX
+ XORQ AX, SI
+ MOVQ SI, (SP)
+ XORQ R9, R14
+ ROLQ $0x0e, R14
+ MOVQ R10, R15
+ ANDQ R11, R15
+ XORQ R14, R15
+ MOVQ R15, 32(SP)
+ XORQ R8, R13
+ ROLQ $0x15, R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 16(SP)
+ NOTQ R12
+ ORQ R10, R14
+ ORQ R13, R12
+ XORQ R13, R14
+ XORQ R11, R12
+ MOVQ R14, 24(SP)
+ MOVQ R12, 8(SP)
+ MOVQ R12, BP
+
+ // Result g
+ MOVQ 72(DI), R11
+ XORQ R9, R11
+ MOVQ 80(DI), R12
+ ROLQ $0x14, R11
+ XORQ BX, R12
+ ROLQ $0x03, R12
+ MOVQ 24(DI), R10
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ R8, R10
+ MOVQ 128(DI), R13
+ MOVQ 176(DI), R14
+ ROLQ $0x1c, R10
+ XORQ R10, AX
+ MOVQ AX, 40(SP)
+ XORQ AX, SI
+ XORQ CX, R13
+ ROLQ $0x2d, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 48(SP)
+ XORQ AX, BP
+ XORQ DX, R14
+ ROLQ $0x3d, R14
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 64(SP)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 72(SP)
+ NOTQ R14
+ XORQ R10, R15
+ ORQ R14, R13
+ XORQ R12, R13
+ MOVQ R13, 56(SP)
+
+ // Result k
+ MOVQ 8(DI), R10
+ MOVQ 56(DI), R11
+ MOVQ 104(DI), R12
+ MOVQ 152(DI), R13
+ MOVQ 160(DI), R14
+ XORQ DX, R11
+ ROLQ $0x06, R11
+ XORQ R8, R12
+ ROLQ $0x19, R12
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ CX, R10
+ ROLQ $0x01, R10
+ XORQ R10, AX
+ MOVQ AX, 80(SP)
+ XORQ AX, SI
+ XORQ R9, R13
+ ROLQ $0x08, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 88(SP)
+ XORQ AX, BP
+ XORQ BX, R14
+ ROLQ $0x12, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 96(SP)
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 104(SP)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 112(SP)
+ XORQ R10, R15
+
+ // Result m
+ MOVQ 40(DI), R11
+ XORQ BX, R11
+ MOVQ 88(DI), R12
+ ROLQ $0x24, R11
+ XORQ CX, R12
+ MOVQ 32(DI), R10
+ ROLQ $0x0a, R12
+ MOVQ R11, AX
+ MOVQ 136(DI), R13
+ ANDQ R12, AX
+ XORQ R9, R10
+ MOVQ 184(DI), R14
+ ROLQ $0x1b, R10
+ XORQ R10, AX
+ MOVQ AX, 120(SP)
+ XORQ AX, SI
+ XORQ DX, R13
+ ROLQ $0x0f, R13
+ MOVQ R12, AX
+ ORQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 128(SP)
+ XORQ AX, BP
+ XORQ R8, R14
+ ROLQ $0x38, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ORQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 136(SP)
+ ORQ R10, R11
+ XORQ R14, R11
+ MOVQ R11, 152(SP)
+ ANDQ R10, R14
+ XORQ R13, R14
+ MOVQ R14, 144(SP)
+ XORQ R11, R15
+
+ // Result s
+ MOVQ 16(DI), R10
+ MOVQ 64(DI), R11
+ MOVQ 112(DI), R12
+ XORQ DX, R10
+ MOVQ 120(DI), R13
+ ROLQ $0x3e, R10
+ XORQ R8, R11
+ MOVQ 168(DI), R14
+ ROLQ $0x37, R11
+ XORQ R9, R12
+ MOVQ R10, R9
+ XORQ CX, R14
+ ROLQ $0x02, R14
+ ANDQ R11, R9
+ XORQ R14, R9
+ MOVQ R9, 192(SP)
+ ROLQ $0x27, R12
+ XORQ R9, R15
+ NOTQ R11
+ XORQ BX, R13
+ MOVQ R11, BX
+ ANDQ R12, BX
+ XORQ R10, BX
+ MOVQ BX, 160(SP)
+ XORQ BX, SI
+ ROLQ $0x29, R13
+ MOVQ R12, CX
+ ORQ R13, CX
+ XORQ R11, CX
+ MOVQ CX, 168(SP)
+ XORQ CX, BP
+ MOVQ R13, DX
+ MOVQ R14, R8
+ ANDQ R14, DX
+ ORQ R10, R8
+ XORQ R12, DX
+ XORQ R13, R8
+ MOVQ DX, 176(SP)
+ MOVQ R8, 184(SP)
+
+ // Prepare round
+ MOVQ BP, BX
+ ROLQ $0x01, BX
+ MOVQ 16(SP), R12
+ XORQ 56(SP), DX
+ XORQ R15, BX
+ XORQ 96(SP), R12
+ XORQ 136(SP), DX
+ XORQ DX, R12
+ MOVQ R12, CX
+ ROLQ $0x01, CX
+ MOVQ 24(SP), R13
+ XORQ 64(SP), R8
+ XORQ SI, CX
+ XORQ 104(SP), R13
+ XORQ 144(SP), R8
+ XORQ R8, R13
+ MOVQ R13, DX
+ ROLQ $0x01, DX
+ MOVQ R15, R8
+ XORQ BP, DX
+ ROLQ $0x01, R8
+ MOVQ SI, R9
+ XORQ R12, R8
+ ROLQ $0x01, R9
+
+ // Result b
+ MOVQ (SP), R10
+ MOVQ 48(SP), R11
+ XORQ R13, R9
+ MOVQ 96(SP), R12
+ MOVQ 144(SP), R13
+ MOVQ 192(SP), R14
+ XORQ CX, R11
+ ROLQ $0x2c, R11
+ XORQ DX, R12
+ XORQ BX, R10
+ ROLQ $0x2b, R12
+ MOVQ R11, SI
+ MOVQ $0x8000000080008008, AX
+ ORQ R12, SI
+ XORQ R10, AX
+ XORQ AX, SI
+ MOVQ SI, (DI)
+ XORQ R9, R14
+ ROLQ $0x0e, R14
+ MOVQ R10, R15
+ ANDQ R11, R15
+ XORQ R14, R15
+ MOVQ R15, 32(DI)
+ XORQ R8, R13
+ ROLQ $0x15, R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 16(DI)
+ NOTQ R12
+ ORQ R10, R14
+ ORQ R13, R12
+ XORQ R13, R14
+ XORQ R11, R12
+ MOVQ R14, 24(DI)
+ MOVQ R12, 8(DI)
+ NOP
+
+ // Result g
+ MOVQ 72(SP), R11
+ XORQ R9, R11
+ MOVQ 80(SP), R12
+ ROLQ $0x14, R11
+ XORQ BX, R12
+ ROLQ $0x03, R12
+ MOVQ 24(SP), R10
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ R8, R10
+ MOVQ 128(SP), R13
+ MOVQ 176(SP), R14
+ ROLQ $0x1c, R10
+ XORQ R10, AX
+ MOVQ AX, 40(DI)
+ NOP
+ XORQ CX, R13
+ ROLQ $0x2d, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 48(DI)
+ NOP
+ XORQ DX, R14
+ ROLQ $0x3d, R14
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 64(DI)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 72(DI)
+ NOTQ R14
+ NOP
+ ORQ R14, R13
+ XORQ R12, R13
+ MOVQ R13, 56(DI)
+
+ // Result k
+ MOVQ 8(SP), R10
+ MOVQ 56(SP), R11
+ MOVQ 104(SP), R12
+ MOVQ 152(SP), R13
+ MOVQ 160(SP), R14
+ XORQ DX, R11
+ ROLQ $0x06, R11
+ XORQ R8, R12
+ ROLQ $0x19, R12
+ MOVQ R11, AX
+ ORQ R12, AX
+ XORQ CX, R10
+ ROLQ $0x01, R10
+ XORQ R10, AX
+ MOVQ AX, 80(DI)
+ NOP
+ XORQ R9, R13
+ ROLQ $0x08, R13
+ MOVQ R12, AX
+ ANDQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 88(DI)
+ NOP
+ XORQ BX, R14
+ ROLQ $0x12, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ANDQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 96(DI)
+ MOVQ R14, AX
+ ORQ R10, AX
+ XORQ R13, AX
+ MOVQ AX, 104(DI)
+ ANDQ R11, R10
+ XORQ R14, R10
+ MOVQ R10, 112(DI)
+ NOP
+
+ // Result m
+ MOVQ 40(SP), R11
+ XORQ BX, R11
+ MOVQ 88(SP), R12
+ ROLQ $0x24, R11
+ XORQ CX, R12
+ MOVQ 32(SP), R10
+ ROLQ $0x0a, R12
+ MOVQ R11, AX
+ MOVQ 136(SP), R13
+ ANDQ R12, AX
+ XORQ R9, R10
+ MOVQ 184(SP), R14
+ ROLQ $0x1b, R10
+ XORQ R10, AX
+ MOVQ AX, 120(DI)
+ NOP
+ XORQ DX, R13
+ ROLQ $0x0f, R13
+ MOVQ R12, AX
+ ORQ R13, AX
+ XORQ R11, AX
+ MOVQ AX, 128(DI)
+ NOP
+ XORQ R8, R14
+ ROLQ $0x38, R14
+ NOTQ R13
+ MOVQ R13, AX
+ ORQ R14, AX
+ XORQ R12, AX
+ MOVQ AX, 136(DI)
+ ORQ R10, R11
+ XORQ R14, R11
+ MOVQ R11, 152(DI)
+ ANDQ R10, R14
+ XORQ R13, R14
+ MOVQ R14, 144(DI)
+ NOP
+
+ // Result s
+ MOVQ 16(SP), R10
+ MOVQ 64(SP), R11
+ MOVQ 112(SP), R12
+ XORQ DX, R10
+ MOVQ 120(SP), R13
+ ROLQ $0x3e, R10
+ XORQ R8, R11
+ MOVQ 168(SP), R14
+ ROLQ $0x37, R11
+ XORQ R9, R12
+ MOVQ R10, R9
+ XORQ CX, R14
+ ROLQ $0x02, R14
+ ANDQ R11, R9
+ XORQ R14, R9
+ MOVQ R9, 192(DI)
+ ROLQ $0x27, R12
+ NOP
+ NOTQ R11
+ XORQ BX, R13
+ MOVQ R11, BX
+ ANDQ R12, BX
+ XORQ R10, BX
+ MOVQ BX, 160(DI)
+ NOP
+ ROLQ $0x29, R13
+ MOVQ R12, CX
+ ORQ R13, CX
+ XORQ R11, CX
+ MOVQ CX, 168(DI)
+ NOP
+ MOVQ R13, DX
+ MOVQ R14, R8
+ ANDQ R14, DX
+ ORQ R10, R8
+ XORQ R12, DX
+ XORQ R13, R8
+ MOVQ DX, 176(DI)
+ MOVQ R8, 184(DI)
+
+ // Revert the internal state to the user state
+ NOTQ 8(DI)
+ NOTQ 16(DI)
+ NOTQ 64(DI)
+ NOTQ 96(DI)
+ NOTQ 136(DI)
+ NOTQ 160(DI)
+ RET
diff --git a/vendor/golang.org/x/crypto/sha3/sha3.go b/vendor/golang.org/x/crypto/sha3/sha3.go
new file mode 100644
index 00000000..6658c444
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/sha3.go
@@ -0,0 +1,244 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha3
+
+import (
+ "crypto/subtle"
+ "encoding/binary"
+ "errors"
+ "unsafe"
+
+ "golang.org/x/sys/cpu"
+)
+
+// spongeDirection indicates the direction bytes are flowing through the sponge.
+type spongeDirection int
+
+const (
+ // spongeAbsorbing indicates that the sponge is absorbing input.
+ spongeAbsorbing spongeDirection = iota
+ // spongeSqueezing indicates that the sponge is being squeezed.
+ spongeSqueezing
+)
+
+type state struct {
+ a [1600 / 8]byte // main state of the hash
+
+ // a[n:rate] is the buffer. If absorbing, it's the remaining space to XOR
+ // into before running the permutation. If squeezing, it's the remaining
+ // output to produce before running the permutation.
+ n, rate int
+
+ // dsbyte contains the "domain separation" bits and the first bit of
+ // the padding. Sections 6.1 and 6.2 of [1] separate the outputs of the
+ // SHA-3 and SHAKE functions by appending bitstrings to the message.
+ // Using a little-endian bit-ordering convention, these are "01" for SHA-3
+ // and "1111" for SHAKE, or 00000010b and 00001111b, respectively. Then the
+ // padding rule from section 5.1 is applied to pad the message to a multiple
+ // of the rate, which involves adding a "1" bit, zero or more "0" bits, and
+ // a final "1" bit. We merge the first "1" bit from the padding into dsbyte,
+ // giving 00000110b (0x06) and 00011111b (0x1f).
+ // [1] http://csrc.nist.gov/publications/drafts/fips-202/fips_202_draft.pdf
+ // "Draft FIPS 202: SHA-3 Standard: Permutation-Based Hash and
+ // Extendable-Output Functions (May 2014)"
+ dsbyte byte
+
+ outputLen int // the default output size in bytes
+ state spongeDirection // whether the sponge is absorbing or squeezing
+}
+
+// BlockSize returns the rate of sponge underlying this hash function.
+func (d *state) BlockSize() int { return d.rate }
+
+// Size returns the output size of the hash function in bytes.
+func (d *state) Size() int { return d.outputLen }
+
+// Reset clears the internal state by zeroing the sponge state and
+// the buffer indexes, and setting Sponge.state to absorbing.
+func (d *state) Reset() {
+ // Zero the permutation's state.
+ for i := range d.a {
+ d.a[i] = 0
+ }
+ d.state = spongeAbsorbing
+ d.n = 0
+}
+
+func (d *state) clone() *state {
+ ret := *d
+ return &ret
+}
+
+// permute applies the KeccakF-1600 permutation.
+func (d *state) permute() {
+ var a *[25]uint64
+ if cpu.IsBigEndian {
+ a = new([25]uint64)
+ for i := range a {
+ a[i] = binary.LittleEndian.Uint64(d.a[i*8:])
+ }
+ } else {
+ a = (*[25]uint64)(unsafe.Pointer(&d.a))
+ }
+
+ keccakF1600(a)
+ d.n = 0
+
+ if cpu.IsBigEndian {
+ for i := range a {
+ binary.LittleEndian.PutUint64(d.a[i*8:], a[i])
+ }
+ }
+}
+
+// pads appends the domain separation bits in dsbyte, applies
+// the multi-bitrate 10..1 padding rule, and permutes the state.
+func (d *state) padAndPermute() {
+ // Pad with this instance's domain-separator bits. We know that there's
+ // at least one byte of space in the sponge because, if it were full,
+ // permute would have been called to empty it. dsbyte also contains the
+ // first one bit for the padding. See the comment in the state struct.
+ d.a[d.n] ^= d.dsbyte
+ // This adds the final one bit for the padding. Because of the way that
+ // bits are numbered from the LSB upwards, the final bit is the MSB of
+ // the last byte.
+ d.a[d.rate-1] ^= 0x80
+ // Apply the permutation
+ d.permute()
+ d.state = spongeSqueezing
+}
+
+// Write absorbs more data into the hash's state. It panics if any
+// output has already been read.
+func (d *state) Write(p []byte) (n int, err error) {
+ if d.state != spongeAbsorbing {
+ panic("sha3: Write after Read")
+ }
+
+ n = len(p)
+
+ for len(p) > 0 {
+ x := subtle.XORBytes(d.a[d.n:d.rate], d.a[d.n:d.rate], p)
+ d.n += x
+ p = p[x:]
+
+ // If the sponge is full, apply the permutation.
+ if d.n == d.rate {
+ d.permute()
+ }
+ }
+
+ return
+}
+
+// Read squeezes an arbitrary number of bytes from the sponge.
+func (d *state) Read(out []byte) (n int, err error) {
+ // If we're still absorbing, pad and apply the permutation.
+ if d.state == spongeAbsorbing {
+ d.padAndPermute()
+ }
+
+ n = len(out)
+
+ // Now, do the squeezing.
+ for len(out) > 0 {
+ // Apply the permutation if we've squeezed the sponge dry.
+ if d.n == d.rate {
+ d.permute()
+ }
+
+ x := copy(out, d.a[d.n:d.rate])
+ d.n += x
+ out = out[x:]
+ }
+
+ return
+}
+
+// Sum applies padding to the hash state and then squeezes out the desired
+// number of output bytes. It panics if any output has already been read.
+func (d *state) Sum(in []byte) []byte {
+ if d.state != spongeAbsorbing {
+ panic("sha3: Sum after Read")
+ }
+
+ // Make a copy of the original hash so that caller can keep writing
+ // and summing.
+ dup := d.clone()
+ hash := make([]byte, dup.outputLen, 64) // explicit cap to allow stack allocation
+ dup.Read(hash)
+ return append(in, hash...)
+}
+
+const (
+ magicSHA3 = "sha\x08"
+ magicShake = "sha\x09"
+ magicCShake = "sha\x0a"
+ magicKeccak = "sha\x0b"
+ // magic || rate || main state || n || sponge direction
+ marshaledSize = len(magicSHA3) + 1 + 200 + 1 + 1
+)
+
+func (d *state) MarshalBinary() ([]byte, error) {
+ return d.AppendBinary(make([]byte, 0, marshaledSize))
+}
+
+func (d *state) AppendBinary(b []byte) ([]byte, error) {
+ switch d.dsbyte {
+ case dsbyteSHA3:
+ b = append(b, magicSHA3...)
+ case dsbyteShake:
+ b = append(b, magicShake...)
+ case dsbyteCShake:
+ b = append(b, magicCShake...)
+ case dsbyteKeccak:
+ b = append(b, magicKeccak...)
+ default:
+ panic("unknown dsbyte")
+ }
+ // rate is at most 168, and n is at most rate.
+ b = append(b, byte(d.rate))
+ b = append(b, d.a[:]...)
+ b = append(b, byte(d.n), byte(d.state))
+ return b, nil
+}
+
+func (d *state) UnmarshalBinary(b []byte) error {
+ if len(b) != marshaledSize {
+ return errors.New("sha3: invalid hash state")
+ }
+
+ magic := string(b[:len(magicSHA3)])
+ b = b[len(magicSHA3):]
+ switch {
+ case magic == magicSHA3 && d.dsbyte == dsbyteSHA3:
+ case magic == magicShake && d.dsbyte == dsbyteShake:
+ case magic == magicCShake && d.dsbyte == dsbyteCShake:
+ case magic == magicKeccak && d.dsbyte == dsbyteKeccak:
+ default:
+ return errors.New("sha3: invalid hash state identifier")
+ }
+
+ rate := int(b[0])
+ b = b[1:]
+ if rate != d.rate {
+ return errors.New("sha3: invalid hash state function")
+ }
+
+ copy(d.a[:], b)
+ b = b[len(d.a):]
+
+ n, state := int(b[0]), spongeDirection(b[1])
+ if n > d.rate {
+ return errors.New("sha3: invalid hash state")
+ }
+ d.n = n
+ if state != spongeAbsorbing && state != spongeSqueezing {
+ return errors.New("sha3: invalid hash state")
+ }
+ d.state = state
+
+ return nil
+}
diff --git a/vendor/golang.org/x/crypto/sha3/sha3_s390x.go b/vendor/golang.org/x/crypto/sha3/sha3_s390x.go
new file mode 100644
index 00000000..00d8034a
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/sha3_s390x.go
@@ -0,0 +1,303 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build gc && !purego
+
+package sha3
+
+// This file contains code for using the 'compute intermediate
+// message digest' (KIMD) and 'compute last message digest' (KLMD)
+// instructions to compute SHA-3 and SHAKE hashes on IBM Z.
+
+import (
+ "hash"
+
+ "golang.org/x/sys/cpu"
+)
+
+// codes represent 7-bit KIMD/KLMD function codes as defined in
+// the Principles of Operation.
+type code uint64
+
+const (
+ // function codes for KIMD/KLMD
+ sha3_224 code = 32
+ sha3_256 = 33
+ sha3_384 = 34
+ sha3_512 = 35
+ shake_128 = 36
+ shake_256 = 37
+ nopad = 0x100
+)
+
+// kimd is a wrapper for the 'compute intermediate message digest' instruction.
+// src must be a multiple of the rate for the given function code.
+//
+//go:noescape
+func kimd(function code, chain *[200]byte, src []byte)
+
+// klmd is a wrapper for the 'compute last message digest' instruction.
+// src padding is handled by the instruction.
+//
+//go:noescape
+func klmd(function code, chain *[200]byte, dst, src []byte)
+
+type asmState struct {
+ a [200]byte // 1600 bit state
+ buf []byte // care must be taken to ensure cap(buf) is a multiple of rate
+ rate int // equivalent to block size
+ storage [3072]byte // underlying storage for buf
+ outputLen int // output length for full security
+ function code // KIMD/KLMD function code
+ state spongeDirection // whether the sponge is absorbing or squeezing
+}
+
+func newAsmState(function code) *asmState {
+ var s asmState
+ s.function = function
+ switch function {
+ case sha3_224:
+ s.rate = 144
+ s.outputLen = 28
+ case sha3_256:
+ s.rate = 136
+ s.outputLen = 32
+ case sha3_384:
+ s.rate = 104
+ s.outputLen = 48
+ case sha3_512:
+ s.rate = 72
+ s.outputLen = 64
+ case shake_128:
+ s.rate = 168
+ s.outputLen = 32
+ case shake_256:
+ s.rate = 136
+ s.outputLen = 64
+ default:
+ panic("sha3: unrecognized function code")
+ }
+
+ // limit s.buf size to a multiple of s.rate
+ s.resetBuf()
+ return &s
+}
+
+func (s *asmState) clone() *asmState {
+ c := *s
+ c.buf = c.storage[:len(s.buf):cap(s.buf)]
+ return &c
+}
+
+// copyIntoBuf copies b into buf. It will panic if there is not enough space to
+// store all of b.
+func (s *asmState) copyIntoBuf(b []byte) {
+ bufLen := len(s.buf)
+ s.buf = s.buf[:len(s.buf)+len(b)]
+ copy(s.buf[bufLen:], b)
+}
+
+// resetBuf points buf at storage, sets the length to 0 and sets cap to be a
+// multiple of the rate.
+func (s *asmState) resetBuf() {
+ max := (cap(s.storage) / s.rate) * s.rate
+ s.buf = s.storage[:0:max]
+}
+
+// Write (via the embedded io.Writer interface) adds more data to the running hash.
+// It never returns an error.
+func (s *asmState) Write(b []byte) (int, error) {
+ if s.state != spongeAbsorbing {
+ panic("sha3: Write after Read")
+ }
+ length := len(b)
+ for len(b) > 0 {
+ if len(s.buf) == 0 && len(b) >= cap(s.buf) {
+ // Hash the data directly and push any remaining bytes
+ // into the buffer.
+ remainder := len(b) % s.rate
+ kimd(s.function, &s.a, b[:len(b)-remainder])
+ if remainder != 0 {
+ s.copyIntoBuf(b[len(b)-remainder:])
+ }
+ return length, nil
+ }
+
+ if len(s.buf) == cap(s.buf) {
+ // flush the buffer
+ kimd(s.function, &s.a, s.buf)
+ s.buf = s.buf[:0]
+ }
+
+ // copy as much as we can into the buffer
+ n := len(b)
+ if len(b) > cap(s.buf)-len(s.buf) {
+ n = cap(s.buf) - len(s.buf)
+ }
+ s.copyIntoBuf(b[:n])
+ b = b[n:]
+ }
+ return length, nil
+}
+
+// Read squeezes an arbitrary number of bytes from the sponge.
+func (s *asmState) Read(out []byte) (n int, err error) {
+ // The 'compute last message digest' instruction only stores the digest
+ // at the first operand (dst) for SHAKE functions.
+ if s.function != shake_128 && s.function != shake_256 {
+ panic("sha3: can only call Read for SHAKE functions")
+ }
+
+ n = len(out)
+
+ // need to pad if we were absorbing
+ if s.state == spongeAbsorbing {
+ s.state = spongeSqueezing
+
+ // write hash directly into out if possible
+ if len(out)%s.rate == 0 {
+ klmd(s.function, &s.a, out, s.buf) // len(out) may be 0
+ s.buf = s.buf[:0]
+ return
+ }
+
+ // write hash into buffer
+ max := cap(s.buf)
+ if max > len(out) {
+ max = (len(out)/s.rate)*s.rate + s.rate
+ }
+ klmd(s.function, &s.a, s.buf[:max], s.buf)
+ s.buf = s.buf[:max]
+ }
+
+ for len(out) > 0 {
+ // flush the buffer
+ if len(s.buf) != 0 {
+ c := copy(out, s.buf)
+ out = out[c:]
+ s.buf = s.buf[c:]
+ continue
+ }
+
+ // write hash directly into out if possible
+ if len(out)%s.rate == 0 {
+ klmd(s.function|nopad, &s.a, out, nil)
+ return
+ }
+
+ // write hash into buffer
+ s.resetBuf()
+ if cap(s.buf) > len(out) {
+ s.buf = s.buf[:(len(out)/s.rate)*s.rate+s.rate]
+ }
+ klmd(s.function|nopad, &s.a, s.buf, nil)
+ }
+ return
+}
+
+// Sum appends the current hash to b and returns the resulting slice.
+// It does not change the underlying hash state.
+func (s *asmState) Sum(b []byte) []byte {
+ if s.state != spongeAbsorbing {
+ panic("sha3: Sum after Read")
+ }
+
+ // Copy the state to preserve the original.
+ a := s.a
+
+ // Hash the buffer. Note that we don't clear it because we
+ // aren't updating the state.
+ switch s.function {
+ case sha3_224, sha3_256, sha3_384, sha3_512:
+ klmd(s.function, &a, nil, s.buf)
+ return append(b, a[:s.outputLen]...)
+ case shake_128, shake_256:
+ d := make([]byte, s.outputLen, 64)
+ klmd(s.function, &a, d, s.buf)
+ return append(b, d[:s.outputLen]...)
+ default:
+ panic("sha3: unknown function")
+ }
+}
+
+// Reset resets the Hash to its initial state.
+func (s *asmState) Reset() {
+ for i := range s.a {
+ s.a[i] = 0
+ }
+ s.resetBuf()
+ s.state = spongeAbsorbing
+}
+
+// Size returns the number of bytes Sum will return.
+func (s *asmState) Size() int {
+ return s.outputLen
+}
+
+// BlockSize returns the hash's underlying block size.
+// The Write method must be able to accept any amount
+// of data, but it may operate more efficiently if all writes
+// are a multiple of the block size.
+func (s *asmState) BlockSize() int {
+ return s.rate
+}
+
+// Clone returns a copy of the ShakeHash in its current state.
+func (s *asmState) Clone() ShakeHash {
+ return s.clone()
+}
+
+// new224 returns an assembly implementation of SHA3-224 if available,
+// otherwise it returns a generic implementation.
+func new224() hash.Hash {
+ if cpu.S390X.HasSHA3 {
+ return newAsmState(sha3_224)
+ }
+ return new224Generic()
+}
+
+// new256 returns an assembly implementation of SHA3-256 if available,
+// otherwise it returns a generic implementation.
+func new256() hash.Hash {
+ if cpu.S390X.HasSHA3 {
+ return newAsmState(sha3_256)
+ }
+ return new256Generic()
+}
+
+// new384 returns an assembly implementation of SHA3-384 if available,
+// otherwise it returns a generic implementation.
+func new384() hash.Hash {
+ if cpu.S390X.HasSHA3 {
+ return newAsmState(sha3_384)
+ }
+ return new384Generic()
+}
+
+// new512 returns an assembly implementation of SHA3-512 if available,
+// otherwise it returns a generic implementation.
+func new512() hash.Hash {
+ if cpu.S390X.HasSHA3 {
+ return newAsmState(sha3_512)
+ }
+ return new512Generic()
+}
+
+// newShake128 returns an assembly implementation of SHAKE-128 if available,
+// otherwise it returns a generic implementation.
+func newShake128() ShakeHash {
+ if cpu.S390X.HasSHA3 {
+ return newAsmState(shake_128)
+ }
+ return newShake128Generic()
+}
+
+// newShake256 returns an assembly implementation of SHAKE-256 if available,
+// otherwise it returns a generic implementation.
+func newShake256() ShakeHash {
+ if cpu.S390X.HasSHA3 {
+ return newAsmState(shake_256)
+ }
+ return newShake256Generic()
+}
diff --git a/vendor/golang.org/x/crypto/sha3/sha3_s390x.s b/vendor/golang.org/x/crypto/sha3/sha3_s390x.s
new file mode 100644
index 00000000..826b862c
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/sha3_s390x.s
@@ -0,0 +1,33 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build gc && !purego
+
+#include "textflag.h"
+
+// func kimd(function code, chain *[200]byte, src []byte)
+TEXT ·kimd(SB), NOFRAME|NOSPLIT, $0-40
+ MOVD function+0(FP), R0
+ MOVD chain+8(FP), R1
+ LMG src+16(FP), R2, R3 // R2=base, R3=len
+
+continue:
+ WORD $0xB93E0002 // KIMD --, R2
+ BVS continue // continue if interrupted
+ MOVD $0, R0 // reset R0 for pre-go1.8 compilers
+ RET
+
+// func klmd(function code, chain *[200]byte, dst, src []byte)
+TEXT ·klmd(SB), NOFRAME|NOSPLIT, $0-64
+ // TODO: SHAKE support
+ MOVD function+0(FP), R0
+ MOVD chain+8(FP), R1
+ LMG dst+16(FP), R2, R3 // R2=base, R3=len
+ LMG src+40(FP), R4, R5 // R4=base, R5=len
+
+continue:
+ WORD $0xB93F0024 // KLMD R2, R4
+ BVS continue // continue if interrupted
+ MOVD $0, R0 // reset R0 for pre-go1.8 compilers
+ RET
diff --git a/vendor/golang.org/x/crypto/sha3/shake.go b/vendor/golang.org/x/crypto/sha3/shake.go
new file mode 100644
index 00000000..a6b3a428
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/shake.go
@@ -0,0 +1,193 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha3
+
+// This file defines the ShakeHash interface, and provides
+// functions for creating SHAKE and cSHAKE instances, as well as utility
+// functions for hashing bytes to arbitrary-length output.
+//
+//
+// SHAKE implementation is based on FIPS PUB 202 [1]
+// cSHAKE implementations is based on NIST SP 800-185 [2]
+//
+// [1] https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
+// [2] https://doi.org/10.6028/NIST.SP.800-185
+
+import (
+ "bytes"
+ "encoding/binary"
+ "errors"
+ "hash"
+ "io"
+ "math/bits"
+)
+
+// ShakeHash defines the interface to hash functions that support
+// arbitrary-length output. When used as a plain [hash.Hash], it
+// produces minimum-length outputs that provide full-strength generic
+// security.
+type ShakeHash interface {
+ hash.Hash
+
+ // Read reads more output from the hash; reading affects the hash's
+ // state. (ShakeHash.Read is thus very different from Hash.Sum)
+ // It never returns an error, but subsequent calls to Write or Sum
+ // will panic.
+ io.Reader
+
+ // Clone returns a copy of the ShakeHash in its current state.
+ Clone() ShakeHash
+}
+
+// cSHAKE specific context
+type cshakeState struct {
+ *state // SHA-3 state context and Read/Write operations
+
+ // initBlock is the cSHAKE specific initialization set of bytes. It is initialized
+ // by newCShake function and stores concatenation of N followed by S, encoded
+ // by the method specified in 3.3 of [1].
+ // It is stored here in order for Reset() to be able to put context into
+ // initial state.
+ initBlock []byte
+}
+
+func bytepad(data []byte, rate int) []byte {
+ out := make([]byte, 0, 9+len(data)+rate-1)
+ out = append(out, leftEncode(uint64(rate))...)
+ out = append(out, data...)
+ if padlen := rate - len(out)%rate; padlen < rate {
+ out = append(out, make([]byte, padlen)...)
+ }
+ return out
+}
+
+func leftEncode(x uint64) []byte {
+ // Let n be the smallest positive integer for which 2^(8n) > x.
+ n := (bits.Len64(x) + 7) / 8
+ if n == 0 {
+ n = 1
+ }
+ // Return n || x with n as a byte and x an n bytes in big-endian order.
+ b := make([]byte, 9)
+ binary.BigEndian.PutUint64(b[1:], x)
+ b = b[9-n-1:]
+ b[0] = byte(n)
+ return b
+}
+
+func newCShake(N, S []byte, rate, outputLen int, dsbyte byte) ShakeHash {
+ c := cshakeState{state: &state{rate: rate, outputLen: outputLen, dsbyte: dsbyte}}
+ c.initBlock = make([]byte, 0, 9+len(N)+9+len(S)) // leftEncode returns max 9 bytes
+ c.initBlock = append(c.initBlock, leftEncode(uint64(len(N))*8)...)
+ c.initBlock = append(c.initBlock, N...)
+ c.initBlock = append(c.initBlock, leftEncode(uint64(len(S))*8)...)
+ c.initBlock = append(c.initBlock, S...)
+ c.Write(bytepad(c.initBlock, c.rate))
+ return &c
+}
+
+// Reset resets the hash to initial state.
+func (c *cshakeState) Reset() {
+ c.state.Reset()
+ c.Write(bytepad(c.initBlock, c.rate))
+}
+
+// Clone returns copy of a cSHAKE context within its current state.
+func (c *cshakeState) Clone() ShakeHash {
+ b := make([]byte, len(c.initBlock))
+ copy(b, c.initBlock)
+ return &cshakeState{state: c.clone(), initBlock: b}
+}
+
+// Clone returns copy of SHAKE context within its current state.
+func (c *state) Clone() ShakeHash {
+ return c.clone()
+}
+
+func (c *cshakeState) MarshalBinary() ([]byte, error) {
+ return c.AppendBinary(make([]byte, 0, marshaledSize+len(c.initBlock)))
+}
+
+func (c *cshakeState) AppendBinary(b []byte) ([]byte, error) {
+ b, err := c.state.AppendBinary(b)
+ if err != nil {
+ return nil, err
+ }
+ b = append(b, c.initBlock...)
+ return b, nil
+}
+
+func (c *cshakeState) UnmarshalBinary(b []byte) error {
+ if len(b) <= marshaledSize {
+ return errors.New("sha3: invalid hash state")
+ }
+ if err := c.state.UnmarshalBinary(b[:marshaledSize]); err != nil {
+ return err
+ }
+ c.initBlock = bytes.Clone(b[marshaledSize:])
+ return nil
+}
+
+// NewShake128 creates a new SHAKE128 variable-output-length ShakeHash.
+// Its generic security strength is 128 bits against all attacks if at
+// least 32 bytes of its output are used.
+func NewShake128() ShakeHash {
+ return newShake128()
+}
+
+// NewShake256 creates a new SHAKE256 variable-output-length ShakeHash.
+// Its generic security strength is 256 bits against all attacks if
+// at least 64 bytes of its output are used.
+func NewShake256() ShakeHash {
+ return newShake256()
+}
+
+func newShake128Generic() *state {
+ return &state{rate: rateK256, outputLen: 32, dsbyte: dsbyteShake}
+}
+
+func newShake256Generic() *state {
+ return &state{rate: rateK512, outputLen: 64, dsbyte: dsbyteShake}
+}
+
+// NewCShake128 creates a new instance of cSHAKE128 variable-output-length ShakeHash,
+// a customizable variant of SHAKE128.
+// N is used to define functions based on cSHAKE, it can be empty when plain cSHAKE is
+// desired. S is a customization byte string used for domain separation - two cSHAKE
+// computations on same input with different S yield unrelated outputs.
+// When N and S are both empty, this is equivalent to NewShake128.
+func NewCShake128(N, S []byte) ShakeHash {
+ if len(N) == 0 && len(S) == 0 {
+ return NewShake128()
+ }
+ return newCShake(N, S, rateK256, 32, dsbyteCShake)
+}
+
+// NewCShake256 creates a new instance of cSHAKE256 variable-output-length ShakeHash,
+// a customizable variant of SHAKE256.
+// N is used to define functions based on cSHAKE, it can be empty when plain cSHAKE is
+// desired. S is a customization byte string used for domain separation - two cSHAKE
+// computations on same input with different S yield unrelated outputs.
+// When N and S are both empty, this is equivalent to NewShake256.
+func NewCShake256(N, S []byte) ShakeHash {
+ if len(N) == 0 && len(S) == 0 {
+ return NewShake256()
+ }
+ return newCShake(N, S, rateK512, 64, dsbyteCShake)
+}
+
+// ShakeSum128 writes an arbitrary-length digest of data into hash.
+func ShakeSum128(hash, data []byte) {
+ h := NewShake128()
+ h.Write(data)
+ h.Read(hash)
+}
+
+// ShakeSum256 writes an arbitrary-length digest of data into hash.
+func ShakeSum256(hash, data []byte) {
+ h := NewShake256()
+ h.Write(data)
+ h.Read(hash)
+}
diff --git a/vendor/golang.org/x/crypto/sha3/shake_noasm.go b/vendor/golang.org/x/crypto/sha3/shake_noasm.go
new file mode 100644
index 00000000..4276ba4a
--- /dev/null
+++ b/vendor/golang.org/x/crypto/sha3/shake_noasm.go
@@ -0,0 +1,15 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !gc || purego || !s390x
+
+package sha3
+
+func newShake128() *state {
+ return newShake128Generic()
+}
+
+func newShake256() *state {
+ return newShake256Generic()
+}
diff --git a/vendor/golang.org/x/net/html/atom/atom.go b/vendor/golang.org/x/net/html/atom/atom.go
new file mode 100644
index 00000000..cd0a8ac1
--- /dev/null
+++ b/vendor/golang.org/x/net/html/atom/atom.go
@@ -0,0 +1,78 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package atom provides integer codes (also known as atoms) for a fixed set of
+// frequently occurring HTML strings: tag names and attribute keys such as "p"
+// and "id".
+//
+// Sharing an atom's name between all elements with the same tag can result in
+// fewer string allocations when tokenizing and parsing HTML. Integer
+// comparisons are also generally faster than string comparisons.
+//
+// The value of an atom's particular code is not guaranteed to stay the same
+// between versions of this package. Neither is any ordering guaranteed:
+// whether atom.H1 < atom.H2 may also change. The codes are not guaranteed to
+// be dense. The only guarantees are that e.g. looking up "div" will yield
+// atom.Div, calling atom.Div.String will return "div", and atom.Div != 0.
+package atom // import "golang.org/x/net/html/atom"
+
+// Atom is an integer code for a string. The zero value maps to "".
+type Atom uint32
+
+// String returns the atom's name.
+func (a Atom) String() string {
+ start := uint32(a >> 8)
+ n := uint32(a & 0xff)
+ if start+n > uint32(len(atomText)) {
+ return ""
+ }
+ return atomText[start : start+n]
+}
+
+func (a Atom) string() string {
+ return atomText[a>>8 : a>>8+a&0xff]
+}
+
+// fnv computes the FNV hash with an arbitrary starting value h.
+func fnv(h uint32, s []byte) uint32 {
+ for i := range s {
+ h ^= uint32(s[i])
+ h *= 16777619
+ }
+ return h
+}
+
+func match(s string, t []byte) bool {
+ for i, c := range t {
+ if s[i] != c {
+ return false
+ }
+ }
+ return true
+}
+
+// Lookup returns the atom whose name is s. It returns zero if there is no
+// such atom. The lookup is case sensitive.
+func Lookup(s []byte) Atom {
+ if len(s) == 0 || len(s) > maxAtomLen {
+ return 0
+ }
+ h := fnv(hash0, s)
+ if a := table[h&uint32(len(table)-1)]; int(a&0xff) == len(s) && match(a.string(), s) {
+ return a
+ }
+ if a := table[(h>>16)&uint32(len(table)-1)]; int(a&0xff) == len(s) && match(a.string(), s) {
+ return a
+ }
+ return 0
+}
+
+// String returns a string whose contents are equal to s. In that sense, it is
+// equivalent to string(s) but may be more efficient.
+func String(s []byte) string {
+ if a := Lookup(s); a != 0 {
+ return a.String()
+ }
+ return string(s)
+}
diff --git a/vendor/golang.org/x/net/html/atom/table.go b/vendor/golang.org/x/net/html/atom/table.go
new file mode 100644
index 00000000..b460e6f7
--- /dev/null
+++ b/vendor/golang.org/x/net/html/atom/table.go
@@ -0,0 +1,785 @@
+// Code generated by go generate gen.go; DO NOT EDIT.
+
+//go:generate go run gen.go
+
+package atom
+
+const (
+ A Atom = 0x1
+ Abbr Atom = 0x4
+ Accept Atom = 0x1a06
+ AcceptCharset Atom = 0x1a0e
+ Accesskey Atom = 0x2c09
+ Acronym Atom = 0xaa07
+ Action Atom = 0x26506
+ Address Atom = 0x6f107
+ Align Atom = 0xb105
+ Allowfullscreen Atom = 0x3280f
+ Allowpaymentrequest Atom = 0xc113
+ Allowusermedia Atom = 0xdd0e
+ Alt Atom = 0xf303
+ Annotation Atom = 0x1c90a
+ AnnotationXml Atom = 0x1c90e
+ Applet Atom = 0x30806
+ Area Atom = 0x35004
+ Article Atom = 0x3f607
+ As Atom = 0x3c02
+ Aside Atom = 0x10705
+ Async Atom = 0xff05
+ Audio Atom = 0x11505
+ Autocomplete Atom = 0x26b0c
+ Autofocus Atom = 0x12109
+ Autoplay Atom = 0x13c08
+ B Atom = 0x101
+ Base Atom = 0x3b04
+ Basefont Atom = 0x3b08
+ Bdi Atom = 0xba03
+ Bdo Atom = 0x14b03
+ Bgsound Atom = 0x15e07
+ Big Atom = 0x17003
+ Blink Atom = 0x17305
+ Blockquote Atom = 0x1870a
+ Body Atom = 0x2804
+ Br Atom = 0x202
+ Button Atom = 0x19106
+ Canvas Atom = 0x10306
+ Caption Atom = 0x22407
+ Center Atom = 0x21306
+ Challenge Atom = 0x28e09
+ Charset Atom = 0x2107
+ Checked Atom = 0x5b507
+ Cite Atom = 0x19c04
+ Class Atom = 0x55805
+ Code Atom = 0x5ee04
+ Col Atom = 0x1ab03
+ Colgroup Atom = 0x1ab08
+ Color Atom = 0x1bf05
+ Cols Atom = 0x1c404
+ Colspan Atom = 0x1c407
+ Command Atom = 0x1d707
+ Content Atom = 0x57b07
+ Contenteditable Atom = 0x57b0f
+ Contextmenu Atom = 0x37a0b
+ Controls Atom = 0x1de08
+ Coords Atom = 0x1f006
+ Crossorigin Atom = 0x1fa0b
+ Data Atom = 0x49904
+ Datalist Atom = 0x49908
+ Datetime Atom = 0x2ab08
+ Dd Atom = 0x2bf02
+ Default Atom = 0x10a07
+ Defer Atom = 0x5f005
+ Del Atom = 0x44c03
+ Desc Atom = 0x55504
+ Details Atom = 0x7207
+ Dfn Atom = 0x8703
+ Dialog Atom = 0xbb06
+ Dir Atom = 0x9303
+ Dirname Atom = 0x9307
+ Disabled Atom = 0x16408
+ Div Atom = 0x16b03
+ Dl Atom = 0x5d602
+ Download Atom = 0x45d08
+ Draggable Atom = 0x17a09
+ Dropzone Atom = 0x3ff08
+ Dt Atom = 0x64002
+ Em Atom = 0x6e02
+ Embed Atom = 0x6e05
+ Enctype Atom = 0x28007
+ Face Atom = 0x21104
+ Fieldset Atom = 0x21908
+ Figcaption Atom = 0x2210a
+ Figure Atom = 0x23b06
+ Font Atom = 0x3f04
+ Footer Atom = 0xf606
+ For Atom = 0x24703
+ ForeignObject Atom = 0x2470d
+ Foreignobject Atom = 0x2540d
+ Form Atom = 0x26104
+ Formaction Atom = 0x2610a
+ Formenctype Atom = 0x27c0b
+ Formmethod Atom = 0x2970a
+ Formnovalidate Atom = 0x2a10e
+ Formtarget Atom = 0x2b30a
+ Frame Atom = 0x8b05
+ Frameset Atom = 0x8b08
+ H1 Atom = 0x15c02
+ H2 Atom = 0x56102
+ H3 Atom = 0x2cd02
+ H4 Atom = 0x2fc02
+ H5 Atom = 0x33f02
+ H6 Atom = 0x34902
+ Head Atom = 0x32004
+ Header Atom = 0x32006
+ Headers Atom = 0x32007
+ Height Atom = 0x5206
+ Hgroup Atom = 0x64206
+ Hidden Atom = 0x2bd06
+ High Atom = 0x2ca04
+ Hr Atom = 0x15702
+ Href Atom = 0x2cf04
+ Hreflang Atom = 0x2cf08
+ Html Atom = 0x5604
+ HttpEquiv Atom = 0x2d70a
+ I Atom = 0x601
+ Icon Atom = 0x57a04
+ Id Atom = 0x10902
+ Iframe Atom = 0x2eb06
+ Image Atom = 0x2f105
+ Img Atom = 0x2f603
+ Input Atom = 0x44505
+ Inputmode Atom = 0x44509
+ Ins Atom = 0x20303
+ Integrity Atom = 0x23209
+ Is Atom = 0x16502
+ Isindex Atom = 0x2fe07
+ Ismap Atom = 0x30505
+ Itemid Atom = 0x38506
+ Itemprop Atom = 0x19d08
+ Itemref Atom = 0x3c707
+ Itemscope Atom = 0x66f09
+ Itemtype Atom = 0x30e08
+ Kbd Atom = 0xb903
+ Keygen Atom = 0x3206
+ Keytype Atom = 0xd607
+ Kind Atom = 0x17704
+ Label Atom = 0x5905
+ Lang Atom = 0x2d304
+ Legend Atom = 0x18106
+ Li Atom = 0xb202
+ Link Atom = 0x17404
+ List Atom = 0x49d04
+ Listing Atom = 0x49d07
+ Loop Atom = 0x5d04
+ Low Atom = 0xc303
+ Main Atom = 0x1004
+ Malignmark Atom = 0xb00a
+ Manifest Atom = 0x6d508
+ Map Atom = 0x30703
+ Mark Atom = 0xb604
+ Marquee Atom = 0x31607
+ Math Atom = 0x31d04
+ Max Atom = 0x33703
+ Maxlength Atom = 0x33709
+ Media Atom = 0xe605
+ Mediagroup Atom = 0xe60a
+ Menu Atom = 0x38104
+ Menuitem Atom = 0x38108
+ Meta Atom = 0x4ac04
+ Meter Atom = 0x9805
+ Method Atom = 0x29b06
+ Mglyph Atom = 0x2f706
+ Mi Atom = 0x34102
+ Min Atom = 0x34103
+ Minlength Atom = 0x34109
+ Mn Atom = 0x2a402
+ Mo Atom = 0xa402
+ Ms Atom = 0x67202
+ Mtext Atom = 0x34b05
+ Multiple Atom = 0x35908
+ Muted Atom = 0x36105
+ Name Atom = 0x9604
+ Nav Atom = 0x1303
+ Nobr Atom = 0x3704
+ Noembed Atom = 0x6c07
+ Noframes Atom = 0x8908
+ Nomodule Atom = 0xa208
+ Nonce Atom = 0x1a605
+ Noscript Atom = 0x2c208
+ Novalidate Atom = 0x2a50a
+ Object Atom = 0x25b06
+ Ol Atom = 0x13702
+ Onabort Atom = 0x19507
+ Onafterprint Atom = 0x2290c
+ Onautocomplete Atom = 0x2690e
+ Onautocompleteerror Atom = 0x26913
+ Onauxclick Atom = 0x6140a
+ Onbeforeprint Atom = 0x69c0d
+ Onbeforeunload Atom = 0x6e50e
+ Onblur Atom = 0x1ea06
+ Oncancel Atom = 0x11908
+ Oncanplay Atom = 0x14d09
+ Oncanplaythrough Atom = 0x14d10
+ Onchange Atom = 0x41508
+ Onclick Atom = 0x2e407
+ Onclose Atom = 0x36607
+ Oncontextmenu Atom = 0x3780d
+ Oncopy Atom = 0x38b06
+ Oncuechange Atom = 0x3910b
+ Oncut Atom = 0x39c05
+ Ondblclick Atom = 0x3a10a
+ Ondrag Atom = 0x3ab06
+ Ondragend Atom = 0x3ab09
+ Ondragenter Atom = 0x3b40b
+ Ondragexit Atom = 0x3bf0a
+ Ondragleave Atom = 0x3d90b
+ Ondragover Atom = 0x3e40a
+ Ondragstart Atom = 0x3ee0b
+ Ondrop Atom = 0x3fd06
+ Ondurationchange Atom = 0x40d10
+ Onemptied Atom = 0x40409
+ Onended Atom = 0x41d07
+ Onerror Atom = 0x42407
+ Onfocus Atom = 0x42b07
+ Onhashchange Atom = 0x4370c
+ Oninput Atom = 0x44307
+ Oninvalid Atom = 0x44f09
+ Onkeydown Atom = 0x45809
+ Onkeypress Atom = 0x4650a
+ Onkeyup Atom = 0x47407
+ Onlanguagechange Atom = 0x48110
+ Onload Atom = 0x49106
+ Onloadeddata Atom = 0x4910c
+ Onloadedmetadata Atom = 0x4a410
+ Onloadend Atom = 0x4ba09
+ Onloadstart Atom = 0x4c30b
+ Onmessage Atom = 0x4ce09
+ Onmessageerror Atom = 0x4ce0e
+ Onmousedown Atom = 0x4dc0b
+ Onmouseenter Atom = 0x4e70c
+ Onmouseleave Atom = 0x4f30c
+ Onmousemove Atom = 0x4ff0b
+ Onmouseout Atom = 0x50a0a
+ Onmouseover Atom = 0x5170b
+ Onmouseup Atom = 0x52209
+ Onmousewheel Atom = 0x5300c
+ Onoffline Atom = 0x53c09
+ Ononline Atom = 0x54508
+ Onpagehide Atom = 0x54d0a
+ Onpageshow Atom = 0x5630a
+ Onpaste Atom = 0x56f07
+ Onpause Atom = 0x58a07
+ Onplay Atom = 0x59406
+ Onplaying Atom = 0x59409
+ Onpopstate Atom = 0x59d0a
+ Onprogress Atom = 0x5a70a
+ Onratechange Atom = 0x5bc0c
+ Onrejectionhandled Atom = 0x5c812
+ Onreset Atom = 0x5da07
+ Onresize Atom = 0x5e108
+ Onscroll Atom = 0x5f508
+ Onsecuritypolicyviolation Atom = 0x5fd19
+ Onseeked Atom = 0x61e08
+ Onseeking Atom = 0x62609
+ Onselect Atom = 0x62f08
+ Onshow Atom = 0x63906
+ Onsort Atom = 0x64d06
+ Onstalled Atom = 0x65709
+ Onstorage Atom = 0x66009
+ Onsubmit Atom = 0x66908
+ Onsuspend Atom = 0x67909
+ Ontimeupdate Atom = 0x400c
+ Ontoggle Atom = 0x68208
+ Onunhandledrejection Atom = 0x68a14
+ Onunload Atom = 0x6a908
+ Onvolumechange Atom = 0x6b10e
+ Onwaiting Atom = 0x6bf09
+ Onwheel Atom = 0x6c807
+ Open Atom = 0x1a304
+ Optgroup Atom = 0x5f08
+ Optimum Atom = 0x6cf07
+ Option Atom = 0x6e106
+ Output Atom = 0x51106
+ P Atom = 0xc01
+ Param Atom = 0xc05
+ Pattern Atom = 0x6607
+ Picture Atom = 0x7b07
+ Ping Atom = 0xef04
+ Placeholder Atom = 0x1310b
+ Plaintext Atom = 0x1b209
+ Playsinline Atom = 0x1400b
+ Poster Atom = 0x64706
+ Pre Atom = 0x46a03
+ Preload Atom = 0x47a07
+ Progress Atom = 0x5a908
+ Prompt Atom = 0x52a06
+ Public Atom = 0x57606
+ Q Atom = 0xcf01
+ Radiogroup Atom = 0x30a
+ Rb Atom = 0x3a02
+ Readonly Atom = 0x35108
+ Referrerpolicy Atom = 0x3cb0e
+ Rel Atom = 0x47b03
+ Required Atom = 0x23f08
+ Reversed Atom = 0x8008
+ Rows Atom = 0x9c04
+ Rowspan Atom = 0x9c07
+ Rp Atom = 0x22f02
+ Rt Atom = 0x19a02
+ Rtc Atom = 0x19a03
+ Ruby Atom = 0xfb04
+ S Atom = 0x2501
+ Samp Atom = 0x7804
+ Sandbox Atom = 0x12907
+ Scope Atom = 0x67305
+ Scoped Atom = 0x67306
+ Script Atom = 0x2c406
+ Seamless Atom = 0x36b08
+ Search Atom = 0x55c06
+ Section Atom = 0x1e507
+ Select Atom = 0x63106
+ Selected Atom = 0x63108
+ Shape Atom = 0x1f505
+ Size Atom = 0x5e504
+ Sizes Atom = 0x5e505
+ Slot Atom = 0x20504
+ Small Atom = 0x32605
+ Sortable Atom = 0x64f08
+ Sorted Atom = 0x37206
+ Source Atom = 0x43106
+ Spacer Atom = 0x46e06
+ Span Atom = 0x9f04
+ Spellcheck Atom = 0x5b00a
+ Src Atom = 0x5e903
+ Srcdoc Atom = 0x5e906
+ Srclang Atom = 0x6f707
+ Srcset Atom = 0x6fe06
+ Start Atom = 0x3f405
+ Step Atom = 0x57304
+ Strike Atom = 0xd206
+ Strong Atom = 0x6db06
+ Style Atom = 0x70405
+ Sub Atom = 0x66b03
+ Summary Atom = 0x70907
+ Sup Atom = 0x71003
+ Svg Atom = 0x71303
+ System Atom = 0x71606
+ Tabindex Atom = 0x4b208
+ Table Atom = 0x58505
+ Target Atom = 0x2b706
+ Tbody Atom = 0x2705
+ Td Atom = 0x9202
+ Template Atom = 0x71908
+ Textarea Atom = 0x34c08
+ Tfoot Atom = 0xf505
+ Th Atom = 0x15602
+ Thead Atom = 0x31f05
+ Time Atom = 0x4204
+ Title Atom = 0x11005
+ Tr Atom = 0xcc02
+ Track Atom = 0x1ba05
+ Translate Atom = 0x20809
+ Tt Atom = 0x6802
+ Type Atom = 0xd904
+ Typemustmatch Atom = 0x2830d
+ U Atom = 0xb01
+ Ul Atom = 0xa702
+ Updateviacache Atom = 0x460e
+ Usemap Atom = 0x58e06
+ Value Atom = 0x1505
+ Var Atom = 0x16d03
+ Video Atom = 0x2e005
+ Wbr Atom = 0x56c03
+ Width Atom = 0x63e05
+ Workertype Atom = 0x7210a
+ Wrap Atom = 0x72b04
+ Xmp Atom = 0x12f03
+)
+
+const hash0 = 0x84f70e16
+
+const maxAtomLen = 25
+
+var table = [1 << 9]Atom{
+ 0x1: 0x3ff08, // dropzone
+ 0x2: 0x3b08, // basefont
+ 0x3: 0x23209, // integrity
+ 0x4: 0x43106, // source
+ 0x5: 0x2c09, // accesskey
+ 0x6: 0x1a06, // accept
+ 0x7: 0x6c807, // onwheel
+ 0xb: 0x47407, // onkeyup
+ 0xc: 0x32007, // headers
+ 0xd: 0x67306, // scoped
+ 0xe: 0x67909, // onsuspend
+ 0xf: 0x8908, // noframes
+ 0x10: 0x1fa0b, // crossorigin
+ 0x11: 0x2e407, // onclick
+ 0x12: 0x3f405, // start
+ 0x13: 0x37a0b, // contextmenu
+ 0x14: 0x5e903, // src
+ 0x15: 0x1c404, // cols
+ 0x16: 0xbb06, // dialog
+ 0x17: 0x47a07, // preload
+ 0x18: 0x3c707, // itemref
+ 0x1b: 0x2f105, // image
+ 0x1d: 0x4ba09, // onloadend
+ 0x1e: 0x45d08, // download
+ 0x1f: 0x46a03, // pre
+ 0x23: 0x2970a, // formmethod
+ 0x24: 0x71303, // svg
+ 0x25: 0xcf01, // q
+ 0x26: 0x64002, // dt
+ 0x27: 0x1de08, // controls
+ 0x2a: 0x2804, // body
+ 0x2b: 0xd206, // strike
+ 0x2c: 0x3910b, // oncuechange
+ 0x2d: 0x4c30b, // onloadstart
+ 0x2e: 0x2fe07, // isindex
+ 0x2f: 0xb202, // li
+ 0x30: 0x1400b, // playsinline
+ 0x31: 0x34102, // mi
+ 0x32: 0x30806, // applet
+ 0x33: 0x4ce09, // onmessage
+ 0x35: 0x13702, // ol
+ 0x36: 0x1a304, // open
+ 0x39: 0x14d09, // oncanplay
+ 0x3a: 0x6bf09, // onwaiting
+ 0x3b: 0x11908, // oncancel
+ 0x3c: 0x6a908, // onunload
+ 0x3e: 0x53c09, // onoffline
+ 0x3f: 0x1a0e, // accept-charset
+ 0x40: 0x32004, // head
+ 0x42: 0x3ab09, // ondragend
+ 0x43: 0x1310b, // placeholder
+ 0x44: 0x2b30a, // formtarget
+ 0x45: 0x2540d, // foreignobject
+ 0x47: 0x400c, // ontimeupdate
+ 0x48: 0xdd0e, // allowusermedia
+ 0x4a: 0x69c0d, // onbeforeprint
+ 0x4b: 0x5604, // html
+ 0x4c: 0x9f04, // span
+ 0x4d: 0x64206, // hgroup
+ 0x4e: 0x16408, // disabled
+ 0x4f: 0x4204, // time
+ 0x51: 0x42b07, // onfocus
+ 0x53: 0xb00a, // malignmark
+ 0x55: 0x4650a, // onkeypress
+ 0x56: 0x55805, // class
+ 0x57: 0x1ab08, // colgroup
+ 0x58: 0x33709, // maxlength
+ 0x59: 0x5a908, // progress
+ 0x5b: 0x70405, // style
+ 0x5c: 0x2a10e, // formnovalidate
+ 0x5e: 0x38b06, // oncopy
+ 0x60: 0x26104, // form
+ 0x61: 0xf606, // footer
+ 0x64: 0x30a, // radiogroup
+ 0x66: 0xfb04, // ruby
+ 0x67: 0x4ff0b, // onmousemove
+ 0x68: 0x19d08, // itemprop
+ 0x69: 0x2d70a, // http-equiv
+ 0x6a: 0x15602, // th
+ 0x6c: 0x6e02, // em
+ 0x6d: 0x38108, // menuitem
+ 0x6e: 0x63106, // select
+ 0x6f: 0x48110, // onlanguagechange
+ 0x70: 0x31f05, // thead
+ 0x71: 0x15c02, // h1
+ 0x72: 0x5e906, // srcdoc
+ 0x75: 0x9604, // name
+ 0x76: 0x19106, // button
+ 0x77: 0x55504, // desc
+ 0x78: 0x17704, // kind
+ 0x79: 0x1bf05, // color
+ 0x7c: 0x58e06, // usemap
+ 0x7d: 0x30e08, // itemtype
+ 0x7f: 0x6d508, // manifest
+ 0x81: 0x5300c, // onmousewheel
+ 0x82: 0x4dc0b, // onmousedown
+ 0x84: 0xc05, // param
+ 0x85: 0x2e005, // video
+ 0x86: 0x4910c, // onloadeddata
+ 0x87: 0x6f107, // address
+ 0x8c: 0xef04, // ping
+ 0x8d: 0x24703, // for
+ 0x8f: 0x62f08, // onselect
+ 0x90: 0x30703, // map
+ 0x92: 0xc01, // p
+ 0x93: 0x8008, // reversed
+ 0x94: 0x54d0a, // onpagehide
+ 0x95: 0x3206, // keygen
+ 0x96: 0x34109, // minlength
+ 0x97: 0x3e40a, // ondragover
+ 0x98: 0x42407, // onerror
+ 0x9a: 0x2107, // charset
+ 0x9b: 0x29b06, // method
+ 0x9c: 0x101, // b
+ 0x9d: 0x68208, // ontoggle
+ 0x9e: 0x2bd06, // hidden
+ 0xa0: 0x3f607, // article
+ 0xa2: 0x63906, // onshow
+ 0xa3: 0x64d06, // onsort
+ 0xa5: 0x57b0f, // contenteditable
+ 0xa6: 0x66908, // onsubmit
+ 0xa8: 0x44f09, // oninvalid
+ 0xaa: 0x202, // br
+ 0xab: 0x10902, // id
+ 0xac: 0x5d04, // loop
+ 0xad: 0x5630a, // onpageshow
+ 0xb0: 0x2cf04, // href
+ 0xb2: 0x2210a, // figcaption
+ 0xb3: 0x2690e, // onautocomplete
+ 0xb4: 0x49106, // onload
+ 0xb6: 0x9c04, // rows
+ 0xb7: 0x1a605, // nonce
+ 0xb8: 0x68a14, // onunhandledrejection
+ 0xbb: 0x21306, // center
+ 0xbc: 0x59406, // onplay
+ 0xbd: 0x33f02, // h5
+ 0xbe: 0x49d07, // listing
+ 0xbf: 0x57606, // public
+ 0xc2: 0x23b06, // figure
+ 0xc3: 0x57a04, // icon
+ 0xc4: 0x1ab03, // col
+ 0xc5: 0x47b03, // rel
+ 0xc6: 0xe605, // media
+ 0xc7: 0x12109, // autofocus
+ 0xc8: 0x19a02, // rt
+ 0xca: 0x2d304, // lang
+ 0xcc: 0x49908, // datalist
+ 0xce: 0x2eb06, // iframe
+ 0xcf: 0x36105, // muted
+ 0xd0: 0x6140a, // onauxclick
+ 0xd2: 0x3c02, // as
+ 0xd6: 0x3fd06, // ondrop
+ 0xd7: 0x1c90a, // annotation
+ 0xd8: 0x21908, // fieldset
+ 0xdb: 0x2cf08, // hreflang
+ 0xdc: 0x4e70c, // onmouseenter
+ 0xdd: 0x2a402, // mn
+ 0xde: 0xe60a, // mediagroup
+ 0xdf: 0x9805, // meter
+ 0xe0: 0x56c03, // wbr
+ 0xe2: 0x63e05, // width
+ 0xe3: 0x2290c, // onafterprint
+ 0xe4: 0x30505, // ismap
+ 0xe5: 0x1505, // value
+ 0xe7: 0x1303, // nav
+ 0xe8: 0x54508, // ononline
+ 0xe9: 0xb604, // mark
+ 0xea: 0xc303, // low
+ 0xeb: 0x3ee0b, // ondragstart
+ 0xef: 0x12f03, // xmp
+ 0xf0: 0x22407, // caption
+ 0xf1: 0xd904, // type
+ 0xf2: 0x70907, // summary
+ 0xf3: 0x6802, // tt
+ 0xf4: 0x20809, // translate
+ 0xf5: 0x1870a, // blockquote
+ 0xf8: 0x15702, // hr
+ 0xfa: 0x2705, // tbody
+ 0xfc: 0x7b07, // picture
+ 0xfd: 0x5206, // height
+ 0xfe: 0x19c04, // cite
+ 0xff: 0x2501, // s
+ 0x101: 0xff05, // async
+ 0x102: 0x56f07, // onpaste
+ 0x103: 0x19507, // onabort
+ 0x104: 0x2b706, // target
+ 0x105: 0x14b03, // bdo
+ 0x106: 0x1f006, // coords
+ 0x107: 0x5e108, // onresize
+ 0x108: 0x71908, // template
+ 0x10a: 0x3a02, // rb
+ 0x10b: 0x2a50a, // novalidate
+ 0x10c: 0x460e, // updateviacache
+ 0x10d: 0x71003, // sup
+ 0x10e: 0x6c07, // noembed
+ 0x10f: 0x16b03, // div
+ 0x110: 0x6f707, // srclang
+ 0x111: 0x17a09, // draggable
+ 0x112: 0x67305, // scope
+ 0x113: 0x5905, // label
+ 0x114: 0x22f02, // rp
+ 0x115: 0x23f08, // required
+ 0x116: 0x3780d, // oncontextmenu
+ 0x117: 0x5e504, // size
+ 0x118: 0x5b00a, // spellcheck
+ 0x119: 0x3f04, // font
+ 0x11a: 0x9c07, // rowspan
+ 0x11b: 0x10a07, // default
+ 0x11d: 0x44307, // oninput
+ 0x11e: 0x38506, // itemid
+ 0x11f: 0x5ee04, // code
+ 0x120: 0xaa07, // acronym
+ 0x121: 0x3b04, // base
+ 0x125: 0x2470d, // foreignObject
+ 0x126: 0x2ca04, // high
+ 0x127: 0x3cb0e, // referrerpolicy
+ 0x128: 0x33703, // max
+ 0x129: 0x59d0a, // onpopstate
+ 0x12a: 0x2fc02, // h4
+ 0x12b: 0x4ac04, // meta
+ 0x12c: 0x17305, // blink
+ 0x12e: 0x5f508, // onscroll
+ 0x12f: 0x59409, // onplaying
+ 0x130: 0xc113, // allowpaymentrequest
+ 0x131: 0x19a03, // rtc
+ 0x132: 0x72b04, // wrap
+ 0x134: 0x8b08, // frameset
+ 0x135: 0x32605, // small
+ 0x137: 0x32006, // header
+ 0x138: 0x40409, // onemptied
+ 0x139: 0x34902, // h6
+ 0x13a: 0x35908, // multiple
+ 0x13c: 0x52a06, // prompt
+ 0x13f: 0x28e09, // challenge
+ 0x141: 0x4370c, // onhashchange
+ 0x142: 0x57b07, // content
+ 0x143: 0x1c90e, // annotation-xml
+ 0x144: 0x36607, // onclose
+ 0x145: 0x14d10, // oncanplaythrough
+ 0x148: 0x5170b, // onmouseover
+ 0x149: 0x64f08, // sortable
+ 0x14a: 0xa402, // mo
+ 0x14b: 0x2cd02, // h3
+ 0x14c: 0x2c406, // script
+ 0x14d: 0x41d07, // onended
+ 0x14f: 0x64706, // poster
+ 0x150: 0x7210a, // workertype
+ 0x153: 0x1f505, // shape
+ 0x154: 0x4, // abbr
+ 0x155: 0x1, // a
+ 0x156: 0x2bf02, // dd
+ 0x157: 0x71606, // system
+ 0x158: 0x4ce0e, // onmessageerror
+ 0x159: 0x36b08, // seamless
+ 0x15a: 0x2610a, // formaction
+ 0x15b: 0x6e106, // option
+ 0x15c: 0x31d04, // math
+ 0x15d: 0x62609, // onseeking
+ 0x15e: 0x39c05, // oncut
+ 0x15f: 0x44c03, // del
+ 0x160: 0x11005, // title
+ 0x161: 0x11505, // audio
+ 0x162: 0x63108, // selected
+ 0x165: 0x3b40b, // ondragenter
+ 0x166: 0x46e06, // spacer
+ 0x167: 0x4a410, // onloadedmetadata
+ 0x168: 0x44505, // input
+ 0x16a: 0x58505, // table
+ 0x16b: 0x41508, // onchange
+ 0x16e: 0x5f005, // defer
+ 0x171: 0x50a0a, // onmouseout
+ 0x172: 0x20504, // slot
+ 0x175: 0x3704, // nobr
+ 0x177: 0x1d707, // command
+ 0x17a: 0x7207, // details
+ 0x17b: 0x38104, // menu
+ 0x17c: 0xb903, // kbd
+ 0x17d: 0x57304, // step
+ 0x17e: 0x20303, // ins
+ 0x17f: 0x13c08, // autoplay
+ 0x182: 0x34103, // min
+ 0x183: 0x17404, // link
+ 0x185: 0x40d10, // ondurationchange
+ 0x186: 0x9202, // td
+ 0x187: 0x8b05, // frame
+ 0x18a: 0x2ab08, // datetime
+ 0x18b: 0x44509, // inputmode
+ 0x18c: 0x35108, // readonly
+ 0x18d: 0x21104, // face
+ 0x18f: 0x5e505, // sizes
+ 0x191: 0x4b208, // tabindex
+ 0x192: 0x6db06, // strong
+ 0x193: 0xba03, // bdi
+ 0x194: 0x6fe06, // srcset
+ 0x196: 0x67202, // ms
+ 0x197: 0x5b507, // checked
+ 0x198: 0xb105, // align
+ 0x199: 0x1e507, // section
+ 0x19b: 0x6e05, // embed
+ 0x19d: 0x15e07, // bgsound
+ 0x1a2: 0x49d04, // list
+ 0x1a3: 0x61e08, // onseeked
+ 0x1a4: 0x66009, // onstorage
+ 0x1a5: 0x2f603, // img
+ 0x1a6: 0xf505, // tfoot
+ 0x1a9: 0x26913, // onautocompleteerror
+ 0x1aa: 0x5fd19, // onsecuritypolicyviolation
+ 0x1ad: 0x9303, // dir
+ 0x1ae: 0x9307, // dirname
+ 0x1b0: 0x5a70a, // onprogress
+ 0x1b2: 0x65709, // onstalled
+ 0x1b5: 0x66f09, // itemscope
+ 0x1b6: 0x49904, // data
+ 0x1b7: 0x3d90b, // ondragleave
+ 0x1b8: 0x56102, // h2
+ 0x1b9: 0x2f706, // mglyph
+ 0x1ba: 0x16502, // is
+ 0x1bb: 0x6e50e, // onbeforeunload
+ 0x1bc: 0x2830d, // typemustmatch
+ 0x1bd: 0x3ab06, // ondrag
+ 0x1be: 0x5da07, // onreset
+ 0x1c0: 0x51106, // output
+ 0x1c1: 0x12907, // sandbox
+ 0x1c2: 0x1b209, // plaintext
+ 0x1c4: 0x34c08, // textarea
+ 0x1c7: 0xd607, // keytype
+ 0x1c8: 0x34b05, // mtext
+ 0x1c9: 0x6b10e, // onvolumechange
+ 0x1ca: 0x1ea06, // onblur
+ 0x1cb: 0x58a07, // onpause
+ 0x1cd: 0x5bc0c, // onratechange
+ 0x1ce: 0x10705, // aside
+ 0x1cf: 0x6cf07, // optimum
+ 0x1d1: 0x45809, // onkeydown
+ 0x1d2: 0x1c407, // colspan
+ 0x1d3: 0x1004, // main
+ 0x1d4: 0x66b03, // sub
+ 0x1d5: 0x25b06, // object
+ 0x1d6: 0x55c06, // search
+ 0x1d7: 0x37206, // sorted
+ 0x1d8: 0x17003, // big
+ 0x1d9: 0xb01, // u
+ 0x1db: 0x26b0c, // autocomplete
+ 0x1dc: 0xcc02, // tr
+ 0x1dd: 0xf303, // alt
+ 0x1df: 0x7804, // samp
+ 0x1e0: 0x5c812, // onrejectionhandled
+ 0x1e1: 0x4f30c, // onmouseleave
+ 0x1e2: 0x28007, // enctype
+ 0x1e3: 0xa208, // nomodule
+ 0x1e5: 0x3280f, // allowfullscreen
+ 0x1e6: 0x5f08, // optgroup
+ 0x1e8: 0x27c0b, // formenctype
+ 0x1e9: 0x18106, // legend
+ 0x1ea: 0x10306, // canvas
+ 0x1eb: 0x6607, // pattern
+ 0x1ec: 0x2c208, // noscript
+ 0x1ed: 0x601, // i
+ 0x1ee: 0x5d602, // dl
+ 0x1ef: 0xa702, // ul
+ 0x1f2: 0x52209, // onmouseup
+ 0x1f4: 0x1ba05, // track
+ 0x1f7: 0x3a10a, // ondblclick
+ 0x1f8: 0x3bf0a, // ondragexit
+ 0x1fa: 0x8703, // dfn
+ 0x1fc: 0x26506, // action
+ 0x1fd: 0x35004, // area
+ 0x1fe: 0x31607, // marquee
+ 0x1ff: 0x16d03, // var
+}
+
+const atomText = "abbradiogrouparamainavalueaccept-charsetbodyaccesskeygenobrb" +
+ "asefontimeupdateviacacheightmlabelooptgroupatternoembedetail" +
+ "sampictureversedfnoframesetdirnameterowspanomoduleacronymali" +
+ "gnmarkbdialogallowpaymentrequestrikeytypeallowusermediagroup" +
+ "ingaltfooterubyasyncanvasidefaultitleaudioncancelautofocusan" +
+ "dboxmplaceholderautoplaysinlinebdoncanplaythrough1bgsoundisa" +
+ "bledivarbigblinkindraggablegendblockquotebuttonabortcitempro" +
+ "penoncecolgrouplaintextrackcolorcolspannotation-xmlcommandco" +
+ "ntrolsectionblurcoordshapecrossoriginslotranslatefacenterfie" +
+ "ldsetfigcaptionafterprintegrityfigurequiredforeignObjectfore" +
+ "ignobjectformactionautocompleteerrorformenctypemustmatchalle" +
+ "ngeformmethodformnovalidatetimeformtargethiddenoscripthigh3h" +
+ "reflanghttp-equivideonclickiframeimageimglyph4isindexismappl" +
+ "etitemtypemarqueematheadersmallowfullscreenmaxlength5minleng" +
+ "th6mtextareadonlymultiplemutedoncloseamlessortedoncontextmen" +
+ "uitemidoncopyoncuechangeoncutondblclickondragendondragentero" +
+ "ndragexitemreferrerpolicyondragleaveondragoverondragstarticl" +
+ "eondropzonemptiedondurationchangeonendedonerroronfocusourceo" +
+ "nhashchangeoninputmodeloninvalidonkeydownloadonkeypresspacer" +
+ "onkeyupreloadonlanguagechangeonloadeddatalistingonloadedmeta" +
+ "databindexonloadendonloadstartonmessageerroronmousedownonmou" +
+ "seenteronmouseleaveonmousemoveonmouseoutputonmouseoveronmous" +
+ "eupromptonmousewheelonofflineononlineonpagehidesclassearch2o" +
+ "npageshowbronpastepublicontenteditableonpausemaponplayingonp" +
+ "opstateonprogresspellcheckedonratechangeonrejectionhandledon" +
+ "resetonresizesrcdocodeferonscrollonsecuritypolicyviolationau" +
+ "xclickonseekedonseekingonselectedonshowidthgrouposteronsorta" +
+ "bleonstalledonstorageonsubmitemscopedonsuspendontoggleonunha" +
+ "ndledrejectionbeforeprintonunloadonvolumechangeonwaitingonwh" +
+ "eeloptimumanifestrongoptionbeforeunloaddressrclangsrcsetstyl" +
+ "esummarysupsvgsystemplateworkertypewrap"
diff --git a/vendor/golang.org/x/net/html/const.go b/vendor/golang.org/x/net/html/const.go
new file mode 100644
index 00000000..ff7acf2d
--- /dev/null
+++ b/vendor/golang.org/x/net/html/const.go
@@ -0,0 +1,111 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package html
+
+// Section 12.2.4.2 of the HTML5 specification says "The following elements
+// have varying levels of special parsing rules".
+// https://html.spec.whatwg.org/multipage/syntax.html#the-stack-of-open-elements
+var isSpecialElementMap = map[string]bool{
+ "address": true,
+ "applet": true,
+ "area": true,
+ "article": true,
+ "aside": true,
+ "base": true,
+ "basefont": true,
+ "bgsound": true,
+ "blockquote": true,
+ "body": true,
+ "br": true,
+ "button": true,
+ "caption": true,
+ "center": true,
+ "col": true,
+ "colgroup": true,
+ "dd": true,
+ "details": true,
+ "dir": true,
+ "div": true,
+ "dl": true,
+ "dt": true,
+ "embed": true,
+ "fieldset": true,
+ "figcaption": true,
+ "figure": true,
+ "footer": true,
+ "form": true,
+ "frame": true,
+ "frameset": true,
+ "h1": true,
+ "h2": true,
+ "h3": true,
+ "h4": true,
+ "h5": true,
+ "h6": true,
+ "head": true,
+ "header": true,
+ "hgroup": true,
+ "hr": true,
+ "html": true,
+ "iframe": true,
+ "img": true,
+ "input": true,
+ "keygen": true, // "keygen" has been removed from the spec, but are kept here for backwards compatibility.
+ "li": true,
+ "link": true,
+ "listing": true,
+ "main": true,
+ "marquee": true,
+ "menu": true,
+ "meta": true,
+ "nav": true,
+ "noembed": true,
+ "noframes": true,
+ "noscript": true,
+ "object": true,
+ "ol": true,
+ "p": true,
+ "param": true,
+ "plaintext": true,
+ "pre": true,
+ "script": true,
+ "section": true,
+ "select": true,
+ "source": true,
+ "style": true,
+ "summary": true,
+ "table": true,
+ "tbody": true,
+ "td": true,
+ "template": true,
+ "textarea": true,
+ "tfoot": true,
+ "th": true,
+ "thead": true,
+ "title": true,
+ "tr": true,
+ "track": true,
+ "ul": true,
+ "wbr": true,
+ "xmp": true,
+}
+
+func isSpecialElement(element *Node) bool {
+ switch element.Namespace {
+ case "", "html":
+ return isSpecialElementMap[element.Data]
+ case "math":
+ switch element.Data {
+ case "mi", "mo", "mn", "ms", "mtext", "annotation-xml":
+ return true
+ }
+ case "svg":
+ switch element.Data {
+ case "foreignObject", "desc", "title":
+ return true
+ }
+ }
+ return false
+}
diff --git a/vendor/golang.org/x/net/html/doc.go b/vendor/golang.org/x/net/html/doc.go
new file mode 100644
index 00000000..885c4c59
--- /dev/null
+++ b/vendor/golang.org/x/net/html/doc.go
@@ -0,0 +1,122 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package html implements an HTML5-compliant tokenizer and parser.
+
+Tokenization is done by creating a Tokenizer for an io.Reader r. It is the
+caller's responsibility to ensure that r provides UTF-8 encoded HTML.
+
+ z := html.NewTokenizer(r)
+
+Given a Tokenizer z, the HTML is tokenized by repeatedly calling z.Next(),
+which parses the next token and returns its type, or an error:
+
+ for {
+ tt := z.Next()
+ if tt == html.ErrorToken {
+ // ...
+ return ...
+ }
+ // Process the current token.
+ }
+
+There are two APIs for retrieving the current token. The high-level API is to
+call Token; the low-level API is to call Text or TagName / TagAttr. Both APIs
+allow optionally calling Raw after Next but before Token, Text, TagName, or
+TagAttr. In EBNF notation, the valid call sequence per token is:
+
+ Next {Raw} [ Token | Text | TagName {TagAttr} ]
+
+Token returns an independent data structure that completely describes a token.
+Entities (such as "<") are unescaped, tag names and attribute keys are
+lower-cased, and attributes are collected into a []Attribute. For example:
+
+ for {
+ if z.Next() == html.ErrorToken {
+ // Returning io.EOF indicates success.
+ return z.Err()
+ }
+ emitToken(z.Token())
+ }
+
+The low-level API performs fewer allocations and copies, but the contents of
+the []byte values returned by Text, TagName and TagAttr may change on the next
+call to Next. For example, to extract an HTML page's anchor text:
+
+ depth := 0
+ for {
+ tt := z.Next()
+ switch tt {
+ case html.ErrorToken:
+ return z.Err()
+ case html.TextToken:
+ if depth > 0 {
+ // emitBytes should copy the []byte it receives,
+ // if it doesn't process it immediately.
+ emitBytes(z.Text())
+ }
+ case html.StartTagToken, html.EndTagToken:
+ tn, _ := z.TagName()
+ if len(tn) == 1 && tn[0] == 'a' {
+ if tt == html.StartTagToken {
+ depth++
+ } else {
+ depth--
+ }
+ }
+ }
+ }
+
+Parsing is done by calling Parse with an io.Reader, which returns the root of
+the parse tree (the document element) as a *Node. It is the caller's
+responsibility to ensure that the Reader provides UTF-8 encoded HTML. For
+example, to process each anchor node in depth-first order:
+
+ doc, err := html.Parse(r)
+ if err != nil {
+ // ...
+ }
+ for n := range doc.Descendants() {
+ if n.Type == html.ElementNode && n.Data == "a" {
+ // Do something with n...
+ }
+ }
+
+The relevant specifications include:
+https://html.spec.whatwg.org/multipage/syntax.html and
+https://html.spec.whatwg.org/multipage/syntax.html#tokenization
+
+# Security Considerations
+
+Care should be taken when parsing and interpreting HTML, whether full documents
+or fragments, within the framework of the HTML specification, especially with
+regard to untrusted inputs.
+
+This package provides both a tokenizer and a parser, which implement the
+tokenization, and tokenization and tree construction stages of the WHATWG HTML
+parsing specification respectively. While the tokenizer parses and normalizes
+individual HTML tokens, only the parser constructs the DOM tree from the
+tokenized HTML, as described in the tree construction stage of the
+specification, dynamically modifying or extending the document's DOM tree.
+
+If your use case requires semantically well-formed HTML documents, as defined by
+the WHATWG specification, the parser should be used rather than the tokenizer.
+
+In security contexts, if trust decisions are being made using the tokenized or
+parsed content, the input must be re-serialized (for instance by using Render or
+Token.String) in order for those trust decisions to hold, as the process of
+tokenization or parsing may alter the content.
+*/
+package html // import "golang.org/x/net/html"
+
+// The tokenization algorithm implemented by this package is not a line-by-line
+// transliteration of the relatively verbose state-machine in the WHATWG
+// specification. A more direct approach is used instead, where the program
+// counter implies the state, such as whether it is tokenizing a tag or a text
+// node. Specification compliance is verified by checking expected and actual
+// outputs over a test suite rather than aiming for algorithmic fidelity.
+
+// TODO(nigeltao): Does a DOM API belong in this package or a separate one?
+// TODO(nigeltao): How does parsing interact with a JavaScript engine?
diff --git a/vendor/golang.org/x/net/html/doctype.go b/vendor/golang.org/x/net/html/doctype.go
new file mode 100644
index 00000000..bca3ae9a
--- /dev/null
+++ b/vendor/golang.org/x/net/html/doctype.go
@@ -0,0 +1,156 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package html
+
+import (
+ "strings"
+)
+
+// parseDoctype parses the data from a DoctypeToken into a name,
+// public identifier, and system identifier. It returns a Node whose Type
+// is DoctypeNode, whose Data is the name, and which has attributes
+// named "system" and "public" for the two identifiers if they were present.
+// quirks is whether the document should be parsed in "quirks mode".
+func parseDoctype(s string) (n *Node, quirks bool) {
+ n = &Node{Type: DoctypeNode}
+
+ // Find the name.
+ space := strings.IndexAny(s, whitespace)
+ if space == -1 {
+ space = len(s)
+ }
+ n.Data = s[:space]
+ // The comparison to "html" is case-sensitive.
+ if n.Data != "html" {
+ quirks = true
+ }
+ n.Data = strings.ToLower(n.Data)
+ s = strings.TrimLeft(s[space:], whitespace)
+
+ if len(s) < 6 {
+ // It can't start with "PUBLIC" or "SYSTEM".
+ // Ignore the rest of the string.
+ return n, quirks || s != ""
+ }
+
+ key := strings.ToLower(s[:6])
+ s = s[6:]
+ for key == "public" || key == "system" {
+ s = strings.TrimLeft(s, whitespace)
+ if s == "" {
+ break
+ }
+ quote := s[0]
+ if quote != '"' && quote != '\'' {
+ break
+ }
+ s = s[1:]
+ q := strings.IndexRune(s, rune(quote))
+ var id string
+ if q == -1 {
+ id = s
+ s = ""
+ } else {
+ id = s[:q]
+ s = s[q+1:]
+ }
+ n.Attr = append(n.Attr, Attribute{Key: key, Val: id})
+ if key == "public" {
+ key = "system"
+ } else {
+ key = ""
+ }
+ }
+
+ if key != "" || s != "" {
+ quirks = true
+ } else if len(n.Attr) > 0 {
+ if n.Attr[0].Key == "public" {
+ public := strings.ToLower(n.Attr[0].Val)
+ switch public {
+ case "-//w3o//dtd w3 html strict 3.0//en//", "-/w3d/dtd html 4.0 transitional/en", "html":
+ quirks = true
+ default:
+ for _, q := range quirkyIDs {
+ if strings.HasPrefix(public, q) {
+ quirks = true
+ break
+ }
+ }
+ }
+ // The following two public IDs only cause quirks mode if there is no system ID.
+ if len(n.Attr) == 1 && (strings.HasPrefix(public, "-//w3c//dtd html 4.01 frameset//") ||
+ strings.HasPrefix(public, "-//w3c//dtd html 4.01 transitional//")) {
+ quirks = true
+ }
+ }
+ if lastAttr := n.Attr[len(n.Attr)-1]; lastAttr.Key == "system" &&
+ strings.EqualFold(lastAttr.Val, "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd") {
+ quirks = true
+ }
+ }
+
+ return n, quirks
+}
+
+// quirkyIDs is a list of public doctype identifiers that cause a document
+// to be interpreted in quirks mode. The identifiers should be in lower case.
+var quirkyIDs = []string{
+ "+//silmaril//dtd html pro v0r11 19970101//",
+ "-//advasoft ltd//dtd html 3.0 aswedit + extensions//",
+ "-//as//dtd html 3.0 aswedit + extensions//",
+ "-//ietf//dtd html 2.0 level 1//",
+ "-//ietf//dtd html 2.0 level 2//",
+ "-//ietf//dtd html 2.0 strict level 1//",
+ "-//ietf//dtd html 2.0 strict level 2//",
+ "-//ietf//dtd html 2.0 strict//",
+ "-//ietf//dtd html 2.0//",
+ "-//ietf//dtd html 2.1e//",
+ "-//ietf//dtd html 3.0//",
+ "-//ietf//dtd html 3.2 final//",
+ "-//ietf//dtd html 3.2//",
+ "-//ietf//dtd html 3//",
+ "-//ietf//dtd html level 0//",
+ "-//ietf//dtd html level 1//",
+ "-//ietf//dtd html level 2//",
+ "-//ietf//dtd html level 3//",
+ "-//ietf//dtd html strict level 0//",
+ "-//ietf//dtd html strict level 1//",
+ "-//ietf//dtd html strict level 2//",
+ "-//ietf//dtd html strict level 3//",
+ "-//ietf//dtd html strict//",
+ "-//ietf//dtd html//",
+ "-//metrius//dtd metrius presentational//",
+ "-//microsoft//dtd internet explorer 2.0 html strict//",
+ "-//microsoft//dtd internet explorer 2.0 html//",
+ "-//microsoft//dtd internet explorer 2.0 tables//",
+ "-//microsoft//dtd internet explorer 3.0 html strict//",
+ "-//microsoft//dtd internet explorer 3.0 html//",
+ "-//microsoft//dtd internet explorer 3.0 tables//",
+ "-//netscape comm. corp.//dtd html//",
+ "-//netscape comm. corp.//dtd strict html//",
+ "-//o'reilly and associates//dtd html 2.0//",
+ "-//o'reilly and associates//dtd html extended 1.0//",
+ "-//o'reilly and associates//dtd html extended relaxed 1.0//",
+ "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//",
+ "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//",
+ "-//spyglass//dtd html 2.0 extended//",
+ "-//sq//dtd html 2.0 hotmetal + extensions//",
+ "-//sun microsystems corp.//dtd hotjava html//",
+ "-//sun microsystems corp.//dtd hotjava strict html//",
+ "-//w3c//dtd html 3 1995-03-24//",
+ "-//w3c//dtd html 3.2 draft//",
+ "-//w3c//dtd html 3.2 final//",
+ "-//w3c//dtd html 3.2//",
+ "-//w3c//dtd html 3.2s draft//",
+ "-//w3c//dtd html 4.0 frameset//",
+ "-//w3c//dtd html 4.0 transitional//",
+ "-//w3c//dtd html experimental 19960712//",
+ "-//w3c//dtd html experimental 970421//",
+ "-//w3c//dtd w3 html//",
+ "-//w3o//dtd w3 html 3.0//",
+ "-//webtechs//dtd mozilla html 2.0//",
+ "-//webtechs//dtd mozilla html//",
+}
diff --git a/vendor/golang.org/x/net/html/entity.go b/vendor/golang.org/x/net/html/entity.go
new file mode 100644
index 00000000..b628880a
--- /dev/null
+++ b/vendor/golang.org/x/net/html/entity.go
@@ -0,0 +1,2253 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package html
+
+// All entities that do not end with ';' are 6 or fewer bytes long.
+const longestEntityWithoutSemicolon = 6
+
+// entity is a map from HTML entity names to their values. The semicolon matters:
+// https://html.spec.whatwg.org/multipage/syntax.html#named-character-references
+// lists both "amp" and "amp;" as two separate entries.
+//
+// Note that the HTML5 list is larger than the HTML4 list at
+// http://www.w3.org/TR/html4/sgml/entities.html
+var entity = map[string]rune{
+ "AElig;": '\U000000C6',
+ "AMP;": '\U00000026',
+ "Aacute;": '\U000000C1',
+ "Abreve;": '\U00000102',
+ "Acirc;": '\U000000C2',
+ "Acy;": '\U00000410',
+ "Afr;": '\U0001D504',
+ "Agrave;": '\U000000C0',
+ "Alpha;": '\U00000391',
+ "Amacr;": '\U00000100',
+ "And;": '\U00002A53',
+ "Aogon;": '\U00000104',
+ "Aopf;": '\U0001D538',
+ "ApplyFunction;": '\U00002061',
+ "Aring;": '\U000000C5',
+ "Ascr;": '\U0001D49C',
+ "Assign;": '\U00002254',
+ "Atilde;": '\U000000C3',
+ "Auml;": '\U000000C4',
+ "Backslash;": '\U00002216',
+ "Barv;": '\U00002AE7',
+ "Barwed;": '\U00002306',
+ "Bcy;": '\U00000411',
+ "Because;": '\U00002235',
+ "Bernoullis;": '\U0000212C',
+ "Beta;": '\U00000392',
+ "Bfr;": '\U0001D505',
+ "Bopf;": '\U0001D539',
+ "Breve;": '\U000002D8',
+ "Bscr;": '\U0000212C',
+ "Bumpeq;": '\U0000224E',
+ "CHcy;": '\U00000427',
+ "COPY;": '\U000000A9',
+ "Cacute;": '\U00000106',
+ "Cap;": '\U000022D2',
+ "CapitalDifferentialD;": '\U00002145',
+ "Cayleys;": '\U0000212D',
+ "Ccaron;": '\U0000010C',
+ "Ccedil;": '\U000000C7',
+ "Ccirc;": '\U00000108',
+ "Cconint;": '\U00002230',
+ "Cdot;": '\U0000010A',
+ "Cedilla;": '\U000000B8',
+ "CenterDot;": '\U000000B7',
+ "Cfr;": '\U0000212D',
+ "Chi;": '\U000003A7',
+ "CircleDot;": '\U00002299',
+ "CircleMinus;": '\U00002296',
+ "CirclePlus;": '\U00002295',
+ "CircleTimes;": '\U00002297',
+ "ClockwiseContourIntegral;": '\U00002232',
+ "CloseCurlyDoubleQuote;": '\U0000201D',
+ "CloseCurlyQuote;": '\U00002019',
+ "Colon;": '\U00002237',
+ "Colone;": '\U00002A74',
+ "Congruent;": '\U00002261',
+ "Conint;": '\U0000222F',
+ "ContourIntegral;": '\U0000222E',
+ "Copf;": '\U00002102',
+ "Coproduct;": '\U00002210',
+ "CounterClockwiseContourIntegral;": '\U00002233',
+ "Cross;": '\U00002A2F',
+ "Cscr;": '\U0001D49E',
+ "Cup;": '\U000022D3',
+ "CupCap;": '\U0000224D',
+ "DD;": '\U00002145',
+ "DDotrahd;": '\U00002911',
+ "DJcy;": '\U00000402',
+ "DScy;": '\U00000405',
+ "DZcy;": '\U0000040F',
+ "Dagger;": '\U00002021',
+ "Darr;": '\U000021A1',
+ "Dashv;": '\U00002AE4',
+ "Dcaron;": '\U0000010E',
+ "Dcy;": '\U00000414',
+ "Del;": '\U00002207',
+ "Delta;": '\U00000394',
+ "Dfr;": '\U0001D507',
+ "DiacriticalAcute;": '\U000000B4',
+ "DiacriticalDot;": '\U000002D9',
+ "DiacriticalDoubleAcute;": '\U000002DD',
+ "DiacriticalGrave;": '\U00000060',
+ "DiacriticalTilde;": '\U000002DC',
+ "Diamond;": '\U000022C4',
+ "DifferentialD;": '\U00002146',
+ "Dopf;": '\U0001D53B',
+ "Dot;": '\U000000A8',
+ "DotDot;": '\U000020DC',
+ "DotEqual;": '\U00002250',
+ "DoubleContourIntegral;": '\U0000222F',
+ "DoubleDot;": '\U000000A8',
+ "DoubleDownArrow;": '\U000021D3',
+ "DoubleLeftArrow;": '\U000021D0',
+ "DoubleLeftRightArrow;": '\U000021D4',
+ "DoubleLeftTee;": '\U00002AE4',
+ "DoubleLongLeftArrow;": '\U000027F8',
+ "DoubleLongLeftRightArrow;": '\U000027FA',
+ "DoubleLongRightArrow;": '\U000027F9',
+ "DoubleRightArrow;": '\U000021D2',
+ "DoubleRightTee;": '\U000022A8',
+ "DoubleUpArrow;": '\U000021D1',
+ "DoubleUpDownArrow;": '\U000021D5',
+ "DoubleVerticalBar;": '\U00002225',
+ "DownArrow;": '\U00002193',
+ "DownArrowBar;": '\U00002913',
+ "DownArrowUpArrow;": '\U000021F5',
+ "DownBreve;": '\U00000311',
+ "DownLeftRightVector;": '\U00002950',
+ "DownLeftTeeVector;": '\U0000295E',
+ "DownLeftVector;": '\U000021BD',
+ "DownLeftVectorBar;": '\U00002956',
+ "DownRightTeeVector;": '\U0000295F',
+ "DownRightVector;": '\U000021C1',
+ "DownRightVectorBar;": '\U00002957',
+ "DownTee;": '\U000022A4',
+ "DownTeeArrow;": '\U000021A7',
+ "Downarrow;": '\U000021D3',
+ "Dscr;": '\U0001D49F',
+ "Dstrok;": '\U00000110',
+ "ENG;": '\U0000014A',
+ "ETH;": '\U000000D0',
+ "Eacute;": '\U000000C9',
+ "Ecaron;": '\U0000011A',
+ "Ecirc;": '\U000000CA',
+ "Ecy;": '\U0000042D',
+ "Edot;": '\U00000116',
+ "Efr;": '\U0001D508',
+ "Egrave;": '\U000000C8',
+ "Element;": '\U00002208',
+ "Emacr;": '\U00000112',
+ "EmptySmallSquare;": '\U000025FB',
+ "EmptyVerySmallSquare;": '\U000025AB',
+ "Eogon;": '\U00000118',
+ "Eopf;": '\U0001D53C',
+ "Epsilon;": '\U00000395',
+ "Equal;": '\U00002A75',
+ "EqualTilde;": '\U00002242',
+ "Equilibrium;": '\U000021CC',
+ "Escr;": '\U00002130',
+ "Esim;": '\U00002A73',
+ "Eta;": '\U00000397',
+ "Euml;": '\U000000CB',
+ "Exists;": '\U00002203',
+ "ExponentialE;": '\U00002147',
+ "Fcy;": '\U00000424',
+ "Ffr;": '\U0001D509',
+ "FilledSmallSquare;": '\U000025FC',
+ "FilledVerySmallSquare;": '\U000025AA',
+ "Fopf;": '\U0001D53D',
+ "ForAll;": '\U00002200',
+ "Fouriertrf;": '\U00002131',
+ "Fscr;": '\U00002131',
+ "GJcy;": '\U00000403',
+ "GT;": '\U0000003E',
+ "Gamma;": '\U00000393',
+ "Gammad;": '\U000003DC',
+ "Gbreve;": '\U0000011E',
+ "Gcedil;": '\U00000122',
+ "Gcirc;": '\U0000011C',
+ "Gcy;": '\U00000413',
+ "Gdot;": '\U00000120',
+ "Gfr;": '\U0001D50A',
+ "Gg;": '\U000022D9',
+ "Gopf;": '\U0001D53E',
+ "GreaterEqual;": '\U00002265',
+ "GreaterEqualLess;": '\U000022DB',
+ "GreaterFullEqual;": '\U00002267',
+ "GreaterGreater;": '\U00002AA2',
+ "GreaterLess;": '\U00002277',
+ "GreaterSlantEqual;": '\U00002A7E',
+ "GreaterTilde;": '\U00002273',
+ "Gscr;": '\U0001D4A2',
+ "Gt;": '\U0000226B',
+ "HARDcy;": '\U0000042A',
+ "Hacek;": '\U000002C7',
+ "Hat;": '\U0000005E',
+ "Hcirc;": '\U00000124',
+ "Hfr;": '\U0000210C',
+ "HilbertSpace;": '\U0000210B',
+ "Hopf;": '\U0000210D',
+ "HorizontalLine;": '\U00002500',
+ "Hscr;": '\U0000210B',
+ "Hstrok;": '\U00000126',
+ "HumpDownHump;": '\U0000224E',
+ "HumpEqual;": '\U0000224F',
+ "IEcy;": '\U00000415',
+ "IJlig;": '\U00000132',
+ "IOcy;": '\U00000401',
+ "Iacute;": '\U000000CD',
+ "Icirc;": '\U000000CE',
+ "Icy;": '\U00000418',
+ "Idot;": '\U00000130',
+ "Ifr;": '\U00002111',
+ "Igrave;": '\U000000CC',
+ "Im;": '\U00002111',
+ "Imacr;": '\U0000012A',
+ "ImaginaryI;": '\U00002148',
+ "Implies;": '\U000021D2',
+ "Int;": '\U0000222C',
+ "Integral;": '\U0000222B',
+ "Intersection;": '\U000022C2',
+ "InvisibleComma;": '\U00002063',
+ "InvisibleTimes;": '\U00002062',
+ "Iogon;": '\U0000012E',
+ "Iopf;": '\U0001D540',
+ "Iota;": '\U00000399',
+ "Iscr;": '\U00002110',
+ "Itilde;": '\U00000128',
+ "Iukcy;": '\U00000406',
+ "Iuml;": '\U000000CF',
+ "Jcirc;": '\U00000134',
+ "Jcy;": '\U00000419',
+ "Jfr;": '\U0001D50D',
+ "Jopf;": '\U0001D541',
+ "Jscr;": '\U0001D4A5',
+ "Jsercy;": '\U00000408',
+ "Jukcy;": '\U00000404',
+ "KHcy;": '\U00000425',
+ "KJcy;": '\U0000040C',
+ "Kappa;": '\U0000039A',
+ "Kcedil;": '\U00000136',
+ "Kcy;": '\U0000041A',
+ "Kfr;": '\U0001D50E',
+ "Kopf;": '\U0001D542',
+ "Kscr;": '\U0001D4A6',
+ "LJcy;": '\U00000409',
+ "LT;": '\U0000003C',
+ "Lacute;": '\U00000139',
+ "Lambda;": '\U0000039B',
+ "Lang;": '\U000027EA',
+ "Laplacetrf;": '\U00002112',
+ "Larr;": '\U0000219E',
+ "Lcaron;": '\U0000013D',
+ "Lcedil;": '\U0000013B',
+ "Lcy;": '\U0000041B',
+ "LeftAngleBracket;": '\U000027E8',
+ "LeftArrow;": '\U00002190',
+ "LeftArrowBar;": '\U000021E4',
+ "LeftArrowRightArrow;": '\U000021C6',
+ "LeftCeiling;": '\U00002308',
+ "LeftDoubleBracket;": '\U000027E6',
+ "LeftDownTeeVector;": '\U00002961',
+ "LeftDownVector;": '\U000021C3',
+ "LeftDownVectorBar;": '\U00002959',
+ "LeftFloor;": '\U0000230A',
+ "LeftRightArrow;": '\U00002194',
+ "LeftRightVector;": '\U0000294E',
+ "LeftTee;": '\U000022A3',
+ "LeftTeeArrow;": '\U000021A4',
+ "LeftTeeVector;": '\U0000295A',
+ "LeftTriangle;": '\U000022B2',
+ "LeftTriangleBar;": '\U000029CF',
+ "LeftTriangleEqual;": '\U000022B4',
+ "LeftUpDownVector;": '\U00002951',
+ "LeftUpTeeVector;": '\U00002960',
+ "LeftUpVector;": '\U000021BF',
+ "LeftUpVectorBar;": '\U00002958',
+ "LeftVector;": '\U000021BC',
+ "LeftVectorBar;": '\U00002952',
+ "Leftarrow;": '\U000021D0',
+ "Leftrightarrow;": '\U000021D4',
+ "LessEqualGreater;": '\U000022DA',
+ "LessFullEqual;": '\U00002266',
+ "LessGreater;": '\U00002276',
+ "LessLess;": '\U00002AA1',
+ "LessSlantEqual;": '\U00002A7D',
+ "LessTilde;": '\U00002272',
+ "Lfr;": '\U0001D50F',
+ "Ll;": '\U000022D8',
+ "Lleftarrow;": '\U000021DA',
+ "Lmidot;": '\U0000013F',
+ "LongLeftArrow;": '\U000027F5',
+ "LongLeftRightArrow;": '\U000027F7',
+ "LongRightArrow;": '\U000027F6',
+ "Longleftarrow;": '\U000027F8',
+ "Longleftrightarrow;": '\U000027FA',
+ "Longrightarrow;": '\U000027F9',
+ "Lopf;": '\U0001D543',
+ "LowerLeftArrow;": '\U00002199',
+ "LowerRightArrow;": '\U00002198',
+ "Lscr;": '\U00002112',
+ "Lsh;": '\U000021B0',
+ "Lstrok;": '\U00000141',
+ "Lt;": '\U0000226A',
+ "Map;": '\U00002905',
+ "Mcy;": '\U0000041C',
+ "MediumSpace;": '\U0000205F',
+ "Mellintrf;": '\U00002133',
+ "Mfr;": '\U0001D510',
+ "MinusPlus;": '\U00002213',
+ "Mopf;": '\U0001D544',
+ "Mscr;": '\U00002133',
+ "Mu;": '\U0000039C',
+ "NJcy;": '\U0000040A',
+ "Nacute;": '\U00000143',
+ "Ncaron;": '\U00000147',
+ "Ncedil;": '\U00000145',
+ "Ncy;": '\U0000041D',
+ "NegativeMediumSpace;": '\U0000200B',
+ "NegativeThickSpace;": '\U0000200B',
+ "NegativeThinSpace;": '\U0000200B',
+ "NegativeVeryThinSpace;": '\U0000200B',
+ "NestedGreaterGreater;": '\U0000226B',
+ "NestedLessLess;": '\U0000226A',
+ "NewLine;": '\U0000000A',
+ "Nfr;": '\U0001D511',
+ "NoBreak;": '\U00002060',
+ "NonBreakingSpace;": '\U000000A0',
+ "Nopf;": '\U00002115',
+ "Not;": '\U00002AEC',
+ "NotCongruent;": '\U00002262',
+ "NotCupCap;": '\U0000226D',
+ "NotDoubleVerticalBar;": '\U00002226',
+ "NotElement;": '\U00002209',
+ "NotEqual;": '\U00002260',
+ "NotExists;": '\U00002204',
+ "NotGreater;": '\U0000226F',
+ "NotGreaterEqual;": '\U00002271',
+ "NotGreaterLess;": '\U00002279',
+ "NotGreaterTilde;": '\U00002275',
+ "NotLeftTriangle;": '\U000022EA',
+ "NotLeftTriangleEqual;": '\U000022EC',
+ "NotLess;": '\U0000226E',
+ "NotLessEqual;": '\U00002270',
+ "NotLessGreater;": '\U00002278',
+ "NotLessTilde;": '\U00002274',
+ "NotPrecedes;": '\U00002280',
+ "NotPrecedesSlantEqual;": '\U000022E0',
+ "NotReverseElement;": '\U0000220C',
+ "NotRightTriangle;": '\U000022EB',
+ "NotRightTriangleEqual;": '\U000022ED',
+ "NotSquareSubsetEqual;": '\U000022E2',
+ "NotSquareSupersetEqual;": '\U000022E3',
+ "NotSubsetEqual;": '\U00002288',
+ "NotSucceeds;": '\U00002281',
+ "NotSucceedsSlantEqual;": '\U000022E1',
+ "NotSupersetEqual;": '\U00002289',
+ "NotTilde;": '\U00002241',
+ "NotTildeEqual;": '\U00002244',
+ "NotTildeFullEqual;": '\U00002247',
+ "NotTildeTilde;": '\U00002249',
+ "NotVerticalBar;": '\U00002224',
+ "Nscr;": '\U0001D4A9',
+ "Ntilde;": '\U000000D1',
+ "Nu;": '\U0000039D',
+ "OElig;": '\U00000152',
+ "Oacute;": '\U000000D3',
+ "Ocirc;": '\U000000D4',
+ "Ocy;": '\U0000041E',
+ "Odblac;": '\U00000150',
+ "Ofr;": '\U0001D512',
+ "Ograve;": '\U000000D2',
+ "Omacr;": '\U0000014C',
+ "Omega;": '\U000003A9',
+ "Omicron;": '\U0000039F',
+ "Oopf;": '\U0001D546',
+ "OpenCurlyDoubleQuote;": '\U0000201C',
+ "OpenCurlyQuote;": '\U00002018',
+ "Or;": '\U00002A54',
+ "Oscr;": '\U0001D4AA',
+ "Oslash;": '\U000000D8',
+ "Otilde;": '\U000000D5',
+ "Otimes;": '\U00002A37',
+ "Ouml;": '\U000000D6',
+ "OverBar;": '\U0000203E',
+ "OverBrace;": '\U000023DE',
+ "OverBracket;": '\U000023B4',
+ "OverParenthesis;": '\U000023DC',
+ "PartialD;": '\U00002202',
+ "Pcy;": '\U0000041F',
+ "Pfr;": '\U0001D513',
+ "Phi;": '\U000003A6',
+ "Pi;": '\U000003A0',
+ "PlusMinus;": '\U000000B1',
+ "Poincareplane;": '\U0000210C',
+ "Popf;": '\U00002119',
+ "Pr;": '\U00002ABB',
+ "Precedes;": '\U0000227A',
+ "PrecedesEqual;": '\U00002AAF',
+ "PrecedesSlantEqual;": '\U0000227C',
+ "PrecedesTilde;": '\U0000227E',
+ "Prime;": '\U00002033',
+ "Product;": '\U0000220F',
+ "Proportion;": '\U00002237',
+ "Proportional;": '\U0000221D',
+ "Pscr;": '\U0001D4AB',
+ "Psi;": '\U000003A8',
+ "QUOT;": '\U00000022',
+ "Qfr;": '\U0001D514',
+ "Qopf;": '\U0000211A',
+ "Qscr;": '\U0001D4AC',
+ "RBarr;": '\U00002910',
+ "REG;": '\U000000AE',
+ "Racute;": '\U00000154',
+ "Rang;": '\U000027EB',
+ "Rarr;": '\U000021A0',
+ "Rarrtl;": '\U00002916',
+ "Rcaron;": '\U00000158',
+ "Rcedil;": '\U00000156',
+ "Rcy;": '\U00000420',
+ "Re;": '\U0000211C',
+ "ReverseElement;": '\U0000220B',
+ "ReverseEquilibrium;": '\U000021CB',
+ "ReverseUpEquilibrium;": '\U0000296F',
+ "Rfr;": '\U0000211C',
+ "Rho;": '\U000003A1',
+ "RightAngleBracket;": '\U000027E9',
+ "RightArrow;": '\U00002192',
+ "RightArrowBar;": '\U000021E5',
+ "RightArrowLeftArrow;": '\U000021C4',
+ "RightCeiling;": '\U00002309',
+ "RightDoubleBracket;": '\U000027E7',
+ "RightDownTeeVector;": '\U0000295D',
+ "RightDownVector;": '\U000021C2',
+ "RightDownVectorBar;": '\U00002955',
+ "RightFloor;": '\U0000230B',
+ "RightTee;": '\U000022A2',
+ "RightTeeArrow;": '\U000021A6',
+ "RightTeeVector;": '\U0000295B',
+ "RightTriangle;": '\U000022B3',
+ "RightTriangleBar;": '\U000029D0',
+ "RightTriangleEqual;": '\U000022B5',
+ "RightUpDownVector;": '\U0000294F',
+ "RightUpTeeVector;": '\U0000295C',
+ "RightUpVector;": '\U000021BE',
+ "RightUpVectorBar;": '\U00002954',
+ "RightVector;": '\U000021C0',
+ "RightVectorBar;": '\U00002953',
+ "Rightarrow;": '\U000021D2',
+ "Ropf;": '\U0000211D',
+ "RoundImplies;": '\U00002970',
+ "Rrightarrow;": '\U000021DB',
+ "Rscr;": '\U0000211B',
+ "Rsh;": '\U000021B1',
+ "RuleDelayed;": '\U000029F4',
+ "SHCHcy;": '\U00000429',
+ "SHcy;": '\U00000428',
+ "SOFTcy;": '\U0000042C',
+ "Sacute;": '\U0000015A',
+ "Sc;": '\U00002ABC',
+ "Scaron;": '\U00000160',
+ "Scedil;": '\U0000015E',
+ "Scirc;": '\U0000015C',
+ "Scy;": '\U00000421',
+ "Sfr;": '\U0001D516',
+ "ShortDownArrow;": '\U00002193',
+ "ShortLeftArrow;": '\U00002190',
+ "ShortRightArrow;": '\U00002192',
+ "ShortUpArrow;": '\U00002191',
+ "Sigma;": '\U000003A3',
+ "SmallCircle;": '\U00002218',
+ "Sopf;": '\U0001D54A',
+ "Sqrt;": '\U0000221A',
+ "Square;": '\U000025A1',
+ "SquareIntersection;": '\U00002293',
+ "SquareSubset;": '\U0000228F',
+ "SquareSubsetEqual;": '\U00002291',
+ "SquareSuperset;": '\U00002290',
+ "SquareSupersetEqual;": '\U00002292',
+ "SquareUnion;": '\U00002294',
+ "Sscr;": '\U0001D4AE',
+ "Star;": '\U000022C6',
+ "Sub;": '\U000022D0',
+ "Subset;": '\U000022D0',
+ "SubsetEqual;": '\U00002286',
+ "Succeeds;": '\U0000227B',
+ "SucceedsEqual;": '\U00002AB0',
+ "SucceedsSlantEqual;": '\U0000227D',
+ "SucceedsTilde;": '\U0000227F',
+ "SuchThat;": '\U0000220B',
+ "Sum;": '\U00002211',
+ "Sup;": '\U000022D1',
+ "Superset;": '\U00002283',
+ "SupersetEqual;": '\U00002287',
+ "Supset;": '\U000022D1',
+ "THORN;": '\U000000DE',
+ "TRADE;": '\U00002122',
+ "TSHcy;": '\U0000040B',
+ "TScy;": '\U00000426',
+ "Tab;": '\U00000009',
+ "Tau;": '\U000003A4',
+ "Tcaron;": '\U00000164',
+ "Tcedil;": '\U00000162',
+ "Tcy;": '\U00000422',
+ "Tfr;": '\U0001D517',
+ "Therefore;": '\U00002234',
+ "Theta;": '\U00000398',
+ "ThinSpace;": '\U00002009',
+ "Tilde;": '\U0000223C',
+ "TildeEqual;": '\U00002243',
+ "TildeFullEqual;": '\U00002245',
+ "TildeTilde;": '\U00002248',
+ "Topf;": '\U0001D54B',
+ "TripleDot;": '\U000020DB',
+ "Tscr;": '\U0001D4AF',
+ "Tstrok;": '\U00000166',
+ "Uacute;": '\U000000DA',
+ "Uarr;": '\U0000219F',
+ "Uarrocir;": '\U00002949',
+ "Ubrcy;": '\U0000040E',
+ "Ubreve;": '\U0000016C',
+ "Ucirc;": '\U000000DB',
+ "Ucy;": '\U00000423',
+ "Udblac;": '\U00000170',
+ "Ufr;": '\U0001D518',
+ "Ugrave;": '\U000000D9',
+ "Umacr;": '\U0000016A',
+ "UnderBar;": '\U0000005F',
+ "UnderBrace;": '\U000023DF',
+ "UnderBracket;": '\U000023B5',
+ "UnderParenthesis;": '\U000023DD',
+ "Union;": '\U000022C3',
+ "UnionPlus;": '\U0000228E',
+ "Uogon;": '\U00000172',
+ "Uopf;": '\U0001D54C',
+ "UpArrow;": '\U00002191',
+ "UpArrowBar;": '\U00002912',
+ "UpArrowDownArrow;": '\U000021C5',
+ "UpDownArrow;": '\U00002195',
+ "UpEquilibrium;": '\U0000296E',
+ "UpTee;": '\U000022A5',
+ "UpTeeArrow;": '\U000021A5',
+ "Uparrow;": '\U000021D1',
+ "Updownarrow;": '\U000021D5',
+ "UpperLeftArrow;": '\U00002196',
+ "UpperRightArrow;": '\U00002197',
+ "Upsi;": '\U000003D2',
+ "Upsilon;": '\U000003A5',
+ "Uring;": '\U0000016E',
+ "Uscr;": '\U0001D4B0',
+ "Utilde;": '\U00000168',
+ "Uuml;": '\U000000DC',
+ "VDash;": '\U000022AB',
+ "Vbar;": '\U00002AEB',
+ "Vcy;": '\U00000412',
+ "Vdash;": '\U000022A9',
+ "Vdashl;": '\U00002AE6',
+ "Vee;": '\U000022C1',
+ "Verbar;": '\U00002016',
+ "Vert;": '\U00002016',
+ "VerticalBar;": '\U00002223',
+ "VerticalLine;": '\U0000007C',
+ "VerticalSeparator;": '\U00002758',
+ "VerticalTilde;": '\U00002240',
+ "VeryThinSpace;": '\U0000200A',
+ "Vfr;": '\U0001D519',
+ "Vopf;": '\U0001D54D',
+ "Vscr;": '\U0001D4B1',
+ "Vvdash;": '\U000022AA',
+ "Wcirc;": '\U00000174',
+ "Wedge;": '\U000022C0',
+ "Wfr;": '\U0001D51A',
+ "Wopf;": '\U0001D54E',
+ "Wscr;": '\U0001D4B2',
+ "Xfr;": '\U0001D51B',
+ "Xi;": '\U0000039E',
+ "Xopf;": '\U0001D54F',
+ "Xscr;": '\U0001D4B3',
+ "YAcy;": '\U0000042F',
+ "YIcy;": '\U00000407',
+ "YUcy;": '\U0000042E',
+ "Yacute;": '\U000000DD',
+ "Ycirc;": '\U00000176',
+ "Ycy;": '\U0000042B',
+ "Yfr;": '\U0001D51C',
+ "Yopf;": '\U0001D550',
+ "Yscr;": '\U0001D4B4',
+ "Yuml;": '\U00000178',
+ "ZHcy;": '\U00000416',
+ "Zacute;": '\U00000179',
+ "Zcaron;": '\U0000017D',
+ "Zcy;": '\U00000417',
+ "Zdot;": '\U0000017B',
+ "ZeroWidthSpace;": '\U0000200B',
+ "Zeta;": '\U00000396',
+ "Zfr;": '\U00002128',
+ "Zopf;": '\U00002124',
+ "Zscr;": '\U0001D4B5',
+ "aacute;": '\U000000E1',
+ "abreve;": '\U00000103',
+ "ac;": '\U0000223E',
+ "acd;": '\U0000223F',
+ "acirc;": '\U000000E2',
+ "acute;": '\U000000B4',
+ "acy;": '\U00000430',
+ "aelig;": '\U000000E6',
+ "af;": '\U00002061',
+ "afr;": '\U0001D51E',
+ "agrave;": '\U000000E0',
+ "alefsym;": '\U00002135',
+ "aleph;": '\U00002135',
+ "alpha;": '\U000003B1',
+ "amacr;": '\U00000101',
+ "amalg;": '\U00002A3F',
+ "amp;": '\U00000026',
+ "and;": '\U00002227',
+ "andand;": '\U00002A55',
+ "andd;": '\U00002A5C',
+ "andslope;": '\U00002A58',
+ "andv;": '\U00002A5A',
+ "ang;": '\U00002220',
+ "ange;": '\U000029A4',
+ "angle;": '\U00002220',
+ "angmsd;": '\U00002221',
+ "angmsdaa;": '\U000029A8',
+ "angmsdab;": '\U000029A9',
+ "angmsdac;": '\U000029AA',
+ "angmsdad;": '\U000029AB',
+ "angmsdae;": '\U000029AC',
+ "angmsdaf;": '\U000029AD',
+ "angmsdag;": '\U000029AE',
+ "angmsdah;": '\U000029AF',
+ "angrt;": '\U0000221F',
+ "angrtvb;": '\U000022BE',
+ "angrtvbd;": '\U0000299D',
+ "angsph;": '\U00002222',
+ "angst;": '\U000000C5',
+ "angzarr;": '\U0000237C',
+ "aogon;": '\U00000105',
+ "aopf;": '\U0001D552',
+ "ap;": '\U00002248',
+ "apE;": '\U00002A70',
+ "apacir;": '\U00002A6F',
+ "ape;": '\U0000224A',
+ "apid;": '\U0000224B',
+ "apos;": '\U00000027',
+ "approx;": '\U00002248',
+ "approxeq;": '\U0000224A',
+ "aring;": '\U000000E5',
+ "ascr;": '\U0001D4B6',
+ "ast;": '\U0000002A',
+ "asymp;": '\U00002248',
+ "asympeq;": '\U0000224D',
+ "atilde;": '\U000000E3',
+ "auml;": '\U000000E4',
+ "awconint;": '\U00002233',
+ "awint;": '\U00002A11',
+ "bNot;": '\U00002AED',
+ "backcong;": '\U0000224C',
+ "backepsilon;": '\U000003F6',
+ "backprime;": '\U00002035',
+ "backsim;": '\U0000223D',
+ "backsimeq;": '\U000022CD',
+ "barvee;": '\U000022BD',
+ "barwed;": '\U00002305',
+ "barwedge;": '\U00002305',
+ "bbrk;": '\U000023B5',
+ "bbrktbrk;": '\U000023B6',
+ "bcong;": '\U0000224C',
+ "bcy;": '\U00000431',
+ "bdquo;": '\U0000201E',
+ "becaus;": '\U00002235',
+ "because;": '\U00002235',
+ "bemptyv;": '\U000029B0',
+ "bepsi;": '\U000003F6',
+ "bernou;": '\U0000212C',
+ "beta;": '\U000003B2',
+ "beth;": '\U00002136',
+ "between;": '\U0000226C',
+ "bfr;": '\U0001D51F',
+ "bigcap;": '\U000022C2',
+ "bigcirc;": '\U000025EF',
+ "bigcup;": '\U000022C3',
+ "bigodot;": '\U00002A00',
+ "bigoplus;": '\U00002A01',
+ "bigotimes;": '\U00002A02',
+ "bigsqcup;": '\U00002A06',
+ "bigstar;": '\U00002605',
+ "bigtriangledown;": '\U000025BD',
+ "bigtriangleup;": '\U000025B3',
+ "biguplus;": '\U00002A04',
+ "bigvee;": '\U000022C1',
+ "bigwedge;": '\U000022C0',
+ "bkarow;": '\U0000290D',
+ "blacklozenge;": '\U000029EB',
+ "blacksquare;": '\U000025AA',
+ "blacktriangle;": '\U000025B4',
+ "blacktriangledown;": '\U000025BE',
+ "blacktriangleleft;": '\U000025C2',
+ "blacktriangleright;": '\U000025B8',
+ "blank;": '\U00002423',
+ "blk12;": '\U00002592',
+ "blk14;": '\U00002591',
+ "blk34;": '\U00002593',
+ "block;": '\U00002588',
+ "bnot;": '\U00002310',
+ "bopf;": '\U0001D553',
+ "bot;": '\U000022A5',
+ "bottom;": '\U000022A5',
+ "bowtie;": '\U000022C8',
+ "boxDL;": '\U00002557',
+ "boxDR;": '\U00002554',
+ "boxDl;": '\U00002556',
+ "boxDr;": '\U00002553',
+ "boxH;": '\U00002550',
+ "boxHD;": '\U00002566',
+ "boxHU;": '\U00002569',
+ "boxHd;": '\U00002564',
+ "boxHu;": '\U00002567',
+ "boxUL;": '\U0000255D',
+ "boxUR;": '\U0000255A',
+ "boxUl;": '\U0000255C',
+ "boxUr;": '\U00002559',
+ "boxV;": '\U00002551',
+ "boxVH;": '\U0000256C',
+ "boxVL;": '\U00002563',
+ "boxVR;": '\U00002560',
+ "boxVh;": '\U0000256B',
+ "boxVl;": '\U00002562',
+ "boxVr;": '\U0000255F',
+ "boxbox;": '\U000029C9',
+ "boxdL;": '\U00002555',
+ "boxdR;": '\U00002552',
+ "boxdl;": '\U00002510',
+ "boxdr;": '\U0000250C',
+ "boxh;": '\U00002500',
+ "boxhD;": '\U00002565',
+ "boxhU;": '\U00002568',
+ "boxhd;": '\U0000252C',
+ "boxhu;": '\U00002534',
+ "boxminus;": '\U0000229F',
+ "boxplus;": '\U0000229E',
+ "boxtimes;": '\U000022A0',
+ "boxuL;": '\U0000255B',
+ "boxuR;": '\U00002558',
+ "boxul;": '\U00002518',
+ "boxur;": '\U00002514',
+ "boxv;": '\U00002502',
+ "boxvH;": '\U0000256A',
+ "boxvL;": '\U00002561',
+ "boxvR;": '\U0000255E',
+ "boxvh;": '\U0000253C',
+ "boxvl;": '\U00002524',
+ "boxvr;": '\U0000251C',
+ "bprime;": '\U00002035',
+ "breve;": '\U000002D8',
+ "brvbar;": '\U000000A6',
+ "bscr;": '\U0001D4B7',
+ "bsemi;": '\U0000204F',
+ "bsim;": '\U0000223D',
+ "bsime;": '\U000022CD',
+ "bsol;": '\U0000005C',
+ "bsolb;": '\U000029C5',
+ "bsolhsub;": '\U000027C8',
+ "bull;": '\U00002022',
+ "bullet;": '\U00002022',
+ "bump;": '\U0000224E',
+ "bumpE;": '\U00002AAE',
+ "bumpe;": '\U0000224F',
+ "bumpeq;": '\U0000224F',
+ "cacute;": '\U00000107',
+ "cap;": '\U00002229',
+ "capand;": '\U00002A44',
+ "capbrcup;": '\U00002A49',
+ "capcap;": '\U00002A4B',
+ "capcup;": '\U00002A47',
+ "capdot;": '\U00002A40',
+ "caret;": '\U00002041',
+ "caron;": '\U000002C7',
+ "ccaps;": '\U00002A4D',
+ "ccaron;": '\U0000010D',
+ "ccedil;": '\U000000E7',
+ "ccirc;": '\U00000109',
+ "ccups;": '\U00002A4C',
+ "ccupssm;": '\U00002A50',
+ "cdot;": '\U0000010B',
+ "cedil;": '\U000000B8',
+ "cemptyv;": '\U000029B2',
+ "cent;": '\U000000A2',
+ "centerdot;": '\U000000B7',
+ "cfr;": '\U0001D520',
+ "chcy;": '\U00000447',
+ "check;": '\U00002713',
+ "checkmark;": '\U00002713',
+ "chi;": '\U000003C7',
+ "cir;": '\U000025CB',
+ "cirE;": '\U000029C3',
+ "circ;": '\U000002C6',
+ "circeq;": '\U00002257',
+ "circlearrowleft;": '\U000021BA',
+ "circlearrowright;": '\U000021BB',
+ "circledR;": '\U000000AE',
+ "circledS;": '\U000024C8',
+ "circledast;": '\U0000229B',
+ "circledcirc;": '\U0000229A',
+ "circleddash;": '\U0000229D',
+ "cire;": '\U00002257',
+ "cirfnint;": '\U00002A10',
+ "cirmid;": '\U00002AEF',
+ "cirscir;": '\U000029C2',
+ "clubs;": '\U00002663',
+ "clubsuit;": '\U00002663',
+ "colon;": '\U0000003A',
+ "colone;": '\U00002254',
+ "coloneq;": '\U00002254',
+ "comma;": '\U0000002C',
+ "commat;": '\U00000040',
+ "comp;": '\U00002201',
+ "compfn;": '\U00002218',
+ "complement;": '\U00002201',
+ "complexes;": '\U00002102',
+ "cong;": '\U00002245',
+ "congdot;": '\U00002A6D',
+ "conint;": '\U0000222E',
+ "copf;": '\U0001D554',
+ "coprod;": '\U00002210',
+ "copy;": '\U000000A9',
+ "copysr;": '\U00002117',
+ "crarr;": '\U000021B5',
+ "cross;": '\U00002717',
+ "cscr;": '\U0001D4B8',
+ "csub;": '\U00002ACF',
+ "csube;": '\U00002AD1',
+ "csup;": '\U00002AD0',
+ "csupe;": '\U00002AD2',
+ "ctdot;": '\U000022EF',
+ "cudarrl;": '\U00002938',
+ "cudarrr;": '\U00002935',
+ "cuepr;": '\U000022DE',
+ "cuesc;": '\U000022DF',
+ "cularr;": '\U000021B6',
+ "cularrp;": '\U0000293D',
+ "cup;": '\U0000222A',
+ "cupbrcap;": '\U00002A48',
+ "cupcap;": '\U00002A46',
+ "cupcup;": '\U00002A4A',
+ "cupdot;": '\U0000228D',
+ "cupor;": '\U00002A45',
+ "curarr;": '\U000021B7',
+ "curarrm;": '\U0000293C',
+ "curlyeqprec;": '\U000022DE',
+ "curlyeqsucc;": '\U000022DF',
+ "curlyvee;": '\U000022CE',
+ "curlywedge;": '\U000022CF',
+ "curren;": '\U000000A4',
+ "curvearrowleft;": '\U000021B6',
+ "curvearrowright;": '\U000021B7',
+ "cuvee;": '\U000022CE',
+ "cuwed;": '\U000022CF',
+ "cwconint;": '\U00002232',
+ "cwint;": '\U00002231',
+ "cylcty;": '\U0000232D',
+ "dArr;": '\U000021D3',
+ "dHar;": '\U00002965',
+ "dagger;": '\U00002020',
+ "daleth;": '\U00002138',
+ "darr;": '\U00002193',
+ "dash;": '\U00002010',
+ "dashv;": '\U000022A3',
+ "dbkarow;": '\U0000290F',
+ "dblac;": '\U000002DD',
+ "dcaron;": '\U0000010F',
+ "dcy;": '\U00000434',
+ "dd;": '\U00002146',
+ "ddagger;": '\U00002021',
+ "ddarr;": '\U000021CA',
+ "ddotseq;": '\U00002A77',
+ "deg;": '\U000000B0',
+ "delta;": '\U000003B4',
+ "demptyv;": '\U000029B1',
+ "dfisht;": '\U0000297F',
+ "dfr;": '\U0001D521',
+ "dharl;": '\U000021C3',
+ "dharr;": '\U000021C2',
+ "diam;": '\U000022C4',
+ "diamond;": '\U000022C4',
+ "diamondsuit;": '\U00002666',
+ "diams;": '\U00002666',
+ "die;": '\U000000A8',
+ "digamma;": '\U000003DD',
+ "disin;": '\U000022F2',
+ "div;": '\U000000F7',
+ "divide;": '\U000000F7',
+ "divideontimes;": '\U000022C7',
+ "divonx;": '\U000022C7',
+ "djcy;": '\U00000452',
+ "dlcorn;": '\U0000231E',
+ "dlcrop;": '\U0000230D',
+ "dollar;": '\U00000024',
+ "dopf;": '\U0001D555',
+ "dot;": '\U000002D9',
+ "doteq;": '\U00002250',
+ "doteqdot;": '\U00002251',
+ "dotminus;": '\U00002238',
+ "dotplus;": '\U00002214',
+ "dotsquare;": '\U000022A1',
+ "doublebarwedge;": '\U00002306',
+ "downarrow;": '\U00002193',
+ "downdownarrows;": '\U000021CA',
+ "downharpoonleft;": '\U000021C3',
+ "downharpoonright;": '\U000021C2',
+ "drbkarow;": '\U00002910',
+ "drcorn;": '\U0000231F',
+ "drcrop;": '\U0000230C',
+ "dscr;": '\U0001D4B9',
+ "dscy;": '\U00000455',
+ "dsol;": '\U000029F6',
+ "dstrok;": '\U00000111',
+ "dtdot;": '\U000022F1',
+ "dtri;": '\U000025BF',
+ "dtrif;": '\U000025BE',
+ "duarr;": '\U000021F5',
+ "duhar;": '\U0000296F',
+ "dwangle;": '\U000029A6',
+ "dzcy;": '\U0000045F',
+ "dzigrarr;": '\U000027FF',
+ "eDDot;": '\U00002A77',
+ "eDot;": '\U00002251',
+ "eacute;": '\U000000E9',
+ "easter;": '\U00002A6E',
+ "ecaron;": '\U0000011B',
+ "ecir;": '\U00002256',
+ "ecirc;": '\U000000EA',
+ "ecolon;": '\U00002255',
+ "ecy;": '\U0000044D',
+ "edot;": '\U00000117',
+ "ee;": '\U00002147',
+ "efDot;": '\U00002252',
+ "efr;": '\U0001D522',
+ "eg;": '\U00002A9A',
+ "egrave;": '\U000000E8',
+ "egs;": '\U00002A96',
+ "egsdot;": '\U00002A98',
+ "el;": '\U00002A99',
+ "elinters;": '\U000023E7',
+ "ell;": '\U00002113',
+ "els;": '\U00002A95',
+ "elsdot;": '\U00002A97',
+ "emacr;": '\U00000113',
+ "empty;": '\U00002205',
+ "emptyset;": '\U00002205',
+ "emptyv;": '\U00002205',
+ "emsp;": '\U00002003',
+ "emsp13;": '\U00002004',
+ "emsp14;": '\U00002005',
+ "eng;": '\U0000014B',
+ "ensp;": '\U00002002',
+ "eogon;": '\U00000119',
+ "eopf;": '\U0001D556',
+ "epar;": '\U000022D5',
+ "eparsl;": '\U000029E3',
+ "eplus;": '\U00002A71',
+ "epsi;": '\U000003B5',
+ "epsilon;": '\U000003B5',
+ "epsiv;": '\U000003F5',
+ "eqcirc;": '\U00002256',
+ "eqcolon;": '\U00002255',
+ "eqsim;": '\U00002242',
+ "eqslantgtr;": '\U00002A96',
+ "eqslantless;": '\U00002A95',
+ "equals;": '\U0000003D',
+ "equest;": '\U0000225F',
+ "equiv;": '\U00002261',
+ "equivDD;": '\U00002A78',
+ "eqvparsl;": '\U000029E5',
+ "erDot;": '\U00002253',
+ "erarr;": '\U00002971',
+ "escr;": '\U0000212F',
+ "esdot;": '\U00002250',
+ "esim;": '\U00002242',
+ "eta;": '\U000003B7',
+ "eth;": '\U000000F0',
+ "euml;": '\U000000EB',
+ "euro;": '\U000020AC',
+ "excl;": '\U00000021',
+ "exist;": '\U00002203',
+ "expectation;": '\U00002130',
+ "exponentiale;": '\U00002147',
+ "fallingdotseq;": '\U00002252',
+ "fcy;": '\U00000444',
+ "female;": '\U00002640',
+ "ffilig;": '\U0000FB03',
+ "fflig;": '\U0000FB00',
+ "ffllig;": '\U0000FB04',
+ "ffr;": '\U0001D523',
+ "filig;": '\U0000FB01',
+ "flat;": '\U0000266D',
+ "fllig;": '\U0000FB02',
+ "fltns;": '\U000025B1',
+ "fnof;": '\U00000192',
+ "fopf;": '\U0001D557',
+ "forall;": '\U00002200',
+ "fork;": '\U000022D4',
+ "forkv;": '\U00002AD9',
+ "fpartint;": '\U00002A0D',
+ "frac12;": '\U000000BD',
+ "frac13;": '\U00002153',
+ "frac14;": '\U000000BC',
+ "frac15;": '\U00002155',
+ "frac16;": '\U00002159',
+ "frac18;": '\U0000215B',
+ "frac23;": '\U00002154',
+ "frac25;": '\U00002156',
+ "frac34;": '\U000000BE',
+ "frac35;": '\U00002157',
+ "frac38;": '\U0000215C',
+ "frac45;": '\U00002158',
+ "frac56;": '\U0000215A',
+ "frac58;": '\U0000215D',
+ "frac78;": '\U0000215E',
+ "frasl;": '\U00002044',
+ "frown;": '\U00002322',
+ "fscr;": '\U0001D4BB',
+ "gE;": '\U00002267',
+ "gEl;": '\U00002A8C',
+ "gacute;": '\U000001F5',
+ "gamma;": '\U000003B3',
+ "gammad;": '\U000003DD',
+ "gap;": '\U00002A86',
+ "gbreve;": '\U0000011F',
+ "gcirc;": '\U0000011D',
+ "gcy;": '\U00000433',
+ "gdot;": '\U00000121',
+ "ge;": '\U00002265',
+ "gel;": '\U000022DB',
+ "geq;": '\U00002265',
+ "geqq;": '\U00002267',
+ "geqslant;": '\U00002A7E',
+ "ges;": '\U00002A7E',
+ "gescc;": '\U00002AA9',
+ "gesdot;": '\U00002A80',
+ "gesdoto;": '\U00002A82',
+ "gesdotol;": '\U00002A84',
+ "gesles;": '\U00002A94',
+ "gfr;": '\U0001D524',
+ "gg;": '\U0000226B',
+ "ggg;": '\U000022D9',
+ "gimel;": '\U00002137',
+ "gjcy;": '\U00000453',
+ "gl;": '\U00002277',
+ "glE;": '\U00002A92',
+ "gla;": '\U00002AA5',
+ "glj;": '\U00002AA4',
+ "gnE;": '\U00002269',
+ "gnap;": '\U00002A8A',
+ "gnapprox;": '\U00002A8A',
+ "gne;": '\U00002A88',
+ "gneq;": '\U00002A88',
+ "gneqq;": '\U00002269',
+ "gnsim;": '\U000022E7',
+ "gopf;": '\U0001D558',
+ "grave;": '\U00000060',
+ "gscr;": '\U0000210A',
+ "gsim;": '\U00002273',
+ "gsime;": '\U00002A8E',
+ "gsiml;": '\U00002A90',
+ "gt;": '\U0000003E',
+ "gtcc;": '\U00002AA7',
+ "gtcir;": '\U00002A7A',
+ "gtdot;": '\U000022D7',
+ "gtlPar;": '\U00002995',
+ "gtquest;": '\U00002A7C',
+ "gtrapprox;": '\U00002A86',
+ "gtrarr;": '\U00002978',
+ "gtrdot;": '\U000022D7',
+ "gtreqless;": '\U000022DB',
+ "gtreqqless;": '\U00002A8C',
+ "gtrless;": '\U00002277',
+ "gtrsim;": '\U00002273',
+ "hArr;": '\U000021D4',
+ "hairsp;": '\U0000200A',
+ "half;": '\U000000BD',
+ "hamilt;": '\U0000210B',
+ "hardcy;": '\U0000044A',
+ "harr;": '\U00002194',
+ "harrcir;": '\U00002948',
+ "harrw;": '\U000021AD',
+ "hbar;": '\U0000210F',
+ "hcirc;": '\U00000125',
+ "hearts;": '\U00002665',
+ "heartsuit;": '\U00002665',
+ "hellip;": '\U00002026',
+ "hercon;": '\U000022B9',
+ "hfr;": '\U0001D525',
+ "hksearow;": '\U00002925',
+ "hkswarow;": '\U00002926',
+ "hoarr;": '\U000021FF',
+ "homtht;": '\U0000223B',
+ "hookleftarrow;": '\U000021A9',
+ "hookrightarrow;": '\U000021AA',
+ "hopf;": '\U0001D559',
+ "horbar;": '\U00002015',
+ "hscr;": '\U0001D4BD',
+ "hslash;": '\U0000210F',
+ "hstrok;": '\U00000127',
+ "hybull;": '\U00002043',
+ "hyphen;": '\U00002010',
+ "iacute;": '\U000000ED',
+ "ic;": '\U00002063',
+ "icirc;": '\U000000EE',
+ "icy;": '\U00000438',
+ "iecy;": '\U00000435',
+ "iexcl;": '\U000000A1',
+ "iff;": '\U000021D4',
+ "ifr;": '\U0001D526',
+ "igrave;": '\U000000EC',
+ "ii;": '\U00002148',
+ "iiiint;": '\U00002A0C',
+ "iiint;": '\U0000222D',
+ "iinfin;": '\U000029DC',
+ "iiota;": '\U00002129',
+ "ijlig;": '\U00000133',
+ "imacr;": '\U0000012B',
+ "image;": '\U00002111',
+ "imagline;": '\U00002110',
+ "imagpart;": '\U00002111',
+ "imath;": '\U00000131',
+ "imof;": '\U000022B7',
+ "imped;": '\U000001B5',
+ "in;": '\U00002208',
+ "incare;": '\U00002105',
+ "infin;": '\U0000221E',
+ "infintie;": '\U000029DD',
+ "inodot;": '\U00000131',
+ "int;": '\U0000222B',
+ "intcal;": '\U000022BA',
+ "integers;": '\U00002124',
+ "intercal;": '\U000022BA',
+ "intlarhk;": '\U00002A17',
+ "intprod;": '\U00002A3C',
+ "iocy;": '\U00000451',
+ "iogon;": '\U0000012F',
+ "iopf;": '\U0001D55A',
+ "iota;": '\U000003B9',
+ "iprod;": '\U00002A3C',
+ "iquest;": '\U000000BF',
+ "iscr;": '\U0001D4BE',
+ "isin;": '\U00002208',
+ "isinE;": '\U000022F9',
+ "isindot;": '\U000022F5',
+ "isins;": '\U000022F4',
+ "isinsv;": '\U000022F3',
+ "isinv;": '\U00002208',
+ "it;": '\U00002062',
+ "itilde;": '\U00000129',
+ "iukcy;": '\U00000456',
+ "iuml;": '\U000000EF',
+ "jcirc;": '\U00000135',
+ "jcy;": '\U00000439',
+ "jfr;": '\U0001D527',
+ "jmath;": '\U00000237',
+ "jopf;": '\U0001D55B',
+ "jscr;": '\U0001D4BF',
+ "jsercy;": '\U00000458',
+ "jukcy;": '\U00000454',
+ "kappa;": '\U000003BA',
+ "kappav;": '\U000003F0',
+ "kcedil;": '\U00000137',
+ "kcy;": '\U0000043A',
+ "kfr;": '\U0001D528',
+ "kgreen;": '\U00000138',
+ "khcy;": '\U00000445',
+ "kjcy;": '\U0000045C',
+ "kopf;": '\U0001D55C',
+ "kscr;": '\U0001D4C0',
+ "lAarr;": '\U000021DA',
+ "lArr;": '\U000021D0',
+ "lAtail;": '\U0000291B',
+ "lBarr;": '\U0000290E',
+ "lE;": '\U00002266',
+ "lEg;": '\U00002A8B',
+ "lHar;": '\U00002962',
+ "lacute;": '\U0000013A',
+ "laemptyv;": '\U000029B4',
+ "lagran;": '\U00002112',
+ "lambda;": '\U000003BB',
+ "lang;": '\U000027E8',
+ "langd;": '\U00002991',
+ "langle;": '\U000027E8',
+ "lap;": '\U00002A85',
+ "laquo;": '\U000000AB',
+ "larr;": '\U00002190',
+ "larrb;": '\U000021E4',
+ "larrbfs;": '\U0000291F',
+ "larrfs;": '\U0000291D',
+ "larrhk;": '\U000021A9',
+ "larrlp;": '\U000021AB',
+ "larrpl;": '\U00002939',
+ "larrsim;": '\U00002973',
+ "larrtl;": '\U000021A2',
+ "lat;": '\U00002AAB',
+ "latail;": '\U00002919',
+ "late;": '\U00002AAD',
+ "lbarr;": '\U0000290C',
+ "lbbrk;": '\U00002772',
+ "lbrace;": '\U0000007B',
+ "lbrack;": '\U0000005B',
+ "lbrke;": '\U0000298B',
+ "lbrksld;": '\U0000298F',
+ "lbrkslu;": '\U0000298D',
+ "lcaron;": '\U0000013E',
+ "lcedil;": '\U0000013C',
+ "lceil;": '\U00002308',
+ "lcub;": '\U0000007B',
+ "lcy;": '\U0000043B',
+ "ldca;": '\U00002936',
+ "ldquo;": '\U0000201C',
+ "ldquor;": '\U0000201E',
+ "ldrdhar;": '\U00002967',
+ "ldrushar;": '\U0000294B',
+ "ldsh;": '\U000021B2',
+ "le;": '\U00002264',
+ "leftarrow;": '\U00002190',
+ "leftarrowtail;": '\U000021A2',
+ "leftharpoondown;": '\U000021BD',
+ "leftharpoonup;": '\U000021BC',
+ "leftleftarrows;": '\U000021C7',
+ "leftrightarrow;": '\U00002194',
+ "leftrightarrows;": '\U000021C6',
+ "leftrightharpoons;": '\U000021CB',
+ "leftrightsquigarrow;": '\U000021AD',
+ "leftthreetimes;": '\U000022CB',
+ "leg;": '\U000022DA',
+ "leq;": '\U00002264',
+ "leqq;": '\U00002266',
+ "leqslant;": '\U00002A7D',
+ "les;": '\U00002A7D',
+ "lescc;": '\U00002AA8',
+ "lesdot;": '\U00002A7F',
+ "lesdoto;": '\U00002A81',
+ "lesdotor;": '\U00002A83',
+ "lesges;": '\U00002A93',
+ "lessapprox;": '\U00002A85',
+ "lessdot;": '\U000022D6',
+ "lesseqgtr;": '\U000022DA',
+ "lesseqqgtr;": '\U00002A8B',
+ "lessgtr;": '\U00002276',
+ "lesssim;": '\U00002272',
+ "lfisht;": '\U0000297C',
+ "lfloor;": '\U0000230A',
+ "lfr;": '\U0001D529',
+ "lg;": '\U00002276',
+ "lgE;": '\U00002A91',
+ "lhard;": '\U000021BD',
+ "lharu;": '\U000021BC',
+ "lharul;": '\U0000296A',
+ "lhblk;": '\U00002584',
+ "ljcy;": '\U00000459',
+ "ll;": '\U0000226A',
+ "llarr;": '\U000021C7',
+ "llcorner;": '\U0000231E',
+ "llhard;": '\U0000296B',
+ "lltri;": '\U000025FA',
+ "lmidot;": '\U00000140',
+ "lmoust;": '\U000023B0',
+ "lmoustache;": '\U000023B0',
+ "lnE;": '\U00002268',
+ "lnap;": '\U00002A89',
+ "lnapprox;": '\U00002A89',
+ "lne;": '\U00002A87',
+ "lneq;": '\U00002A87',
+ "lneqq;": '\U00002268',
+ "lnsim;": '\U000022E6',
+ "loang;": '\U000027EC',
+ "loarr;": '\U000021FD',
+ "lobrk;": '\U000027E6',
+ "longleftarrow;": '\U000027F5',
+ "longleftrightarrow;": '\U000027F7',
+ "longmapsto;": '\U000027FC',
+ "longrightarrow;": '\U000027F6',
+ "looparrowleft;": '\U000021AB',
+ "looparrowright;": '\U000021AC',
+ "lopar;": '\U00002985',
+ "lopf;": '\U0001D55D',
+ "loplus;": '\U00002A2D',
+ "lotimes;": '\U00002A34',
+ "lowast;": '\U00002217',
+ "lowbar;": '\U0000005F',
+ "loz;": '\U000025CA',
+ "lozenge;": '\U000025CA',
+ "lozf;": '\U000029EB',
+ "lpar;": '\U00000028',
+ "lparlt;": '\U00002993',
+ "lrarr;": '\U000021C6',
+ "lrcorner;": '\U0000231F',
+ "lrhar;": '\U000021CB',
+ "lrhard;": '\U0000296D',
+ "lrm;": '\U0000200E',
+ "lrtri;": '\U000022BF',
+ "lsaquo;": '\U00002039',
+ "lscr;": '\U0001D4C1',
+ "lsh;": '\U000021B0',
+ "lsim;": '\U00002272',
+ "lsime;": '\U00002A8D',
+ "lsimg;": '\U00002A8F',
+ "lsqb;": '\U0000005B',
+ "lsquo;": '\U00002018',
+ "lsquor;": '\U0000201A',
+ "lstrok;": '\U00000142',
+ "lt;": '\U0000003C',
+ "ltcc;": '\U00002AA6',
+ "ltcir;": '\U00002A79',
+ "ltdot;": '\U000022D6',
+ "lthree;": '\U000022CB',
+ "ltimes;": '\U000022C9',
+ "ltlarr;": '\U00002976',
+ "ltquest;": '\U00002A7B',
+ "ltrPar;": '\U00002996',
+ "ltri;": '\U000025C3',
+ "ltrie;": '\U000022B4',
+ "ltrif;": '\U000025C2',
+ "lurdshar;": '\U0000294A',
+ "luruhar;": '\U00002966',
+ "mDDot;": '\U0000223A',
+ "macr;": '\U000000AF',
+ "male;": '\U00002642',
+ "malt;": '\U00002720',
+ "maltese;": '\U00002720',
+ "map;": '\U000021A6',
+ "mapsto;": '\U000021A6',
+ "mapstodown;": '\U000021A7',
+ "mapstoleft;": '\U000021A4',
+ "mapstoup;": '\U000021A5',
+ "marker;": '\U000025AE',
+ "mcomma;": '\U00002A29',
+ "mcy;": '\U0000043C',
+ "mdash;": '\U00002014',
+ "measuredangle;": '\U00002221',
+ "mfr;": '\U0001D52A',
+ "mho;": '\U00002127',
+ "micro;": '\U000000B5',
+ "mid;": '\U00002223',
+ "midast;": '\U0000002A',
+ "midcir;": '\U00002AF0',
+ "middot;": '\U000000B7',
+ "minus;": '\U00002212',
+ "minusb;": '\U0000229F',
+ "minusd;": '\U00002238',
+ "minusdu;": '\U00002A2A',
+ "mlcp;": '\U00002ADB',
+ "mldr;": '\U00002026',
+ "mnplus;": '\U00002213',
+ "models;": '\U000022A7',
+ "mopf;": '\U0001D55E',
+ "mp;": '\U00002213',
+ "mscr;": '\U0001D4C2',
+ "mstpos;": '\U0000223E',
+ "mu;": '\U000003BC',
+ "multimap;": '\U000022B8',
+ "mumap;": '\U000022B8',
+ "nLeftarrow;": '\U000021CD',
+ "nLeftrightarrow;": '\U000021CE',
+ "nRightarrow;": '\U000021CF',
+ "nVDash;": '\U000022AF',
+ "nVdash;": '\U000022AE',
+ "nabla;": '\U00002207',
+ "nacute;": '\U00000144',
+ "nap;": '\U00002249',
+ "napos;": '\U00000149',
+ "napprox;": '\U00002249',
+ "natur;": '\U0000266E',
+ "natural;": '\U0000266E',
+ "naturals;": '\U00002115',
+ "nbsp;": '\U000000A0',
+ "ncap;": '\U00002A43',
+ "ncaron;": '\U00000148',
+ "ncedil;": '\U00000146',
+ "ncong;": '\U00002247',
+ "ncup;": '\U00002A42',
+ "ncy;": '\U0000043D',
+ "ndash;": '\U00002013',
+ "ne;": '\U00002260',
+ "neArr;": '\U000021D7',
+ "nearhk;": '\U00002924',
+ "nearr;": '\U00002197',
+ "nearrow;": '\U00002197',
+ "nequiv;": '\U00002262',
+ "nesear;": '\U00002928',
+ "nexist;": '\U00002204',
+ "nexists;": '\U00002204',
+ "nfr;": '\U0001D52B',
+ "nge;": '\U00002271',
+ "ngeq;": '\U00002271',
+ "ngsim;": '\U00002275',
+ "ngt;": '\U0000226F',
+ "ngtr;": '\U0000226F',
+ "nhArr;": '\U000021CE',
+ "nharr;": '\U000021AE',
+ "nhpar;": '\U00002AF2',
+ "ni;": '\U0000220B',
+ "nis;": '\U000022FC',
+ "nisd;": '\U000022FA',
+ "niv;": '\U0000220B',
+ "njcy;": '\U0000045A',
+ "nlArr;": '\U000021CD',
+ "nlarr;": '\U0000219A',
+ "nldr;": '\U00002025',
+ "nle;": '\U00002270',
+ "nleftarrow;": '\U0000219A',
+ "nleftrightarrow;": '\U000021AE',
+ "nleq;": '\U00002270',
+ "nless;": '\U0000226E',
+ "nlsim;": '\U00002274',
+ "nlt;": '\U0000226E',
+ "nltri;": '\U000022EA',
+ "nltrie;": '\U000022EC',
+ "nmid;": '\U00002224',
+ "nopf;": '\U0001D55F',
+ "not;": '\U000000AC',
+ "notin;": '\U00002209',
+ "notinva;": '\U00002209',
+ "notinvb;": '\U000022F7',
+ "notinvc;": '\U000022F6',
+ "notni;": '\U0000220C',
+ "notniva;": '\U0000220C',
+ "notnivb;": '\U000022FE',
+ "notnivc;": '\U000022FD',
+ "npar;": '\U00002226',
+ "nparallel;": '\U00002226',
+ "npolint;": '\U00002A14',
+ "npr;": '\U00002280',
+ "nprcue;": '\U000022E0',
+ "nprec;": '\U00002280',
+ "nrArr;": '\U000021CF',
+ "nrarr;": '\U0000219B',
+ "nrightarrow;": '\U0000219B',
+ "nrtri;": '\U000022EB',
+ "nrtrie;": '\U000022ED',
+ "nsc;": '\U00002281',
+ "nsccue;": '\U000022E1',
+ "nscr;": '\U0001D4C3',
+ "nshortmid;": '\U00002224',
+ "nshortparallel;": '\U00002226',
+ "nsim;": '\U00002241',
+ "nsime;": '\U00002244',
+ "nsimeq;": '\U00002244',
+ "nsmid;": '\U00002224',
+ "nspar;": '\U00002226',
+ "nsqsube;": '\U000022E2',
+ "nsqsupe;": '\U000022E3',
+ "nsub;": '\U00002284',
+ "nsube;": '\U00002288',
+ "nsubseteq;": '\U00002288',
+ "nsucc;": '\U00002281',
+ "nsup;": '\U00002285',
+ "nsupe;": '\U00002289',
+ "nsupseteq;": '\U00002289',
+ "ntgl;": '\U00002279',
+ "ntilde;": '\U000000F1',
+ "ntlg;": '\U00002278',
+ "ntriangleleft;": '\U000022EA',
+ "ntrianglelefteq;": '\U000022EC',
+ "ntriangleright;": '\U000022EB',
+ "ntrianglerighteq;": '\U000022ED',
+ "nu;": '\U000003BD',
+ "num;": '\U00000023',
+ "numero;": '\U00002116',
+ "numsp;": '\U00002007',
+ "nvDash;": '\U000022AD',
+ "nvHarr;": '\U00002904',
+ "nvdash;": '\U000022AC',
+ "nvinfin;": '\U000029DE',
+ "nvlArr;": '\U00002902',
+ "nvrArr;": '\U00002903',
+ "nwArr;": '\U000021D6',
+ "nwarhk;": '\U00002923',
+ "nwarr;": '\U00002196',
+ "nwarrow;": '\U00002196',
+ "nwnear;": '\U00002927',
+ "oS;": '\U000024C8',
+ "oacute;": '\U000000F3',
+ "oast;": '\U0000229B',
+ "ocir;": '\U0000229A',
+ "ocirc;": '\U000000F4',
+ "ocy;": '\U0000043E',
+ "odash;": '\U0000229D',
+ "odblac;": '\U00000151',
+ "odiv;": '\U00002A38',
+ "odot;": '\U00002299',
+ "odsold;": '\U000029BC',
+ "oelig;": '\U00000153',
+ "ofcir;": '\U000029BF',
+ "ofr;": '\U0001D52C',
+ "ogon;": '\U000002DB',
+ "ograve;": '\U000000F2',
+ "ogt;": '\U000029C1',
+ "ohbar;": '\U000029B5',
+ "ohm;": '\U000003A9',
+ "oint;": '\U0000222E',
+ "olarr;": '\U000021BA',
+ "olcir;": '\U000029BE',
+ "olcross;": '\U000029BB',
+ "oline;": '\U0000203E',
+ "olt;": '\U000029C0',
+ "omacr;": '\U0000014D',
+ "omega;": '\U000003C9',
+ "omicron;": '\U000003BF',
+ "omid;": '\U000029B6',
+ "ominus;": '\U00002296',
+ "oopf;": '\U0001D560',
+ "opar;": '\U000029B7',
+ "operp;": '\U000029B9',
+ "oplus;": '\U00002295',
+ "or;": '\U00002228',
+ "orarr;": '\U000021BB',
+ "ord;": '\U00002A5D',
+ "order;": '\U00002134',
+ "orderof;": '\U00002134',
+ "ordf;": '\U000000AA',
+ "ordm;": '\U000000BA',
+ "origof;": '\U000022B6',
+ "oror;": '\U00002A56',
+ "orslope;": '\U00002A57',
+ "orv;": '\U00002A5B',
+ "oscr;": '\U00002134',
+ "oslash;": '\U000000F8',
+ "osol;": '\U00002298',
+ "otilde;": '\U000000F5',
+ "otimes;": '\U00002297',
+ "otimesas;": '\U00002A36',
+ "ouml;": '\U000000F6',
+ "ovbar;": '\U0000233D',
+ "par;": '\U00002225',
+ "para;": '\U000000B6',
+ "parallel;": '\U00002225',
+ "parsim;": '\U00002AF3',
+ "parsl;": '\U00002AFD',
+ "part;": '\U00002202',
+ "pcy;": '\U0000043F',
+ "percnt;": '\U00000025',
+ "period;": '\U0000002E',
+ "permil;": '\U00002030',
+ "perp;": '\U000022A5',
+ "pertenk;": '\U00002031',
+ "pfr;": '\U0001D52D',
+ "phi;": '\U000003C6',
+ "phiv;": '\U000003D5',
+ "phmmat;": '\U00002133',
+ "phone;": '\U0000260E',
+ "pi;": '\U000003C0',
+ "pitchfork;": '\U000022D4',
+ "piv;": '\U000003D6',
+ "planck;": '\U0000210F',
+ "planckh;": '\U0000210E',
+ "plankv;": '\U0000210F',
+ "plus;": '\U0000002B',
+ "plusacir;": '\U00002A23',
+ "plusb;": '\U0000229E',
+ "pluscir;": '\U00002A22',
+ "plusdo;": '\U00002214',
+ "plusdu;": '\U00002A25',
+ "pluse;": '\U00002A72',
+ "plusmn;": '\U000000B1',
+ "plussim;": '\U00002A26',
+ "plustwo;": '\U00002A27',
+ "pm;": '\U000000B1',
+ "pointint;": '\U00002A15',
+ "popf;": '\U0001D561',
+ "pound;": '\U000000A3',
+ "pr;": '\U0000227A',
+ "prE;": '\U00002AB3',
+ "prap;": '\U00002AB7',
+ "prcue;": '\U0000227C',
+ "pre;": '\U00002AAF',
+ "prec;": '\U0000227A',
+ "precapprox;": '\U00002AB7',
+ "preccurlyeq;": '\U0000227C',
+ "preceq;": '\U00002AAF',
+ "precnapprox;": '\U00002AB9',
+ "precneqq;": '\U00002AB5',
+ "precnsim;": '\U000022E8',
+ "precsim;": '\U0000227E',
+ "prime;": '\U00002032',
+ "primes;": '\U00002119',
+ "prnE;": '\U00002AB5',
+ "prnap;": '\U00002AB9',
+ "prnsim;": '\U000022E8',
+ "prod;": '\U0000220F',
+ "profalar;": '\U0000232E',
+ "profline;": '\U00002312',
+ "profsurf;": '\U00002313',
+ "prop;": '\U0000221D',
+ "propto;": '\U0000221D',
+ "prsim;": '\U0000227E',
+ "prurel;": '\U000022B0',
+ "pscr;": '\U0001D4C5',
+ "psi;": '\U000003C8',
+ "puncsp;": '\U00002008',
+ "qfr;": '\U0001D52E',
+ "qint;": '\U00002A0C',
+ "qopf;": '\U0001D562',
+ "qprime;": '\U00002057',
+ "qscr;": '\U0001D4C6',
+ "quaternions;": '\U0000210D',
+ "quatint;": '\U00002A16',
+ "quest;": '\U0000003F',
+ "questeq;": '\U0000225F',
+ "quot;": '\U00000022',
+ "rAarr;": '\U000021DB',
+ "rArr;": '\U000021D2',
+ "rAtail;": '\U0000291C',
+ "rBarr;": '\U0000290F',
+ "rHar;": '\U00002964',
+ "racute;": '\U00000155',
+ "radic;": '\U0000221A',
+ "raemptyv;": '\U000029B3',
+ "rang;": '\U000027E9',
+ "rangd;": '\U00002992',
+ "range;": '\U000029A5',
+ "rangle;": '\U000027E9',
+ "raquo;": '\U000000BB',
+ "rarr;": '\U00002192',
+ "rarrap;": '\U00002975',
+ "rarrb;": '\U000021E5',
+ "rarrbfs;": '\U00002920',
+ "rarrc;": '\U00002933',
+ "rarrfs;": '\U0000291E',
+ "rarrhk;": '\U000021AA',
+ "rarrlp;": '\U000021AC',
+ "rarrpl;": '\U00002945',
+ "rarrsim;": '\U00002974',
+ "rarrtl;": '\U000021A3',
+ "rarrw;": '\U0000219D',
+ "ratail;": '\U0000291A',
+ "ratio;": '\U00002236',
+ "rationals;": '\U0000211A',
+ "rbarr;": '\U0000290D',
+ "rbbrk;": '\U00002773',
+ "rbrace;": '\U0000007D',
+ "rbrack;": '\U0000005D',
+ "rbrke;": '\U0000298C',
+ "rbrksld;": '\U0000298E',
+ "rbrkslu;": '\U00002990',
+ "rcaron;": '\U00000159',
+ "rcedil;": '\U00000157',
+ "rceil;": '\U00002309',
+ "rcub;": '\U0000007D',
+ "rcy;": '\U00000440',
+ "rdca;": '\U00002937',
+ "rdldhar;": '\U00002969',
+ "rdquo;": '\U0000201D',
+ "rdquor;": '\U0000201D',
+ "rdsh;": '\U000021B3',
+ "real;": '\U0000211C',
+ "realine;": '\U0000211B',
+ "realpart;": '\U0000211C',
+ "reals;": '\U0000211D',
+ "rect;": '\U000025AD',
+ "reg;": '\U000000AE',
+ "rfisht;": '\U0000297D',
+ "rfloor;": '\U0000230B',
+ "rfr;": '\U0001D52F',
+ "rhard;": '\U000021C1',
+ "rharu;": '\U000021C0',
+ "rharul;": '\U0000296C',
+ "rho;": '\U000003C1',
+ "rhov;": '\U000003F1',
+ "rightarrow;": '\U00002192',
+ "rightarrowtail;": '\U000021A3',
+ "rightharpoondown;": '\U000021C1',
+ "rightharpoonup;": '\U000021C0',
+ "rightleftarrows;": '\U000021C4',
+ "rightleftharpoons;": '\U000021CC',
+ "rightrightarrows;": '\U000021C9',
+ "rightsquigarrow;": '\U0000219D',
+ "rightthreetimes;": '\U000022CC',
+ "ring;": '\U000002DA',
+ "risingdotseq;": '\U00002253',
+ "rlarr;": '\U000021C4',
+ "rlhar;": '\U000021CC',
+ "rlm;": '\U0000200F',
+ "rmoust;": '\U000023B1',
+ "rmoustache;": '\U000023B1',
+ "rnmid;": '\U00002AEE',
+ "roang;": '\U000027ED',
+ "roarr;": '\U000021FE',
+ "robrk;": '\U000027E7',
+ "ropar;": '\U00002986',
+ "ropf;": '\U0001D563',
+ "roplus;": '\U00002A2E',
+ "rotimes;": '\U00002A35',
+ "rpar;": '\U00000029',
+ "rpargt;": '\U00002994',
+ "rppolint;": '\U00002A12',
+ "rrarr;": '\U000021C9',
+ "rsaquo;": '\U0000203A',
+ "rscr;": '\U0001D4C7',
+ "rsh;": '\U000021B1',
+ "rsqb;": '\U0000005D',
+ "rsquo;": '\U00002019',
+ "rsquor;": '\U00002019',
+ "rthree;": '\U000022CC',
+ "rtimes;": '\U000022CA',
+ "rtri;": '\U000025B9',
+ "rtrie;": '\U000022B5',
+ "rtrif;": '\U000025B8',
+ "rtriltri;": '\U000029CE',
+ "ruluhar;": '\U00002968',
+ "rx;": '\U0000211E',
+ "sacute;": '\U0000015B',
+ "sbquo;": '\U0000201A',
+ "sc;": '\U0000227B',
+ "scE;": '\U00002AB4',
+ "scap;": '\U00002AB8',
+ "scaron;": '\U00000161',
+ "sccue;": '\U0000227D',
+ "sce;": '\U00002AB0',
+ "scedil;": '\U0000015F',
+ "scirc;": '\U0000015D',
+ "scnE;": '\U00002AB6',
+ "scnap;": '\U00002ABA',
+ "scnsim;": '\U000022E9',
+ "scpolint;": '\U00002A13',
+ "scsim;": '\U0000227F',
+ "scy;": '\U00000441',
+ "sdot;": '\U000022C5',
+ "sdotb;": '\U000022A1',
+ "sdote;": '\U00002A66',
+ "seArr;": '\U000021D8',
+ "searhk;": '\U00002925',
+ "searr;": '\U00002198',
+ "searrow;": '\U00002198',
+ "sect;": '\U000000A7',
+ "semi;": '\U0000003B',
+ "seswar;": '\U00002929',
+ "setminus;": '\U00002216',
+ "setmn;": '\U00002216',
+ "sext;": '\U00002736',
+ "sfr;": '\U0001D530',
+ "sfrown;": '\U00002322',
+ "sharp;": '\U0000266F',
+ "shchcy;": '\U00000449',
+ "shcy;": '\U00000448',
+ "shortmid;": '\U00002223',
+ "shortparallel;": '\U00002225',
+ "shy;": '\U000000AD',
+ "sigma;": '\U000003C3',
+ "sigmaf;": '\U000003C2',
+ "sigmav;": '\U000003C2',
+ "sim;": '\U0000223C',
+ "simdot;": '\U00002A6A',
+ "sime;": '\U00002243',
+ "simeq;": '\U00002243',
+ "simg;": '\U00002A9E',
+ "simgE;": '\U00002AA0',
+ "siml;": '\U00002A9D',
+ "simlE;": '\U00002A9F',
+ "simne;": '\U00002246',
+ "simplus;": '\U00002A24',
+ "simrarr;": '\U00002972',
+ "slarr;": '\U00002190',
+ "smallsetminus;": '\U00002216',
+ "smashp;": '\U00002A33',
+ "smeparsl;": '\U000029E4',
+ "smid;": '\U00002223',
+ "smile;": '\U00002323',
+ "smt;": '\U00002AAA',
+ "smte;": '\U00002AAC',
+ "softcy;": '\U0000044C',
+ "sol;": '\U0000002F',
+ "solb;": '\U000029C4',
+ "solbar;": '\U0000233F',
+ "sopf;": '\U0001D564',
+ "spades;": '\U00002660',
+ "spadesuit;": '\U00002660',
+ "spar;": '\U00002225',
+ "sqcap;": '\U00002293',
+ "sqcup;": '\U00002294',
+ "sqsub;": '\U0000228F',
+ "sqsube;": '\U00002291',
+ "sqsubset;": '\U0000228F',
+ "sqsubseteq;": '\U00002291',
+ "sqsup;": '\U00002290',
+ "sqsupe;": '\U00002292',
+ "sqsupset;": '\U00002290',
+ "sqsupseteq;": '\U00002292',
+ "squ;": '\U000025A1',
+ "square;": '\U000025A1',
+ "squarf;": '\U000025AA',
+ "squf;": '\U000025AA',
+ "srarr;": '\U00002192',
+ "sscr;": '\U0001D4C8',
+ "ssetmn;": '\U00002216',
+ "ssmile;": '\U00002323',
+ "sstarf;": '\U000022C6',
+ "star;": '\U00002606',
+ "starf;": '\U00002605',
+ "straightepsilon;": '\U000003F5',
+ "straightphi;": '\U000003D5',
+ "strns;": '\U000000AF',
+ "sub;": '\U00002282',
+ "subE;": '\U00002AC5',
+ "subdot;": '\U00002ABD',
+ "sube;": '\U00002286',
+ "subedot;": '\U00002AC3',
+ "submult;": '\U00002AC1',
+ "subnE;": '\U00002ACB',
+ "subne;": '\U0000228A',
+ "subplus;": '\U00002ABF',
+ "subrarr;": '\U00002979',
+ "subset;": '\U00002282',
+ "subseteq;": '\U00002286',
+ "subseteqq;": '\U00002AC5',
+ "subsetneq;": '\U0000228A',
+ "subsetneqq;": '\U00002ACB',
+ "subsim;": '\U00002AC7',
+ "subsub;": '\U00002AD5',
+ "subsup;": '\U00002AD3',
+ "succ;": '\U0000227B',
+ "succapprox;": '\U00002AB8',
+ "succcurlyeq;": '\U0000227D',
+ "succeq;": '\U00002AB0',
+ "succnapprox;": '\U00002ABA',
+ "succneqq;": '\U00002AB6',
+ "succnsim;": '\U000022E9',
+ "succsim;": '\U0000227F',
+ "sum;": '\U00002211',
+ "sung;": '\U0000266A',
+ "sup;": '\U00002283',
+ "sup1;": '\U000000B9',
+ "sup2;": '\U000000B2',
+ "sup3;": '\U000000B3',
+ "supE;": '\U00002AC6',
+ "supdot;": '\U00002ABE',
+ "supdsub;": '\U00002AD8',
+ "supe;": '\U00002287',
+ "supedot;": '\U00002AC4',
+ "suphsol;": '\U000027C9',
+ "suphsub;": '\U00002AD7',
+ "suplarr;": '\U0000297B',
+ "supmult;": '\U00002AC2',
+ "supnE;": '\U00002ACC',
+ "supne;": '\U0000228B',
+ "supplus;": '\U00002AC0',
+ "supset;": '\U00002283',
+ "supseteq;": '\U00002287',
+ "supseteqq;": '\U00002AC6',
+ "supsetneq;": '\U0000228B',
+ "supsetneqq;": '\U00002ACC',
+ "supsim;": '\U00002AC8',
+ "supsub;": '\U00002AD4',
+ "supsup;": '\U00002AD6',
+ "swArr;": '\U000021D9',
+ "swarhk;": '\U00002926',
+ "swarr;": '\U00002199',
+ "swarrow;": '\U00002199',
+ "swnwar;": '\U0000292A',
+ "szlig;": '\U000000DF',
+ "target;": '\U00002316',
+ "tau;": '\U000003C4',
+ "tbrk;": '\U000023B4',
+ "tcaron;": '\U00000165',
+ "tcedil;": '\U00000163',
+ "tcy;": '\U00000442',
+ "tdot;": '\U000020DB',
+ "telrec;": '\U00002315',
+ "tfr;": '\U0001D531',
+ "there4;": '\U00002234',
+ "therefore;": '\U00002234',
+ "theta;": '\U000003B8',
+ "thetasym;": '\U000003D1',
+ "thetav;": '\U000003D1',
+ "thickapprox;": '\U00002248',
+ "thicksim;": '\U0000223C',
+ "thinsp;": '\U00002009',
+ "thkap;": '\U00002248',
+ "thksim;": '\U0000223C',
+ "thorn;": '\U000000FE',
+ "tilde;": '\U000002DC',
+ "times;": '\U000000D7',
+ "timesb;": '\U000022A0',
+ "timesbar;": '\U00002A31',
+ "timesd;": '\U00002A30',
+ "tint;": '\U0000222D',
+ "toea;": '\U00002928',
+ "top;": '\U000022A4',
+ "topbot;": '\U00002336',
+ "topcir;": '\U00002AF1',
+ "topf;": '\U0001D565',
+ "topfork;": '\U00002ADA',
+ "tosa;": '\U00002929',
+ "tprime;": '\U00002034',
+ "trade;": '\U00002122',
+ "triangle;": '\U000025B5',
+ "triangledown;": '\U000025BF',
+ "triangleleft;": '\U000025C3',
+ "trianglelefteq;": '\U000022B4',
+ "triangleq;": '\U0000225C',
+ "triangleright;": '\U000025B9',
+ "trianglerighteq;": '\U000022B5',
+ "tridot;": '\U000025EC',
+ "trie;": '\U0000225C',
+ "triminus;": '\U00002A3A',
+ "triplus;": '\U00002A39',
+ "trisb;": '\U000029CD',
+ "tritime;": '\U00002A3B',
+ "trpezium;": '\U000023E2',
+ "tscr;": '\U0001D4C9',
+ "tscy;": '\U00000446',
+ "tshcy;": '\U0000045B',
+ "tstrok;": '\U00000167',
+ "twixt;": '\U0000226C',
+ "twoheadleftarrow;": '\U0000219E',
+ "twoheadrightarrow;": '\U000021A0',
+ "uArr;": '\U000021D1',
+ "uHar;": '\U00002963',
+ "uacute;": '\U000000FA',
+ "uarr;": '\U00002191',
+ "ubrcy;": '\U0000045E',
+ "ubreve;": '\U0000016D',
+ "ucirc;": '\U000000FB',
+ "ucy;": '\U00000443',
+ "udarr;": '\U000021C5',
+ "udblac;": '\U00000171',
+ "udhar;": '\U0000296E',
+ "ufisht;": '\U0000297E',
+ "ufr;": '\U0001D532',
+ "ugrave;": '\U000000F9',
+ "uharl;": '\U000021BF',
+ "uharr;": '\U000021BE',
+ "uhblk;": '\U00002580',
+ "ulcorn;": '\U0000231C',
+ "ulcorner;": '\U0000231C',
+ "ulcrop;": '\U0000230F',
+ "ultri;": '\U000025F8',
+ "umacr;": '\U0000016B',
+ "uml;": '\U000000A8',
+ "uogon;": '\U00000173',
+ "uopf;": '\U0001D566',
+ "uparrow;": '\U00002191',
+ "updownarrow;": '\U00002195',
+ "upharpoonleft;": '\U000021BF',
+ "upharpoonright;": '\U000021BE',
+ "uplus;": '\U0000228E',
+ "upsi;": '\U000003C5',
+ "upsih;": '\U000003D2',
+ "upsilon;": '\U000003C5',
+ "upuparrows;": '\U000021C8',
+ "urcorn;": '\U0000231D',
+ "urcorner;": '\U0000231D',
+ "urcrop;": '\U0000230E',
+ "uring;": '\U0000016F',
+ "urtri;": '\U000025F9',
+ "uscr;": '\U0001D4CA',
+ "utdot;": '\U000022F0',
+ "utilde;": '\U00000169',
+ "utri;": '\U000025B5',
+ "utrif;": '\U000025B4',
+ "uuarr;": '\U000021C8',
+ "uuml;": '\U000000FC',
+ "uwangle;": '\U000029A7',
+ "vArr;": '\U000021D5',
+ "vBar;": '\U00002AE8',
+ "vBarv;": '\U00002AE9',
+ "vDash;": '\U000022A8',
+ "vangrt;": '\U0000299C',
+ "varepsilon;": '\U000003F5',
+ "varkappa;": '\U000003F0',
+ "varnothing;": '\U00002205',
+ "varphi;": '\U000003D5',
+ "varpi;": '\U000003D6',
+ "varpropto;": '\U0000221D',
+ "varr;": '\U00002195',
+ "varrho;": '\U000003F1',
+ "varsigma;": '\U000003C2',
+ "vartheta;": '\U000003D1',
+ "vartriangleleft;": '\U000022B2',
+ "vartriangleright;": '\U000022B3',
+ "vcy;": '\U00000432',
+ "vdash;": '\U000022A2',
+ "vee;": '\U00002228',
+ "veebar;": '\U000022BB',
+ "veeeq;": '\U0000225A',
+ "vellip;": '\U000022EE',
+ "verbar;": '\U0000007C',
+ "vert;": '\U0000007C',
+ "vfr;": '\U0001D533',
+ "vltri;": '\U000022B2',
+ "vopf;": '\U0001D567',
+ "vprop;": '\U0000221D',
+ "vrtri;": '\U000022B3',
+ "vscr;": '\U0001D4CB',
+ "vzigzag;": '\U0000299A',
+ "wcirc;": '\U00000175',
+ "wedbar;": '\U00002A5F',
+ "wedge;": '\U00002227',
+ "wedgeq;": '\U00002259',
+ "weierp;": '\U00002118',
+ "wfr;": '\U0001D534',
+ "wopf;": '\U0001D568',
+ "wp;": '\U00002118',
+ "wr;": '\U00002240',
+ "wreath;": '\U00002240',
+ "wscr;": '\U0001D4CC',
+ "xcap;": '\U000022C2',
+ "xcirc;": '\U000025EF',
+ "xcup;": '\U000022C3',
+ "xdtri;": '\U000025BD',
+ "xfr;": '\U0001D535',
+ "xhArr;": '\U000027FA',
+ "xharr;": '\U000027F7',
+ "xi;": '\U000003BE',
+ "xlArr;": '\U000027F8',
+ "xlarr;": '\U000027F5',
+ "xmap;": '\U000027FC',
+ "xnis;": '\U000022FB',
+ "xodot;": '\U00002A00',
+ "xopf;": '\U0001D569',
+ "xoplus;": '\U00002A01',
+ "xotime;": '\U00002A02',
+ "xrArr;": '\U000027F9',
+ "xrarr;": '\U000027F6',
+ "xscr;": '\U0001D4CD',
+ "xsqcup;": '\U00002A06',
+ "xuplus;": '\U00002A04',
+ "xutri;": '\U000025B3',
+ "xvee;": '\U000022C1',
+ "xwedge;": '\U000022C0',
+ "yacute;": '\U000000FD',
+ "yacy;": '\U0000044F',
+ "ycirc;": '\U00000177',
+ "ycy;": '\U0000044B',
+ "yen;": '\U000000A5',
+ "yfr;": '\U0001D536',
+ "yicy;": '\U00000457',
+ "yopf;": '\U0001D56A',
+ "yscr;": '\U0001D4CE',
+ "yucy;": '\U0000044E',
+ "yuml;": '\U000000FF',
+ "zacute;": '\U0000017A',
+ "zcaron;": '\U0000017E',
+ "zcy;": '\U00000437',
+ "zdot;": '\U0000017C',
+ "zeetrf;": '\U00002128',
+ "zeta;": '\U000003B6',
+ "zfr;": '\U0001D537',
+ "zhcy;": '\U00000436',
+ "zigrarr;": '\U000021DD',
+ "zopf;": '\U0001D56B',
+ "zscr;": '\U0001D4CF',
+ "zwj;": '\U0000200D',
+ "zwnj;": '\U0000200C',
+ "AElig": '\U000000C6',
+ "AMP": '\U00000026',
+ "Aacute": '\U000000C1',
+ "Acirc": '\U000000C2',
+ "Agrave": '\U000000C0',
+ "Aring": '\U000000C5',
+ "Atilde": '\U000000C3',
+ "Auml": '\U000000C4',
+ "COPY": '\U000000A9',
+ "Ccedil": '\U000000C7',
+ "ETH": '\U000000D0',
+ "Eacute": '\U000000C9',
+ "Ecirc": '\U000000CA',
+ "Egrave": '\U000000C8',
+ "Euml": '\U000000CB',
+ "GT": '\U0000003E',
+ "Iacute": '\U000000CD',
+ "Icirc": '\U000000CE',
+ "Igrave": '\U000000CC',
+ "Iuml": '\U000000CF',
+ "LT": '\U0000003C',
+ "Ntilde": '\U000000D1',
+ "Oacute": '\U000000D3',
+ "Ocirc": '\U000000D4',
+ "Ograve": '\U000000D2',
+ "Oslash": '\U000000D8',
+ "Otilde": '\U000000D5',
+ "Ouml": '\U000000D6',
+ "QUOT": '\U00000022',
+ "REG": '\U000000AE',
+ "THORN": '\U000000DE',
+ "Uacute": '\U000000DA',
+ "Ucirc": '\U000000DB',
+ "Ugrave": '\U000000D9',
+ "Uuml": '\U000000DC',
+ "Yacute": '\U000000DD',
+ "aacute": '\U000000E1',
+ "acirc": '\U000000E2',
+ "acute": '\U000000B4',
+ "aelig": '\U000000E6',
+ "agrave": '\U000000E0',
+ "amp": '\U00000026',
+ "aring": '\U000000E5',
+ "atilde": '\U000000E3',
+ "auml": '\U000000E4',
+ "brvbar": '\U000000A6',
+ "ccedil": '\U000000E7',
+ "cedil": '\U000000B8',
+ "cent": '\U000000A2',
+ "copy": '\U000000A9',
+ "curren": '\U000000A4',
+ "deg": '\U000000B0',
+ "divide": '\U000000F7',
+ "eacute": '\U000000E9',
+ "ecirc": '\U000000EA',
+ "egrave": '\U000000E8',
+ "eth": '\U000000F0',
+ "euml": '\U000000EB',
+ "frac12": '\U000000BD',
+ "frac14": '\U000000BC',
+ "frac34": '\U000000BE',
+ "gt": '\U0000003E',
+ "iacute": '\U000000ED',
+ "icirc": '\U000000EE',
+ "iexcl": '\U000000A1',
+ "igrave": '\U000000EC',
+ "iquest": '\U000000BF',
+ "iuml": '\U000000EF',
+ "laquo": '\U000000AB',
+ "lt": '\U0000003C',
+ "macr": '\U000000AF',
+ "micro": '\U000000B5',
+ "middot": '\U000000B7',
+ "nbsp": '\U000000A0',
+ "not": '\U000000AC',
+ "ntilde": '\U000000F1',
+ "oacute": '\U000000F3',
+ "ocirc": '\U000000F4',
+ "ograve": '\U000000F2',
+ "ordf": '\U000000AA',
+ "ordm": '\U000000BA',
+ "oslash": '\U000000F8',
+ "otilde": '\U000000F5',
+ "ouml": '\U000000F6',
+ "para": '\U000000B6',
+ "plusmn": '\U000000B1',
+ "pound": '\U000000A3',
+ "quot": '\U00000022',
+ "raquo": '\U000000BB',
+ "reg": '\U000000AE',
+ "sect": '\U000000A7',
+ "shy": '\U000000AD',
+ "sup1": '\U000000B9',
+ "sup2": '\U000000B2',
+ "sup3": '\U000000B3',
+ "szlig": '\U000000DF',
+ "thorn": '\U000000FE',
+ "times": '\U000000D7',
+ "uacute": '\U000000FA',
+ "ucirc": '\U000000FB',
+ "ugrave": '\U000000F9',
+ "uml": '\U000000A8',
+ "uuml": '\U000000FC',
+ "yacute": '\U000000FD',
+ "yen": '\U000000A5',
+ "yuml": '\U000000FF',
+}
+
+// HTML entities that are two unicode codepoints.
+var entity2 = map[string][2]rune{
+ // TODO(nigeltao): Handle replacements that are wider than their names.
+ // "nLt;": {'\u226A', '\u20D2'},
+ // "nGt;": {'\u226B', '\u20D2'},
+ "NotEqualTilde;": {'\u2242', '\u0338'},
+ "NotGreaterFullEqual;": {'\u2267', '\u0338'},
+ "NotGreaterGreater;": {'\u226B', '\u0338'},
+ "NotGreaterSlantEqual;": {'\u2A7E', '\u0338'},
+ "NotHumpDownHump;": {'\u224E', '\u0338'},
+ "NotHumpEqual;": {'\u224F', '\u0338'},
+ "NotLeftTriangleBar;": {'\u29CF', '\u0338'},
+ "NotLessLess;": {'\u226A', '\u0338'},
+ "NotLessSlantEqual;": {'\u2A7D', '\u0338'},
+ "NotNestedGreaterGreater;": {'\u2AA2', '\u0338'},
+ "NotNestedLessLess;": {'\u2AA1', '\u0338'},
+ "NotPrecedesEqual;": {'\u2AAF', '\u0338'},
+ "NotRightTriangleBar;": {'\u29D0', '\u0338'},
+ "NotSquareSubset;": {'\u228F', '\u0338'},
+ "NotSquareSuperset;": {'\u2290', '\u0338'},
+ "NotSubset;": {'\u2282', '\u20D2'},
+ "NotSucceedsEqual;": {'\u2AB0', '\u0338'},
+ "NotSucceedsTilde;": {'\u227F', '\u0338'},
+ "NotSuperset;": {'\u2283', '\u20D2'},
+ "ThickSpace;": {'\u205F', '\u200A'},
+ "acE;": {'\u223E', '\u0333'},
+ "bne;": {'\u003D', '\u20E5'},
+ "bnequiv;": {'\u2261', '\u20E5'},
+ "caps;": {'\u2229', '\uFE00'},
+ "cups;": {'\u222A', '\uFE00'},
+ "fjlig;": {'\u0066', '\u006A'},
+ "gesl;": {'\u22DB', '\uFE00'},
+ "gvertneqq;": {'\u2269', '\uFE00'},
+ "gvnE;": {'\u2269', '\uFE00'},
+ "lates;": {'\u2AAD', '\uFE00'},
+ "lesg;": {'\u22DA', '\uFE00'},
+ "lvertneqq;": {'\u2268', '\uFE00'},
+ "lvnE;": {'\u2268', '\uFE00'},
+ "nGg;": {'\u22D9', '\u0338'},
+ "nGtv;": {'\u226B', '\u0338'},
+ "nLl;": {'\u22D8', '\u0338'},
+ "nLtv;": {'\u226A', '\u0338'},
+ "nang;": {'\u2220', '\u20D2'},
+ "napE;": {'\u2A70', '\u0338'},
+ "napid;": {'\u224B', '\u0338'},
+ "nbump;": {'\u224E', '\u0338'},
+ "nbumpe;": {'\u224F', '\u0338'},
+ "ncongdot;": {'\u2A6D', '\u0338'},
+ "nedot;": {'\u2250', '\u0338'},
+ "nesim;": {'\u2242', '\u0338'},
+ "ngE;": {'\u2267', '\u0338'},
+ "ngeqq;": {'\u2267', '\u0338'},
+ "ngeqslant;": {'\u2A7E', '\u0338'},
+ "nges;": {'\u2A7E', '\u0338'},
+ "nlE;": {'\u2266', '\u0338'},
+ "nleqq;": {'\u2266', '\u0338'},
+ "nleqslant;": {'\u2A7D', '\u0338'},
+ "nles;": {'\u2A7D', '\u0338'},
+ "notinE;": {'\u22F9', '\u0338'},
+ "notindot;": {'\u22F5', '\u0338'},
+ "nparsl;": {'\u2AFD', '\u20E5'},
+ "npart;": {'\u2202', '\u0338'},
+ "npre;": {'\u2AAF', '\u0338'},
+ "npreceq;": {'\u2AAF', '\u0338'},
+ "nrarrc;": {'\u2933', '\u0338'},
+ "nrarrw;": {'\u219D', '\u0338'},
+ "nsce;": {'\u2AB0', '\u0338'},
+ "nsubE;": {'\u2AC5', '\u0338'},
+ "nsubset;": {'\u2282', '\u20D2'},
+ "nsubseteqq;": {'\u2AC5', '\u0338'},
+ "nsucceq;": {'\u2AB0', '\u0338'},
+ "nsupE;": {'\u2AC6', '\u0338'},
+ "nsupset;": {'\u2283', '\u20D2'},
+ "nsupseteqq;": {'\u2AC6', '\u0338'},
+ "nvap;": {'\u224D', '\u20D2'},
+ "nvge;": {'\u2265', '\u20D2'},
+ "nvgt;": {'\u003E', '\u20D2'},
+ "nvle;": {'\u2264', '\u20D2'},
+ "nvlt;": {'\u003C', '\u20D2'},
+ "nvltrie;": {'\u22B4', '\u20D2'},
+ "nvrtrie;": {'\u22B5', '\u20D2'},
+ "nvsim;": {'\u223C', '\u20D2'},
+ "race;": {'\u223D', '\u0331'},
+ "smtes;": {'\u2AAC', '\uFE00'},
+ "sqcaps;": {'\u2293', '\uFE00'},
+ "sqcups;": {'\u2294', '\uFE00'},
+ "varsubsetneq;": {'\u228A', '\uFE00'},
+ "varsubsetneqq;": {'\u2ACB', '\uFE00'},
+ "varsupsetneq;": {'\u228B', '\uFE00'},
+ "varsupsetneqq;": {'\u2ACC', '\uFE00'},
+ "vnsub;": {'\u2282', '\u20D2'},
+ "vnsup;": {'\u2283', '\u20D2'},
+ "vsubnE;": {'\u2ACB', '\uFE00'},
+ "vsubne;": {'\u228A', '\uFE00'},
+ "vsupnE;": {'\u2ACC', '\uFE00'},
+ "vsupne;": {'\u228B', '\uFE00'},
+}
diff --git a/vendor/golang.org/x/net/html/escape.go b/vendor/golang.org/x/net/html/escape.go
new file mode 100644
index 00000000..04c6bec2
--- /dev/null
+++ b/vendor/golang.org/x/net/html/escape.go
@@ -0,0 +1,339 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package html
+
+import (
+ "bytes"
+ "strings"
+ "unicode/utf8"
+)
+
+// These replacements permit compatibility with old numeric entities that
+// assumed Windows-1252 encoding.
+// https://html.spec.whatwg.org/multipage/syntax.html#consume-a-character-reference
+var replacementTable = [...]rune{
+ '\u20AC', // First entry is what 0x80 should be replaced with.
+ '\u0081',
+ '\u201A',
+ '\u0192',
+ '\u201E',
+ '\u2026',
+ '\u2020',
+ '\u2021',
+ '\u02C6',
+ '\u2030',
+ '\u0160',
+ '\u2039',
+ '\u0152',
+ '\u008D',
+ '\u017D',
+ '\u008F',
+ '\u0090',
+ '\u2018',
+ '\u2019',
+ '\u201C',
+ '\u201D',
+ '\u2022',
+ '\u2013',
+ '\u2014',
+ '\u02DC',
+ '\u2122',
+ '\u0161',
+ '\u203A',
+ '\u0153',
+ '\u009D',
+ '\u017E',
+ '\u0178', // Last entry is 0x9F.
+ // 0x00->'\uFFFD' is handled programmatically.
+ // 0x0D->'\u000D' is a no-op.
+}
+
+// unescapeEntity reads an entity like "<" from b[src:] and writes the
+// corresponding "<" to b[dst:], returning the incremented dst and src cursors.
+// Precondition: b[src] == '&' && dst <= src.
+// attribute should be true if parsing an attribute value.
+func unescapeEntity(b []byte, dst, src int, attribute bool) (dst1, src1 int) {
+ // https://html.spec.whatwg.org/multipage/syntax.html#consume-a-character-reference
+
+ // i starts at 1 because we already know that s[0] == '&'.
+ i, s := 1, b[src:]
+
+ if len(s) <= 1 {
+ b[dst] = b[src]
+ return dst + 1, src + 1
+ }
+
+ if s[i] == '#' {
+ if len(s) <= 3 { // We need to have at least ".".
+ b[dst] = b[src]
+ return dst + 1, src + 1
+ }
+ i++
+ c := s[i]
+ hex := false
+ if c == 'x' || c == 'X' {
+ hex = true
+ i++
+ }
+
+ x := '\x00'
+ for i < len(s) {
+ c = s[i]
+ i++
+ if hex {
+ if '0' <= c && c <= '9' {
+ x = 16*x + rune(c) - '0'
+ continue
+ } else if 'a' <= c && c <= 'f' {
+ x = 16*x + rune(c) - 'a' + 10
+ continue
+ } else if 'A' <= c && c <= 'F' {
+ x = 16*x + rune(c) - 'A' + 10
+ continue
+ }
+ } else if '0' <= c && c <= '9' {
+ x = 10*x + rune(c) - '0'
+ continue
+ }
+ if c != ';' {
+ i--
+ }
+ break
+ }
+
+ if i <= 3 { // No characters matched.
+ b[dst] = b[src]
+ return dst + 1, src + 1
+ }
+
+ if 0x80 <= x && x <= 0x9F {
+ // Replace characters from Windows-1252 with UTF-8 equivalents.
+ x = replacementTable[x-0x80]
+ } else if x == 0 || (0xD800 <= x && x <= 0xDFFF) || x > 0x10FFFF {
+ // Replace invalid characters with the replacement character.
+ x = '\uFFFD'
+ }
+
+ return dst + utf8.EncodeRune(b[dst:], x), src + i
+ }
+
+ // Consume the maximum number of characters possible, with the
+ // consumed characters matching one of the named references.
+
+ for i < len(s) {
+ c := s[i]
+ i++
+ // Lower-cased characters are more common in entities, so we check for them first.
+ if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9' {
+ continue
+ }
+ if c != ';' {
+ i--
+ }
+ break
+ }
+
+ entityName := string(s[1:i])
+ if entityName == "" {
+ // No-op.
+ } else if attribute && entityName[len(entityName)-1] != ';' && len(s) > i && s[i] == '=' {
+ // No-op.
+ } else if x := entity[entityName]; x != 0 {
+ return dst + utf8.EncodeRune(b[dst:], x), src + i
+ } else if x := entity2[entityName]; x[0] != 0 {
+ dst1 := dst + utf8.EncodeRune(b[dst:], x[0])
+ return dst1 + utf8.EncodeRune(b[dst1:], x[1]), src + i
+ } else if !attribute {
+ maxLen := len(entityName) - 1
+ if maxLen > longestEntityWithoutSemicolon {
+ maxLen = longestEntityWithoutSemicolon
+ }
+ for j := maxLen; j > 1; j-- {
+ if x := entity[entityName[:j]]; x != 0 {
+ return dst + utf8.EncodeRune(b[dst:], x), src + j + 1
+ }
+ }
+ }
+
+ dst1, src1 = dst+i, src+i
+ copy(b[dst:dst1], b[src:src1])
+ return dst1, src1
+}
+
+// unescape unescapes b's entities in-place, so that "a<b" becomes "a' byte that, per above, we'd like to avoid escaping unless we have to.
+//
+// Studying the summary table (and T actions in its '>' column) closely, we
+// only need to escape in states 43, 44, 49, 51 and 52. State 43 is at the
+// start of the comment data. State 52 is after a '!'. The other three states
+// are after a '-'.
+//
+// Our algorithm is thus to escape every '&' and to escape '>' if and only if:
+// - The '>' is after a '!' or '-' (in the unescaped data) or
+// - The '>' is at the start of the comment data (after the opening ""); err != nil {
+ return err
+ }
+ return nil
+ case DoctypeNode:
+ if _, err := w.WriteString("')
+ case RawNode:
+ _, err := w.WriteString(n.Data)
+ return err
+ default:
+ return errors.New("html: unknown node type")
+ }
+
+ // Render the opening tag.
+ if err := w.WriteByte('<'); err != nil {
+ return err
+ }
+ if _, err := w.WriteString(n.Data); err != nil {
+ return err
+ }
+ for _, a := range n.Attr {
+ if err := w.WriteByte(' '); err != nil {
+ return err
+ }
+ if a.Namespace != "" {
+ if _, err := w.WriteString(a.Namespace); err != nil {
+ return err
+ }
+ if err := w.WriteByte(':'); err != nil {
+ return err
+ }
+ }
+ if _, err := w.WriteString(a.Key); err != nil {
+ return err
+ }
+ if _, err := w.WriteString(`="`); err != nil {
+ return err
+ }
+ if err := escape(w, a.Val); err != nil {
+ return err
+ }
+ if err := w.WriteByte('"'); err != nil {
+ return err
+ }
+ }
+ if voidElements[n.Data] {
+ if n.FirstChild != nil {
+ return fmt.Errorf("html: void element <%s> has child nodes", n.Data)
+ }
+ _, err := w.WriteString("/>")
+ return err
+ }
+ if err := w.WriteByte('>'); err != nil {
+ return err
+ }
+
+ // Add initial newline where there is danger of a newline beging ignored.
+ if c := n.FirstChild; c != nil && c.Type == TextNode && strings.HasPrefix(c.Data, "\n") {
+ switch n.Data {
+ case "pre", "listing", "textarea":
+ if err := w.WriteByte('\n'); err != nil {
+ return err
+ }
+ }
+ }
+
+ // Render any child nodes
+ if childTextNodesAreLiteral(n) {
+ for c := n.FirstChild; c != nil; c = c.NextSibling {
+ if c.Type == TextNode {
+ if _, err := w.WriteString(c.Data); err != nil {
+ return err
+ }
+ } else {
+ if err := render1(w, c); err != nil {
+ return err
+ }
+ }
+ }
+ if n.Data == "plaintext" {
+ // Don't render anything else. must be the
+ // last element in the file, with no closing tag.
+ return plaintextAbort
+ }
+ } else {
+ for c := n.FirstChild; c != nil; c = c.NextSibling {
+ if err := render1(w, c); err != nil {
+ return err
+ }
+ }
+ }
+
+ // Render the closing tag.
+ if _, err := w.WriteString(""); err != nil {
+ return err
+ }
+ if _, err := w.WriteString(n.Data); err != nil {
+ return err
+ }
+ return w.WriteByte('>')
+}
+
+func childTextNodesAreLiteral(n *Node) bool {
+ // Per WHATWG HTML 13.3, if the parent of the current node is a style,
+ // script, xmp, iframe, noembed, noframes, or plaintext element, and the
+ // current node is a text node, append the value of the node's data
+ // literally. The specification is not explicit about it, but we only
+ // enforce this if we are in the HTML namespace (i.e. when the namespace is
+ // "").
+ // NOTE: we also always include noscript elements, although the
+ // specification states that they should only be rendered as such if
+ // scripting is enabled for the node (which is not something we track).
+ if n.Namespace != "" {
+ return false
+ }
+ switch n.Data {
+ case "iframe", "noembed", "noframes", "noscript", "plaintext", "script", "style", "xmp":
+ return true
+ default:
+ return false
+ }
+}
+
+// writeQuoted writes s to w surrounded by quotes. Normally it will use double
+// quotes, but if s contains a double quote, it will use single quotes.
+// It is used for writing the identifiers in a doctype declaration.
+// In valid HTML, they can't contain both types of quotes.
+func writeQuoted(w writer, s string) error {
+ var q byte = '"'
+ if strings.Contains(s, `"`) {
+ q = '\''
+ }
+ if err := w.WriteByte(q); err != nil {
+ return err
+ }
+ if _, err := w.WriteString(s); err != nil {
+ return err
+ }
+ if err := w.WriteByte(q); err != nil {
+ return err
+ }
+ return nil
+}
+
+// Section 12.1.2, "Elements", gives this list of void elements. Void elements
+// are those that can't have any contents.
+var voidElements = map[string]bool{
+ "area": true,
+ "base": true,
+ "br": true,
+ "col": true,
+ "embed": true,
+ "hr": true,
+ "img": true,
+ "input": true,
+ "keygen": true, // "keygen" has been removed from the spec, but are kept here for backwards compatibility.
+ "link": true,
+ "meta": true,
+ "param": true,
+ "source": true,
+ "track": true,
+ "wbr": true,
+}
diff --git a/vendor/golang.org/x/net/html/token.go b/vendor/golang.org/x/net/html/token.go
new file mode 100644
index 00000000..6598c1f7
--- /dev/null
+++ b/vendor/golang.org/x/net/html/token.go
@@ -0,0 +1,1286 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package html
+
+import (
+ "bytes"
+ "errors"
+ "io"
+ "strconv"
+ "strings"
+
+ "golang.org/x/net/html/atom"
+)
+
+// A TokenType is the type of a Token.
+type TokenType uint32
+
+const (
+ // ErrorToken means that an error occurred during tokenization.
+ ErrorToken TokenType = iota
+ // TextToken means a text node.
+ TextToken
+ // A StartTagToken looks like .
+ StartTagToken
+ // An EndTagToken looks like .
+ EndTagToken
+ // A SelfClosingTagToken tag looks like .
+ SelfClosingTagToken
+ // A CommentToken looks like .
+ CommentToken
+ // A DoctypeToken looks like
+ DoctypeToken
+)
+
+// ErrBufferExceeded means that the buffering limit was exceeded.
+var ErrBufferExceeded = errors.New("max buffer exceeded")
+
+// String returns a string representation of the TokenType.
+func (t TokenType) String() string {
+ switch t {
+ case ErrorToken:
+ return "Error"
+ case TextToken:
+ return "Text"
+ case StartTagToken:
+ return "StartTag"
+ case EndTagToken:
+ return "EndTag"
+ case SelfClosingTagToken:
+ return "SelfClosingTag"
+ case CommentToken:
+ return "Comment"
+ case DoctypeToken:
+ return "Doctype"
+ }
+ return "Invalid(" + strconv.Itoa(int(t)) + ")"
+}
+
+// An Attribute is an attribute namespace-key-value triple. Namespace is
+// non-empty for foreign attributes like xlink, Key is alphabetic (and hence
+// does not contain escapable characters like '&', '<' or '>'), and Val is
+// unescaped (it looks like "a"
+ case EndTagToken:
+ return "" + t.tagString() + ">"
+ case SelfClosingTagToken:
+ return "<" + t.tagString() + "/>"
+ case CommentToken:
+ return ""
+ case DoctypeToken:
+ return ""
+ }
+ return "Invalid(" + strconv.Itoa(int(t.Type)) + ")"
+}
+
+// span is a range of bytes in a Tokenizer's buffer. The start is inclusive,
+// the end is exclusive.
+type span struct {
+ start, end int
+}
+
+// A Tokenizer returns a stream of HTML Tokens.
+type Tokenizer struct {
+ // r is the source of the HTML text.
+ r io.Reader
+ // tt is the TokenType of the current token.
+ tt TokenType
+ // err is the first error encountered during tokenization. It is possible
+ // for tt != Error && err != nil to hold: this means that Next returned a
+ // valid token but the subsequent Next call will return an error token.
+ // For example, if the HTML text input was just "plain", then the first
+ // Next call would set z.err to io.EOF but return a TextToken, and all
+ // subsequent Next calls would return an ErrorToken.
+ // err is never reset. Once it becomes non-nil, it stays non-nil.
+ err error
+ // readErr is the error returned by the io.Reader r. It is separate from
+ // err because it is valid for an io.Reader to return (n int, err1 error)
+ // such that n > 0 && err1 != nil, and callers should always process the
+ // n > 0 bytes before considering the error err1.
+ readErr error
+ // buf[raw.start:raw.end] holds the raw bytes of the current token.
+ // buf[raw.end:] is buffered input that will yield future tokens.
+ raw span
+ buf []byte
+ // maxBuf limits the data buffered in buf. A value of 0 means unlimited.
+ maxBuf int
+ // buf[data.start:data.end] holds the raw bytes of the current token's data:
+ // a text token's text, a tag token's tag name, etc.
+ data span
+ // pendingAttr is the attribute key and value currently being tokenized.
+ // When complete, pendingAttr is pushed onto attr. nAttrReturned is
+ // incremented on each call to TagAttr.
+ pendingAttr [2]span
+ attr [][2]span
+ nAttrReturned int
+ // rawTag is the "script" in "" that closes the next token. If
+ // non-empty, the subsequent call to Next will return a raw or RCDATA text
+ // token: one that treats " " as text instead of an element.
+ // rawTag's contents are lower-cased.
+ rawTag string
+ // textIsRaw is whether the current text token's data is not escaped.
+ textIsRaw bool
+ // convertNUL is whether NUL bytes in the current token's data should
+ // be converted into \ufffd replacement characters.
+ convertNUL bool
+ // allowCDATA is whether CDATA sections are allowed in the current context.
+ allowCDATA bool
+}
+
+// AllowCDATA sets whether or not the tokenizer recognizes as
+// the text "foo". The default value is false, which means to recognize it as
+// a bogus comment "" instead.
+//
+// Strictly speaking, an HTML5 compliant tokenizer should allow CDATA if and
+// only if tokenizing foreign content, such as MathML and SVG. However,
+// tracking foreign-contentness is difficult to do purely in the tokenizer,
+// as opposed to the parser, due to HTML integration points: an element
+// can contain a that is foreign-to-SVG but not foreign-to-
+// HTML. For strict compliance with the HTML5 tokenization algorithm, it is the
+// responsibility of the user of a tokenizer to call AllowCDATA as appropriate.
+// In practice, if using the tokenizer without caring whether MathML or SVG
+// CDATA is text or comments, such as tokenizing HTML to find all the anchor
+// text, it is acceptable to ignore this responsibility.
+func (z *Tokenizer) AllowCDATA(allowCDATA bool) {
+ z.allowCDATA = allowCDATA
+}
+
+// NextIsNotRawText instructs the tokenizer that the next token should not be
+// considered as 'raw text'. Some elements, such as script and title elements,
+// normally require the next token after the opening tag to be 'raw text' that
+// has no child elements. For example, tokenizing "ac d "
+// yields a start tag token for "", a text token for "ac d", and
+// an end tag token for " ". There are no distinct start tag or end tag
+// tokens for the "" and " ".
+//
+// This tokenizer implementation will generally look for raw text at the right
+// times. Strictly speaking, an HTML5 compliant tokenizer should not look for
+// raw text if in foreign content: generally needs raw text, but a
+// inside an does not. Another example is that a