auth, etcdserver: hash password in the API layer

release-3.5
Hitoshi Mitake 2020-05-25 01:49:45 +09:00
parent d8c8f903ee
commit 5a3da48cdf
9 changed files with 530 additions and 350 deletions

View File

@ -265,6 +265,7 @@ Empty field.
| name | | string |
| password | | string |
| options | | authpb.UserAddOptions |
| hashedPassword | | string |
@ -281,7 +282,8 @@ Empty field.
| Field | Description | Type |
| ----- | ----------- | ---- |
| name | name is the name of the user whose password is being changed. | string |
| password | password is the new password for the user. | string |
| password | password is the new password for the user. Note that this field will be removed in the API layer. | string |
| hashedPassword | hashedPassword is the new password for the user. Note that this field will be initialized in the API layer. | string |

View File

@ -17,7 +17,7 @@
"Auth"
],
"summary": "Authenticate processes an authenticate request.",
"operationId": "Authenticate",
"operationId": "Auth_Authenticate",
"parameters": [
{
"name": "body",
@ -50,7 +50,7 @@
"Auth"
],
"summary": "AuthDisable disables authentication.",
"operationId": "AuthDisable",
"operationId": "Auth_AuthDisable",
"parameters": [
{
"name": "body",
@ -83,7 +83,7 @@
"Auth"
],
"summary": "AuthEnable enables authentication.",
"operationId": "AuthEnable",
"operationId": "Auth_AuthEnable",
"parameters": [
{
"name": "body",
@ -116,7 +116,7 @@
"Auth"
],
"summary": "RoleAdd adds a new role. Role name cannot be empty.",
"operationId": "RoleAdd",
"operationId": "Auth_RoleAdd",
"parameters": [
{
"name": "body",
@ -149,7 +149,7 @@
"Auth"
],
"summary": "RoleDelete deletes a specified role.",
"operationId": "RoleDelete",
"operationId": "Auth_RoleDelete",
"parameters": [
{
"name": "body",
@ -182,7 +182,7 @@
"Auth"
],
"summary": "RoleGet gets detailed role information.",
"operationId": "RoleGet",
"operationId": "Auth_RoleGet",
"parameters": [
{
"name": "body",
@ -215,7 +215,7 @@
"Auth"
],
"summary": "RoleGrantPermission grants a permission of a specified key or range to a specified role.",
"operationId": "RoleGrantPermission",
"operationId": "Auth_RoleGrantPermission",
"parameters": [
{
"name": "body",
@ -248,7 +248,7 @@
"Auth"
],
"summary": "RoleList gets lists of all roles.",
"operationId": "RoleList",
"operationId": "Auth_RoleList",
"parameters": [
{
"name": "body",
@ -281,7 +281,7 @@
"Auth"
],
"summary": "RoleRevokePermission revokes a key or range permission of a specified role.",
"operationId": "RoleRevokePermission",
"operationId": "Auth_RoleRevokePermission",
"parameters": [
{
"name": "body",
@ -314,7 +314,7 @@
"Auth"
],
"summary": "AuthStatus displays authentication status.",
"operationId": "AuthStatus",
"operationId": "Auth_AuthStatus",
"parameters": [
{
"name": "body",
@ -347,7 +347,7 @@
"Auth"
],
"summary": "UserAdd adds a new user. User name cannot be empty.",
"operationId": "UserAdd",
"operationId": "Auth_UserAdd",
"parameters": [
{
"name": "body",
@ -380,7 +380,7 @@
"Auth"
],
"summary": "UserChangePassword changes the password of a specified user.",
"operationId": "UserChangePassword",
"operationId": "Auth_UserChangePassword",
"parameters": [
{
"name": "body",
@ -413,7 +413,7 @@
"Auth"
],
"summary": "UserDelete deletes a specified user.",
"operationId": "UserDelete",
"operationId": "Auth_UserDelete",
"parameters": [
{
"name": "body",
@ -446,7 +446,7 @@
"Auth"
],
"summary": "UserGet gets detailed user information.",
"operationId": "UserGet",
"operationId": "Auth_UserGet",
"parameters": [
{
"name": "body",
@ -479,7 +479,7 @@
"Auth"
],
"summary": "UserGrant grants a role to a specified user.",
"operationId": "UserGrantRole",
"operationId": "Auth_UserGrantRole",
"parameters": [
{
"name": "body",
@ -512,7 +512,7 @@
"Auth"
],
"summary": "UserList gets a list of all users.",
"operationId": "UserList",
"operationId": "Auth_UserList",
"parameters": [
{
"name": "body",
@ -545,7 +545,7 @@
"Auth"
],
"summary": "UserRevokeRole revokes a role of specified user.",
"operationId": "UserRevokeRole",
"operationId": "Auth_UserRevokeRole",
"parameters": [
{
"name": "body",
@ -578,7 +578,7 @@
"Cluster"
],
"summary": "MemberAdd adds a member into the cluster.",
"operationId": "MemberAdd",
"operationId": "Cluster_MemberAdd",
"parameters": [
{
"name": "body",
@ -611,7 +611,7 @@
"Cluster"
],
"summary": "MemberList lists all the members in the cluster.",
"operationId": "MemberList",
"operationId": "Cluster_MemberList",
"parameters": [
{
"name": "body",
@ -644,7 +644,7 @@
"Cluster"
],
"summary": "MemberPromote promotes a member from raft learner (non-voting) to raft voting member.",
"operationId": "MemberPromote",
"operationId": "Cluster_MemberPromote",
"parameters": [
{
"name": "body",
@ -677,7 +677,7 @@
"Cluster"
],
"summary": "MemberRemove removes an existing member from the cluster.",
"operationId": "MemberRemove",
"operationId": "Cluster_MemberRemove",
"parameters": [
{
"name": "body",
@ -710,7 +710,7 @@
"Cluster"
],
"summary": "MemberUpdate updates the member configuration.",
"operationId": "MemberUpdate",
"operationId": "Cluster_MemberUpdate",
"parameters": [
{
"name": "body",
@ -743,7 +743,7 @@
"KV"
],
"summary": "Compact compacts the event history in the etcd key-value store. The key-value\nstore should be periodically compacted or the event history will continue to grow\nindefinitely.",
"operationId": "Compact",
"operationId": "KV_Compact",
"parameters": [
{
"name": "body",
@ -776,7 +776,7 @@
"KV"
],
"summary": "DeleteRange deletes the given range from the key-value store.\nA delete request increments the revision of the key-value store\nand generates a delete event in the event history for every deleted key.",
"operationId": "DeleteRange",
"operationId": "KV_DeleteRange",
"parameters": [
{
"name": "body",
@ -809,7 +809,7 @@
"Lease"
],
"summary": "LeaseLeases lists all existing leases.",
"operationId": "LeaseLeases2",
"operationId": "Lease_LeaseLeases2",
"parameters": [
{
"name": "body",
@ -842,7 +842,7 @@
"Lease"
],
"summary": "LeaseRevoke revokes a lease. All keys attached to the lease will expire and be deleted.",
"operationId": "LeaseRevoke2",
"operationId": "Lease_LeaseRevoke2",
"parameters": [
{
"name": "body",
@ -875,7 +875,7 @@
"Lease"
],
"summary": "LeaseTimeToLive retrieves lease information.",
"operationId": "LeaseTimeToLive2",
"operationId": "Lease_LeaseTimeToLive2",
"parameters": [
{
"name": "body",
@ -908,7 +908,7 @@
"KV"
],
"summary": "Put puts the given key into the key-value store.\nA put request increments the revision of the key-value store\nand generates one event in the event history.",
"operationId": "Put",
"operationId": "KV_Put",
"parameters": [
{
"name": "body",
@ -941,7 +941,7 @@
"KV"
],
"summary": "Range gets the keys in the range from the key-value store.",
"operationId": "Range",
"operationId": "KV_Range",
"parameters": [
{
"name": "body",
@ -974,7 +974,7 @@
"KV"
],
"summary": "Txn processes multiple requests in a single transaction.\nA txn request increments the revision of the key-value store\nand generates events with the same revision for every completed request.\nIt is not allowed to modify the same key several times within one txn.",
"operationId": "Txn",
"operationId": "KV_Txn",
"parameters": [
{
"name": "body",
@ -1007,7 +1007,7 @@
"Lease"
],
"summary": "LeaseGrant creates a lease which expires if the server does not receive a keepAlive\nwithin a given time to live period. All keys attached to the lease will be expired and\ndeleted if the lease expires. Each expired key generates a delete event in the event history.",
"operationId": "LeaseGrant",
"operationId": "Lease_LeaseGrant",
"parameters": [
{
"name": "body",
@ -1040,7 +1040,7 @@
"Lease"
],
"summary": "LeaseKeepAlive keeps the lease alive by streaming keep alive requests from the client\nto the server and streaming keep alive responses from the server to the client.",
"operationId": "LeaseKeepAlive",
"operationId": "Lease_LeaseKeepAlive",
"parameters": [
{
"description": " (streaming inputs)",
@ -1083,7 +1083,7 @@
"Lease"
],
"summary": "LeaseLeases lists all existing leases.",
"operationId": "LeaseLeases",
"operationId": "Lease_LeaseLeases",
"parameters": [
{
"name": "body",
@ -1116,7 +1116,7 @@
"Lease"
],
"summary": "LeaseRevoke revokes a lease. All keys attached to the lease will expire and be deleted.",
"operationId": "LeaseRevoke",
"operationId": "Lease_LeaseRevoke",
"parameters": [
{
"name": "body",
@ -1149,7 +1149,7 @@
"Lease"
],
"summary": "LeaseTimeToLive retrieves lease information.",
"operationId": "LeaseTimeToLive",
"operationId": "Lease_LeaseTimeToLive",
"parameters": [
{
"name": "body",
@ -1182,7 +1182,7 @@
"Maintenance"
],
"summary": "Alarm activates, deactivates, and queries alarms regarding cluster health.",
"operationId": "Alarm",
"operationId": "Maintenance_Alarm",
"parameters": [
{
"name": "body",
@ -1215,7 +1215,7 @@
"Maintenance"
],
"summary": "Defragment defragments a member's backend database to recover storage space.",
"operationId": "Defragment",
"operationId": "Maintenance_Defragment",
"parameters": [
{
"name": "body",
@ -1248,7 +1248,7 @@
"Maintenance"
],
"summary": "Downgrade requests downgrade, cancel downgrade on the cluster version.",
"operationId": "Downgrade",
"operationId": "Maintenance_Downgrade",
"parameters": [
{
"name": "body",
@ -1281,7 +1281,7 @@
"Maintenance"
],
"summary": "HashKV computes the hash of all MVCC keys up to a given revision.\nIt only iterates \"key\" bucket in backend storage.",
"operationId": "HashKV",
"operationId": "Maintenance_HashKV",
"parameters": [
{
"name": "body",
@ -1314,7 +1314,7 @@
"Maintenance"
],
"summary": "Snapshot sends a snapshot of the entire backend from a member over a stream to a client.",
"operationId": "Snapshot",
"operationId": "Maintenance_Snapshot",
"parameters": [
{
"name": "body",
@ -1356,7 +1356,7 @@
"Maintenance"
],
"summary": "Status gets the status of the member.",
"operationId": "Status",
"operationId": "Maintenance_Status",
"parameters": [
{
"name": "body",
@ -1389,7 +1389,7 @@
"Maintenance"
],
"summary": "MoveLeader requests current leader node to transfer its leadership to transferee.",
"operationId": "MoveLeader",
"operationId": "Maintenance_MoveLeader",
"parameters": [
{
"name": "body",
@ -1422,7 +1422,7 @@
"Watch"
],
"summary": "Watch watches for events happening or that have happened. Both input and output\nare streams; the input stream is for creating and canceling watchers and the output\nstream sends events. One watch RPC can watch on multiple key ranges, streaming events\nfor several watches at once. The entire event history can be watched starting from the\nlast compaction revision.",
"operationId": "Watch",
"operationId": "Watch_Watch",
"parameters": [
{
"description": " (streaming inputs)",
@ -1790,6 +1790,9 @@
"etcdserverpbAuthUserAddRequest": {
"type": "object",
"properties": {
"hashedPassword": {
"type": "string"
},
"name": {
"type": "string"
},
@ -1812,12 +1815,16 @@
"etcdserverpbAuthUserChangePasswordRequest": {
"type": "object",
"properties": {
"hashedPassword": {
"description": "hashedPassword is the new password for the user. Note that this field will be initialized in the API layer.",
"type": "string"
},
"name": {
"description": "name is the name of the user whose password is being changed.",
"type": "string"
},
"password": {
"description": "password is the new password for the user.",
"description": "password is the new password for the user. Note that this field will be removed in the API layer.",
"type": "string"
}
}

View File

@ -14,7 +14,7 @@
"/v3/election/campaign": {
"post": {
"summary": "Campaign waits to acquire leadership in an election, returning a LeaderKey\nrepresenting the leadership if successful. The LeaderKey can then be used\nto issue new values on the election, transactionally guard API requests on\nleadership still being held, and resign from the election.",
"operationId": "Campaign",
"operationId": "Election_Campaign",
"responses": {
"200": {
"description": "A successful response.",
@ -47,7 +47,7 @@
"/v3/election/leader": {
"post": {
"summary": "Leader returns the current election proclamation, if any.",
"operationId": "Leader",
"operationId": "Election_Leader",
"responses": {
"200": {
"description": "A successful response.",
@ -80,7 +80,7 @@
"/v3/election/observe": {
"post": {
"summary": "Observe streams election proclamations in-order as made by the election's\nelected leaders.",
"operationId": "Observe",
"operationId": "Election_Observe",
"responses": {
"200": {
"description": "A successful response.(streaming responses)",
@ -122,7 +122,7 @@
"/v3/election/proclaim": {
"post": {
"summary": "Proclaim updates the leader's posted value with a new value.",
"operationId": "Proclaim",
"operationId": "Election_Proclaim",
"responses": {
"200": {
"description": "A successful response.",
@ -155,7 +155,7 @@
"/v3/election/resign": {
"post": {
"summary": "Resign releases election leadership so other campaigners may acquire\nleadership on the election.",
"operationId": "Resign",
"operationId": "Election_Resign",
"responses": {
"200": {
"description": "A successful response.",

View File

@ -14,7 +14,7 @@
"/v3/lock/lock": {
"post": {
"summary": "Lock acquires a distributed shared lock on a given named lock.\nOn success, it will return a unique key that exists so long as the\nlock is held by the caller. This key can be used in conjunction with\ntransactions to safely ensure updates to etcd only occur while holding\nlock ownership. The lock is held until Unlock is called on the key or the\nlease associate with the owner expires.",
"operationId": "Lock",
"operationId": "Lock_Lock",
"responses": {
"200": {
"description": "A successful response.",
@ -47,7 +47,7 @@
"/v3/lock/unlock": {
"post": {
"summary": "Unlock takes a key returned by Lock and releases the hold on lock. The\nnext Lock caller waiting for the lock will then be woken up and given\nownership of the lock.",
"operationId": "Unlock",
"operationId": "Lock_Unlock",
"responses": {
"200": {
"description": "A successful response.",

View File

@ -17,6 +17,7 @@ package auth
import (
"bytes"
"context"
"encoding/base64"
"encoding/binary"
"errors"
"sort"
@ -185,6 +186,9 @@ type AuthStore interface {
// HasRole checks that user has role
HasRole(user, role string) bool
// BcryptCost gets strength of hashing bcrypted auth password
BcryptCost() int
}
type TokenProvider interface {
@ -371,27 +375,19 @@ func (as *authStore) Recover(be backend.Backend) {
as.enabledMu.Unlock()
}
func (as *authStore) selectPassword(password string, hashedPassword string) ([]byte, error) {
if password != "" && hashedPassword == "" {
// This path is for processing log entries created by etcd whose version is older than 3.5
return bcrypt.GenerateFromPassword([]byte(password), as.bcryptCost)
}
return base64.StdEncoding.DecodeString(hashedPassword)
}
func (as *authStore) UserAdd(r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) {
if len(r.Name) == 0 {
return nil, ErrUserEmpty
}
var hashed []byte
var err error
noPassword := r.Options != nil && r.Options.NoPassword
if !noPassword {
hashed, err = bcrypt.GenerateFromPassword([]byte(r.Password), as.bcryptCost)
if err != nil {
as.lg.Error(
"failed to bcrypt hash password",
zap.String("user-name", r.Name),
zap.Error(err),
)
return nil, err
}
}
tx := as.be.BatchTx()
tx.Lock()
defer tx.Unlock()
@ -408,9 +404,19 @@ func (as *authStore) UserAdd(r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse,
}
}
var password []byte
var err error
if !options.NoPassword {
password, err = as.selectPassword(r.Password, r.HashedPassword)
if err != nil {
return nil, ErrNoPasswordUser
}
}
newUser := &authpb.User{
Name: []byte(r.Name),
Password: hashed,
Password: password,
Options: options,
}
@ -455,18 +461,6 @@ func (as *authStore) UserDelete(r *pb.AuthUserDeleteRequest) (*pb.AuthUserDelete
}
func (as *authStore) UserChangePassword(r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) {
// TODO(mitake): measure the cost of bcrypt.GenerateFromPassword()
// If the cost is too high, we should move the encryption to outside of the raft
hashed, err := bcrypt.GenerateFromPassword([]byte(r.Password), as.bcryptCost)
if err != nil {
as.lg.Error(
"failed to bcrypt hash password",
zap.String("user-name", r.Name),
zap.Error(err),
)
return nil, err
}
tx := as.be.BatchTx()
tx.Lock()
defer tx.Unlock()
@ -476,10 +470,20 @@ func (as *authStore) UserChangePassword(r *pb.AuthUserChangePasswordRequest) (*p
return nil, ErrUserNotFound
}
var password []byte
var err error
if !user.Options.NoPassword {
password, err = as.selectPassword(r.Password, r.HashedPassword)
if err != nil {
return nil, ErrNoPasswordUser
}
}
updatedUser := &authpb.User{
Name: []byte(r.Name),
Roles: user.Roles,
Password: hashed,
Password: password,
Options: user.Options,
}

View File

@ -16,6 +16,7 @@ package auth
import (
"context"
"encoding/base64"
"fmt"
"os"
"reflect"
@ -95,6 +96,11 @@ func TestNewAuthStoreBcryptCost(t *testing.T) {
b.Close()
}
func encodePassword(s string) string {
hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(s), bcrypt.MinCost)
return base64.StdEncoding.EncodeToString([]byte(hashedPassword))
}
func setupAuthStore(t *testing.T) (store *authStore, teardownfunc func(t *testing.T)) {
b, tPath := backend.NewDefaultTmpBackend()
@ -114,7 +120,7 @@ func setupAuthStore(t *testing.T) (store *authStore, teardownfunc func(t *testin
t.Fatal(err)
}
ua := &pb.AuthUserAddRequest{Name: "foo", Password: "bar", Options: &authpb.UserAddOptions{NoPassword: false}}
ua := &pb.AuthUserAddRequest{Name: "foo", HashedPassword: encodePassword("bar"), Options: &authpb.UserAddOptions{NoPassword: false}}
_, err = as.UserAdd(ua) // add a non-existing user
if err != nil {
t.Fatal(err)
@ -129,7 +135,7 @@ func setupAuthStore(t *testing.T) (store *authStore, teardownfunc func(t *testin
}
func enableAuthAndCreateRoot(as *authStore) error {
_, err := as.UserAdd(&pb.AuthUserAddRequest{Name: "root", Password: "root", Options: &authpb.UserAddOptions{NoPassword: false}})
_, err := as.UserAdd(&pb.AuthUserAddRequest{Name: "root", HashedPassword: encodePassword("root"), Options: &authpb.UserAddOptions{NoPassword: false}})
if err != nil {
return err
}
@ -239,7 +245,7 @@ func TestUserChangePassword(t *testing.T) {
t.Fatal(err)
}
_, err = as.UserChangePassword(&pb.AuthUserChangePasswordRequest{Name: "foo", Password: "baz"})
_, err = as.UserChangePassword(&pb.AuthUserChangePasswordRequest{Name: "foo", HashedPassword: encodePassword("baz")})
if err != nil {
t.Fatal(err)
}
@ -251,7 +257,7 @@ func TestUserChangePassword(t *testing.T) {
}
// change a non-existing user
_, err = as.UserChangePassword(&pb.AuthUserChangePasswordRequest{Name: "foo-test", Password: "bar"})
_, err = as.UserChangePassword(&pb.AuthUserChangePasswordRequest{Name: "foo-test", HashedPassword: encodePassword("bar")})
if err == nil {
t.Fatalf("expected %v, got %v", ErrUserNotFound, err)
}
@ -396,7 +402,7 @@ func TestListUsers(t *testing.T) {
as, tearDown := setupAuthStore(t)
defer tearDown(t)
ua := &pb.AuthUserAddRequest{Name: "user1", Password: "pwd1", Options: &authpb.UserAddOptions{NoPassword: false}}
ua := &pb.AuthUserAddRequest{Name: "user1", HashedPassword: encodePassword("pwd1"), Options: &authpb.UserAddOptions{NoPassword: false}}
_, err := as.UserAdd(ua) // add a non-existing user
if err != nil {
t.Fatal(err)
@ -770,7 +776,7 @@ func TestHammerSimpleAuthenticate(t *testing.T) {
// create lots of users
for i := 0; i < 50; i++ {
u := fmt.Sprintf("user-%d", i)
ua := &pb.AuthUserAddRequest{Name: u, Password: "123", Options: &authpb.UserAddOptions{NoPassword: false}}
ua := &pb.AuthUserAddRequest{Name: u, HashedPassword: encodePassword("123"), Options: &authpb.UserAddOptions{NoPassword: false}}
if _, err := as.UserAdd(ua); err != nil {
t.Fatal(err)
}
@ -815,7 +821,7 @@ func TestRolesOrder(t *testing.T) {
}
username := "user"
_, err = as.UserAdd(&pb.AuthUserAddRequest{Name: username, Password: "pass", Options: &authpb.UserAddOptions{NoPassword: false}})
_, err = as.UserAdd(&pb.AuthUserAddRequest{Name: username, HashedPassword: encodePassword("pass"), Options: &authpb.UserAddOptions{NoPassword: false}})
if err != nil {
t.Fatal(err)
}
@ -902,3 +908,45 @@ func TestUserNoPasswordAdd(t *testing.T) {
t.Fatalf("expected %v, got %v", ErrAuthFailed, err)
}
}
func TestUserAddWithOldLog(t *testing.T) {
as, tearDown := setupAuthStore(t)
defer tearDown(t)
ua := &pb.AuthUserAddRequest{Name: "bar", Password: "baz", Options: &authpb.UserAddOptions{NoPassword: false}}
_, err := as.UserAdd(ua)
if err != nil {
t.Fatal(err)
}
}
func TestUserChangePasswordWithOldLog(t *testing.T) {
as, tearDown := setupAuthStore(t)
defer tearDown(t)
ctx1 := context.WithValue(context.WithValue(context.TODO(), AuthenticateParamIndex{}, uint64(1)), AuthenticateParamSimpleTokenPrefix{}, "dummy")
_, err := as.Authenticate(ctx1, "foo", "bar")
if err != nil {
t.Fatal(err)
}
_, err = as.UserChangePassword(&pb.AuthUserChangePasswordRequest{Name: "foo", Password: "baz"})
if err != nil {
t.Fatal(err)
}
ctx2 := context.WithValue(context.WithValue(context.TODO(), AuthenticateParamIndex{}, uint64(2)), AuthenticateParamSimpleTokenPrefix{}, "dummy")
_, err = as.Authenticate(ctx2, "foo", "baz")
if err != nil {
t.Fatal(err)
}
// change a non-existing user
_, err = as.UserChangePassword(&pb.AuthUserChangePasswordRequest{Name: "foo-test", HashedPassword: encodePassword("bar")})
if err == nil {
t.Fatalf("expected %v, got %v", ErrUserNotFound, err)
}
if err != ErrUserNotFound {
t.Fatalf("expected %v, got %v", ErrUserNotFound, err)
}
}

View File

@ -2847,9 +2847,10 @@ func (m *AuthenticateRequest) GetPassword() string {
}
type AuthUserAddRequest struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"`
Options *authpb.UserAddOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"`
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"`
Options *authpb.UserAddOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"`
HashedPassword string `protobuf:"bytes,4,opt,name=hashedPassword,proto3" json:"hashedPassword,omitempty"`
}
func (m *AuthUserAddRequest) Reset() { *m = AuthUserAddRequest{} }
@ -2878,6 +2879,13 @@ func (m *AuthUserAddRequest) GetOptions() *authpb.UserAddOptions {
return nil
}
func (m *AuthUserAddRequest) GetHashedPassword() string {
if m != nil {
return m.HashedPassword
}
return ""
}
type AuthUserGetRequest struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
}
@ -2914,8 +2922,10 @@ func (m *AuthUserDeleteRequest) GetName() string {
type AuthUserChangePasswordRequest struct {
// name is the name of the user whose password is being changed.
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
// password is the new password for the user.
// password is the new password for the user. Note that this field will be removed in the API layer.
Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"`
// hashedPassword is the new password for the user. Note that this field will be initialized in the API layer.
HashedPassword string `protobuf:"bytes,3,opt,name=hashedPassword,proto3" json:"hashedPassword,omitempty"`
}
func (m *AuthUserChangePasswordRequest) Reset() { *m = AuthUserChangePasswordRequest{} }
@ -2939,6 +2949,13 @@ func (m *AuthUserChangePasswordRequest) GetPassword() string {
return ""
}
func (m *AuthUserChangePasswordRequest) GetHashedPassword() string {
if m != nil {
return m.HashedPassword
}
return ""
}
type AuthUserGrantRoleRequest struct {
// user is the name of the user which should be granted a given role.
User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"`
@ -7927,6 +7944,12 @@ func (m *AuthUserAddRequest) MarshalTo(dAtA []byte) (int, error) {
}
i += n45
}
if len(m.HashedPassword) > 0 {
dAtA[i] = 0x22
i++
i = encodeVarintRpc(dAtA, i, uint64(len(m.HashedPassword)))
i += copy(dAtA[i:], m.HashedPassword)
}
return i, nil
}
@ -8005,6 +8028,12 @@ func (m *AuthUserChangePasswordRequest) MarshalTo(dAtA []byte) (int, error) {
i = encodeVarintRpc(dAtA, i, uint64(len(m.Password)))
i += copy(dAtA[i:], m.Password)
}
if len(m.HashedPassword) > 0 {
dAtA[i] = 0x1a
i++
i = encodeVarintRpc(dAtA, i, uint64(len(m.HashedPassword)))
i += copy(dAtA[i:], m.HashedPassword)
}
return i, nil
}
@ -9918,6 +9947,10 @@ func (m *AuthUserAddRequest) Size() (n int) {
l = m.Options.Size()
n += 1 + l + sovRpc(uint64(l))
}
l = len(m.HashedPassword)
if l > 0 {
n += 1 + l + sovRpc(uint64(l))
}
return n
}
@ -9952,6 +9985,10 @@ func (m *AuthUserChangePasswordRequest) Size() (n int) {
if l > 0 {
n += 1 + l + sovRpc(uint64(l))
}
l = len(m.HashedPassword)
if l > 0 {
n += 1 + l + sovRpc(uint64(l))
}
return n
}
@ -17831,6 +17868,35 @@ func (m *AuthUserAddRequest) Unmarshal(dAtA []byte) error {
return err
}
iNdEx = postIndex
case 4:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field HashedPassword", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRpc
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthRpc
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.HashedPassword = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipRpc(dAtA[iNdEx:])
@ -18097,6 +18163,35 @@ func (m *AuthUserChangePasswordRequest) Unmarshal(dAtA []byte) error {
}
m.Password = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field HashedPassword", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRpc
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthRpc
}
postIndex := iNdEx + intStringLen
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.HashedPassword = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipRpc(dAtA[iNdEx:])
@ -20629,261 +20724,262 @@ var (
func init() { proto.RegisterFile("rpc.proto", fileDescriptorRpc) }
var fileDescriptorRpc = []byte{
// 4089 bytes of a gzipped FileDescriptorProto
// 4111 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x5b, 0x5b, 0x73, 0x1b, 0xc9,
0x75, 0xe6, 0x00, 0xc4, 0xed, 0xe0, 0x42, 0xb0, 0x79, 0x11, 0x04, 0x49, 0x14, 0xb7, 0xb5, 0xda,
0xe5, 0x4a, 0xbb, 0xc4, 0x9a, 0xb6, 0xb3, 0x55, 0x4a, 0xe2, 0x18, 0x22, 0xb1, 0x12, 0x97, 0x14,
0xc1, 0x1d, 0x42, 0xda, 0x4b, 0xb9, 0xc2, 0x1a, 0x02, 0x2d, 0x72, 0x42, 0x60, 0x06, 0x9e, 0x19,
0x40, 0xe4, 0xe6, 0xe2, 0x94, 0xcb, 0x71, 0x25, 0xaf, 0x76, 0x55, 0x2a, 0x79, 0xc8, 0x53, 0x2a,
0xe5, 0xf2, 0x83, 0x9f, 0xf3, 0x17, 0xf2, 0x94, 0x4b, 0xe5, 0x0f, 0xa4, 0x36, 0x7e, 0x49, 0x7e,
0x44, 0x2a, 0xd5, 0xb7, 0x99, 0x9e, 0x1b, 0x29, 0x2f, 0x76, 0xf7, 0x85, 0x9c, 0x3e, 0x7d, 0xfa,
0x7c, 0xa7, 0x4f, 0x77, 0x9f, 0xd3, 0x7d, 0xba, 0x01, 0x25, 0x67, 0xdc, 0xdf, 0x1c, 0x3b, 0xb6,
0x67, 0xa3, 0x0a, 0xf1, 0xfa, 0x03, 0x97, 0x38, 0x53, 0xe2, 0x8c, 0x4f, 0x9a, 0xcb, 0xa7, 0xf6,
0xa9, 0xcd, 0x2a, 0x5a, 0xf4, 0x8b, 0xf3, 0x34, 0x6f, 0x52, 0x9e, 0xd6, 0x68, 0xda, 0xef, 0xb3,
0x3f, 0xe3, 0x93, 0xd6, 0xf9, 0x54, 0x54, 0xdd, 0x62, 0x55, 0xc6, 0xc4, 0x3b, 0x63, 0x7f, 0xc6,
0x27, 0xec, 0x9f, 0xa8, 0xbc, 0x7d, 0x6a, 0xdb, 0xa7, 0x43, 0xd2, 0x32, 0xc6, 0x66, 0xcb, 0xb0,
0x2c, 0xdb, 0x33, 0x3c, 0xd3, 0xb6, 0x5c, 0x5e, 0x8b, 0xff, 0x4a, 0x83, 0x9a, 0x4e, 0xdc, 0xb1,
0x6d, 0xb9, 0xe4, 0x29, 0x31, 0x06, 0xc4, 0x41, 0x77, 0x00, 0xfa, 0xc3, 0x89, 0xeb, 0x11, 0xe7,
0xd8, 0x1c, 0x34, 0xb4, 0x75, 0x6d, 0x63, 0x5e, 0x2f, 0x09, 0xca, 0xee, 0x00, 0xdd, 0x82, 0xd2,
0x88, 0x8c, 0x4e, 0x78, 0x6d, 0x86, 0xd5, 0x16, 0x39, 0x61, 0x77, 0x80, 0x9a, 0x50, 0x74, 0xc8,
0xd4, 0x74, 0x4d, 0xdb, 0x6a, 0x64, 0xd7, 0xb5, 0x8d, 0xac, 0xee, 0x97, 0x69, 0x43, 0xc7, 0x78,
0xe9, 0x1d, 0x7b, 0xc4, 0x19, 0x35, 0xe6, 0x79, 0x43, 0x4a, 0xe8, 0x11, 0x67, 0x84, 0x7f, 0x96,
0x83, 0x8a, 0x6e, 0x58, 0xa7, 0x44, 0x27, 0x3f, 0x9e, 0x10, 0xd7, 0x43, 0x75, 0xc8, 0x9e, 0x93,
0x4b, 0x06, 0x5f, 0xd1, 0xe9, 0x27, 0x6f, 0x6f, 0x9d, 0x92, 0x63, 0x62, 0x71, 0xe0, 0x0a, 0x6d,
0x6f, 0x9d, 0x92, 0x8e, 0x35, 0x40, 0xcb, 0x90, 0x1b, 0x9a, 0x23, 0xd3, 0x13, 0xa8, 0xbc, 0x10,
0x52, 0x67, 0x3e, 0xa2, 0xce, 0x36, 0x80, 0x6b, 0x3b, 0xde, 0xb1, 0xed, 0x0c, 0x88, 0xd3, 0xc8,
0xad, 0x6b, 0x1b, 0xb5, 0xad, 0x37, 0x37, 0xd5, 0x81, 0xd8, 0x54, 0x15, 0xda, 0x3c, 0xb2, 0x1d,
0xaf, 0x4b, 0x79, 0xf5, 0x92, 0x2b, 0x3f, 0xd1, 0x87, 0x50, 0x66, 0x42, 0x3c, 0xc3, 0x39, 0x25,
0x5e, 0x23, 0xcf, 0xa4, 0xdc, 0xbf, 0x46, 0x4a, 0x8f, 0x31, 0xeb, 0x0c, 0x9e, 0x7f, 0x23, 0x0c,
0x15, 0x97, 0x38, 0xa6, 0x31, 0x34, 0xbf, 0x30, 0x4e, 0x86, 0xa4, 0x51, 0x58, 0xd7, 0x36, 0x8a,
0x7a, 0x88, 0x46, 0xfb, 0x7f, 0x4e, 0x2e, 0xdd, 0x63, 0xdb, 0x1a, 0x5e, 0x36, 0x8a, 0x8c, 0xa1,
0x48, 0x09, 0x5d, 0x6b, 0x78, 0xc9, 0x06, 0xcd, 0x9e, 0x58, 0x1e, 0xaf, 0x2d, 0xb1, 0xda, 0x12,
0xa3, 0xb0, 0xea, 0x0d, 0xa8, 0x8f, 0x4c, 0xeb, 0x78, 0x64, 0x0f, 0x8e, 0x7d, 0x83, 0x00, 0x33,
0x48, 0x6d, 0x64, 0x5a, 0xcf, 0xec, 0x81, 0x2e, 0xcd, 0x42, 0x39, 0x8d, 0x8b, 0x30, 0x67, 0x59,
0x70, 0x1a, 0x17, 0x2a, 0xe7, 0x26, 0x2c, 0x51, 0x99, 0x7d, 0x87, 0x18, 0x1e, 0x09, 0x98, 0x2b,
0x8c, 0x79, 0x71, 0x64, 0x5a, 0xdb, 0xac, 0x26, 0xc4, 0x6f, 0x5c, 0xc4, 0xf8, 0xab, 0x82, 0xdf,
0xb8, 0x08, 0xf3, 0xe3, 0x4d, 0x28, 0xf9, 0x36, 0x47, 0x45, 0x98, 0x3f, 0xe8, 0x1e, 0x74, 0xea,
0x73, 0x08, 0x20, 0xdf, 0x3e, 0xda, 0xee, 0x1c, 0xec, 0xd4, 0x35, 0x54, 0x86, 0xc2, 0x4e, 0x87,
0x17, 0x32, 0xf8, 0x31, 0x40, 0x60, 0x5d, 0x54, 0x80, 0xec, 0x5e, 0xe7, 0xb3, 0xfa, 0x1c, 0xe5,
0x79, 0xd1, 0xd1, 0x8f, 0x76, 0xbb, 0x07, 0x75, 0x8d, 0x36, 0xde, 0xd6, 0x3b, 0xed, 0x5e, 0xa7,
0x9e, 0xa1, 0x1c, 0xcf, 0xba, 0x3b, 0xf5, 0x2c, 0x2a, 0x41, 0xee, 0x45, 0x7b, 0xff, 0x79, 0xa7,
0x3e, 0x8f, 0x7f, 0xa9, 0x41, 0x55, 0x8c, 0x17, 0x5f, 0x13, 0xe8, 0x7b, 0x90, 0x3f, 0x63, 0xeb,
0x82, 0x4d, 0xc5, 0xf2, 0xd6, 0xed, 0xc8, 0xe0, 0x86, 0xd6, 0x8e, 0x2e, 0x78, 0x11, 0x86, 0xec,
0xf9, 0xd4, 0x6d, 0x64, 0xd6, 0xb3, 0x1b, 0xe5, 0xad, 0xfa, 0x26, 0x5f, 0xb0, 0x9b, 0x7b, 0xe4,
0xf2, 0x85, 0x31, 0x9c, 0x10, 0x9d, 0x56, 0x22, 0x04, 0xf3, 0x23, 0xdb, 0x21, 0x6c, 0xc6, 0x16,
0x75, 0xf6, 0x4d, 0xa7, 0x31, 0x1b, 0x34, 0x31, 0x5b, 0x79, 0x01, 0xff, 0x5a, 0x03, 0x38, 0x9c,
0x78, 0xe9, 0x4b, 0x63, 0x19, 0x72, 0x53, 0x2a, 0x58, 0x2c, 0x0b, 0x5e, 0x60, 0x6b, 0x82, 0x18,
0x2e, 0xf1, 0xd7, 0x04, 0x2d, 0xa0, 0x1b, 0x50, 0x18, 0x3b, 0x64, 0x7a, 0x7c, 0x3e, 0x65, 0x20,
0x45, 0x3d, 0x4f, 0x8b, 0x7b, 0x53, 0xf4, 0x06, 0x54, 0xcc, 0x53, 0xcb, 0x76, 0xc8, 0x31, 0x97,
0x95, 0x63, 0xb5, 0x65, 0x4e, 0x63, 0x7a, 0x2b, 0x2c, 0x5c, 0x70, 0x5e, 0x65, 0xd9, 0xa7, 0x24,
0x6c, 0x41, 0x99, 0xa9, 0x3a, 0x93, 0xf9, 0xde, 0x09, 0x74, 0xcc, 0xb0, 0x66, 0x71, 0x13, 0x0a,
0xad, 0xf1, 0x8f, 0x00, 0xed, 0x90, 0x21, 0xf1, 0xc8, 0x2c, 0xde, 0x43, 0xb1, 0x49, 0x56, 0xb5,
0x09, 0xfe, 0x85, 0x06, 0x4b, 0x21, 0xf1, 0x33, 0x75, 0xab, 0x01, 0x85, 0x01, 0x13, 0xc6, 0x35,
0xc8, 0xea, 0xb2, 0x88, 0x1e, 0x42, 0x51, 0x28, 0xe0, 0x36, 0xb2, 0x29, 0x93, 0xa6, 0xc0, 0x75,
0x72, 0xf1, 0xaf, 0x33, 0x50, 0x12, 0x1d, 0xed, 0x8e, 0x51, 0x1b, 0xaa, 0x0e, 0x2f, 0x1c, 0xb3,
0xfe, 0x08, 0x8d, 0x9a, 0xe9, 0x4e, 0xe8, 0xe9, 0x9c, 0x5e, 0x11, 0x4d, 0x18, 0x19, 0xfd, 0x3e,
0x94, 0xa5, 0x88, 0xf1, 0xc4, 0x13, 0x26, 0x6f, 0x84, 0x05, 0x04, 0xf3, 0xef, 0xe9, 0x9c, 0x0e,
0x82, 0xfd, 0x70, 0xe2, 0xa1, 0x1e, 0x2c, 0xcb, 0xc6, 0xbc, 0x37, 0x42, 0x8d, 0x2c, 0x93, 0xb2,
0x1e, 0x96, 0x12, 0x1f, 0xaa, 0xa7, 0x73, 0x3a, 0x12, 0xed, 0x95, 0x4a, 0x55, 0x25, 0xef, 0x82,
0x3b, 0xef, 0x98, 0x4a, 0xbd, 0x0b, 0x2b, 0xae, 0x52, 0xef, 0xc2, 0x7a, 0x5c, 0x82, 0x82, 0x28,
0xe1, 0x7f, 0xce, 0x00, 0xc8, 0xd1, 0xe8, 0x8e, 0xd1, 0x0e, 0xd4, 0x1c, 0x51, 0x0a, 0x59, 0xeb,
0x56, 0xa2, 0xb5, 0xc4, 0x20, 0xce, 0xe9, 0x55, 0xd9, 0x88, 0x2b, 0xf7, 0x03, 0xa8, 0xf8, 0x52,
0x02, 0x83, 0xdd, 0x4c, 0x30, 0x98, 0x2f, 0xa1, 0x2c, 0x1b, 0x50, 0x93, 0x7d, 0x02, 0x2b, 0x7e,
0xfb, 0x04, 0x9b, 0xbd, 0x71, 0x85, 0xcd, 0x7c, 0x81, 0x4b, 0x52, 0x82, 0x6a, 0x35, 0x55, 0xb1,
0xc0, 0x6c, 0x37, 0x13, 0xcc, 0x16, 0x57, 0x8c, 0x1a, 0x0e, 0x68, 0xbc, 0xe4, 0x45, 0xfc, 0x3f,
0x59, 0x28, 0x6c, 0xdb, 0xa3, 0xb1, 0xe1, 0xd0, 0xd1, 0xc8, 0x3b, 0xc4, 0x9d, 0x0c, 0x3d, 0x66,
0xae, 0xda, 0xd6, 0xbd, 0xb0, 0x44, 0xc1, 0x26, 0xff, 0xeb, 0x8c, 0x55, 0x17, 0x4d, 0x68, 0x63,
0x11, 0x1e, 0x33, 0xaf, 0xd1, 0x58, 0x04, 0x47, 0xd1, 0x44, 0x2e, 0xe4, 0x6c, 0xb0, 0x90, 0x9b,
0x50, 0x98, 0x12, 0x27, 0x08, 0xe9, 0x4f, 0xe7, 0x74, 0x49, 0x40, 0xef, 0xc0, 0x42, 0x34, 0xbc,
0xe4, 0x04, 0x4f, 0xad, 0x1f, 0x8e, 0x46, 0xf7, 0xa0, 0x12, 0x8a, 0x71, 0x79, 0xc1, 0x57, 0x1e,
0x29, 0x21, 0x6e, 0x55, 0xfa, 0x55, 0x1a, 0x8f, 0x2b, 0x4f, 0xe7, 0xa4, 0x67, 0x5d, 0x95, 0x9e,
0xb5, 0x28, 0x5a, 0x09, 0xdf, 0x1a, 0x72, 0x32, 0x3f, 0x0c, 0x3b, 0x19, 0xfc, 0x43, 0xa8, 0x86,
0x0c, 0x44, 0xe3, 0x4e, 0xe7, 0xe3, 0xe7, 0xed, 0x7d, 0x1e, 0xa4, 0x9e, 0xb0, 0xb8, 0xa4, 0xd7,
0x35, 0x1a, 0xeb, 0xf6, 0x3b, 0x47, 0x47, 0xf5, 0x0c, 0xaa, 0x42, 0xe9, 0xa0, 0xdb, 0x3b, 0xe6,
0x5c, 0x59, 0xfc, 0xc4, 0x97, 0x20, 0x82, 0x9c, 0x12, 0xdb, 0xe6, 0x94, 0xd8, 0xa6, 0xc9, 0xd8,
0x96, 0x09, 0x62, 0x1b, 0x0b, 0x73, 0xfb, 0x9d, 0xf6, 0x51, 0xa7, 0x3e, 0xff, 0xb8, 0x06, 0x15,
0x6e, 0xdf, 0xe3, 0x89, 0x45, 0x43, 0xed, 0x3f, 0x6a, 0x00, 0xc1, 0x6a, 0x42, 0x2d, 0x28, 0xf4,
0x39, 0x4e, 0x43, 0x63, 0xce, 0x68, 0x25, 0x71, 0xc8, 0x74, 0xc9, 0x85, 0xbe, 0x03, 0x05, 0x77,
0xd2, 0xef, 0x13, 0x57, 0x86, 0xbc, 0x1b, 0x51, 0x7f, 0x28, 0xbc, 0x95, 0x2e, 0xf9, 0x68, 0x93,
0x97, 0x86, 0x39, 0x9c, 0xb0, 0x00, 0x78, 0x75, 0x13, 0xc1, 0x87, 0xff, 0x5e, 0x83, 0xb2, 0x32,
0x79, 0xbf, 0xa2, 0x13, 0xbe, 0x0d, 0x25, 0xa6, 0x03, 0x19, 0x08, 0x37, 0x5c, 0xd4, 0x03, 0x02,
0xfa, 0x3d, 0x28, 0xc9, 0x15, 0x20, 0x3d, 0x71, 0x23, 0x59, 0x6c, 0x77, 0xac, 0x07, 0xac, 0x78,
0x0f, 0x16, 0x99, 0x55, 0xfa, 0x74, 0x73, 0x2d, 0xed, 0xa8, 0x6e, 0x3f, 0xb5, 0xc8, 0xf6, 0xb3,
0x09, 0xc5, 0xf1, 0xd9, 0xa5, 0x6b, 0xf6, 0x8d, 0xa1, 0xd0, 0xc2, 0x2f, 0xe3, 0x8f, 0x00, 0xa9,
0xc2, 0x66, 0xe9, 0x2e, 0xae, 0x42, 0xf9, 0xa9, 0xe1, 0x9e, 0x09, 0x95, 0xf0, 0x43, 0xa8, 0xd2,
0xe2, 0xde, 0x8b, 0xd7, 0xd0, 0x91, 0x1d, 0x0e, 0x24, 0xf7, 0x4c, 0x36, 0x47, 0x30, 0x7f, 0x66,
0xb8, 0x67, 0xac, 0xa3, 0x55, 0x9d, 0x7d, 0xa3, 0x77, 0xa0, 0xde, 0xe7, 0x9d, 0x3c, 0x8e, 0x1c,
0x19, 0x16, 0x04, 0xdd, 0xdf, 0x09, 0x7e, 0x0a, 0x15, 0xde, 0x87, 0xaf, 0x5b, 0x09, 0xbc, 0x08,
0x0b, 0x47, 0x96, 0x31, 0x76, 0xcf, 0x6c, 0x19, 0xdd, 0x68, 0xa7, 0xeb, 0x01, 0x6d, 0x26, 0xc4,
0xb7, 0x61, 0xc1, 0x21, 0x23, 0xc3, 0xb4, 0x4c, 0xeb, 0xf4, 0xf8, 0xe4, 0xd2, 0x23, 0xae, 0x38,
0x30, 0xd5, 0x7c, 0xf2, 0x63, 0x4a, 0xa5, 0xaa, 0x9d, 0x0c, 0xed, 0x13, 0xe1, 0xe6, 0xd8, 0x37,
0xfe, 0x79, 0x06, 0x2a, 0x9f, 0x18, 0x5e, 0x5f, 0x0e, 0x1d, 0xda, 0x85, 0x9a, 0xef, 0xdc, 0x18,
0x45, 0xe8, 0x12, 0x09, 0xb1, 0xac, 0x8d, 0xdc, 0x4a, 0xcb, 0xe8, 0x58, 0xed, 0xab, 0x04, 0x26,
0xca, 0xb0, 0xfa, 0x64, 0xe8, 0x8b, 0xca, 0xa4, 0x8b, 0x62, 0x8c, 0xaa, 0x28, 0x95, 0x80, 0xba,
0x50, 0x1f, 0x3b, 0xf6, 0xa9, 0x43, 0x5c, 0xd7, 0x17, 0xc6, 0xc3, 0x18, 0x4e, 0x10, 0x76, 0x28,
0x58, 0x03, 0x71, 0x0b, 0xe3, 0x30, 0xe9, 0xf1, 0x42, 0xb0, 0x9f, 0xe1, 0xce, 0xe9, 0x3f, 0x32,
0x80, 0xe2, 0x9d, 0xfa, 0x5d, 0xb7, 0x78, 0xf7, 0xa1, 0xe6, 0x7a, 0x86, 0x13, 0x9b, 0x6c, 0x55,
0x46, 0xf5, 0x3d, 0xfe, 0xdb, 0xe0, 0x2b, 0x74, 0x6c, 0xd9, 0x9e, 0xf9, 0xf2, 0x52, 0xec, 0x92,
0x6b, 0x92, 0x7c, 0xc0, 0xa8, 0xa8, 0x03, 0x85, 0x97, 0xe6, 0xd0, 0x23, 0x8e, 0xdb, 0xc8, 0xad,
0x67, 0x37, 0x6a, 0x5b, 0x0f, 0xaf, 0x1b, 0x86, 0xcd, 0x0f, 0x19, 0x7f, 0xef, 0x72, 0x4c, 0x74,
0xd9, 0x56, 0xdd, 0x79, 0xe6, 0x43, 0xbb, 0xf1, 0x9b, 0x50, 0x7c, 0x45, 0x45, 0xd0, 0x53, 0x76,
0x81, 0x6f, 0x16, 0x59, 0x99, 0x1f, 0xb2, 0x5f, 0x3a, 0xc6, 0xe9, 0x88, 0x58, 0x9e, 0x3c, 0x07,
0xca, 0x32, 0xbe, 0x0f, 0x10, 0xc0, 0x50, 0x97, 0x7f, 0xd0, 0x3d, 0x7c, 0xde, 0xab, 0xcf, 0xa1,
0x0a, 0x14, 0x0f, 0xba, 0x3b, 0x9d, 0xfd, 0x0e, 0x8d, 0x0f, 0xb8, 0x25, 0x4d, 0x1a, 0x1a, 0x4b,
0x15, 0x53, 0x0b, 0x61, 0xe2, 0x55, 0x58, 0x4e, 0x1a, 0x40, 0xba, 0x17, 0xad, 0x8a, 0x59, 0x3a,
0xd3, 0x52, 0x51, 0xa1, 0x33, 0xe1, 0xee, 0x36, 0xa0, 0xc0, 0x67, 0xef, 0x40, 0x6c, 0xce, 0x65,
0x91, 0x1a, 0x82, 0x4f, 0x46, 0x32, 0x10, 0xa3, 0xe4, 0x97, 0x13, 0xdd, 0x4b, 0x2e, 0xd1, 0xbd,
0xa0, 0x7b, 0x50, 0xf5, 0x57, 0x83, 0xe1, 0x8a, 0xbd, 0x40, 0x49, 0xaf, 0xc8, 0x89, 0x4e, 0x69,
0x21, 0xa3, 0x17, 0xc2, 0x46, 0x47, 0xf7, 0x21, 0x4f, 0xa6, 0xc4, 0xf2, 0xdc, 0x46, 0x99, 0x45,
0x8c, 0xaa, 0xdc, 0xbb, 0x77, 0x28, 0x55, 0x17, 0x95, 0xf8, 0xfb, 0xb0, 0xc8, 0xce, 0x48, 0x4f,
0x1c, 0xc3, 0x52, 0x0f, 0x73, 0xbd, 0xde, 0xbe, 0x30, 0x37, 0xfd, 0x44, 0x35, 0xc8, 0xec, 0xee,
0x08, 0x23, 0x64, 0x76, 0x77, 0xf0, 0x4f, 0x35, 0x40, 0x6a, 0xbb, 0x99, 0xec, 0x1c, 0x11, 0x2e,
0xe1, 0xb3, 0x01, 0xfc, 0x32, 0xe4, 0x88, 0xe3, 0xd8, 0x0e, 0xb3, 0x68, 0x49, 0xe7, 0x05, 0xfc,
0xa6, 0xd0, 0x41, 0x27, 0x53, 0xfb, 0xdc, 0x5f, 0x83, 0x5c, 0x9a, 0xe6, 0xab, 0xba, 0x07, 0x4b,
0x21, 0xae, 0x99, 0x22, 0xd7, 0x87, 0xb0, 0xc0, 0x84, 0x6d, 0x9f, 0x91, 0xfe, 0xf9, 0xd8, 0x36,
0xad, 0x18, 0x1e, 0x1d, 0xb9, 0xc0, 0xc1, 0xd2, 0x7e, 0xf0, 0x8e, 0x55, 0x7c, 0x62, 0xaf, 0xb7,
0x8f, 0x3f, 0x83, 0xd5, 0x88, 0x1c, 0xa9, 0xfe, 0x1f, 0x41, 0xb9, 0xef, 0x13, 0x5d, 0xb1, 0xd7,
0xb9, 0x13, 0x56, 0x2e, 0xda, 0x54, 0x6d, 0x81, 0xbb, 0x70, 0x23, 0x26, 0x7a, 0xa6, 0x3e, 0xbf,
0x0d, 0x2b, 0x4c, 0xe0, 0x1e, 0x21, 0xe3, 0xf6, 0xd0, 0x9c, 0xa6, 0x5a, 0x7a, 0x2c, 0x3a, 0xa5,
0x30, 0x7e, 0xb3, 0xf3, 0x02, 0xff, 0x81, 0x40, 0xec, 0x99, 0x23, 0xd2, 0xb3, 0xf7, 0xd3, 0x75,
0xa3, 0xd1, 0xec, 0x9c, 0x5c, 0xba, 0x62, 0x5b, 0xc3, 0xbe, 0xf1, 0x3f, 0x69, 0xc2, 0x54, 0x6a,
0xf3, 0x6f, 0x78, 0x26, 0xaf, 0x01, 0x9c, 0xd2, 0x25, 0x43, 0x06, 0xb4, 0x82, 0x67, 0x54, 0x14,
0x8a, 0xaf, 0x27, 0xf5, 0xdf, 0x15, 0xa1, 0xe7, 0xb2, 0x98, 0xe7, 0xec, 0x8f, 0xef, 0xe5, 0xee,
0x40, 0x99, 0x11, 0x8e, 0x3c, 0xc3, 0x9b, 0xb8, 0xb1, 0xc1, 0xf8, 0x0b, 0x31, 0xed, 0x65, 0xa3,
0x99, 0xfa, 0xf5, 0x1d, 0xc8, 0xb3, 0xc3, 0x84, 0xdc, 0x4a, 0xdf, 0x4c, 0x98, 0x8f, 0x5c, 0x0f,
0x5d, 0x30, 0xe2, 0x9f, 0x6b, 0x90, 0x7f, 0xc6, 0x52, 0xb0, 0x8a, 0x6a, 0xf3, 0x72, 0x2c, 0x2c,
0x63, 0xc4, 0x13, 0x43, 0x25, 0x9d, 0x7d, 0xb3, 0xad, 0x27, 0x21, 0xce, 0x73, 0x7d, 0x9f, 0x6f,
0x71, 0x4b, 0xba, 0x5f, 0xa6, 0x36, 0xeb, 0x0f, 0x4d, 0x62, 0x79, 0xac, 0x76, 0x9e, 0xd5, 0x2a,
0x14, 0xba, 0x7b, 0x36, 0xdd, 0x7d, 0x62, 0x38, 0x96, 0x48, 0x9a, 0x16, 0xf5, 0x80, 0x80, 0xf7,
0xa1, 0xce, 0xf5, 0x68, 0x0f, 0x06, 0xca, 0x06, 0xd3, 0x47, 0xd3, 0x22, 0x68, 0x21, 0x69, 0x99,
0xa8, 0xb4, 0x5f, 0x69, 0xb0, 0xa8, 0x88, 0x9b, 0xc9, 0xaa, 0xef, 0x42, 0x9e, 0x27, 0xa9, 0xc5,
0x4e, 0x67, 0x39, 0xdc, 0x8a, 0xc3, 0xe8, 0x82, 0x07, 0x6d, 0x42, 0x81, 0x7f, 0xc9, 0x33, 0x40,
0x32, 0xbb, 0x64, 0xc2, 0xf7, 0x61, 0x49, 0x90, 0xc8, 0xc8, 0x4e, 0x5a, 0x18, 0x6c, 0x30, 0xf0,
0x9f, 0xc1, 0x72, 0x98, 0x6d, 0xa6, 0x2e, 0x29, 0x4a, 0x66, 0x5e, 0x47, 0xc9, 0xb6, 0x54, 0xf2,
0xf9, 0x78, 0xa0, 0xec, 0xa3, 0xa2, 0x33, 0x46, 0x1d, 0xaf, 0x4c, 0x78, 0xbc, 0x82, 0x0e, 0x48,
0x11, 0xdf, 0x6a, 0x07, 0x3e, 0x90, 0xd3, 0x61, 0xdf, 0x74, 0x7d, 0x1f, 0x8e, 0xa1, 0x32, 0x34,
0x2d, 0x62, 0x38, 0x22, 0x73, 0xae, 0xf1, 0xcc, 0xb9, 0x4a, 0xc3, 0x5f, 0x00, 0x52, 0x1b, 0x7e,
0xab, 0x4a, 0xbf, 0x25, 0x4d, 0x76, 0xe8, 0xd8, 0x23, 0x3b, 0xd5, 0xec, 0xf8, 0xcf, 0x61, 0x25,
0xc2, 0xf7, 0xad, 0xaa, 0xb9, 0x04, 0x8b, 0x3b, 0x44, 0x6e, 0x68, 0xa4, 0xdb, 0xfb, 0x08, 0x90,
0x4a, 0x9c, 0x29, 0xb2, 0xb5, 0x60, 0xf1, 0x99, 0x3d, 0xa5, 0x2e, 0x92, 0x52, 0x03, 0xdf, 0xc0,
0xf3, 0x10, 0xbe, 0x29, 0xfc, 0x32, 0x05, 0x57, 0x1b, 0xcc, 0x04, 0xfe, 0x6f, 0x1a, 0x54, 0xda,
0x43, 0xc3, 0x19, 0x49, 0xe0, 0x1f, 0x40, 0x9e, 0x9f, 0xae, 0x45, 0x42, 0xeb, 0xad, 0xb0, 0x18,
0x95, 0x97, 0x17, 0xda, 0xfc, 0x2c, 0x2e, 0x5a, 0x51, 0xc5, 0xc5, 0x9d, 0xd7, 0x4e, 0xe4, 0x0e,
0x6c, 0x07, 0xbd, 0x07, 0x39, 0x83, 0x36, 0x61, 0xa1, 0xa8, 0x16, 0xcd, 0x6b, 0x30, 0x69, 0xec,
0x0c, 0xc0, 0xb9, 0xf0, 0xf7, 0xa0, 0xac, 0x20, 0xa0, 0x02, 0x64, 0x9f, 0x74, 0xc4, 0x86, 0xbd,
0xbd, 0xdd, 0xdb, 0x7d, 0xc1, 0x13, 0x3a, 0x35, 0x80, 0x9d, 0x8e, 0x5f, 0xce, 0xe0, 0x4f, 0x45,
0x2b, 0xe1, 0xf6, 0x55, 0x7d, 0xb4, 0x34, 0x7d, 0x32, 0xaf, 0xa5, 0xcf, 0x05, 0x54, 0x45, 0xf7,
0x67, 0x0d, 0x63, 0x4c, 0x5e, 0x4a, 0x18, 0x53, 0x94, 0xd7, 0x05, 0x23, 0xfe, 0x8d, 0x06, 0xf5,
0x1d, 0xfb, 0x95, 0x75, 0xea, 0x18, 0x03, 0x7f, 0x9d, 0x7c, 0x18, 0x19, 0xa9, 0xcd, 0x48, 0x72,
0x34, 0xc2, 0x1f, 0x10, 0x22, 0x23, 0xd6, 0x08, 0xd2, 0x86, 0x3c, 0x16, 0xca, 0x22, 0xfe, 0x00,
0x16, 0x22, 0x8d, 0xa8, 0xed, 0x5f, 0xb4, 0xf7, 0x77, 0x77, 0xa8, 0xad, 0x59, 0x62, 0xad, 0x73,
0xd0, 0x7e, 0xbc, 0xdf, 0x11, 0x17, 0x48, 0xed, 0x83, 0xed, 0xce, 0x7e, 0x3d, 0x83, 0xfb, 0xb0,
0xa8, 0xc0, 0xcf, 0x7a, 0x33, 0x90, 0xa2, 0xdd, 0x02, 0x54, 0x45, 0xb4, 0x17, 0x8b, 0xf2, 0x5f,
0x33, 0x50, 0x93, 0x94, 0x6f, 0x06, 0x13, 0xad, 0x42, 0x7e, 0x70, 0x72, 0x64, 0x7e, 0x21, 0x6f,
0x8e, 0x44, 0x89, 0xd2, 0x87, 0x1c, 0x87, 0x5f, 0xdf, 0x8a, 0x12, 0x0d, 0xe3, 0x8e, 0xf1, 0xd2,
0xdb, 0xb5, 0x06, 0xe4, 0x82, 0x6d, 0x0a, 0xe6, 0xf5, 0x80, 0xc0, 0x32, 0x4c, 0xe2, 0x9a, 0x97,
0x9d, 0xac, 0x94, 0x6b, 0x5f, 0xf4, 0x00, 0xea, 0xf4, 0xbb, 0x3d, 0x1e, 0x0f, 0x4d, 0x32, 0xe0,
0x02, 0x0a, 0x8c, 0x27, 0x46, 0xa7, 0xe8, 0xec, 0x2c, 0xe2, 0x36, 0x8a, 0x2c, 0x2c, 0x89, 0x12,
0x5a, 0x87, 0x32, 0xd7, 0x6f, 0xd7, 0x7a, 0xee, 0x12, 0x76, 0xf7, 0x99, 0xd5, 0x55, 0x52, 0x78,
0x9b, 0x01, 0xd1, 0x6d, 0xc6, 0x12, 0x2c, 0xb6, 0x27, 0xde, 0x59, 0xc7, 0xa2, 0xb1, 0x42, 0x5a,
0x79, 0x19, 0x10, 0x25, 0xee, 0x98, 0xae, 0x4a, 0x15, 0xac, 0xe1, 0x01, 0xe9, 0xc0, 0x12, 0x25,
0x12, 0xcb, 0x33, 0xfb, 0x4a, 0x5c, 0x95, 0x3b, 0x2f, 0x2d, 0xb2, 0xf3, 0x32, 0x5c, 0xf7, 0x95,
0xed, 0x0c, 0x84, 0xcd, 0xfd, 0x32, 0x9e, 0x72, 0xc4, 0xe7, 0x6e, 0x68, 0xf7, 0xf4, 0x3b, 0x4a,
0x41, 0xef, 0x43, 0xc1, 0x1e, 0xb3, 0x0b, 0x7e, 0x91, 0x85, 0x59, 0xdd, 0xe4, 0x4f, 0x02, 0x36,
0x85, 0xe0, 0x2e, 0xaf, 0xd5, 0x25, 0x1b, 0xde, 0x08, 0x70, 0x9f, 0x10, 0xef, 0x0a, 0x5c, 0xfc,
0x10, 0x56, 0x24, 0xa7, 0xb8, 0x74, 0xb8, 0x82, 0xb9, 0x0b, 0x77, 0x24, 0xf3, 0xf6, 0x99, 0x61,
0x9d, 0x92, 0x43, 0xa1, 0xe2, 0x57, 0xb5, 0xcf, 0x63, 0x68, 0xf8, 0x7a, 0xb2, 0x83, 0xb0, 0x3d,
0x54, 0x15, 0x98, 0xb8, 0x62, 0xfa, 0x97, 0x74, 0xf6, 0x4d, 0x69, 0x8e, 0x3d, 0xf4, 0x77, 0xbe,
0xf4, 0x1b, 0x6f, 0xc3, 0x4d, 0x29, 0x43, 0x1c, 0x51, 0xc3, 0x42, 0x62, 0x0a, 0x25, 0x09, 0x11,
0x06, 0xa3, 0x4d, 0xaf, 0x1e, 0x28, 0x95, 0x33, 0x6c, 0x5a, 0x26, 0x53, 0x53, 0x64, 0xae, 0xf0,
0x39, 0x44, 0x15, 0x53, 0x36, 0x37, 0x92, 0x4c, 0x05, 0xa8, 0x64, 0x31, 0x10, 0x94, 0x1c, 0x1b,
0x88, 0x98, 0xe8, 0x1f, 0xc1, 0x9a, 0xaf, 0x04, 0xb5, 0xdb, 0x21, 0x71, 0x46, 0xa6, 0xeb, 0x2a,
0x69, 0xea, 0xa4, 0x8e, 0xbf, 0x05, 0xf3, 0x63, 0x22, 0x62, 0x46, 0x79, 0x0b, 0xc9, 0x49, 0xa4,
0x34, 0x66, 0xf5, 0x78, 0x00, 0x77, 0xa5, 0x74, 0x6e, 0xd1, 0x44, 0xf1, 0x51, 0xa5, 0x64, 0xf2,
0x2e, 0x93, 0x92, 0xbc, 0xcb, 0x46, 0xae, 0x4e, 0x3e, 0xe2, 0x86, 0x94, 0x4b, 0x74, 0xa6, 0xbd,
0xc0, 0x1e, 0xb7, 0xa9, 0xbf, 0xb2, 0x67, 0x12, 0xf6, 0xd7, 0x1a, 0xd7, 0xec, 0xeb, 0x72, 0xc8,
0x84, 0xf5, 0x50, 0xde, 0x4b, 0xc8, 0x22, 0xdd, 0xe4, 0xd2, 0x01, 0xd0, 0xd5, 0xd4, 0xe5, 0xbc,
0x1e, 0xa2, 0xe1, 0x13, 0x58, 0x0e, 0xbb, 0xa1, 0x99, 0x74, 0x59, 0x86, 0x9c, 0x67, 0x9f, 0x13,
0x19, 0x1a, 0x78, 0x41, 0xda, 0xce, 0xf7, 0x51, 0x33, 0xd9, 0xce, 0x08, 0x84, 0xb1, 0xd5, 0x31,
0xab, 0xbe, 0x74, 0x62, 0xc9, 0x23, 0x0b, 0x2f, 0xe0, 0x03, 0x58, 0x8d, 0x7a, 0xac, 0x99, 0x54,
0x7e, 0xc1, 0xd7, 0x52, 0x92, 0x53, 0x9b, 0x49, 0xee, 0xc7, 0x81, 0x5f, 0x52, 0x7c, 0xdb, 0x4c,
0x22, 0x75, 0x68, 0x26, 0xb9, 0xba, 0xaf, 0x63, 0xe9, 0xf8, 0x9e, 0x6f, 0x26, 0x61, 0x6e, 0x20,
0x6c, 0xf6, 0xe1, 0x0f, 0xdc, 0x55, 0xf6, 0x4a, 0x77, 0x25, 0x16, 0x49, 0xe0, 0x50, 0xbf, 0x81,
0x49, 0x27, 0x30, 0x02, 0x5f, 0x3e, 0x2b, 0x06, 0x0d, 0x67, 0x3e, 0x06, 0x2b, 0xc8, 0x89, 0xad,
0x46, 0x80, 0x99, 0x06, 0xe3, 0x93, 0xc0, 0x8d, 0xc7, 0x82, 0xc4, 0x4c, 0x82, 0x3f, 0x85, 0xf5,
0xf4, 0xf8, 0x30, 0x8b, 0xe4, 0x07, 0x2d, 0x28, 0xf9, 0x67, 0x17, 0xe5, 0x79, 0x58, 0x19, 0x0a,
0x07, 0xdd, 0xa3, 0xc3, 0xf6, 0x76, 0x87, 0xbf, 0x0f, 0xdb, 0xee, 0xea, 0xfa, 0xf3, 0xc3, 0x5e,
0x3d, 0xb3, 0xf5, 0xdb, 0x2c, 0x64, 0xf6, 0x5e, 0xa0, 0xcf, 0x20, 0xc7, 0x1f, 0x4b, 0x5c, 0xf1,
0x42, 0xa6, 0x79, 0xd5, 0x7b, 0x10, 0x7c, 0xe3, 0xa7, 0xff, 0xf9, 0xdb, 0x5f, 0x66, 0x16, 0x71,
0xa5, 0x35, 0xfd, 0x6e, 0xeb, 0x7c, 0xda, 0x62, 0x61, 0xea, 0x91, 0xf6, 0x00, 0x7d, 0x0c, 0xd9,
0xc3, 0x89, 0x87, 0x52, 0x5f, 0xce, 0x34, 0xd3, 0x9f, 0x88, 0xe0, 0x15, 0x26, 0x74, 0x01, 0x83,
0x10, 0x3a, 0x9e, 0x78, 0x54, 0xe4, 0x8f, 0xa1, 0xac, 0x3e, 0xf0, 0xb8, 0xf6, 0x39, 0x4d, 0xf3,
0xfa, 0xc7, 0x23, 0xf8, 0x0e, 0x83, 0xba, 0x81, 0x91, 0x80, 0xe2, 0x4f, 0x50, 0xd4, 0x5e, 0xf4,
0x2e, 0x2c, 0x94, 0xfa, 0xd8, 0xa6, 0x99, 0xfe, 0x9e, 0x24, 0xd6, 0x0b, 0xef, 0xc2, 0xa2, 0x22,
0xff, 0x44, 0x3c, 0x25, 0xe9, 0x7b, 0xe8, 0x6e, 0xc2, 0x53, 0x02, 0xf5, 0xd2, 0xbc, 0xb9, 0x9e,
0xce, 0x20, 0x40, 0x6e, 0x33, 0x90, 0x55, 0xbc, 0x28, 0x40, 0xfa, 0x3e, 0xcb, 0x23, 0xed, 0xc1,
0x56, 0x1f, 0x72, 0xec, 0x42, 0x0a, 0x7d, 0x2e, 0x3f, 0x9a, 0x09, 0x37, 0x73, 0x29, 0x03, 0x1d,
0xba, 0xca, 0xc2, 0xcb, 0x0c, 0xa8, 0x86, 0x4b, 0x14, 0x88, 0x5d, 0x47, 0x3d, 0xd2, 0x1e, 0x6c,
0x68, 0xef, 0x6b, 0x5b, 0xbf, 0xc9, 0x41, 0x8e, 0x65, 0x62, 0xd1, 0x39, 0x40, 0x70, 0x39, 0x13,
0xed, 0x5d, 0xec, 0xba, 0x27, 0xda, 0xbb, 0xf8, 0xbd, 0x0e, 0x6e, 0x32, 0xd0, 0x65, 0xbc, 0x40,
0x41, 0x59, 0x82, 0xb7, 0xc5, 0x72, 0xd6, 0xd4, 0x8e, 0x7f, 0xa3, 0x89, 0x44, 0x34, 0x5f, 0x4b,
0x28, 0x49, 0x5a, 0xe8, 0x86, 0x26, 0x3a, 0x1d, 0x12, 0x6e, 0x67, 0xf0, 0xf7, 0x19, 0x60, 0x0b,
0xd7, 0x03, 0x40, 0x87, 0x71, 0x3c, 0xd2, 0x1e, 0x7c, 0xde, 0xc0, 0x4b, 0xc2, 0xca, 0x91, 0x1a,
0xf4, 0x13, 0xa8, 0x85, 0x6f, 0x20, 0xd0, 0xbd, 0x04, 0xac, 0xe8, 0x45, 0x46, 0xf3, 0xcd, 0xab,
0x99, 0x84, 0x4e, 0x6b, 0x4c, 0x27, 0x01, 0xce, 0x91, 0xcf, 0x09, 0x19, 0x1b, 0x94, 0x49, 0x8c,
0x01, 0xfa, 0x07, 0x4d, 0x5c, 0x10, 0x05, 0x57, 0x0a, 0x28, 0x49, 0x7a, 0xec, 0xc2, 0xa2, 0x79,
0xff, 0x1a, 0x2e, 0xa1, 0xc4, 0x1f, 0x32, 0x25, 0x3e, 0xc0, 0xcb, 0x81, 0x12, 0x9e, 0x39, 0x22,
0x9e, 0x2d, 0xb4, 0xf8, 0xfc, 0x36, 0xbe, 0x11, 0x32, 0x4e, 0xa8, 0x36, 0x18, 0x2c, 0x7e, 0x2d,
0x90, 0x38, 0x58, 0xa1, 0x6b, 0x86, 0xc4, 0xc1, 0x0a, 0xdf, 0x29, 0x24, 0x0d, 0x16, 0xbf, 0x04,
0x48, 0x1a, 0x2c, 0xbf, 0x66, 0xeb, 0x7f, 0xe7, 0xa1, 0xb0, 0xcd, 0x9f, 0x70, 0x23, 0x1b, 0x4a,
0x7e, 0x56, 0x1d, 0xad, 0x25, 0xa5, 0x05, 0x83, 0x63, 0x4d, 0xf3, 0x6e, 0x6a, 0xbd, 0x50, 0xe8,
0x0d, 0xa6, 0xd0, 0x2d, 0xbc, 0x4a, 0x91, 0xc5, 0x2b, 0xf1, 0x16, 0xcf, 0x3d, 0xb5, 0x8c, 0xc1,
0x80, 0x1a, 0xe2, 0x4f, 0xa1, 0xa2, 0xa6, 0xbd, 0xd1, 0x1b, 0x89, 0xa9, 0x48, 0x35, 0x73, 0xde,
0xc4, 0x57, 0xb1, 0x08, 0xe4, 0x37, 0x19, 0xf2, 0x1a, 0xbe, 0x99, 0x80, 0xec, 0x30, 0xd6, 0x10,
0x38, 0x4f, 0x59, 0x27, 0x83, 0x87, 0x32, 0xe2, 0xc9, 0xe0, 0xe1, 0x8c, 0xf7, 0x95, 0xe0, 0x13,
0xc6, 0x4a, 0xc1, 0x5d, 0x80, 0x20, 0xf1, 0x8c, 0x12, 0x6d, 0xa9, 0x9c, 0xeb, 0xa2, 0xce, 0x21,
0x9e, 0xb3, 0xc6, 0x98, 0xc1, 0x8a, 0x79, 0x17, 0x81, 0x1d, 0x9a, 0xae, 0xc7, 0x17, 0x66, 0x35,
0x94, 0x49, 0x46, 0x89, 0xfd, 0x09, 0xa7, 0xa3, 0x9b, 0xf7, 0xae, 0xe4, 0x11, 0xe8, 0xf7, 0x19,
0xfa, 0x5d, 0xdc, 0x4c, 0x40, 0x1f, 0x73, 0x5e, 0x3a, 0xd9, 0xfe, 0x2f, 0x0f, 0xe5, 0x67, 0x86,
0x69, 0x79, 0xc4, 0x32, 0xac, 0x3e, 0x41, 0x27, 0x90, 0x63, 0x91, 0x3a, 0xea, 0x88, 0xd5, 0x2c,
0x6b, 0xd4, 0x11, 0x87, 0x52, 0x90, 0x78, 0x9d, 0x01, 0x37, 0xf1, 0x0a, 0x05, 0x1e, 0x05, 0xa2,
0x5b, 0x2c, 0x73, 0x48, 0x3b, 0xfd, 0x12, 0xf2, 0xe2, 0x72, 0x2e, 0x22, 0x28, 0x94, 0xab, 0x69,
0xde, 0x4e, 0xae, 0x4c, 0x9a, 0xcb, 0x2a, 0x8c, 0xcb, 0xf8, 0x28, 0xce, 0x14, 0x20, 0x48, 0x89,
0x47, 0x47, 0x34, 0x96, 0x41, 0x6f, 0xae, 0xa7, 0x33, 0x24, 0xd9, 0x54, 0xc5, 0x1c, 0xf8, 0xbc,
0x14, 0xf7, 0x8f, 0x61, 0xfe, 0xa9, 0xe1, 0x9e, 0xa1, 0x48, 0xec, 0x55, 0x9e, 0x76, 0x35, 0x9b,
0x49, 0x55, 0x02, 0xe5, 0x2e, 0x43, 0xb9, 0xc9, 0x5d, 0x99, 0x8a, 0x72, 0x66, 0xb8, 0x34, 0xa8,
0xa1, 0x01, 0xe4, 0xf9, 0x4b, 0xaf, 0xa8, 0xfd, 0x42, 0xaf, 0xc5, 0xa2, 0xf6, 0x0b, 0x3f, 0x0e,
0xbb, 0x1e, 0x65, 0x0c, 0x45, 0xf9, 0xb4, 0x0a, 0x45, 0xee, 0xd9, 0x23, 0xcf, 0xb0, 0x9a, 0x6b,
0x69, 0xd5, 0x02, 0xeb, 0x1e, 0xc3, 0xba, 0x83, 0x1b, 0xb1, 0xb1, 0x12, 0x9c, 0x8f, 0xb4, 0x07,
0xef, 0x6b, 0xe8, 0x27, 0x00, 0xc1, 0x2d, 0x42, 0x6c, 0x05, 0x46, 0x2f, 0x24, 0x62, 0x2b, 0x30,
0x76, 0x01, 0x81, 0x37, 0x19, 0xee, 0x06, 0xbe, 0x17, 0xc5, 0xf5, 0x1c, 0xc3, 0x72, 0x5f, 0x12,
0xe7, 0x3d, 0x9e, 0x14, 0x75, 0xcf, 0xcc, 0x31, 0xed, 0xb2, 0x03, 0x25, 0x3f, 0x49, 0x1c, 0xf5,
0xb6, 0xd1, 0xe4, 0x75, 0xd4, 0xdb, 0xc6, 0xb2, 0xcb, 0x61, 0xb7, 0x13, 0x9a, 0x2d, 0x92, 0x95,
0x2e, 0xc0, 0x5f, 0xd5, 0x61, 0x9e, 0xee, 0xba, 0xe9, 0xe6, 0x24, 0xc8, 0x9b, 0x44, 0x7b, 0x1f,
0x4b, 0x7a, 0x46, 0x7b, 0x1f, 0x4f, 0xb9, 0x84, 0x37, 0x27, 0xec, 0x07, 0x47, 0x3c, 0x45, 0x41,
0x7b, 0x6a, 0x43, 0x59, 0x49, 0xac, 0xa0, 0x04, 0x61, 0xe1, 0x6c, 0x6a, 0x34, 0xdc, 0x25, 0x64,
0x65, 0xf0, 0x2d, 0x86, 0xb7, 0xc2, 0xc3, 0x1d, 0xc3, 0x1b, 0x70, 0x0e, 0x0a, 0x28, 0x7a, 0x27,
0xd6, 0x7d, 0x42, 0xef, 0xc2, 0x6b, 0x7f, 0x3d, 0x9d, 0x21, 0xb5, 0x77, 0xc1, 0xc2, 0x7f, 0x05,
0x15, 0x35, 0xbd, 0x82, 0x12, 0x94, 0x8f, 0x64, 0x80, 0xa3, 0x71, 0x24, 0x29, 0x3b, 0x13, 0xf6,
0x6c, 0xfe, 0x2f, 0xb8, 0x24, 0x1b, 0x05, 0x1e, 0x42, 0x41, 0xe4, 0x5b, 0x92, 0x4c, 0x1a, 0x4e,
0x17, 0x27, 0x99, 0x34, 0x92, 0xac, 0x09, 0xef, 0x9e, 0x19, 0x22, 0x3d, 0x52, 0xca, 0x58, 0x2d,
0xd0, 0x9e, 0x10, 0x2f, 0x0d, 0x2d, 0xc8, 0x64, 0xa6, 0xa1, 0x29, 0xc7, 0xf9, 0x34, 0xb4, 0x53,
0xe2, 0x09, 0x7f, 0x20, 0x8f, 0xc9, 0x28, 0x45, 0x98, 0x1a, 0x1f, 0xf1, 0x55, 0x2c, 0x49, 0x87,
0x9b, 0x00, 0x50, 0x06, 0xc7, 0x0b, 0x80, 0x20, 0x1b, 0x14, 0xdd, 0xb1, 0x26, 0x66, 0xb7, 0xa3,
0x3b, 0xd6, 0xe4, 0x84, 0x52, 0xd8, 0xf7, 0x05, 0xb8, 0xfc, 0x6c, 0x45, 0x91, 0x7f, 0xa1, 0x01,
0x8a, 0x27, 0x8e, 0xd0, 0xc3, 0x64, 0xe9, 0x89, 0x39, 0xf3, 0xe6, 0xbb, 0xaf, 0xc7, 0x9c, 0x14,
0xce, 0x02, 0x95, 0xfa, 0x8c, 0x7b, 0xfc, 0x8a, 0x2a, 0xf5, 0x97, 0x1a, 0x54, 0x43, 0x59, 0x27,
0xf4, 0x56, 0xca, 0x98, 0x46, 0x52, 0xee, 0xcd, 0xb7, 0xaf, 0xe5, 0x4b, 0xda, 0xca, 0x2b, 0x33,
0x40, 0x9e, 0x69, 0x7e, 0xa6, 0x41, 0x2d, 0x9c, 0xa5, 0x42, 0x29, 0xb2, 0x63, 0x29, 0xfb, 0xe6,
0xc6, 0xf5, 0x8c, 0x57, 0x0f, 0x4f, 0x70, 0x9c, 0x19, 0x42, 0x41, 0xe4, 0xb5, 0x92, 0x26, 0x7e,
0x38, 0xd9, 0x9f, 0x34, 0xf1, 0x23, 0x49, 0xb1, 0x84, 0x89, 0xef, 0xd8, 0x43, 0xa2, 0x2c, 0x33,
0x91, 0xf8, 0x4a, 0x43, 0xbb, 0x7a, 0x99, 0x45, 0xb2, 0x66, 0x69, 0x68, 0xc1, 0x32, 0x93, 0x19,
0x2f, 0x94, 0x22, 0xec, 0x9a, 0x65, 0x16, 0x4d, 0x98, 0x25, 0x2c, 0x33, 0x06, 0xa8, 0x2c, 0xb3,
0x20, 0x37, 0x95, 0xb4, 0xcc, 0x62, 0x77, 0x17, 0x49, 0xcb, 0x2c, 0x9e, 0xde, 0x4a, 0x18, 0x47,
0x86, 0x1b, 0x5a, 0x66, 0x4b, 0x09, 0x69, 0x2c, 0xf4, 0x6e, 0x8a, 0x11, 0x13, 0xaf, 0x44, 0x9a,
0xef, 0xbd, 0x26, 0x77, 0xea, 0x1c, 0xe7, 0xe6, 0x97, 0x73, 0xfc, 0x6f, 0x35, 0x58, 0x4e, 0x4a,
0x81, 0xa1, 0x14, 0x9c, 0x94, 0xab, 0x94, 0xe6, 0xe6, 0xeb, 0xb2, 0x5f, 0x6d, 0x2d, 0x7f, 0xd6,
0x3f, 0xae, 0xff, 0xcb, 0x97, 0x6b, 0xda, 0xbf, 0x7f, 0xb9, 0xa6, 0xfd, 0xd7, 0x97, 0x6b, 0xda,
0xdf, 0xfd, 0xf7, 0xda, 0xdc, 0x49, 0x9e, 0xfd, 0x2e, 0xf8, 0xbb, 0xff, 0x1f, 0x00, 0x00, 0xff,
0xff, 0x96, 0xe0, 0x1c, 0xf8, 0x9e, 0x3c, 0x00, 0x00,
0x75, 0xe6, 0x00, 0xc4, 0xed, 0xe0, 0x42, 0xb0, 0x79, 0x11, 0x04, 0x49, 0x14, 0xb7, 0xb5, 0xd2,
0x72, 0xa5, 0x5d, 0x62, 0x4d, 0xdb, 0xd9, 0x2a, 0x25, 0x71, 0x0c, 0x91, 0x58, 0x89, 0x4b, 0x8a,
0xe4, 0x0e, 0x21, 0xed, 0xa5, 0x5c, 0x61, 0x0d, 0x81, 0x26, 0x39, 0x21, 0x30, 0x03, 0xcf, 0x0c,
0x20, 0x72, 0x73, 0x71, 0xca, 0xe5, 0xb8, 0x92, 0x57, 0xbb, 0x2a, 0x95, 0x3c, 0x24, 0x2f, 0xa9,
0x94, 0xcb, 0x0f, 0x7e, 0xce, 0x5f, 0xc8, 0x53, 0x2e, 0x95, 0x3f, 0x90, 0xda, 0xf8, 0x25, 0xf9,
0x11, 0x29, 0x57, 0xdf, 0x66, 0x7a, 0x6e, 0xa4, 0x6c, 0xac, 0xf6, 0x85, 0x9c, 0x3e, 0x7d, 0xfa,
0x7c, 0xa7, 0x4f, 0x77, 0x9f, 0xd3, 0x7d, 0xba, 0x01, 0x25, 0x67, 0xd4, 0x5b, 0x1f, 0x39, 0xb6,
0x67, 0xa3, 0x0a, 0xf1, 0x7a, 0x7d, 0x97, 0x38, 0x13, 0xe2, 0x8c, 0x8e, 0x9b, 0x8b, 0xa7, 0xf6,
0xa9, 0xcd, 0x2a, 0x5a, 0xf4, 0x8b, 0xf3, 0x34, 0x6f, 0x52, 0x9e, 0xd6, 0x70, 0xd2, 0xeb, 0xb1,
0x3f, 0xa3, 0xe3, 0xd6, 0xf9, 0x44, 0x54, 0xdd, 0x62, 0x55, 0xc6, 0xd8, 0x3b, 0x63, 0x7f, 0x46,
0xc7, 0xec, 0x9f, 0xa8, 0xbc, 0x7d, 0x6a, 0xdb, 0xa7, 0x03, 0xd2, 0x32, 0x46, 0x66, 0xcb, 0xb0,
0x2c, 0xdb, 0x33, 0x3c, 0xd3, 0xb6, 0x5c, 0x5e, 0x8b, 0xff, 0x4a, 0x83, 0x9a, 0x4e, 0xdc, 0x91,
0x6d, 0xb9, 0xe4, 0x19, 0x31, 0xfa, 0xc4, 0x41, 0x77, 0x00, 0x7a, 0x83, 0xb1, 0xeb, 0x11, 0xe7,
0xc8, 0xec, 0x37, 0xb4, 0x55, 0x6d, 0x6d, 0x56, 0x2f, 0x09, 0xca, 0x76, 0x1f, 0xdd, 0x82, 0xd2,
0x90, 0x0c, 0x8f, 0x79, 0x6d, 0x86, 0xd5, 0x16, 0x39, 0x61, 0xbb, 0x8f, 0x9a, 0x50, 0x74, 0xc8,
0xc4, 0x74, 0x4d, 0xdb, 0x6a, 0x64, 0x57, 0xb5, 0xb5, 0xac, 0xee, 0x97, 0x69, 0x43, 0xc7, 0x38,
0xf1, 0x8e, 0x3c, 0xe2, 0x0c, 0x1b, 0xb3, 0xbc, 0x21, 0x25, 0x74, 0x89, 0x33, 0xc4, 0x3f, 0xc9,
0x41, 0x45, 0x37, 0xac, 0x53, 0xa2, 0x93, 0x1f, 0x8e, 0x89, 0xeb, 0xa1, 0x3a, 0x64, 0xcf, 0xc9,
0x25, 0x83, 0xaf, 0xe8, 0xf4, 0x93, 0xb7, 0xb7, 0x4e, 0xc9, 0x11, 0xb1, 0x38, 0x70, 0x85, 0xb6,
0xb7, 0x4e, 0x49, 0xc7, 0xea, 0xa3, 0x45, 0xc8, 0x0d, 0xcc, 0xa1, 0xe9, 0x09, 0x54, 0x5e, 0x08,
0xa9, 0x33, 0x1b, 0x51, 0x67, 0x13, 0xc0, 0xb5, 0x1d, 0xef, 0xc8, 0x76, 0xfa, 0xc4, 0x69, 0xe4,
0x56, 0xb5, 0xb5, 0xda, 0xc6, 0xdb, 0xeb, 0xea, 0x40, 0xac, 0xab, 0x0a, 0xad, 0x1f, 0xda, 0x8e,
0xb7, 0x4f, 0x79, 0xf5, 0x92, 0x2b, 0x3f, 0xd1, 0x47, 0x50, 0x66, 0x42, 0x3c, 0xc3, 0x39, 0x25,
0x5e, 0x23, 0xcf, 0xa4, 0xdc, 0xbf, 0x46, 0x4a, 0x97, 0x31, 0xeb, 0x0c, 0x9e, 0x7f, 0x23, 0x0c,
0x15, 0x97, 0x38, 0xa6, 0x31, 0x30, 0xbf, 0x34, 0x8e, 0x07, 0xa4, 0x51, 0x58, 0xd5, 0xd6, 0x8a,
0x7a, 0x88, 0x46, 0xfb, 0x7f, 0x4e, 0x2e, 0xdd, 0x23, 0xdb, 0x1a, 0x5c, 0x36, 0x8a, 0x8c, 0xa1,
0x48, 0x09, 0xfb, 0xd6, 0xe0, 0x92, 0x0d, 0x9a, 0x3d, 0xb6, 0x3c, 0x5e, 0x5b, 0x62, 0xb5, 0x25,
0x46, 0x61, 0xd5, 0x6b, 0x50, 0x1f, 0x9a, 0xd6, 0xd1, 0xd0, 0xee, 0x1f, 0xf9, 0x06, 0x01, 0x66,
0x90, 0xda, 0xd0, 0xb4, 0x9e, 0xdb, 0x7d, 0x5d, 0x9a, 0x85, 0x72, 0x1a, 0x17, 0x61, 0xce, 0xb2,
0xe0, 0x34, 0x2e, 0x54, 0xce, 0x75, 0x58, 0xa0, 0x32, 0x7b, 0x0e, 0x31, 0x3c, 0x12, 0x30, 0x57,
0x18, 0xf3, 0xfc, 0xd0, 0xb4, 0x36, 0x59, 0x4d, 0x88, 0xdf, 0xb8, 0x88, 0xf1, 0x57, 0x05, 0xbf,
0x71, 0x11, 0xe6, 0xc7, 0xeb, 0x50, 0xf2, 0x6d, 0x8e, 0x8a, 0x30, 0xbb, 0xb7, 0xbf, 0xd7, 0xa9,
0xcf, 0x20, 0x80, 0x7c, 0xfb, 0x70, 0xb3, 0xb3, 0xb7, 0x55, 0xd7, 0x50, 0x19, 0x0a, 0x5b, 0x1d,
0x5e, 0xc8, 0xe0, 0x27, 0x00, 0x81, 0x75, 0x51, 0x01, 0xb2, 0x3b, 0x9d, 0xcf, 0xeb, 0x33, 0x94,
0xe7, 0x65, 0x47, 0x3f, 0xdc, 0xde, 0xdf, 0xab, 0x6b, 0xb4, 0xf1, 0xa6, 0xde, 0x69, 0x77, 0x3b,
0xf5, 0x0c, 0xe5, 0x78, 0xbe, 0xbf, 0x55, 0xcf, 0xa2, 0x12, 0xe4, 0x5e, 0xb6, 0x77, 0x5f, 0x74,
0xea, 0xb3, 0xf8, 0xe7, 0x1a, 0x54, 0xc5, 0x78, 0xf1, 0x35, 0x81, 0xbe, 0x03, 0xf9, 0x33, 0xb6,
0x2e, 0xd8, 0x54, 0x2c, 0x6f, 0xdc, 0x8e, 0x0c, 0x6e, 0x68, 0xed, 0xe8, 0x82, 0x17, 0x61, 0xc8,
0x9e, 0x4f, 0xdc, 0x46, 0x66, 0x35, 0xbb, 0x56, 0xde, 0xa8, 0xaf, 0xf3, 0x05, 0xbb, 0xbe, 0x43,
0x2e, 0x5f, 0x1a, 0x83, 0x31, 0xd1, 0x69, 0x25, 0x42, 0x30, 0x3b, 0xb4, 0x1d, 0xc2, 0x66, 0x6c,
0x51, 0x67, 0xdf, 0x74, 0x1a, 0xb3, 0x41, 0x13, 0xb3, 0x95, 0x17, 0xf0, 0x2f, 0x35, 0x80, 0x83,
0xb1, 0x97, 0xbe, 0x34, 0x16, 0x21, 0x37, 0xa1, 0x82, 0xc5, 0xb2, 0xe0, 0x05, 0xb6, 0x26, 0x88,
0xe1, 0x12, 0x7f, 0x4d, 0xd0, 0x02, 0xba, 0x01, 0x85, 0x91, 0x43, 0x26, 0x47, 0xe7, 0x13, 0x06,
0x52, 0xd4, 0xf3, 0xb4, 0xb8, 0x33, 0x41, 0x6f, 0x41, 0xc5, 0x3c, 0xb5, 0x6c, 0x87, 0x1c, 0x71,
0x59, 0x39, 0x56, 0x5b, 0xe6, 0x34, 0xa6, 0xb7, 0xc2, 0xc2, 0x05, 0xe7, 0x55, 0x96, 0x5d, 0x4a,
0xc2, 0x16, 0x94, 0x99, 0xaa, 0x53, 0x99, 0xef, 0xdd, 0x40, 0xc7, 0x0c, 0x6b, 0x16, 0x37, 0xa1,
0xd0, 0x1a, 0xff, 0x00, 0xd0, 0x16, 0x19, 0x10, 0x8f, 0x4c, 0xe3, 0x3d, 0x14, 0x9b, 0x64, 0x55,
0x9b, 0xe0, 0x9f, 0x69, 0xb0, 0x10, 0x12, 0x3f, 0x55, 0xb7, 0x1a, 0x50, 0xe8, 0x33, 0x61, 0x5c,
0x83, 0xac, 0x2e, 0x8b, 0xe8, 0x11, 0x14, 0x85, 0x02, 0x6e, 0x23, 0x9b, 0x32, 0x69, 0x0a, 0x5c,
0x27, 0x17, 0xff, 0x32, 0x03, 0x25, 0xd1, 0xd1, 0xfd, 0x11, 0x6a, 0x43, 0xd5, 0xe1, 0x85, 0x23,
0xd6, 0x1f, 0xa1, 0x51, 0x33, 0xdd, 0x09, 0x3d, 0x9b, 0xd1, 0x2b, 0xa2, 0x09, 0x23, 0xa3, 0xdf,
0x87, 0xb2, 0x14, 0x31, 0x1a, 0x7b, 0xc2, 0xe4, 0x8d, 0xb0, 0x80, 0x60, 0xfe, 0x3d, 0x9b, 0xd1,
0x41, 0xb0, 0x1f, 0x8c, 0x3d, 0xd4, 0x85, 0x45, 0xd9, 0x98, 0xf7, 0x46, 0xa8, 0x91, 0x65, 0x52,
0x56, 0xc3, 0x52, 0xe2, 0x43, 0xf5, 0x6c, 0x46, 0x47, 0xa2, 0xbd, 0x52, 0xa9, 0xaa, 0xe4, 0x5d,
0x70, 0xe7, 0x1d, 0x53, 0xa9, 0x7b, 0x61, 0xc5, 0x55, 0xea, 0x5e, 0x58, 0x4f, 0x4a, 0x50, 0x10,
0x25, 0xfc, 0x2f, 0x19, 0x00, 0x39, 0x1a, 0xfb, 0x23, 0xb4, 0x05, 0x35, 0x47, 0x94, 0x42, 0xd6,
0xba, 0x95, 0x68, 0x2d, 0x31, 0x88, 0x33, 0x7a, 0x55, 0x36, 0xe2, 0xca, 0x7d, 0x0f, 0x2a, 0xbe,
0x94, 0xc0, 0x60, 0x37, 0x13, 0x0c, 0xe6, 0x4b, 0x28, 0xcb, 0x06, 0xd4, 0x64, 0x9f, 0xc2, 0x92,
0xdf, 0x3e, 0xc1, 0x66, 0x6f, 0x5d, 0x61, 0x33, 0x5f, 0xe0, 0x82, 0x94, 0xa0, 0x5a, 0x4d, 0x55,
0x2c, 0x30, 0xdb, 0xcd, 0x04, 0xb3, 0xc5, 0x15, 0xa3, 0x86, 0x03, 0x1a, 0x2f, 0x79, 0x11, 0xff,
0x6f, 0x16, 0x0a, 0x9b, 0xf6, 0x70, 0x64, 0x38, 0x74, 0x34, 0xf2, 0x0e, 0x71, 0xc7, 0x03, 0x8f,
0x99, 0xab, 0xb6, 0x71, 0x2f, 0x2c, 0x51, 0xb0, 0xc9, 0xff, 0x3a, 0x63, 0xd5, 0x45, 0x13, 0xda,
0x58, 0x84, 0xc7, 0xcc, 0x6b, 0x34, 0x16, 0xc1, 0x51, 0x34, 0x91, 0x0b, 0x39, 0x1b, 0x2c, 0xe4,
0x26, 0x14, 0x26, 0xc4, 0x09, 0x42, 0xfa, 0xb3, 0x19, 0x5d, 0x12, 0xd0, 0xbb, 0x30, 0x17, 0x0d,
0x2f, 0x39, 0xc1, 0x53, 0xeb, 0x85, 0xa3, 0xd1, 0x3d, 0xa8, 0x84, 0x62, 0x5c, 0x5e, 0xf0, 0x95,
0x87, 0x4a, 0x88, 0x5b, 0x96, 0x7e, 0x95, 0xc6, 0xe3, 0xca, 0xb3, 0x19, 0xe9, 0x59, 0x97, 0xa5,
0x67, 0x2d, 0x8a, 0x56, 0xc2, 0xb7, 0x86, 0x9c, 0xcc, 0xf7, 0xc3, 0x4e, 0x06, 0x7f, 0x1f, 0xaa,
0x21, 0x03, 0xd1, 0xb8, 0xd3, 0xf9, 0xe4, 0x45, 0x7b, 0x97, 0x07, 0xa9, 0xa7, 0x2c, 0x2e, 0xe9,
0x75, 0x8d, 0xc6, 0xba, 0xdd, 0xce, 0xe1, 0x61, 0x3d, 0x83, 0xaa, 0x50, 0xda, 0xdb, 0xef, 0x1e,
0x71, 0xae, 0x2c, 0x7e, 0xea, 0x4b, 0x10, 0x41, 0x4e, 0x89, 0x6d, 0x33, 0x4a, 0x6c, 0xd3, 0x64,
0x6c, 0xcb, 0x04, 0xb1, 0x8d, 0x85, 0xb9, 0xdd, 0x4e, 0xfb, 0xb0, 0x53, 0x9f, 0x7d, 0x52, 0x83,
0x0a, 0xb7, 0xef, 0xd1, 0xd8, 0xa2, 0xa1, 0xf6, 0x9f, 0x34, 0x80, 0x60, 0x35, 0xa1, 0x16, 0x14,
0x7a, 0x1c, 0xa7, 0xa1, 0x31, 0x67, 0xb4, 0x94, 0x38, 0x64, 0xba, 0xe4, 0x42, 0xdf, 0x82, 0x82,
0x3b, 0xee, 0xf5, 0x88, 0x2b, 0x43, 0xde, 0x8d, 0xa8, 0x3f, 0x14, 0xde, 0x4a, 0x97, 0x7c, 0xb4,
0xc9, 0x89, 0x61, 0x0e, 0xc6, 0x2c, 0x00, 0x5e, 0xdd, 0x44, 0xf0, 0xe1, 0xbf, 0xd7, 0xa0, 0xac,
0x4c, 0xde, 0xdf, 0xd1, 0x09, 0xdf, 0x86, 0x12, 0xd3, 0x81, 0xf4, 0x85, 0x1b, 0x2e, 0xea, 0x01,
0x01, 0xfd, 0x1e, 0x94, 0xe4, 0x0a, 0x90, 0x9e, 0xb8, 0x91, 0x2c, 0x76, 0x7f, 0xa4, 0x07, 0xac,
0x78, 0x07, 0xe6, 0x99, 0x55, 0x7a, 0x74, 0x73, 0x2d, 0xed, 0xa8, 0x6e, 0x3f, 0xb5, 0xc8, 0xf6,
0xb3, 0x09, 0xc5, 0xd1, 0xd9, 0xa5, 0x6b, 0xf6, 0x8c, 0x81, 0xd0, 0xc2, 0x2f, 0xe3, 0x8f, 0x01,
0xa9, 0xc2, 0xa6, 0xe9, 0x2e, 0xae, 0x42, 0xf9, 0x99, 0xe1, 0x9e, 0x09, 0x95, 0xf0, 0x23, 0xa8,
0xd2, 0xe2, 0xce, 0xcb, 0xd7, 0xd0, 0x91, 0x1d, 0x0e, 0x24, 0xf7, 0x54, 0x36, 0x47, 0x30, 0x7b,
0x66, 0xb8, 0x67, 0xac, 0xa3, 0x55, 0x9d, 0x7d, 0xa3, 0x77, 0xa1, 0xde, 0xe3, 0x9d, 0x3c, 0x8a,
0x1c, 0x19, 0xe6, 0x04, 0xdd, 0xdf, 0x09, 0x7e, 0x06, 0x15, 0xde, 0x87, 0xaf, 0x5b, 0x09, 0x3c,
0x0f, 0x73, 0x87, 0x96, 0x31, 0x72, 0xcf, 0x6c, 0x19, 0xdd, 0x68, 0xa7, 0xeb, 0x01, 0x6d, 0x2a,
0xc4, 0x77, 0x60, 0xce, 0x21, 0x43, 0xc3, 0xb4, 0x4c, 0xeb, 0xf4, 0xe8, 0xf8, 0xd2, 0x23, 0xae,
0x38, 0x30, 0xd5, 0x7c, 0xf2, 0x13, 0x4a, 0xa5, 0xaa, 0x1d, 0x0f, 0xec, 0x63, 0xe1, 0xe6, 0xd8,
0x37, 0xfe, 0x69, 0x06, 0x2a, 0x9f, 0x1a, 0x5e, 0x4f, 0x0e, 0x1d, 0xda, 0x86, 0x9a, 0xef, 0xdc,
0x18, 0x45, 0xe8, 0x12, 0x09, 0xb1, 0xac, 0x8d, 0xdc, 0x4a, 0xcb, 0xe8, 0x58, 0xed, 0xa9, 0x04,
0x26, 0xca, 0xb0, 0x7a, 0x64, 0xe0, 0x8b, 0xca, 0xa4, 0x8b, 0x62, 0x8c, 0xaa, 0x28, 0x95, 0x80,
0xf6, 0xa1, 0x3e, 0x72, 0xec, 0x53, 0x87, 0xb8, 0xae, 0x2f, 0x8c, 0x87, 0x31, 0x9c, 0x20, 0xec,
0x40, 0xb0, 0x06, 0xe2, 0xe6, 0x46, 0x61, 0xd2, 0x93, 0xb9, 0x60, 0x3f, 0xc3, 0x9d, 0xd3, 0x7f,
0x66, 0x00, 0xc5, 0x3b, 0xf5, 0xdb, 0x6e, 0xf1, 0xee, 0x43, 0xcd, 0xf5, 0x0c, 0x27, 0x36, 0xd9,
0xaa, 0x8c, 0xea, 0x7b, 0xfc, 0x77, 0xc0, 0x57, 0xe8, 0xc8, 0xb2, 0x3d, 0xf3, 0xe4, 0x52, 0xec,
0x92, 0x6b, 0x92, 0xbc, 0xc7, 0xa8, 0xa8, 0x03, 0x85, 0x13, 0x73, 0xe0, 0x11, 0xc7, 0x6d, 0xe4,
0x56, 0xb3, 0x6b, 0xb5, 0x8d, 0x47, 0xd7, 0x0d, 0xc3, 0xfa, 0x47, 0x8c, 0xbf, 0x7b, 0x39, 0x22,
0xba, 0x6c, 0xab, 0xee, 0x3c, 0xf3, 0xa1, 0xdd, 0xf8, 0x4d, 0x28, 0xbe, 0xa2, 0x22, 0xe8, 0x29,
0xbb, 0xc0, 0x37, 0x8b, 0xac, 0xcc, 0x0f, 0xd9, 0x27, 0x8e, 0x71, 0x3a, 0x24, 0x96, 0x27, 0xcf,
0x81, 0xb2, 0x8c, 0xef, 0x03, 0x04, 0x30, 0xd4, 0xe5, 0xef, 0xed, 0x1f, 0xbc, 0xe8, 0xd6, 0x67,
0x50, 0x05, 0x8a, 0x7b, 0xfb, 0x5b, 0x9d, 0xdd, 0x0e, 0x8d, 0x0f, 0xb8, 0x25, 0x4d, 0x1a, 0x1a,
0x4b, 0x15, 0x53, 0x0b, 0x61, 0xe2, 0x65, 0x58, 0x4c, 0x1a, 0x40, 0xba, 0x17, 0xad, 0x8a, 0x59,
0x3a, 0xd5, 0x52, 0x51, 0xa1, 0x33, 0xe1, 0xee, 0x36, 0xa0, 0xc0, 0x67, 0x6f, 0x5f, 0x6c, 0xce,
0x65, 0x91, 0x1a, 0x82, 0x4f, 0x46, 0xd2, 0x17, 0xa3, 0xe4, 0x97, 0x13, 0xdd, 0x4b, 0x2e, 0xd1,
0xbd, 0xa0, 0x7b, 0x50, 0xf5, 0x57, 0x83, 0xe1, 0x8a, 0xbd, 0x40, 0x49, 0xaf, 0xc8, 0x89, 0x4e,
0x69, 0x21, 0xa3, 0x17, 0xc2, 0x46, 0x47, 0xf7, 0x21, 0x4f, 0x26, 0xc4, 0xf2, 0xdc, 0x46, 0x99,
0x45, 0x8c, 0xaa, 0xdc, 0xbb, 0x77, 0x28, 0x55, 0x17, 0x95, 0xf8, 0xbb, 0x30, 0xcf, 0xce, 0x48,
0x4f, 0x1d, 0xc3, 0x52, 0x0f, 0x73, 0xdd, 0xee, 0xae, 0x30, 0x37, 0xfd, 0x44, 0x35, 0xc8, 0x6c,
0x6f, 0x09, 0x23, 0x64, 0xb6, 0xb7, 0xf0, 0x8f, 0x35, 0x40, 0x6a, 0xbb, 0xa9, 0xec, 0x1c, 0x11,
0x2e, 0xe1, 0xb3, 0x01, 0xfc, 0x22, 0xe4, 0x88, 0xe3, 0xd8, 0x0e, 0xb3, 0x68, 0x49, 0xe7, 0x05,
0xfc, 0xb6, 0xd0, 0x41, 0x27, 0x13, 0xfb, 0xdc, 0x5f, 0x83, 0x5c, 0x9a, 0xe6, 0xab, 0xba, 0x03,
0x0b, 0x21, 0xae, 0xa9, 0x22, 0xd7, 0x47, 0x30, 0xc7, 0x84, 0x6d, 0x9e, 0x91, 0xde, 0xf9, 0xc8,
0x36, 0xad, 0x18, 0x1e, 0x1d, 0xb9, 0xc0, 0xc1, 0xd2, 0x7e, 0xf0, 0x8e, 0x55, 0x7c, 0x62, 0xb7,
0xbb, 0x8b, 0x3f, 0x87, 0xe5, 0x88, 0x1c, 0xa9, 0xfe, 0x1f, 0x41, 0xb9, 0xe7, 0x13, 0x5d, 0xb1,
0xd7, 0xb9, 0x13, 0x56, 0x2e, 0xda, 0x54, 0x6d, 0x81, 0xf7, 0xe1, 0x46, 0x4c, 0xf4, 0x54, 0x7d,
0x7e, 0x07, 0x96, 0x98, 0xc0, 0x1d, 0x42, 0x46, 0xed, 0x81, 0x39, 0x49, 0xb5, 0xf4, 0x48, 0x74,
0x4a, 0x61, 0x7c, 0xb3, 0xf3, 0x02, 0xff, 0x81, 0x40, 0xec, 0x9a, 0x43, 0xd2, 0xb5, 0x77, 0xd3,
0x75, 0xa3, 0xd1, 0xec, 0x9c, 0x5c, 0xba, 0x62, 0x5b, 0xc3, 0xbe, 0xf1, 0x3f, 0x6b, 0xc2, 0x54,
0x6a, 0xf3, 0x37, 0x3c, 0x93, 0x57, 0x00, 0x4e, 0xe9, 0x92, 0x21, 0x7d, 0x5a, 0xc1, 0x33, 0x2a,
0x0a, 0xc5, 0xd7, 0x93, 0xfa, 0xef, 0x8a, 0xd0, 0x73, 0x51, 0xcc, 0x73, 0xf6, 0xc7, 0xf7, 0x72,
0x77, 0xa0, 0xcc, 0x08, 0x87, 0x9e, 0xe1, 0x8d, 0xdd, 0xd8, 0x60, 0xfc, 0x85, 0x98, 0xf6, 0xb2,
0xd1, 0x54, 0xfd, 0xfa, 0x16, 0xe4, 0xd9, 0x61, 0x42, 0x6e, 0xa5, 0x6f, 0x26, 0xcc, 0x47, 0xae,
0x87, 0x2e, 0x18, 0xf1, 0x4f, 0x35, 0xc8, 0x3f, 0x67, 0x29, 0x58, 0x45, 0xb5, 0x59, 0x39, 0x16,
0x96, 0x31, 0xe4, 0x89, 0xa1, 0x92, 0xce, 0xbe, 0xd9, 0xd6, 0x93, 0x10, 0xe7, 0x85, 0xbe, 0xcb,
0xb7, 0xb8, 0x25, 0xdd, 0x2f, 0x53, 0x9b, 0xf5, 0x06, 0x26, 0xb1, 0x3c, 0x56, 0x3b, 0xcb, 0x6a,
0x15, 0x0a, 0xdd, 0x3d, 0x9b, 0xee, 0x2e, 0x31, 0x1c, 0x4b, 0x24, 0x4d, 0x8b, 0x7a, 0x40, 0xc0,
0xbb, 0x50, 0xe7, 0x7a, 0xb4, 0xfb, 0x7d, 0x65, 0x83, 0xe9, 0xa3, 0x69, 0x11, 0xb4, 0x90, 0xb4,
0x4c, 0x54, 0xda, 0x2f, 0x34, 0x98, 0x57, 0xc4, 0x4d, 0x65, 0xd5, 0xf7, 0x20, 0xcf, 0x93, 0xd4,
0x62, 0xa7, 0xb3, 0x18, 0x6e, 0xc5, 0x61, 0x74, 0xc1, 0x83, 0xd6, 0xa1, 0xc0, 0xbf, 0xe4, 0x19,
0x20, 0x99, 0x5d, 0x32, 0xe1, 0xfb, 0xb0, 0x20, 0x48, 0x64, 0x68, 0x27, 0x2d, 0x0c, 0x36, 0x18,
0xf8, 0xcf, 0x60, 0x31, 0xcc, 0x36, 0x55, 0x97, 0x14, 0x25, 0x33, 0xaf, 0xa3, 0x64, 0x5b, 0x2a,
0xf9, 0x62, 0xd4, 0x57, 0xf6, 0x51, 0xd1, 0x19, 0xa3, 0x8e, 0x57, 0x26, 0x3c, 0x5e, 0x41, 0x07,
0xa4, 0x88, 0x6f, 0xb4, 0x03, 0x1f, 0xca, 0xe9, 0xb0, 0x6b, 0xba, 0xbe, 0x0f, 0xc7, 0x50, 0x19,
0x98, 0x16, 0x31, 0x1c, 0x91, 0x39, 0xd7, 0x78, 0xe6, 0x5c, 0xa5, 0xe1, 0x2f, 0x01, 0xa9, 0x0d,
0xbf, 0x51, 0xa5, 0x1f, 0x48, 0x93, 0x1d, 0x38, 0xf6, 0xd0, 0x4e, 0x35, 0x3b, 0xfe, 0x73, 0x58,
0x8a, 0xf0, 0x7d, 0xa3, 0x6a, 0x2e, 0xc0, 0xfc, 0x16, 0x91, 0x1b, 0x1a, 0xe9, 0xf6, 0x3e, 0x06,
0xa4, 0x12, 0xa7, 0x8a, 0x6c, 0x2d, 0x98, 0x7f, 0x6e, 0x4f, 0xa8, 0x8b, 0xa4, 0xd4, 0xc0, 0x37,
0xf0, 0x3c, 0x84, 0x6f, 0x0a, 0xbf, 0x4c, 0xc1, 0xd5, 0x06, 0x53, 0x81, 0xff, 0xbb, 0x06, 0x95,
0xf6, 0xc0, 0x70, 0x86, 0x12, 0xf8, 0x7b, 0x90, 0xe7, 0xa7, 0x6b, 0x91, 0xd0, 0x7a, 0x10, 0x16,
0xa3, 0xf2, 0xf2, 0x42, 0x9b, 0x9f, 0xc5, 0x45, 0x2b, 0xaa, 0xb8, 0xb8, 0xf3, 0xda, 0x8a, 0xdc,
0x81, 0x6d, 0xa1, 0xf7, 0x21, 0x67, 0xd0, 0x26, 0x2c, 0x14, 0xd5, 0xa2, 0x79, 0x0d, 0x26, 0x8d,
0x9d, 0x01, 0x38, 0x17, 0xfe, 0x0e, 0x94, 0x15, 0x04, 0x54, 0x80, 0xec, 0xd3, 0x8e, 0xd8, 0xb0,
0xb7, 0x37, 0xbb, 0xdb, 0x2f, 0x79, 0x42, 0xa7, 0x06, 0xb0, 0xd5, 0xf1, 0xcb, 0x19, 0xfc, 0x99,
0x68, 0x25, 0xdc, 0xbe, 0xaa, 0x8f, 0x96, 0xa6, 0x4f, 0xe6, 0xb5, 0xf4, 0xb9, 0x80, 0xaa, 0xe8,
0xfe, 0xb4, 0x61, 0x8c, 0xc9, 0x4b, 0x09, 0x63, 0x8a, 0xf2, 0xba, 0x60, 0xc4, 0xbf, 0xd2, 0xa0,
0xbe, 0x65, 0xbf, 0xb2, 0x4e, 0x1d, 0xa3, 0xef, 0xaf, 0x93, 0x8f, 0x22, 0x23, 0xb5, 0x1e, 0x49,
0x8e, 0x46, 0xf8, 0x03, 0x42, 0x64, 0xc4, 0x1a, 0x41, 0xda, 0x90, 0xc7, 0x42, 0x59, 0xc4, 0x1f,
0xc2, 0x5c, 0xa4, 0x11, 0xb5, 0xfd, 0xcb, 0xf6, 0xee, 0xf6, 0x16, 0xb5, 0x35, 0x4b, 0xac, 0x75,
0xf6, 0xda, 0x4f, 0x76, 0x3b, 0xe2, 0x02, 0xa9, 0xbd, 0xb7, 0xd9, 0xd9, 0xad, 0x67, 0x70, 0x0f,
0xe6, 0x15, 0xf8, 0x69, 0x6f, 0x06, 0x52, 0xb4, 0x9b, 0x83, 0xaa, 0x88, 0xf6, 0x62, 0x51, 0xfe,
0x5b, 0x06, 0x6a, 0x92, 0xf2, 0x66, 0x30, 0xd1, 0x32, 0xe4, 0xfb, 0xc7, 0x87, 0xe6, 0x97, 0xf2,
0xe6, 0x48, 0x94, 0x28, 0x7d, 0xc0, 0x71, 0xf8, 0xf5, 0xad, 0x28, 0xd1, 0x30, 0xee, 0x18, 0x27,
0xde, 0xb6, 0xd5, 0x27, 0x17, 0x6c, 0x53, 0x30, 0xab, 0x07, 0x04, 0x96, 0x61, 0x12, 0xd7, 0xbc,
0xec, 0x64, 0xa5, 0x5c, 0xfb, 0xa2, 0x87, 0x50, 0xa7, 0xdf, 0xed, 0xd1, 0x68, 0x60, 0x92, 0x3e,
0x17, 0x50, 0x60, 0x3c, 0x31, 0x3a, 0x45, 0x67, 0x67, 0x11, 0xb7, 0x51, 0x64, 0x61, 0x49, 0x94,
0xd0, 0x2a, 0x94, 0xb9, 0x7e, 0xdb, 0xd6, 0x0b, 0x97, 0xb0, 0xbb, 0xcf, 0xac, 0xae, 0x92, 0xc2,
0xdb, 0x0c, 0x88, 0x6e, 0x33, 0x16, 0x60, 0xbe, 0x3d, 0xf6, 0xce, 0x3a, 0x16, 0x8d, 0x15, 0xd2,
0xca, 0x8b, 0x80, 0x28, 0x71, 0xcb, 0x74, 0x55, 0xaa, 0x60, 0x0d, 0x0f, 0x48, 0x07, 0x16, 0x28,
0x91, 0x58, 0x9e, 0xd9, 0x53, 0xe2, 0xaa, 0xdc, 0x79, 0x69, 0x91, 0x9d, 0x97, 0xe1, 0xba, 0xaf,
0x6c, 0xa7, 0x2f, 0x6c, 0xee, 0x97, 0xf1, 0x3f, 0x6a, 0x1c, 0xf2, 0x85, 0x1b, 0xda, 0x3e, 0xfd,
0x96, 0x62, 0xd0, 0x07, 0x50, 0xb0, 0x47, 0xec, 0x86, 0x5f, 0xa4, 0x61, 0x96, 0xd7, 0xf9, 0x9b,
0x80, 0x75, 0x21, 0x78, 0x9f, 0xd7, 0xea, 0x92, 0x0d, 0x3d, 0x80, 0xda, 0x99, 0xe1, 0x9e, 0x91,
0xfe, 0x81, 0x94, 0xc9, 0x4f, 0x7e, 0x11, 0x2a, 0x5e, 0x0b, 0xf4, 0x7b, 0x4a, 0xbc, 0x2b, 0xf4,
0xc3, 0x8f, 0x60, 0x49, 0x72, 0x8a, 0xdb, 0x89, 0x2b, 0x98, 0x5f, 0xc1, 0x1d, 0xc9, 0xbc, 0x79,
0x66, 0x58, 0xa7, 0x44, 0x02, 0xfe, 0xae, 0x16, 0x88, 0xf7, 0x27, 0x9b, 0xd8, 0x9f, 0x27, 0xd0,
0xf0, 0xfb, 0xc3, 0x4e, 0xd6, 0xf6, 0x40, 0x55, 0x74, 0xec, 0x8a, 0xf5, 0x54, 0xd2, 0xd9, 0x37,
0xa5, 0x39, 0xf6, 0xc0, 0xdf, 0x4a, 0xd3, 0x6f, 0xbc, 0x09, 0x37, 0xa5, 0x0c, 0x71, 0xe6, 0x0d,
0x0b, 0x89, 0x29, 0x9e, 0x24, 0x44, 0x18, 0x96, 0x36, 0xbd, 0x7a, 0xe0, 0x55, 0xce, 0xf0, 0x10,
0x30, 0x99, 0x9a, 0x22, 0x73, 0x89, 0x4f, 0x4a, 0xaa, 0x98, 0xb2, 0x5b, 0x92, 0x64, 0x2a, 0x40,
0x25, 0x8b, 0x01, 0xa3, 0xe4, 0xd8, 0x80, 0xc5, 0x44, 0xff, 0x00, 0x56, 0x7c, 0x25, 0xa8, 0xdd,
0x0e, 0x88, 0x33, 0x34, 0x5d, 0x57, 0xc9, 0x7b, 0x27, 0x75, 0xfc, 0x01, 0xcc, 0x8e, 0x88, 0x08,
0x42, 0xe5, 0x0d, 0x24, 0x27, 0xa5, 0xd2, 0x98, 0xd5, 0xe3, 0x3e, 0xdc, 0x95, 0xd2, 0xb9, 0x45,
0x13, 0xc5, 0x47, 0x95, 0x92, 0xd9, 0xc0, 0x4c, 0x4a, 0x36, 0x30, 0x1b, 0xb9, 0x8b, 0xf9, 0x98,
0x1b, 0x52, 0xae, 0xf9, 0xa9, 0x36, 0x17, 0x3b, 0xdc, 0xa6, 0xbe, 0xab, 0x98, 0x4a, 0xd8, 0x5f,
0x0b, 0x2f, 0xf0, 0x75, 0x79, 0x78, 0xc2, 0x7a, 0x28, 0x2f, 0x3a, 0x64, 0x91, 0xee, 0x9a, 0xe9,
0x00, 0xe8, 0x6a, 0x2e, 0x74, 0x56, 0x0f, 0xd1, 0xf0, 0x31, 0x2c, 0x86, 0xfd, 0xda, 0x54, 0xba,
0x2c, 0x42, 0xce, 0xb3, 0xcf, 0x89, 0x8c, 0x35, 0xbc, 0x20, 0x6d, 0xe7, 0xfb, 0xbc, 0xa9, 0x6c,
0x67, 0x04, 0xc2, 0xd8, 0xea, 0x98, 0x56, 0x5f, 0x3a, 0xb1, 0xe4, 0x19, 0x88, 0x17, 0xf0, 0x1e,
0x2c, 0x47, 0x3d, 0xdb, 0x54, 0x2a, 0xbf, 0xe4, 0x6b, 0x29, 0xc9, 0xf9, 0x4d, 0x25, 0xf7, 0x93,
0xc0, 0x2f, 0x29, 0xbe, 0x6d, 0x2a, 0x91, 0x3a, 0x34, 0x93, 0x5c, 0xdd, 0xd7, 0xb1, 0x74, 0x7c,
0xcf, 0x37, 0x95, 0x30, 0x37, 0x10, 0x36, 0xfd, 0xf0, 0x07, 0xee, 0x2a, 0x7b, 0xa5, 0xbb, 0x12,
0x8b, 0x24, 0x70, 0xa8, 0x6f, 0x60, 0xd2, 0x09, 0x8c, 0xc0, 0x97, 0x4f, 0x8b, 0x41, 0xc3, 0x99,
0x8f, 0xc1, 0x0a, 0x72, 0x62, 0xab, 0x11, 0x60, 0xaa, 0xc1, 0xf8, 0x34, 0x70, 0xe3, 0xb1, 0x20,
0x31, 0x95, 0xe0, 0xcf, 0x60, 0x35, 0x3d, 0x3e, 0x4c, 0x23, 0xf9, 0x61, 0x0b, 0x4a, 0xfe, 0x61,
0x48, 0x79, 0x6f, 0x56, 0x86, 0xc2, 0xde, 0xfe, 0xe1, 0x41, 0x7b, 0xb3, 0xc3, 0x1f, 0x9c, 0x6d,
0xee, 0xeb, 0xfa, 0x8b, 0x83, 0x6e, 0x3d, 0xb3, 0xf1, 0xeb, 0x2c, 0x64, 0x76, 0x5e, 0xa2, 0xcf,
0x21, 0xc7, 0x5f, 0x5f, 0x5c, 0xf1, 0xe4, 0xa6, 0x79, 0xd5, 0x03, 0x13, 0x7c, 0xe3, 0xc7, 0xff,
0xf5, 0xeb, 0x9f, 0x67, 0xe6, 0x71, 0xa5, 0x35, 0xf9, 0x76, 0xeb, 0x7c, 0xd2, 0x62, 0x61, 0xea,
0xb1, 0xf6, 0x10, 0x7d, 0x02, 0xd9, 0x83, 0xb1, 0x87, 0x52, 0x9f, 0xe2, 0x34, 0xd3, 0xdf, 0x9c,
0xe0, 0x25, 0x26, 0x74, 0x0e, 0x83, 0x10, 0x3a, 0x1a, 0x7b, 0x54, 0xe4, 0x0f, 0xa1, 0xac, 0xbe,
0x18, 0xb9, 0xf6, 0x7d, 0x4e, 0xf3, 0xfa, 0xd7, 0x28, 0xf8, 0x0e, 0x83, 0xba, 0x81, 0x91, 0x80,
0xe2, 0x6f, 0x5a, 0xd4, 0x5e, 0x74, 0x2f, 0x2c, 0x94, 0xfa, 0x7a, 0xa7, 0x99, 0xfe, 0x40, 0x25,
0xd6, 0x0b, 0xef, 0xc2, 0xa2, 0x22, 0xff, 0x44, 0xbc, 0x4d, 0xe9, 0x79, 0xe8, 0x6e, 0xc2, 0xdb,
0x04, 0xf5, 0x16, 0xbe, 0xb9, 0x9a, 0xce, 0x20, 0x40, 0x6e, 0x33, 0x90, 0x65, 0x3c, 0x2f, 0x40,
0x7a, 0x3e, 0xcb, 0x63, 0xed, 0xe1, 0x46, 0x0f, 0x72, 0xec, 0x86, 0x0b, 0x7d, 0x21, 0x3f, 0x9a,
0x09, 0x57, 0x7d, 0x29, 0x03, 0x1d, 0xba, 0x1b, 0xc3, 0x8b, 0x0c, 0xa8, 0x86, 0x4b, 0x14, 0x88,
0xdd, 0x6f, 0x3d, 0xd6, 0x1e, 0xae, 0x69, 0x1f, 0x68, 0x1b, 0xbf, 0xca, 0x41, 0x8e, 0xa5, 0x76,
0xd1, 0x39, 0x40, 0x70, 0xdb, 0x13, 0xed, 0x5d, 0xec, 0xfe, 0x28, 0xda, 0xbb, 0xf8, 0x45, 0x11,
0x6e, 0x32, 0xd0, 0x45, 0x3c, 0x47, 0x41, 0x59, 0xc6, 0xb8, 0xc5, 0x92, 0xe0, 0xd4, 0x8e, 0x7f,
0xa3, 0x89, 0xcc, 0x36, 0x5f, 0x4b, 0x28, 0x49, 0x5a, 0xe8, 0xca, 0x27, 0x3a, 0x1d, 0x12, 0xae,
0x7b, 0xf0, 0x77, 0x19, 0x60, 0x0b, 0xd7, 0x03, 0x40, 0x87, 0x71, 0x3c, 0xd6, 0x1e, 0x7e, 0xd1,
0xc0, 0x0b, 0xc2, 0xca, 0x91, 0x1a, 0xf4, 0x23, 0xa8, 0x85, 0xaf, 0x34, 0xd0, 0xbd, 0x04, 0xac,
0xe8, 0xcd, 0x48, 0xf3, 0xed, 0xab, 0x99, 0x84, 0x4e, 0x2b, 0x4c, 0x27, 0x01, 0xce, 0x91, 0xcf,
0x09, 0x19, 0x19, 0x94, 0x49, 0x8c, 0x01, 0xfa, 0x07, 0x4d, 0xdc, 0x38, 0x05, 0x77, 0x14, 0x28,
0x49, 0x7a, 0xec, 0x06, 0xa4, 0x79, 0xff, 0x1a, 0x2e, 0xa1, 0xc4, 0x1f, 0x32, 0x25, 0x3e, 0xc4,
0x8b, 0x81, 0x12, 0x9e, 0x39, 0x24, 0x9e, 0x2d, 0xb4, 0xf8, 0xe2, 0x36, 0xbe, 0x11, 0x32, 0x4e,
0xa8, 0x36, 0x18, 0x2c, 0x7e, 0xcf, 0x90, 0x38, 0x58, 0xa1, 0x7b, 0x8b, 0xc4, 0xc1, 0x0a, 0x5f,
0x52, 0x24, 0x0d, 0x16, 0xbf, 0x55, 0x48, 0x1a, 0x2c, 0xbf, 0x66, 0xe3, 0xff, 0x66, 0xa1, 0xb0,
0xc9, 0xdf, 0x84, 0x23, 0x1b, 0x4a, 0x7e, 0x9a, 0x1e, 0xad, 0x24, 0xe5, 0x19, 0x83, 0x63, 0x4d,
0xf3, 0x6e, 0x6a, 0xbd, 0x50, 0xe8, 0x2d, 0xa6, 0xd0, 0x2d, 0xbc, 0x4c, 0x91, 0xc5, 0xb3, 0xf3,
0x16, 0x4f, 0x66, 0xb5, 0x8c, 0x7e, 0x9f, 0x1a, 0xe2, 0x4f, 0xa1, 0xa2, 0xe6, 0xd1, 0xd1, 0x5b,
0x89, 0xb9, 0x4d, 0x35, 0x15, 0xdf, 0xc4, 0x57, 0xb1, 0x08, 0xe4, 0xb7, 0x19, 0xf2, 0x0a, 0xbe,
0x99, 0x80, 0xec, 0x30, 0xd6, 0x10, 0x38, 0xcf, 0x81, 0x27, 0x83, 0x87, 0x52, 0xec, 0xc9, 0xe0,
0xe1, 0x14, 0xfa, 0x95, 0xe0, 0x63, 0xc6, 0x4a, 0xc1, 0x5d, 0x80, 0x20, 0x93, 0x8d, 0x12, 0x6d,
0xa9, 0x9c, 0xeb, 0xa2, 0xce, 0x21, 0x9e, 0x04, 0xc7, 0x98, 0xc1, 0x8a, 0x79, 0x17, 0x81, 0x1d,
0x98, 0xae, 0xc7, 0x17, 0x66, 0x35, 0x94, 0x9a, 0x46, 0x89, 0xfd, 0x09, 0xe7, 0xb7, 0x9b, 0xf7,
0xae, 0xe4, 0x11, 0xe8, 0xf7, 0x19, 0xfa, 0x5d, 0xdc, 0x4c, 0x40, 0x1f, 0x71, 0x5e, 0x3a, 0xd9,
0xfe, 0x3f, 0x0f, 0xe5, 0xe7, 0x86, 0x69, 0x79, 0xc4, 0x32, 0xac, 0x1e, 0x41, 0xc7, 0x90, 0x63,
0x91, 0x3a, 0xea, 0x88, 0xd5, 0xb4, 0x6d, 0xd4, 0x11, 0x87, 0x72, 0x9a, 0x78, 0x95, 0x01, 0x37,
0xf1, 0x12, 0x05, 0x1e, 0x06, 0xa2, 0x5b, 0x2c, 0x15, 0x49, 0x3b, 0x7d, 0x02, 0x79, 0x71, 0xdb,
0x17, 0x11, 0x14, 0x4a, 0xfe, 0x34, 0x6f, 0x27, 0x57, 0x26, 0xcd, 0x65, 0x15, 0xc6, 0x65, 0x7c,
0x14, 0x67, 0x02, 0x10, 0xe4, 0xd8, 0xa3, 0x23, 0x1a, 0x4b, 0xc9, 0x37, 0x57, 0xd3, 0x19, 0x92,
0x6c, 0xaa, 0x62, 0xf6, 0x7d, 0x5e, 0x8a, 0xfb, 0xc7, 0x30, 0xfb, 0xcc, 0x70, 0xcf, 0x50, 0x24,
0xf6, 0x2a, 0x6f, 0xc5, 0x9a, 0xcd, 0xa4, 0x2a, 0x81, 0x72, 0x97, 0xa1, 0xdc, 0xe4, 0xae, 0x4c,
0x45, 0x39, 0x33, 0x5c, 0x1a, 0xd4, 0x50, 0x1f, 0xf2, 0xfc, 0xe9, 0x58, 0xd4, 0x7e, 0xa1, 0xe7,
0x67, 0x51, 0xfb, 0x85, 0x5f, 0x9b, 0x5d, 0x8f, 0x32, 0x82, 0xa2, 0x7c, 0xab, 0x85, 0x22, 0x17,
0xf7, 0x91, 0x77, 0x5d, 0xcd, 0x95, 0xb4, 0x6a, 0x81, 0x75, 0x8f, 0x61, 0xdd, 0xc1, 0x8d, 0xd8,
0x58, 0x09, 0xce, 0xc7, 0xda, 0xc3, 0x0f, 0x34, 0xf4, 0x23, 0x80, 0xe0, 0x5a, 0x22, 0xb6, 0x02,
0xa3, 0x37, 0x1c, 0xb1, 0x15, 0x18, 0xbb, 0xd1, 0xc0, 0xeb, 0x0c, 0x77, 0x0d, 0xdf, 0x8b, 0xe2,
0x7a, 0x8e, 0x61, 0xb9, 0x27, 0xc4, 0x79, 0x9f, 0x67, 0x59, 0xdd, 0x33, 0x73, 0x44, 0xbb, 0xec,
0x40, 0xc9, 0xcf, 0x3a, 0x47, 0xbd, 0x6d, 0x34, 0x1b, 0x1e, 0xf5, 0xb6, 0xb1, 0x74, 0x75, 0xd8,
0xed, 0x84, 0x66, 0x8b, 0x64, 0xa5, 0x0b, 0xf0, 0x17, 0x75, 0x98, 0xa5, 0xbb, 0x6e, 0xba, 0x39,
0x09, 0xf2, 0x26, 0xd1, 0xde, 0xc7, 0xb2, 0xa8, 0xd1, 0xde, 0xc7, 0x53, 0x2e, 0xe1, 0xcd, 0x09,
0xfb, 0x05, 0x13, 0x4f, 0x51, 0xd0, 0x9e, 0xda, 0x50, 0x56, 0x12, 0x2b, 0x28, 0x41, 0x58, 0x38,
0x3d, 0x1b, 0x0d, 0x77, 0x09, 0x59, 0x19, 0x7c, 0x8b, 0xe1, 0x2d, 0xf1, 0x70, 0xc7, 0xf0, 0xfa,
0x9c, 0x83, 0x02, 0x8a, 0xde, 0x89, 0x75, 0x9f, 0xd0, 0xbb, 0xf0, 0xda, 0x5f, 0x4d, 0x67, 0x48,
0xed, 0x5d, 0xb0, 0xf0, 0x5f, 0x41, 0x45, 0x4d, 0xaf, 0xa0, 0x04, 0xe5, 0x23, 0x29, 0xe5, 0x68,
0x1c, 0x49, 0xca, 0xce, 0x84, 0x3d, 0x9b, 0xff, 0x93, 0x30, 0xc9, 0x46, 0x81, 0x07, 0x50, 0x10,
0xf9, 0x96, 0x24, 0x93, 0x86, 0xd3, 0xcf, 0x49, 0x26, 0x8d, 0x24, 0x6b, 0xc2, 0xbb, 0x67, 0x86,
0x48, 0x8f, 0x94, 0x32, 0x56, 0x0b, 0xb4, 0xa7, 0xc4, 0x4b, 0x43, 0x0b, 0x32, 0x99, 0x69, 0x68,
0xca, 0x71, 0x3e, 0x0d, 0xed, 0x94, 0x78, 0xc2, 0x1f, 0xc8, 0x63, 0x32, 0x4a, 0x11, 0xa6, 0xc6,
0x47, 0x7c, 0x15, 0x4b, 0xd2, 0xe1, 0x26, 0x00, 0x94, 0xc1, 0xf1, 0x02, 0x20, 0xc8, 0x06, 0x45,
0x77, 0xac, 0x89, 0x59, 0xf0, 0xe8, 0x8e, 0x35, 0x39, 0xa1, 0x14, 0xf6, 0x7d, 0x01, 0x2e, 0x3f,
0x5b, 0x51, 0xe4, 0x9f, 0x69, 0x80, 0xe2, 0x89, 0x23, 0xf4, 0x28, 0x59, 0x7a, 0x62, 0x6e, 0xbd,
0xf9, 0xde, 0xeb, 0x31, 0x27, 0x85, 0xb3, 0x40, 0xa5, 0x1e, 0xe3, 0x1e, 0xbd, 0xa2, 0x4a, 0xfd,
0xa5, 0x06, 0xd5, 0x50, 0xd6, 0x09, 0x3d, 0x48, 0x19, 0xd3, 0x48, 0xca, 0xbd, 0xf9, 0xce, 0xb5,
0x7c, 0x49, 0x5b, 0x79, 0x65, 0x06, 0xc8, 0x33, 0xcd, 0x4f, 0x34, 0xa8, 0x85, 0xb3, 0x54, 0x28,
0x45, 0x76, 0x2c, 0x65, 0xdf, 0x5c, 0xbb, 0x9e, 0xf1, 0xea, 0xe1, 0x09, 0x8e, 0x33, 0x03, 0x28,
0x88, 0xbc, 0x56, 0xd2, 0xc4, 0x0f, 0x27, 0xfb, 0x93, 0x26, 0x7e, 0x24, 0x29, 0x96, 0x30, 0xf1,
0x1d, 0x7b, 0x40, 0x94, 0x65, 0x26, 0x12, 0x5f, 0x69, 0x68, 0x57, 0x2f, 0xb3, 0x48, 0xd6, 0x2c,
0x0d, 0x2d, 0x58, 0x66, 0x32, 0xe3, 0x85, 0x52, 0x84, 0x5d, 0xb3, 0xcc, 0xa2, 0x09, 0xb3, 0x84,
0x65, 0xc6, 0x00, 0x95, 0x65, 0x16, 0xe4, 0xa6, 0x92, 0x96, 0x59, 0xec, 0xee, 0x22, 0x69, 0x99,
0xc5, 0xd3, 0x5b, 0x09, 0xe3, 0xc8, 0x70, 0x43, 0xcb, 0x6c, 0x21, 0x21, 0x8d, 0x85, 0xde, 0x4b,
0x31, 0x62, 0xe2, 0x95, 0x48, 0xf3, 0xfd, 0xd7, 0xe4, 0x4e, 0x9d, 0xe3, 0xdc, 0xfc, 0x72, 0x8e,
0xff, 0xad, 0x06, 0x8b, 0x49, 0x29, 0x30, 0x94, 0x82, 0x93, 0x72, 0x95, 0xd2, 0x5c, 0x7f, 0x5d,
0xf6, 0xab, 0xad, 0xe5, 0xcf, 0xfa, 0x27, 0xf5, 0x7f, 0xfd, 0x6a, 0x45, 0xfb, 0x8f, 0xaf, 0x56,
0xb4, 0xff, 0xfe, 0x6a, 0x45, 0xfb, 0xbb, 0xff, 0x59, 0x99, 0x39, 0xce, 0xb3, 0x1f, 0x1a, 0x7f,
0xfb, 0x37, 0x01, 0x00, 0x00, 0xff, 0xff, 0x7a, 0xd4, 0x63, 0xa4, 0xef, 0x3c, 0x00, 0x00,
}

View File

@ -1050,6 +1050,7 @@ message AuthUserAddRequest {
string name = 1;
string password = 2;
authpb.UserAddOptions options = 3;
string hashedPassword = 4;
}
message AuthUserGetRequest {
@ -1064,8 +1065,10 @@ message AuthUserDeleteRequest {
message AuthUserChangePasswordRequest {
// name is the name of the user whose password is being changed.
string name = 1;
// password is the new password for the user.
// password is the new password for the user. Note that this field will be removed in the API layer.
string password = 2;
// hashedPassword is the new password for the user. Note that this field will be initialized in the API layer.
string hashedPassword = 3;
}
message AuthUserGrantRoleRequest {

View File

@ -17,6 +17,7 @@ package etcdserver
import (
"bytes"
"context"
"encoding/base64"
"encoding/binary"
"time"
@ -32,6 +33,7 @@ import (
"github.com/gogo/protobuf/proto"
"go.uber.org/zap"
"golang.org/x/crypto/bcrypt"
)
const (
@ -464,6 +466,15 @@ func (s *EtcdServer) Authenticate(ctx context.Context, r *pb.AuthenticateRequest
}
func (s *EtcdServer) UserAdd(ctx context.Context, r *pb.AuthUserAddRequest) (*pb.AuthUserAddResponse, error) {
if r.Options == nil || !r.Options.NoPassword {
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(r.Password), s.authStore.BcryptCost())
if err != nil {
return nil, err
}
r.HashedPassword = base64.StdEncoding.EncodeToString(hashedPassword)
r.Password = ""
}
resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthUserAdd: r})
if err != nil {
return nil, err
@ -480,6 +491,15 @@ func (s *EtcdServer) UserDelete(ctx context.Context, r *pb.AuthUserDeleteRequest
}
func (s *EtcdServer) UserChangePassword(ctx context.Context, r *pb.AuthUserChangePasswordRequest) (*pb.AuthUserChangePasswordResponse, error) {
if r.Password != "" {
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(r.Password), s.authStore.BcryptCost())
if err != nil {
return nil, err
}
r.HashedPassword = base64.StdEncoding.EncodeToString(hashedPassword)
r.Password = ""
}
resp, err := s.raftRequest(ctx, pb.InternalRaftRequest{AuthUserChangePassword: r})
if err != nil {
return nil, err