// Code generated by protoc-gen-twirp v7.1.0, DO NOT EDIT.
// source: rpc.proto

/*
Package rpc is a generated twirp stub package.
This code was generated with github.com/twitchtv/twirp/protoc-gen-twirp v7.1.0.

It is generated from these files:
	rpc.proto
*/
package rpc

import (
	bytes "bytes"
	strings "strings"

	context "context"

	fmt "fmt"

	ioutil "io/ioutil"

	http "net/http"

	strconv "strconv"

	jsonpb "github.com/golang/protobuf/jsonpb"

	proto "github.com/golang/protobuf/proto"

	twirp "github.com/twitchtv/twirp"

	ctxsetters "github.com/twitchtv/twirp/ctxsetters"

	// Imports only used by utility functions:

	io "io"

	json "encoding/json"

	path "path"

	url "net/url"
)

// This is a compile-time assertion to ensure that this generated file
// is compatible with the twirp package used in your project.
// A compilation error at this line likely means your copy of the
// twirp package needs to be updated.
const _ = twirp.TwirpPackageIsVersion7

// =========================
// AutoRollService Interface
// =========================

// AutoRollService provides interactions with the AutoRoll frontend.
type AutoRollService interface {
	// GetRollers retrieves AutoRollMiniStatuses for all known rollers.
	GetRollers(context.Context, *GetRollersRequest) (*GetRollersResponse, error)

	// GetMiniStatus retrieves the AutoRollMiniStatus for one roller.
	GetMiniStatus(context.Context, *GetMiniStatusRequest) (*GetMiniStatusResponse, error)

	// GetStatus retrieves the AutoRollStatus for one roller.
	GetStatus(context.Context, *GetStatusRequest) (*GetStatusResponse, error)

	// SetMode sets the mode for a roller.
	SetMode(context.Context, *SetModeRequest) (*SetModeResponse, error)

	// SetStrategy sets the strategy for a roller.
	SetStrategy(context.Context, *SetStrategyRequest) (*SetStrategyResponse, error)

	// CreateManualRoll initiates the creation of a manual roll.
	CreateManualRoll(context.Context, *CreateManualRollRequest) (*CreateManualRollResponse, error)

	// Unthrottle clears any throttling of the roller, allowing it to roll again.
	Unthrottle(context.Context, *UnthrottleRequest) (*UnthrottleResponse, error)
}

// ===============================
// AutoRollService Protobuf Client
// ===============================

type autoRollServiceProtobufClient struct {
	client      HTTPClient
	urls        [7]string
	interceptor twirp.Interceptor
	opts        twirp.ClientOptions
}

// NewAutoRollServiceProtobufClient creates a Protobuf client that implements the AutoRollService interface.
// It communicates using Protobuf and can be configured with a custom HTTPClient.
func NewAutoRollServiceProtobufClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) AutoRollService {
	if c, ok := client.(*http.Client); ok {
		client = withoutRedirects(c)
	}

	clientOpts := twirp.ClientOptions{}
	for _, o := range opts {
		o(&clientOpts)
	}

	// Build method URLs: <baseURL>[<prefix>]/<package>.<Service>/<Method>
	serviceURL := sanitizeBaseURL(baseURL)
	serviceURL += baseServicePath(clientOpts.PathPrefix(), "autoroll.rpc", "AutoRollService")
	urls := [7]string{
		serviceURL + "GetRollers",
		serviceURL + "GetMiniStatus",
		serviceURL + "GetStatus",
		serviceURL + "SetMode",
		serviceURL + "SetStrategy",
		serviceURL + "CreateManualRoll",
		serviceURL + "Unthrottle",
	}

	return &autoRollServiceProtobufClient{
		client:      client,
		urls:        urls,
		interceptor: twirp.ChainInterceptors(clientOpts.Interceptors...),
		opts:        clientOpts,
	}
}

func (c *autoRollServiceProtobufClient) GetRollers(ctx context.Context, in *GetRollersRequest) (*GetRollersResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "autoroll.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "AutoRollService")
	ctx = ctxsetters.WithMethodName(ctx, "GetRollers")
	caller := c.callGetRollers
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *GetRollersRequest) (*GetRollersResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetRollersRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetRollersRequest) when calling interceptor")
					}
					return c.callGetRollers(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetRollersResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetRollersResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *autoRollServiceProtobufClient) callGetRollers(ctx context.Context, in *GetRollersRequest) (*GetRollersResponse, error) {
	out := new(GetRollersResponse)
	ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}

	callClientResponseReceived(ctx, c.opts.Hooks)

	return out, nil
}

func (c *autoRollServiceProtobufClient) GetMiniStatus(ctx context.Context, in *GetMiniStatusRequest) (*GetMiniStatusResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "autoroll.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "AutoRollService")
	ctx = ctxsetters.WithMethodName(ctx, "GetMiniStatus")
	caller := c.callGetMiniStatus
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *GetMiniStatusRequest) (*GetMiniStatusResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetMiniStatusRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetMiniStatusRequest) when calling interceptor")
					}
					return c.callGetMiniStatus(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetMiniStatusResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetMiniStatusResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *autoRollServiceProtobufClient) callGetMiniStatus(ctx context.Context, in *GetMiniStatusRequest) (*GetMiniStatusResponse, error) {
	out := new(GetMiniStatusResponse)
	ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[1], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}

	callClientResponseReceived(ctx, c.opts.Hooks)

	return out, nil
}

func (c *autoRollServiceProtobufClient) GetStatus(ctx context.Context, in *GetStatusRequest) (*GetStatusResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "autoroll.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "AutoRollService")
	ctx = ctxsetters.WithMethodName(ctx, "GetStatus")
	caller := c.callGetStatus
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *GetStatusRequest) (*GetStatusResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetStatusRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetStatusRequest) when calling interceptor")
					}
					return c.callGetStatus(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetStatusResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetStatusResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *autoRollServiceProtobufClient) callGetStatus(ctx context.Context, in *GetStatusRequest) (*GetStatusResponse, error) {
	out := new(GetStatusResponse)
	ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[2], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}

	callClientResponseReceived(ctx, c.opts.Hooks)

	return out, nil
}

func (c *autoRollServiceProtobufClient) SetMode(ctx context.Context, in *SetModeRequest) (*SetModeResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "autoroll.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "AutoRollService")
	ctx = ctxsetters.WithMethodName(ctx, "SetMode")
	caller := c.callSetMode
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *SetModeRequest) (*SetModeResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*SetModeRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*SetModeRequest) when calling interceptor")
					}
					return c.callSetMode(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*SetModeResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*SetModeResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *autoRollServiceProtobufClient) callSetMode(ctx context.Context, in *SetModeRequest) (*SetModeResponse, error) {
	out := new(SetModeResponse)
	ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[3], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}

	callClientResponseReceived(ctx, c.opts.Hooks)

	return out, nil
}

func (c *autoRollServiceProtobufClient) SetStrategy(ctx context.Context, in *SetStrategyRequest) (*SetStrategyResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "autoroll.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "AutoRollService")
	ctx = ctxsetters.WithMethodName(ctx, "SetStrategy")
	caller := c.callSetStrategy
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *SetStrategyRequest) (*SetStrategyResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*SetStrategyRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*SetStrategyRequest) when calling interceptor")
					}
					return c.callSetStrategy(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*SetStrategyResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*SetStrategyResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *autoRollServiceProtobufClient) callSetStrategy(ctx context.Context, in *SetStrategyRequest) (*SetStrategyResponse, error) {
	out := new(SetStrategyResponse)
	ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[4], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}

	callClientResponseReceived(ctx, c.opts.Hooks)

	return out, nil
}

func (c *autoRollServiceProtobufClient) CreateManualRoll(ctx context.Context, in *CreateManualRollRequest) (*CreateManualRollResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "autoroll.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "AutoRollService")
	ctx = ctxsetters.WithMethodName(ctx, "CreateManualRoll")
	caller := c.callCreateManualRoll
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *CreateManualRollRequest) (*CreateManualRollResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*CreateManualRollRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*CreateManualRollRequest) when calling interceptor")
					}
					return c.callCreateManualRoll(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*CreateManualRollResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*CreateManualRollResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *autoRollServiceProtobufClient) callCreateManualRoll(ctx context.Context, in *CreateManualRollRequest) (*CreateManualRollResponse, error) {
	out := new(CreateManualRollResponse)
	ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[5], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}

	callClientResponseReceived(ctx, c.opts.Hooks)

	return out, nil
}

func (c *autoRollServiceProtobufClient) Unthrottle(ctx context.Context, in *UnthrottleRequest) (*UnthrottleResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "autoroll.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "AutoRollService")
	ctx = ctxsetters.WithMethodName(ctx, "Unthrottle")
	caller := c.callUnthrottle
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *UnthrottleRequest) (*UnthrottleResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*UnthrottleRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*UnthrottleRequest) when calling interceptor")
					}
					return c.callUnthrottle(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*UnthrottleResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*UnthrottleResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *autoRollServiceProtobufClient) callUnthrottle(ctx context.Context, in *UnthrottleRequest) (*UnthrottleResponse, error) {
	out := new(UnthrottleResponse)
	ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[6], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}

	callClientResponseReceived(ctx, c.opts.Hooks)

	return out, nil
}

// ===========================
// AutoRollService JSON Client
// ===========================

type autoRollServiceJSONClient struct {
	client      HTTPClient
	urls        [7]string
	interceptor twirp.Interceptor
	opts        twirp.ClientOptions
}

// NewAutoRollServiceJSONClient creates a JSON client that implements the AutoRollService interface.
// It communicates using JSON and can be configured with a custom HTTPClient.
func NewAutoRollServiceJSONClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) AutoRollService {
	if c, ok := client.(*http.Client); ok {
		client = withoutRedirects(c)
	}

	clientOpts := twirp.ClientOptions{}
	for _, o := range opts {
		o(&clientOpts)
	}

	// Build method URLs: <baseURL>[<prefix>]/<package>.<Service>/<Method>
	serviceURL := sanitizeBaseURL(baseURL)
	serviceURL += baseServicePath(clientOpts.PathPrefix(), "autoroll.rpc", "AutoRollService")
	urls := [7]string{
		serviceURL + "GetRollers",
		serviceURL + "GetMiniStatus",
		serviceURL + "GetStatus",
		serviceURL + "SetMode",
		serviceURL + "SetStrategy",
		serviceURL + "CreateManualRoll",
		serviceURL + "Unthrottle",
	}

	return &autoRollServiceJSONClient{
		client:      client,
		urls:        urls,
		interceptor: twirp.ChainInterceptors(clientOpts.Interceptors...),
		opts:        clientOpts,
	}
}

func (c *autoRollServiceJSONClient) GetRollers(ctx context.Context, in *GetRollersRequest) (*GetRollersResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "autoroll.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "AutoRollService")
	ctx = ctxsetters.WithMethodName(ctx, "GetRollers")
	caller := c.callGetRollers
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *GetRollersRequest) (*GetRollersResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetRollersRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetRollersRequest) when calling interceptor")
					}
					return c.callGetRollers(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetRollersResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetRollersResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *autoRollServiceJSONClient) callGetRollers(ctx context.Context, in *GetRollersRequest) (*GetRollersResponse, error) {
	out := new(GetRollersResponse)
	ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}

	callClientResponseReceived(ctx, c.opts.Hooks)

	return out, nil
}

func (c *autoRollServiceJSONClient) GetMiniStatus(ctx context.Context, in *GetMiniStatusRequest) (*GetMiniStatusResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "autoroll.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "AutoRollService")
	ctx = ctxsetters.WithMethodName(ctx, "GetMiniStatus")
	caller := c.callGetMiniStatus
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *GetMiniStatusRequest) (*GetMiniStatusResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetMiniStatusRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetMiniStatusRequest) when calling interceptor")
					}
					return c.callGetMiniStatus(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetMiniStatusResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetMiniStatusResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *autoRollServiceJSONClient) callGetMiniStatus(ctx context.Context, in *GetMiniStatusRequest) (*GetMiniStatusResponse, error) {
	out := new(GetMiniStatusResponse)
	ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[1], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}

	callClientResponseReceived(ctx, c.opts.Hooks)

	return out, nil
}

func (c *autoRollServiceJSONClient) GetStatus(ctx context.Context, in *GetStatusRequest) (*GetStatusResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "autoroll.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "AutoRollService")
	ctx = ctxsetters.WithMethodName(ctx, "GetStatus")
	caller := c.callGetStatus
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *GetStatusRequest) (*GetStatusResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetStatusRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetStatusRequest) when calling interceptor")
					}
					return c.callGetStatus(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetStatusResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetStatusResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *autoRollServiceJSONClient) callGetStatus(ctx context.Context, in *GetStatusRequest) (*GetStatusResponse, error) {
	out := new(GetStatusResponse)
	ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[2], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}

	callClientResponseReceived(ctx, c.opts.Hooks)

	return out, nil
}

func (c *autoRollServiceJSONClient) SetMode(ctx context.Context, in *SetModeRequest) (*SetModeResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "autoroll.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "AutoRollService")
	ctx = ctxsetters.WithMethodName(ctx, "SetMode")
	caller := c.callSetMode
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *SetModeRequest) (*SetModeResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*SetModeRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*SetModeRequest) when calling interceptor")
					}
					return c.callSetMode(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*SetModeResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*SetModeResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *autoRollServiceJSONClient) callSetMode(ctx context.Context, in *SetModeRequest) (*SetModeResponse, error) {
	out := new(SetModeResponse)
	ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[3], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}

	callClientResponseReceived(ctx, c.opts.Hooks)

	return out, nil
}

func (c *autoRollServiceJSONClient) SetStrategy(ctx context.Context, in *SetStrategyRequest) (*SetStrategyResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "autoroll.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "AutoRollService")
	ctx = ctxsetters.WithMethodName(ctx, "SetStrategy")
	caller := c.callSetStrategy
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *SetStrategyRequest) (*SetStrategyResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*SetStrategyRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*SetStrategyRequest) when calling interceptor")
					}
					return c.callSetStrategy(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*SetStrategyResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*SetStrategyResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *autoRollServiceJSONClient) callSetStrategy(ctx context.Context, in *SetStrategyRequest) (*SetStrategyResponse, error) {
	out := new(SetStrategyResponse)
	ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[4], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}

	callClientResponseReceived(ctx, c.opts.Hooks)

	return out, nil
}

func (c *autoRollServiceJSONClient) CreateManualRoll(ctx context.Context, in *CreateManualRollRequest) (*CreateManualRollResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "autoroll.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "AutoRollService")
	ctx = ctxsetters.WithMethodName(ctx, "CreateManualRoll")
	caller := c.callCreateManualRoll
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *CreateManualRollRequest) (*CreateManualRollResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*CreateManualRollRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*CreateManualRollRequest) when calling interceptor")
					}
					return c.callCreateManualRoll(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*CreateManualRollResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*CreateManualRollResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *autoRollServiceJSONClient) callCreateManualRoll(ctx context.Context, in *CreateManualRollRequest) (*CreateManualRollResponse, error) {
	out := new(CreateManualRollResponse)
	ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[5], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}

	callClientResponseReceived(ctx, c.opts.Hooks)

	return out, nil
}

func (c *autoRollServiceJSONClient) Unthrottle(ctx context.Context, in *UnthrottleRequest) (*UnthrottleResponse, error) {
	ctx = ctxsetters.WithPackageName(ctx, "autoroll.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "AutoRollService")
	ctx = ctxsetters.WithMethodName(ctx, "Unthrottle")
	caller := c.callUnthrottle
	if c.interceptor != nil {
		caller = func(ctx context.Context, req *UnthrottleRequest) (*UnthrottleResponse, error) {
			resp, err := c.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*UnthrottleRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*UnthrottleRequest) when calling interceptor")
					}
					return c.callUnthrottle(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*UnthrottleResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*UnthrottleResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}
	return caller(ctx, in)
}

func (c *autoRollServiceJSONClient) callUnthrottle(ctx context.Context, in *UnthrottleRequest) (*UnthrottleResponse, error) {
	out := new(UnthrottleResponse)
	ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[6], in, out)
	if err != nil {
		twerr, ok := err.(twirp.Error)
		if !ok {
			twerr = twirp.InternalErrorWith(err)
		}
		callClientError(ctx, c.opts.Hooks, twerr)
		return nil, err
	}

	callClientResponseReceived(ctx, c.opts.Hooks)

	return out, nil
}

// ==============================
// AutoRollService Server Handler
// ==============================

type autoRollServiceServer struct {
	AutoRollService
	interceptor      twirp.Interceptor
	hooks            *twirp.ServerHooks
	pathPrefix       string // prefix for routing
	jsonSkipDefaults bool   // do not include unpopulated fields (default values) in the response
}

// NewAutoRollServiceServer builds a TwirpServer that can be used as an http.Handler to handle
// HTTP requests that are routed to the right method in the provided svc implementation.
// The opts are twirp.ServerOption modifiers, for example twirp.WithServerHooks(hooks).
func NewAutoRollServiceServer(svc AutoRollService, opts ...interface{}) TwirpServer {
	serverOpts := twirp.ServerOptions{}
	for _, opt := range opts {
		switch o := opt.(type) {
		case twirp.ServerOption:
			o(&serverOpts)
		case *twirp.ServerHooks: // backwards compatibility, allow to specify hooks as an argument
			twirp.WithServerHooks(o)(&serverOpts)
		case nil: // backwards compatibility, allow nil value for the argument
			continue
		default:
			panic(fmt.Sprintf("Invalid option type %T on NewAutoRollServiceServer", o))
		}
	}

	return &autoRollServiceServer{
		AutoRollService:  svc,
		pathPrefix:       serverOpts.PathPrefix(),
		interceptor:      twirp.ChainInterceptors(serverOpts.Interceptors...),
		hooks:            serverOpts.Hooks,
		jsonSkipDefaults: serverOpts.JSONSkipDefaults,
	}
}

// writeError writes an HTTP response with a valid Twirp error format, and triggers hooks.
// If err is not a twirp.Error, it will get wrapped with twirp.InternalErrorWith(err)
func (s *autoRollServiceServer) writeError(ctx context.Context, resp http.ResponseWriter, err error) {
	writeError(ctx, resp, err, s.hooks)
}

// AutoRollServicePathPrefix is a convenience constant that could used to identify URL paths.
// Should be used with caution, it only matches routes generated by Twirp Go clients,
// that add a "/twirp" prefix by default, and use CamelCase service and method names.
// More info: https://twitchtv.github.io/twirp/docs/routing.html
const AutoRollServicePathPrefix = "/twirp/autoroll.rpc.AutoRollService/"

func (s *autoRollServiceServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
	ctx := req.Context()
	ctx = ctxsetters.WithPackageName(ctx, "autoroll.rpc")
	ctx = ctxsetters.WithServiceName(ctx, "AutoRollService")
	ctx = ctxsetters.WithResponseWriter(ctx, resp)

	var err error
	ctx, err = callRequestReceived(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	if req.Method != "POST" {
		msg := fmt.Sprintf("unsupported method %q (only POST is allowed)", req.Method)
		s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path))
		return
	}

	// Verify path format: [<prefix>]/<package>.<Service>/<Method>
	prefix, pkgService, method := parseTwirpPath(req.URL.Path)
	if pkgService != "autoroll.rpc.AutoRollService" {
		msg := fmt.Sprintf("no handler for path %q", req.URL.Path)
		s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path))
		return
	}
	if prefix != s.pathPrefix {
		msg := fmt.Sprintf("invalid path prefix %q, expected %q, on path %q", prefix, s.pathPrefix, req.URL.Path)
		s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path))
		return
	}

	switch method {
	case "GetRollers":
		s.serveGetRollers(ctx, resp, req)
		return
	case "GetMiniStatus":
		s.serveGetMiniStatus(ctx, resp, req)
		return
	case "GetStatus":
		s.serveGetStatus(ctx, resp, req)
		return
	case "SetMode":
		s.serveSetMode(ctx, resp, req)
		return
	case "SetStrategy":
		s.serveSetStrategy(ctx, resp, req)
		return
	case "CreateManualRoll":
		s.serveCreateManualRoll(ctx, resp, req)
		return
	case "Unthrottle":
		s.serveUnthrottle(ctx, resp, req)
		return
	default:
		msg := fmt.Sprintf("no handler for path %q", req.URL.Path)
		s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path))
		return
	}
}

func (s *autoRollServiceServer) serveGetRollers(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	header := req.Header.Get("Content-Type")
	i := strings.Index(header, ";")
	if i == -1 {
		i = len(header)
	}
	switch strings.TrimSpace(strings.ToLower(header[:i])) {
	case "application/json":
		s.serveGetRollersJSON(ctx, resp, req)
	case "application/protobuf":
		s.serveGetRollersProtobuf(ctx, resp, req)
	default:
		msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type"))
		twerr := badRouteError(msg, req.Method, req.URL.Path)
		s.writeError(ctx, resp, twerr)
	}
}

func (s *autoRollServiceServer) serveGetRollersJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "GetRollers")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	reqContent := new(GetRollersRequest)
	unmarshaler := jsonpb.Unmarshaler{AllowUnknownFields: true}
	if err = unmarshaler.Unmarshal(req.Body, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the json request could not be decoded"))
		return
	}

	handler := s.AutoRollService.GetRollers
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *GetRollersRequest) (*GetRollersResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetRollersRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetRollersRequest) when calling interceptor")
					}
					return s.AutoRollService.GetRollers(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetRollersResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetRollersResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *GetRollersResponse
	func() {
		defer ensurePanicResponses(ctx, resp, s.hooks)
		respContent, err = handler(ctx, reqContent)
	}()

	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *GetRollersResponse and nil error while calling GetRollers. nil responses are not supported"))
		return
	}

	ctx = callResponsePrepared(ctx, s.hooks)

	var buf bytes.Buffer
	marshaler := &jsonpb.Marshaler{OrigName: true, EmitDefaults: !s.jsonSkipDefaults}
	if err = marshaler.Marshal(&buf, respContent); err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response"))
		return
	}

	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	respBytes := buf.Bytes()
	resp.Header().Set("Content-Type", "application/json")
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
	resp.WriteHeader(http.StatusOK)

	if n, err := resp.Write(respBytes); err != nil {
		msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
		twerr := twirp.NewError(twirp.Unknown, msg)
		ctx = callError(ctx, s.hooks, twerr)
	}
	callResponseSent(ctx, s.hooks)
}

func (s *autoRollServiceServer) serveGetRollersProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "GetRollers")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	buf, err := ioutil.ReadAll(req.Body)
	if err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to read request body"))
		return
	}
	reqContent := new(GetRollersRequest)
	if err = proto.Unmarshal(buf, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
		return
	}

	handler := s.AutoRollService.GetRollers
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *GetRollersRequest) (*GetRollersResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetRollersRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetRollersRequest) when calling interceptor")
					}
					return s.AutoRollService.GetRollers(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetRollersResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetRollersResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *GetRollersResponse
	func() {
		defer ensurePanicResponses(ctx, resp, s.hooks)
		respContent, err = handler(ctx, reqContent)
	}()

	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *GetRollersResponse and nil error while calling GetRollers. nil responses are not supported"))
		return
	}

	ctx = callResponsePrepared(ctx, s.hooks)

	respBytes, err := proto.Marshal(respContent)
	if err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response"))
		return
	}

	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	resp.Header().Set("Content-Type", "application/protobuf")
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
	resp.WriteHeader(http.StatusOK)
	if n, err := resp.Write(respBytes); err != nil {
		msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
		twerr := twirp.NewError(twirp.Unknown, msg)
		ctx = callError(ctx, s.hooks, twerr)
	}
	callResponseSent(ctx, s.hooks)
}

func (s *autoRollServiceServer) serveGetMiniStatus(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	header := req.Header.Get("Content-Type")
	i := strings.Index(header, ";")
	if i == -1 {
		i = len(header)
	}
	switch strings.TrimSpace(strings.ToLower(header[:i])) {
	case "application/json":
		s.serveGetMiniStatusJSON(ctx, resp, req)
	case "application/protobuf":
		s.serveGetMiniStatusProtobuf(ctx, resp, req)
	default:
		msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type"))
		twerr := badRouteError(msg, req.Method, req.URL.Path)
		s.writeError(ctx, resp, twerr)
	}
}

func (s *autoRollServiceServer) serveGetMiniStatusJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "GetMiniStatus")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	reqContent := new(GetMiniStatusRequest)
	unmarshaler := jsonpb.Unmarshaler{AllowUnknownFields: true}
	if err = unmarshaler.Unmarshal(req.Body, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the json request could not be decoded"))
		return
	}

	handler := s.AutoRollService.GetMiniStatus
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *GetMiniStatusRequest) (*GetMiniStatusResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetMiniStatusRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetMiniStatusRequest) when calling interceptor")
					}
					return s.AutoRollService.GetMiniStatus(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetMiniStatusResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetMiniStatusResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *GetMiniStatusResponse
	func() {
		defer ensurePanicResponses(ctx, resp, s.hooks)
		respContent, err = handler(ctx, reqContent)
	}()

	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *GetMiniStatusResponse and nil error while calling GetMiniStatus. nil responses are not supported"))
		return
	}

	ctx = callResponsePrepared(ctx, s.hooks)

	var buf bytes.Buffer
	marshaler := &jsonpb.Marshaler{OrigName: true, EmitDefaults: !s.jsonSkipDefaults}
	if err = marshaler.Marshal(&buf, respContent); err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response"))
		return
	}

	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	respBytes := buf.Bytes()
	resp.Header().Set("Content-Type", "application/json")
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
	resp.WriteHeader(http.StatusOK)

	if n, err := resp.Write(respBytes); err != nil {
		msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
		twerr := twirp.NewError(twirp.Unknown, msg)
		ctx = callError(ctx, s.hooks, twerr)
	}
	callResponseSent(ctx, s.hooks)
}

func (s *autoRollServiceServer) serveGetMiniStatusProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "GetMiniStatus")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	buf, err := ioutil.ReadAll(req.Body)
	if err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to read request body"))
		return
	}
	reqContent := new(GetMiniStatusRequest)
	if err = proto.Unmarshal(buf, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
		return
	}

	handler := s.AutoRollService.GetMiniStatus
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *GetMiniStatusRequest) (*GetMiniStatusResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetMiniStatusRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetMiniStatusRequest) when calling interceptor")
					}
					return s.AutoRollService.GetMiniStatus(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetMiniStatusResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetMiniStatusResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *GetMiniStatusResponse
	func() {
		defer ensurePanicResponses(ctx, resp, s.hooks)
		respContent, err = handler(ctx, reqContent)
	}()

	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *GetMiniStatusResponse and nil error while calling GetMiniStatus. nil responses are not supported"))
		return
	}

	ctx = callResponsePrepared(ctx, s.hooks)

	respBytes, err := proto.Marshal(respContent)
	if err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response"))
		return
	}

	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	resp.Header().Set("Content-Type", "application/protobuf")
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
	resp.WriteHeader(http.StatusOK)
	if n, err := resp.Write(respBytes); err != nil {
		msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
		twerr := twirp.NewError(twirp.Unknown, msg)
		ctx = callError(ctx, s.hooks, twerr)
	}
	callResponseSent(ctx, s.hooks)
}

func (s *autoRollServiceServer) serveGetStatus(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	header := req.Header.Get("Content-Type")
	i := strings.Index(header, ";")
	if i == -1 {
		i = len(header)
	}
	switch strings.TrimSpace(strings.ToLower(header[:i])) {
	case "application/json":
		s.serveGetStatusJSON(ctx, resp, req)
	case "application/protobuf":
		s.serveGetStatusProtobuf(ctx, resp, req)
	default:
		msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type"))
		twerr := badRouteError(msg, req.Method, req.URL.Path)
		s.writeError(ctx, resp, twerr)
	}
}

func (s *autoRollServiceServer) serveGetStatusJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "GetStatus")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	reqContent := new(GetStatusRequest)
	unmarshaler := jsonpb.Unmarshaler{AllowUnknownFields: true}
	if err = unmarshaler.Unmarshal(req.Body, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the json request could not be decoded"))
		return
	}

	handler := s.AutoRollService.GetStatus
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *GetStatusRequest) (*GetStatusResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetStatusRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetStatusRequest) when calling interceptor")
					}
					return s.AutoRollService.GetStatus(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetStatusResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetStatusResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *GetStatusResponse
	func() {
		defer ensurePanicResponses(ctx, resp, s.hooks)
		respContent, err = handler(ctx, reqContent)
	}()

	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *GetStatusResponse and nil error while calling GetStatus. nil responses are not supported"))
		return
	}

	ctx = callResponsePrepared(ctx, s.hooks)

	var buf bytes.Buffer
	marshaler := &jsonpb.Marshaler{OrigName: true, EmitDefaults: !s.jsonSkipDefaults}
	if err = marshaler.Marshal(&buf, respContent); err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response"))
		return
	}

	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	respBytes := buf.Bytes()
	resp.Header().Set("Content-Type", "application/json")
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
	resp.WriteHeader(http.StatusOK)

	if n, err := resp.Write(respBytes); err != nil {
		msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
		twerr := twirp.NewError(twirp.Unknown, msg)
		ctx = callError(ctx, s.hooks, twerr)
	}
	callResponseSent(ctx, s.hooks)
}

func (s *autoRollServiceServer) serveGetStatusProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "GetStatus")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	buf, err := ioutil.ReadAll(req.Body)
	if err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to read request body"))
		return
	}
	reqContent := new(GetStatusRequest)
	if err = proto.Unmarshal(buf, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
		return
	}

	handler := s.AutoRollService.GetStatus
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *GetStatusRequest) (*GetStatusResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*GetStatusRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*GetStatusRequest) when calling interceptor")
					}
					return s.AutoRollService.GetStatus(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*GetStatusResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*GetStatusResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *GetStatusResponse
	func() {
		defer ensurePanicResponses(ctx, resp, s.hooks)
		respContent, err = handler(ctx, reqContent)
	}()

	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *GetStatusResponse and nil error while calling GetStatus. nil responses are not supported"))
		return
	}

	ctx = callResponsePrepared(ctx, s.hooks)

	respBytes, err := proto.Marshal(respContent)
	if err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response"))
		return
	}

	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	resp.Header().Set("Content-Type", "application/protobuf")
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
	resp.WriteHeader(http.StatusOK)
	if n, err := resp.Write(respBytes); err != nil {
		msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
		twerr := twirp.NewError(twirp.Unknown, msg)
		ctx = callError(ctx, s.hooks, twerr)
	}
	callResponseSent(ctx, s.hooks)
}

func (s *autoRollServiceServer) serveSetMode(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	header := req.Header.Get("Content-Type")
	i := strings.Index(header, ";")
	if i == -1 {
		i = len(header)
	}
	switch strings.TrimSpace(strings.ToLower(header[:i])) {
	case "application/json":
		s.serveSetModeJSON(ctx, resp, req)
	case "application/protobuf":
		s.serveSetModeProtobuf(ctx, resp, req)
	default:
		msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type"))
		twerr := badRouteError(msg, req.Method, req.URL.Path)
		s.writeError(ctx, resp, twerr)
	}
}

func (s *autoRollServiceServer) serveSetModeJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "SetMode")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	reqContent := new(SetModeRequest)
	unmarshaler := jsonpb.Unmarshaler{AllowUnknownFields: true}
	if err = unmarshaler.Unmarshal(req.Body, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the json request could not be decoded"))
		return
	}

	handler := s.AutoRollService.SetMode
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *SetModeRequest) (*SetModeResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*SetModeRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*SetModeRequest) when calling interceptor")
					}
					return s.AutoRollService.SetMode(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*SetModeResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*SetModeResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *SetModeResponse
	func() {
		defer ensurePanicResponses(ctx, resp, s.hooks)
		respContent, err = handler(ctx, reqContent)
	}()

	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *SetModeResponse and nil error while calling SetMode. nil responses are not supported"))
		return
	}

	ctx = callResponsePrepared(ctx, s.hooks)

	var buf bytes.Buffer
	marshaler := &jsonpb.Marshaler{OrigName: true, EmitDefaults: !s.jsonSkipDefaults}
	if err = marshaler.Marshal(&buf, respContent); err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response"))
		return
	}

	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	respBytes := buf.Bytes()
	resp.Header().Set("Content-Type", "application/json")
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
	resp.WriteHeader(http.StatusOK)

	if n, err := resp.Write(respBytes); err != nil {
		msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
		twerr := twirp.NewError(twirp.Unknown, msg)
		ctx = callError(ctx, s.hooks, twerr)
	}
	callResponseSent(ctx, s.hooks)
}

func (s *autoRollServiceServer) serveSetModeProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "SetMode")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	buf, err := ioutil.ReadAll(req.Body)
	if err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to read request body"))
		return
	}
	reqContent := new(SetModeRequest)
	if err = proto.Unmarshal(buf, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
		return
	}

	handler := s.AutoRollService.SetMode
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *SetModeRequest) (*SetModeResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*SetModeRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*SetModeRequest) when calling interceptor")
					}
					return s.AutoRollService.SetMode(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*SetModeResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*SetModeResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *SetModeResponse
	func() {
		defer ensurePanicResponses(ctx, resp, s.hooks)
		respContent, err = handler(ctx, reqContent)
	}()

	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *SetModeResponse and nil error while calling SetMode. nil responses are not supported"))
		return
	}

	ctx = callResponsePrepared(ctx, s.hooks)

	respBytes, err := proto.Marshal(respContent)
	if err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response"))
		return
	}

	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	resp.Header().Set("Content-Type", "application/protobuf")
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
	resp.WriteHeader(http.StatusOK)
	if n, err := resp.Write(respBytes); err != nil {
		msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
		twerr := twirp.NewError(twirp.Unknown, msg)
		ctx = callError(ctx, s.hooks, twerr)
	}
	callResponseSent(ctx, s.hooks)
}

func (s *autoRollServiceServer) serveSetStrategy(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	header := req.Header.Get("Content-Type")
	i := strings.Index(header, ";")
	if i == -1 {
		i = len(header)
	}
	switch strings.TrimSpace(strings.ToLower(header[:i])) {
	case "application/json":
		s.serveSetStrategyJSON(ctx, resp, req)
	case "application/protobuf":
		s.serveSetStrategyProtobuf(ctx, resp, req)
	default:
		msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type"))
		twerr := badRouteError(msg, req.Method, req.URL.Path)
		s.writeError(ctx, resp, twerr)
	}
}

func (s *autoRollServiceServer) serveSetStrategyJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "SetStrategy")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	reqContent := new(SetStrategyRequest)
	unmarshaler := jsonpb.Unmarshaler{AllowUnknownFields: true}
	if err = unmarshaler.Unmarshal(req.Body, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the json request could not be decoded"))
		return
	}

	handler := s.AutoRollService.SetStrategy
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *SetStrategyRequest) (*SetStrategyResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*SetStrategyRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*SetStrategyRequest) when calling interceptor")
					}
					return s.AutoRollService.SetStrategy(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*SetStrategyResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*SetStrategyResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *SetStrategyResponse
	func() {
		defer ensurePanicResponses(ctx, resp, s.hooks)
		respContent, err = handler(ctx, reqContent)
	}()

	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *SetStrategyResponse and nil error while calling SetStrategy. nil responses are not supported"))
		return
	}

	ctx = callResponsePrepared(ctx, s.hooks)

	var buf bytes.Buffer
	marshaler := &jsonpb.Marshaler{OrigName: true, EmitDefaults: !s.jsonSkipDefaults}
	if err = marshaler.Marshal(&buf, respContent); err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response"))
		return
	}

	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	respBytes := buf.Bytes()
	resp.Header().Set("Content-Type", "application/json")
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
	resp.WriteHeader(http.StatusOK)

	if n, err := resp.Write(respBytes); err != nil {
		msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
		twerr := twirp.NewError(twirp.Unknown, msg)
		ctx = callError(ctx, s.hooks, twerr)
	}
	callResponseSent(ctx, s.hooks)
}

func (s *autoRollServiceServer) serveSetStrategyProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "SetStrategy")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	buf, err := ioutil.ReadAll(req.Body)
	if err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to read request body"))
		return
	}
	reqContent := new(SetStrategyRequest)
	if err = proto.Unmarshal(buf, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
		return
	}

	handler := s.AutoRollService.SetStrategy
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *SetStrategyRequest) (*SetStrategyResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*SetStrategyRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*SetStrategyRequest) when calling interceptor")
					}
					return s.AutoRollService.SetStrategy(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*SetStrategyResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*SetStrategyResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *SetStrategyResponse
	func() {
		defer ensurePanicResponses(ctx, resp, s.hooks)
		respContent, err = handler(ctx, reqContent)
	}()

	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *SetStrategyResponse and nil error while calling SetStrategy. nil responses are not supported"))
		return
	}

	ctx = callResponsePrepared(ctx, s.hooks)

	respBytes, err := proto.Marshal(respContent)
	if err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response"))
		return
	}

	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	resp.Header().Set("Content-Type", "application/protobuf")
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
	resp.WriteHeader(http.StatusOK)
	if n, err := resp.Write(respBytes); err != nil {
		msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
		twerr := twirp.NewError(twirp.Unknown, msg)
		ctx = callError(ctx, s.hooks, twerr)
	}
	callResponseSent(ctx, s.hooks)
}

func (s *autoRollServiceServer) serveCreateManualRoll(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	header := req.Header.Get("Content-Type")
	i := strings.Index(header, ";")
	if i == -1 {
		i = len(header)
	}
	switch strings.TrimSpace(strings.ToLower(header[:i])) {
	case "application/json":
		s.serveCreateManualRollJSON(ctx, resp, req)
	case "application/protobuf":
		s.serveCreateManualRollProtobuf(ctx, resp, req)
	default:
		msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type"))
		twerr := badRouteError(msg, req.Method, req.URL.Path)
		s.writeError(ctx, resp, twerr)
	}
}

func (s *autoRollServiceServer) serveCreateManualRollJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "CreateManualRoll")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	reqContent := new(CreateManualRollRequest)
	unmarshaler := jsonpb.Unmarshaler{AllowUnknownFields: true}
	if err = unmarshaler.Unmarshal(req.Body, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the json request could not be decoded"))
		return
	}

	handler := s.AutoRollService.CreateManualRoll
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *CreateManualRollRequest) (*CreateManualRollResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*CreateManualRollRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*CreateManualRollRequest) when calling interceptor")
					}
					return s.AutoRollService.CreateManualRoll(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*CreateManualRollResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*CreateManualRollResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *CreateManualRollResponse
	func() {
		defer ensurePanicResponses(ctx, resp, s.hooks)
		respContent, err = handler(ctx, reqContent)
	}()

	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *CreateManualRollResponse and nil error while calling CreateManualRoll. nil responses are not supported"))
		return
	}

	ctx = callResponsePrepared(ctx, s.hooks)

	var buf bytes.Buffer
	marshaler := &jsonpb.Marshaler{OrigName: true, EmitDefaults: !s.jsonSkipDefaults}
	if err = marshaler.Marshal(&buf, respContent); err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response"))
		return
	}

	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	respBytes := buf.Bytes()
	resp.Header().Set("Content-Type", "application/json")
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
	resp.WriteHeader(http.StatusOK)

	if n, err := resp.Write(respBytes); err != nil {
		msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
		twerr := twirp.NewError(twirp.Unknown, msg)
		ctx = callError(ctx, s.hooks, twerr)
	}
	callResponseSent(ctx, s.hooks)
}

func (s *autoRollServiceServer) serveCreateManualRollProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "CreateManualRoll")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	buf, err := ioutil.ReadAll(req.Body)
	if err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to read request body"))
		return
	}
	reqContent := new(CreateManualRollRequest)
	if err = proto.Unmarshal(buf, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
		return
	}

	handler := s.AutoRollService.CreateManualRoll
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *CreateManualRollRequest) (*CreateManualRollResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*CreateManualRollRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*CreateManualRollRequest) when calling interceptor")
					}
					return s.AutoRollService.CreateManualRoll(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*CreateManualRollResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*CreateManualRollResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *CreateManualRollResponse
	func() {
		defer ensurePanicResponses(ctx, resp, s.hooks)
		respContent, err = handler(ctx, reqContent)
	}()

	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *CreateManualRollResponse and nil error while calling CreateManualRoll. nil responses are not supported"))
		return
	}

	ctx = callResponsePrepared(ctx, s.hooks)

	respBytes, err := proto.Marshal(respContent)
	if err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response"))
		return
	}

	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	resp.Header().Set("Content-Type", "application/protobuf")
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
	resp.WriteHeader(http.StatusOK)
	if n, err := resp.Write(respBytes); err != nil {
		msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
		twerr := twirp.NewError(twirp.Unknown, msg)
		ctx = callError(ctx, s.hooks, twerr)
	}
	callResponseSent(ctx, s.hooks)
}

func (s *autoRollServiceServer) serveUnthrottle(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	header := req.Header.Get("Content-Type")
	i := strings.Index(header, ";")
	if i == -1 {
		i = len(header)
	}
	switch strings.TrimSpace(strings.ToLower(header[:i])) {
	case "application/json":
		s.serveUnthrottleJSON(ctx, resp, req)
	case "application/protobuf":
		s.serveUnthrottleProtobuf(ctx, resp, req)
	default:
		msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type"))
		twerr := badRouteError(msg, req.Method, req.URL.Path)
		s.writeError(ctx, resp, twerr)
	}
}

func (s *autoRollServiceServer) serveUnthrottleJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "Unthrottle")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	reqContent := new(UnthrottleRequest)
	unmarshaler := jsonpb.Unmarshaler{AllowUnknownFields: true}
	if err = unmarshaler.Unmarshal(req.Body, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the json request could not be decoded"))
		return
	}

	handler := s.AutoRollService.Unthrottle
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *UnthrottleRequest) (*UnthrottleResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*UnthrottleRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*UnthrottleRequest) when calling interceptor")
					}
					return s.AutoRollService.Unthrottle(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*UnthrottleResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*UnthrottleResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *UnthrottleResponse
	func() {
		defer ensurePanicResponses(ctx, resp, s.hooks)
		respContent, err = handler(ctx, reqContent)
	}()

	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *UnthrottleResponse and nil error while calling Unthrottle. nil responses are not supported"))
		return
	}

	ctx = callResponsePrepared(ctx, s.hooks)

	var buf bytes.Buffer
	marshaler := &jsonpb.Marshaler{OrigName: true, EmitDefaults: !s.jsonSkipDefaults}
	if err = marshaler.Marshal(&buf, respContent); err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response"))
		return
	}

	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	respBytes := buf.Bytes()
	resp.Header().Set("Content-Type", "application/json")
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
	resp.WriteHeader(http.StatusOK)

	if n, err := resp.Write(respBytes); err != nil {
		msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
		twerr := twirp.NewError(twirp.Unknown, msg)
		ctx = callError(ctx, s.hooks, twerr)
	}
	callResponseSent(ctx, s.hooks)
}

func (s *autoRollServiceServer) serveUnthrottleProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) {
	var err error
	ctx = ctxsetters.WithMethodName(ctx, "Unthrottle")
	ctx, err = callRequestRouted(ctx, s.hooks)
	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}

	buf, err := ioutil.ReadAll(req.Body)
	if err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to read request body"))
		return
	}
	reqContent := new(UnthrottleRequest)
	if err = proto.Unmarshal(buf, reqContent); err != nil {
		s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded"))
		return
	}

	handler := s.AutoRollService.Unthrottle
	if s.interceptor != nil {
		handler = func(ctx context.Context, req *UnthrottleRequest) (*UnthrottleResponse, error) {
			resp, err := s.interceptor(
				func(ctx context.Context, req interface{}) (interface{}, error) {
					typedReq, ok := req.(*UnthrottleRequest)
					if !ok {
						return nil, twirp.InternalError("failed type assertion req.(*UnthrottleRequest) when calling interceptor")
					}
					return s.AutoRollService.Unthrottle(ctx, typedReq)
				},
			)(ctx, req)
			if resp != nil {
				typedResp, ok := resp.(*UnthrottleResponse)
				if !ok {
					return nil, twirp.InternalError("failed type assertion resp.(*UnthrottleResponse) when calling interceptor")
				}
				return typedResp, err
			}
			return nil, err
		}
	}

	// Call service method
	var respContent *UnthrottleResponse
	func() {
		defer ensurePanicResponses(ctx, resp, s.hooks)
		respContent, err = handler(ctx, reqContent)
	}()

	if err != nil {
		s.writeError(ctx, resp, err)
		return
	}
	if respContent == nil {
		s.writeError(ctx, resp, twirp.InternalError("received a nil *UnthrottleResponse and nil error while calling Unthrottle. nil responses are not supported"))
		return
	}

	ctx = callResponsePrepared(ctx, s.hooks)

	respBytes, err := proto.Marshal(respContent)
	if err != nil {
		s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response"))
		return
	}

	ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK)
	resp.Header().Set("Content-Type", "application/protobuf")
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes)))
	resp.WriteHeader(http.StatusOK)
	if n, err := resp.Write(respBytes); err != nil {
		msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error())
		twerr := twirp.NewError(twirp.Unknown, msg)
		ctx = callError(ctx, s.hooks, twerr)
	}
	callResponseSent(ctx, s.hooks)
}

func (s *autoRollServiceServer) ServiceDescriptor() ([]byte, int) {
	return twirpFileDescriptor0, 0
}

func (s *autoRollServiceServer) ProtocGenTwirpVersion() string {
	return "v7.1.0"
}

// PathPrefix returns the base service path, in the form: "/<prefix>/<package>.<Service>/"
// that is everything in a Twirp route except for the <Method>. This can be used for routing,
// for example to identify the requests that are targeted to this service in a mux.
func (s *autoRollServiceServer) PathPrefix() string {
	return baseServicePath(s.pathPrefix, "autoroll.rpc", "AutoRollService")
}

// =====
// Utils
// =====

// HTTPClient is the interface used by generated clients to send HTTP requests.
// It is fulfilled by *(net/http).Client, which is sufficient for most users.
// Users can provide their own implementation for special retry policies.
//
// HTTPClient implementations should not follow redirects. Redirects are
// automatically disabled if *(net/http).Client is passed to client
// constructors. See the withoutRedirects function in this file for more
// details.
type HTTPClient interface {
	Do(req *http.Request) (*http.Response, error)
}

// TwirpServer is the interface generated server structs will support: they're
// HTTP handlers with additional methods for accessing metadata about the
// service. Those accessors are a low-level API for building reflection tools.
// Most people can think of TwirpServers as just http.Handlers.
type TwirpServer interface {
	http.Handler

	// ServiceDescriptor returns gzipped bytes describing the .proto file that
	// this service was generated from. Once unzipped, the bytes can be
	// unmarshalled as a
	// github.com/golang/protobuf/protoc-gen-go/descriptor.FileDescriptorProto.
	//
	// The returned integer is the index of this particular service within that
	// FileDescriptorProto's 'Service' slice of ServiceDescriptorProtos. This is a
	// low-level field, expected to be used for reflection.
	ServiceDescriptor() ([]byte, int)

	// ProtocGenTwirpVersion is the semantic version string of the version of
	// twirp used to generate this file.
	ProtocGenTwirpVersion() string

	// PathPrefix returns the HTTP URL path prefix for all methods handled by this
	// service. This can be used with an HTTP mux to route Twirp requests.
	// The path prefix is in the form: "/<prefix>/<package>.<Service>/"
	// that is, everything in a Twirp route except for the <Method> at the end.
	PathPrefix() string
}

// WriteError writes an HTTP response with a valid Twirp error format (code, msg, meta).
// Useful outside of the Twirp server (e.g. http middleware), but does not trigger hooks.
// If err is not a twirp.Error, it will get wrapped with twirp.InternalErrorWith(err)
func WriteError(resp http.ResponseWriter, err error) {
	writeError(context.Background(), resp, err, nil)
}

// writeError writes Twirp errors in the response and triggers hooks.
func writeError(ctx context.Context, resp http.ResponseWriter, err error, hooks *twirp.ServerHooks) {
	// Non-twirp errors are wrapped as Internal (default)
	twerr, ok := err.(twirp.Error)
	if !ok {
		twerr = twirp.InternalErrorWith(err)
	}

	statusCode := twirp.ServerHTTPStatusFromErrorCode(twerr.Code())
	ctx = ctxsetters.WithStatusCode(ctx, statusCode)
	ctx = callError(ctx, hooks, twerr)

	respBody := marshalErrorToJSON(twerr)

	resp.Header().Set("Content-Type", "application/json") // Error responses are always JSON
	resp.Header().Set("Content-Length", strconv.Itoa(len(respBody)))
	resp.WriteHeader(statusCode) // set HTTP status code and send response

	_, writeErr := resp.Write(respBody)
	if writeErr != nil {
		// We have three options here. We could log the error, call the Error
		// hook, or just silently ignore the error.
		//
		// Logging is unacceptable because we don't have a user-controlled
		// logger; writing out to stderr without permission is too rude.
		//
		// Calling the Error hook would confuse users: it would mean the Error
		// hook got called twice for one request, which is likely to lead to
		// duplicated log messages and metrics, no matter how well we document
		// the behavior.
		//
		// Silently ignoring the error is our least-bad option. It's highly
		// likely that the connection is broken and the original 'err' says
		// so anyway.
		_ = writeErr
	}

	callResponseSent(ctx, hooks)
}

// sanitizeBaseURL parses the the baseURL, and adds the "http" scheme if needed.
// If the URL is unparsable, the baseURL is returned unchaged.
func sanitizeBaseURL(baseURL string) string {
	u, err := url.Parse(baseURL)
	if err != nil {
		return baseURL // invalid URL will fail later when making requests
	}
	if u.Scheme == "" {
		u.Scheme = "http"
	}
	return u.String()
}

// baseServicePath composes the path prefix for the service (without <Method>).
// e.g.: baseServicePath("/twirp", "my.pkg", "MyService")
//       returns => "/twirp/my.pkg.MyService/"
// e.g.: baseServicePath("", "", "MyService")
//       returns => "/MyService/"
func baseServicePath(prefix, pkg, service string) string {
	fullServiceName := service
	if pkg != "" {
		fullServiceName = pkg + "." + service
	}
	return path.Join("/", prefix, fullServiceName) + "/"
}

// parseTwirpPath extracts path components form a valid Twirp route.
// Expected format: "[<prefix>]/<package>.<Service>/<Method>"
// e.g.: prefix, pkgService, method := parseTwirpPath("/twirp/pkg.Svc/MakeHat")
func parseTwirpPath(path string) (string, string, string) {
	parts := strings.Split(path, "/")
	if len(parts) < 2 {
		return "", "", ""
	}
	method := parts[len(parts)-1]
	pkgService := parts[len(parts)-2]
	prefix := strings.Join(parts[0:len(parts)-2], "/")
	return prefix, pkgService, method
}

// getCustomHTTPReqHeaders retrieves a copy of any headers that are set in
// a context through the twirp.WithHTTPRequestHeaders function.
// If there are no headers set, or if they have the wrong type, nil is returned.
func getCustomHTTPReqHeaders(ctx context.Context) http.Header {
	header, ok := twirp.HTTPRequestHeaders(ctx)
	if !ok || header == nil {
		return nil
	}
	copied := make(http.Header)
	for k, vv := range header {
		if vv == nil {
			copied[k] = nil
			continue
		}
		copied[k] = make([]string, len(vv))
		copy(copied[k], vv)
	}
	return copied
}

// newRequest makes an http.Request from a client, adding common headers.
func newRequest(ctx context.Context, url string, reqBody io.Reader, contentType string) (*http.Request, error) {
	req, err := http.NewRequest("POST", url, reqBody)
	if err != nil {
		return nil, err
	}
	req = req.WithContext(ctx)
	if customHeader := getCustomHTTPReqHeaders(ctx); customHeader != nil {
		req.Header = customHeader
	}
	req.Header.Set("Accept", contentType)
	req.Header.Set("Content-Type", contentType)
	req.Header.Set("Twirp-Version", "v7.1.0")
	return req, nil
}

// JSON serialization for errors
type twerrJSON struct {
	Code string            `json:"code"`
	Msg  string            `json:"msg"`
	Meta map[string]string `json:"meta,omitempty"`
}

// marshalErrorToJSON returns JSON from a twirp.Error, that can be used as HTTP error response body.
// If serialization fails, it will use a descriptive Internal error instead.
func marshalErrorToJSON(twerr twirp.Error) []byte {
	// make sure that msg is not too large
	msg := twerr.Msg()
	if len(msg) > 1e6 {
		msg = msg[:1e6]
	}

	tj := twerrJSON{
		Code: string(twerr.Code()),
		Msg:  msg,
		Meta: twerr.MetaMap(),
	}

	buf, err := json.Marshal(&tj)
	if err != nil {
		buf = []byte("{\"type\": \"" + twirp.Internal + "\", \"msg\": \"There was an error but it could not be serialized into JSON\"}") // fallback
	}

	return buf
}

// errorFromResponse builds a twirp.Error from a non-200 HTTP response.
// If the response has a valid serialized Twirp error, then it's returned.
// If not, the response status code is used to generate a similar twirp
// error. See twirpErrorFromIntermediary for more info on intermediary errors.
func errorFromResponse(resp *http.Response) twirp.Error {
	statusCode := resp.StatusCode
	statusText := http.StatusText(statusCode)

	if isHTTPRedirect(statusCode) {
		// Unexpected redirect: it must be an error from an intermediary.
		// Twirp clients don't follow redirects automatically, Twirp only handles
		// POST requests, redirects should only happen on GET and HEAD requests.
		location := resp.Header.Get("Location")
		msg := fmt.Sprintf("unexpected HTTP status code %d %q received, Location=%q", statusCode, statusText, location)
		return twirpErrorFromIntermediary(statusCode, msg, location)
	}

	respBodyBytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return wrapInternal(err, "failed to read server error response body")
	}

	var tj twerrJSON
	dec := json.NewDecoder(bytes.NewReader(respBodyBytes))
	dec.DisallowUnknownFields()
	if err := dec.Decode(&tj); err != nil || tj.Code == "" {
		// Invalid JSON response; it must be an error from an intermediary.
		msg := fmt.Sprintf("Error from intermediary with HTTP status code %d %q", statusCode, statusText)
		return twirpErrorFromIntermediary(statusCode, msg, string(respBodyBytes))
	}

	errorCode := twirp.ErrorCode(tj.Code)
	if !twirp.IsValidErrorCode(errorCode) {
		msg := "invalid type returned from server error response: " + tj.Code
		return twirp.InternalError(msg).WithMeta("body", string(respBodyBytes))
	}

	twerr := twirp.NewError(errorCode, tj.Msg)
	for k, v := range tj.Meta {
		twerr = twerr.WithMeta(k, v)
	}
	return twerr
}

// twirpErrorFromIntermediary maps HTTP errors from non-twirp sources to twirp errors.
// The mapping is similar to gRPC: https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md.
// Returned twirp Errors have some additional metadata for inspection.
func twirpErrorFromIntermediary(status int, msg string, bodyOrLocation string) twirp.Error {
	var code twirp.ErrorCode
	if isHTTPRedirect(status) { // 3xx
		code = twirp.Internal
	} else {
		switch status {
		case 400: // Bad Request
			code = twirp.Internal
		case 401: // Unauthorized
			code = twirp.Unauthenticated
		case 403: // Forbidden
			code = twirp.PermissionDenied
		case 404: // Not Found
			code = twirp.BadRoute
		case 429: // Too Many Requests
			code = twirp.ResourceExhausted
		case 502, 503, 504: // Bad Gateway, Service Unavailable, Gateway Timeout
			code = twirp.Unavailable
		default: // All other codes
			code = twirp.Unknown
		}
	}

	twerr := twirp.NewError(code, msg)
	twerr = twerr.WithMeta("http_error_from_intermediary", "true") // to easily know if this error was from intermediary
	twerr = twerr.WithMeta("status_code", strconv.Itoa(status))
	if isHTTPRedirect(status) {
		twerr = twerr.WithMeta("location", bodyOrLocation)
	} else {
		twerr = twerr.WithMeta("body", bodyOrLocation)
	}
	return twerr
}

func isHTTPRedirect(status int) bool {
	return status >= 300 && status <= 399
}

// wrapInternal wraps an error with a prefix as an Internal error.
// The original error cause is accessible by github.com/pkg/errors.Cause.
func wrapInternal(err error, prefix string) twirp.Error {
	return twirp.InternalErrorWith(&wrappedError{prefix: prefix, cause: err})
}

type wrappedError struct {
	prefix string
	cause  error
}

func (e *wrappedError) Error() string { return e.prefix + ": " + e.cause.Error() }
func (e *wrappedError) Unwrap() error { return e.cause } // for go1.13 + errors.Is/As
func (e *wrappedError) Cause() error  { return e.cause } // for github.com/pkg/errors

// ensurePanicResponses makes sure that rpc methods causing a panic still result in a Twirp Internal
// error response (status 500), and error hooks are properly called with the panic wrapped as an error.
// The panic is re-raised so it can be handled normally with middleware.
func ensurePanicResponses(ctx context.Context, resp http.ResponseWriter, hooks *twirp.ServerHooks) {
	if r := recover(); r != nil {
		// Wrap the panic as an error so it can be passed to error hooks.
		// The original error is accessible from error hooks, but not visible in the response.
		err := errFromPanic(r)
		twerr := &internalWithCause{msg: "Internal service panic", cause: err}
		// Actually write the error
		writeError(ctx, resp, twerr, hooks)
		// If possible, flush the error to the wire.
		f, ok := resp.(http.Flusher)
		if ok {
			f.Flush()
		}

		panic(r)
	}
}

// errFromPanic returns the typed error if the recovered panic is an error, otherwise formats as error.
func errFromPanic(p interface{}) error {
	if err, ok := p.(error); ok {
		return err
	}
	return fmt.Errorf("panic: %v", p)
}

// internalWithCause is a Twirp Internal error wrapping an original error cause,
// but the original error message is not exposed on Msg(). The original error
// can be checked with go1.13+ errors.Is/As, and also by (github.com/pkg/errors).Unwrap
type internalWithCause struct {
	msg   string
	cause error
}

func (e *internalWithCause) Unwrap() error                               { return e.cause } // for go1.13 + errors.Is/As
func (e *internalWithCause) Cause() error                                { return e.cause } // for github.com/pkg/errors
func (e *internalWithCause) Error() string                               { return e.msg + ": " + e.cause.Error() }
func (e *internalWithCause) Code() twirp.ErrorCode                       { return twirp.Internal }
func (e *internalWithCause) Msg() string                                 { return e.msg }
func (e *internalWithCause) Meta(key string) string                      { return "" }
func (e *internalWithCause) MetaMap() map[string]string                  { return nil }
func (e *internalWithCause) WithMeta(key string, val string) twirp.Error { return e }

// malformedRequestError is used when the twirp server cannot unmarshal a request
func malformedRequestError(msg string) twirp.Error {
	return twirp.NewError(twirp.Malformed, msg)
}

// badRouteError is used when the twirp server cannot route a request
func badRouteError(msg string, method, url string) twirp.Error {
	err := twirp.NewError(twirp.BadRoute, msg)
	err = err.WithMeta("twirp_invalid_route", method+" "+url)
	return err
}

// withoutRedirects makes sure that the POST request can not be redirected.
// The standard library will, by default, redirect requests (including POSTs) if it gets a 302 or
// 303 response, and also 301s in go1.8. It redirects by making a second request, changing the
// method to GET and removing the body. This produces very confusing error messages, so instead we
// set a redirect policy that always errors. This stops Go from executing the redirect.
//
// We have to be a little careful in case the user-provided http.Client has its own CheckRedirect
// policy - if so, we'll run through that policy first.
//
// Because this requires modifying the http.Client, we make a new copy of the client and return it.
func withoutRedirects(in *http.Client) *http.Client {
	copy := *in
	copy.CheckRedirect = func(req *http.Request, via []*http.Request) error {
		if in.CheckRedirect != nil {
			// Run the input's redirect if it exists, in case it has side effects, but ignore any error it
			// returns, since we want to use ErrUseLastResponse.
			err := in.CheckRedirect(req, via)
			_ = err // Silly, but this makes sure generated code passes errcheck -blank, which some people use.
		}
		return http.ErrUseLastResponse
	}
	return &copy
}

// doProtobufRequest makes a Protobuf request to the remote Twirp service.
func doProtobufRequest(ctx context.Context, client HTTPClient, hooks *twirp.ClientHooks, url string, in, out proto.Message) (_ context.Context, err error) {
	reqBodyBytes, err := proto.Marshal(in)
	if err != nil {
		return ctx, wrapInternal(err, "failed to marshal proto request")
	}
	reqBody := bytes.NewBuffer(reqBodyBytes)
	if err = ctx.Err(); err != nil {
		return ctx, wrapInternal(err, "aborted because context was done")
	}

	req, err := newRequest(ctx, url, reqBody, "application/protobuf")
	if err != nil {
		return ctx, wrapInternal(err, "could not build request")
	}
	ctx, err = callClientRequestPrepared(ctx, hooks, req)
	if err != nil {
		return ctx, err
	}

	req = req.WithContext(ctx)
	resp, err := client.Do(req)
	if err != nil {
		return ctx, wrapInternal(err, "failed to do request")
	}

	defer func() {
		cerr := resp.Body.Close()
		if err == nil && cerr != nil {
			err = wrapInternal(cerr, "failed to close response body")
		}
	}()

	if err = ctx.Err(); err != nil {
		return ctx, wrapInternal(err, "aborted because context was done")
	}

	if resp.StatusCode != 200 {
		return ctx, errorFromResponse(resp)
	}

	respBodyBytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return ctx, wrapInternal(err, "failed to read response body")
	}
	if err = ctx.Err(); err != nil {
		return ctx, wrapInternal(err, "aborted because context was done")
	}

	if err = proto.Unmarshal(respBodyBytes, out); err != nil {
		return ctx, wrapInternal(err, "failed to unmarshal proto response")
	}
	return ctx, nil
}

// doJSONRequest makes a JSON request to the remote Twirp service.
func doJSONRequest(ctx context.Context, client HTTPClient, hooks *twirp.ClientHooks, url string, in, out proto.Message) (_ context.Context, err error) {
	reqBody := bytes.NewBuffer(nil)
	marshaler := &jsonpb.Marshaler{OrigName: true}
	if err = marshaler.Marshal(reqBody, in); err != nil {
		return ctx, wrapInternal(err, "failed to marshal json request")
	}
	if err = ctx.Err(); err != nil {
		return ctx, wrapInternal(err, "aborted because context was done")
	}

	req, err := newRequest(ctx, url, reqBody, "application/json")
	if err != nil {
		return ctx, wrapInternal(err, "could not build request")
	}
	ctx, err = callClientRequestPrepared(ctx, hooks, req)
	if err != nil {
		return ctx, err
	}

	req = req.WithContext(ctx)
	resp, err := client.Do(req)
	if err != nil {
		return ctx, wrapInternal(err, "failed to do request")
	}

	defer func() {
		cerr := resp.Body.Close()
		if err == nil && cerr != nil {
			err = wrapInternal(cerr, "failed to close response body")
		}
	}()

	if err = ctx.Err(); err != nil {
		return ctx, wrapInternal(err, "aborted because context was done")
	}

	if resp.StatusCode != 200 {
		return ctx, errorFromResponse(resp)
	}

	unmarshaler := jsonpb.Unmarshaler{AllowUnknownFields: true}
	if err = unmarshaler.Unmarshal(resp.Body, out); err != nil {
		return ctx, wrapInternal(err, "failed to unmarshal json response")
	}
	if err = ctx.Err(); err != nil {
		return ctx, wrapInternal(err, "aborted because context was done")
	}
	return ctx, nil
}

// Call twirp.ServerHooks.RequestReceived if the hook is available
func callRequestReceived(ctx context.Context, h *twirp.ServerHooks) (context.Context, error) {
	if h == nil || h.RequestReceived == nil {
		return ctx, nil
	}
	return h.RequestReceived(ctx)
}

// Call twirp.ServerHooks.RequestRouted if the hook is available
func callRequestRouted(ctx context.Context, h *twirp.ServerHooks) (context.Context, error) {
	if h == nil || h.RequestRouted == nil {
		return ctx, nil
	}
	return h.RequestRouted(ctx)
}

// Call twirp.ServerHooks.ResponsePrepared if the hook is available
func callResponsePrepared(ctx context.Context, h *twirp.ServerHooks) context.Context {
	if h == nil || h.ResponsePrepared == nil {
		return ctx
	}
	return h.ResponsePrepared(ctx)
}

// Call twirp.ServerHooks.ResponseSent if the hook is available
func callResponseSent(ctx context.Context, h *twirp.ServerHooks) {
	if h == nil || h.ResponseSent == nil {
		return
	}
	h.ResponseSent(ctx)
}

// Call twirp.ServerHooks.Error if the hook is available
func callError(ctx context.Context, h *twirp.ServerHooks, err twirp.Error) context.Context {
	if h == nil || h.Error == nil {
		return ctx
	}
	return h.Error(ctx, err)
}

func callClientResponseReceived(ctx context.Context, h *twirp.ClientHooks) {
	if h == nil || h.ResponseReceived == nil {
		return
	}
	h.ResponseReceived(ctx)
}

func callClientRequestPrepared(ctx context.Context, h *twirp.ClientHooks, req *http.Request) (context.Context, error) {
	if h == nil || h.RequestPrepared == nil {
		return ctx, nil
	}
	return h.RequestPrepared(ctx, req)
}

func callClientError(ctx context.Context, h *twirp.ClientHooks, err twirp.Error) {
	if h == nil || h.Error == nil {
		return
	}
	h.Error(ctx, err)
}

var twirpFileDescriptor0 = []byte{
	// 1689 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0xdd, 0x72, 0xe3, 0x48,
	0x15, 0xc6, 0x3f, 0xf1, 0xcf, 0x51, 0xe2, 0x78, 0x3a, 0xd9, 0x1d, 0xe1, 0xdd, 0x61, 0x32, 0x5a,
	0x98, 0x0a, 0x5b, 0x5b, 0x36, 0x78, 0x06, 0x76, 0x6a, 0xb7, 0xb8, 0x48, 0x1c, 0xe7, 0x87, 0xf5,
	0x38, 0x41, 0x8e, 0x6b, 0x80, 0x1b, 0x95, 0x6c, 0xb5, 0x1d, 0xed, 0x48, 0x6a, 0xd3, 0x2d, 0x65,
	0xca, 0x57, 0xbc, 0x06, 0x2f, 0x40, 0x15, 0x77, 0x3c, 0x02, 0xb7, 0x3c, 0x03, 0xcf, 0xc0, 0x0b,
	0x50, 0xdc, 0x50, 0xdd, 0xea, 0x96, 0x65, 0x39, 0x76, 0xbc, 0x6c, 0xed, 0x95, 0xd5, 0xe7, 0x7c,
	0xa7, 0xfb, 0xf4, 0xf9, 0xf9, 0x4e, 0x1b, 0xaa, 0x74, 0x36, 0x6e, 0xce, 0x28, 0x09, 0x09, 0xda,
	0xb5, 0xa3, 0x90, 0x50, 0xe2, 0x79, 0x4d, 0x3a, 0x1b, 0x37, 0x9e, 0x4f, 0x09, 0x99, 0x7a, 0xb8,
	0x25, 0x74, 0xa3, 0x68, 0xd2, 0x0a, 0x5d, 0x1f, 0xb3, 0xd0, 0xf6, 0x67, 0x31, 0xdc, 0xf8, 0x6b,
	0x1e, 0xd0, 0x49, 0x14, 0x12, 0x93, 0x78, 0xde, 0x5b, 0x37, 0x70, 0x07, 0xa1, 0x1d, 0x46, 0x0c,
	0x7d, 0x02, 0x55, 0xbe, 0x07, 0xa6, 0x96, 0xeb, 0xe8, 0xb9, 0xa3, 0xdc, 0x71, 0xd5, 0xac, 0xc4,
	0x82, 0x2b, 0x07, 0x3d, 0x03, 0x18, 0xdf, 0xb9, 0x9e, 0x63, 0x05, 0xb6, 0x8f, 0xf5, 0xbc, 0xd0,
	0x56, 0x85, 0xa4, 0x6f, 0xfb, 0x18, 0x3d, 0x07, 0x6d, 0x66, 0x53, 0x1c, 0x84, 0xb1, 0xbe, 0x20,
	0xf4, 0x10, 0x8b, 0x04, 0xe0, 0x25, 0x14, 0x7d, 0xe2, 0x60, 0xbd, 0x78, 0x94, 0x3b, 0xae, 0xb5,
	0x51, 0x33, 0xed, 0x71, 0xf3, 0x2d, 0x71, 0xb0, 0x29, 0xf4, 0xe8, 0x18, 0xea, 0xe3, 0x88, 0x8a,
	0x9d, 0xb8, 0xda, 0xa2, 0xf8, 0x5e, 0xdf, 0x11, 0xbb, 0xd5, 0xa4, 0x9c, 0x7b, 0x6d, 0xe2, 0x7b,
	0x64, 0xc0, 0x9e, 0x67, 0xb3, 0x14, 0xac, 0x24, 0x60, 0x1a, 0x17, 0x2a, 0xcc, 0x33, 0x80, 0x20,
	0xf2, 0xad, 0x89, 0xed, 0x7a, 0xd8, 0xd1, 0xcb, 0x47, 0xb9, 0xe3, 0x1d, 0xb3, 0x1a, 0x44, 0xfe,
	0xb9, 0x10, 0x28, 0xf5, 0x08, 0xdf, 0xb9, 0x81, 0xa3, 0x57, 0x12, 0xf5, 0xa9, 0x10, 0x18, 0x7f,
	0xcb, 0x43, 0xe9, 0x96, 0xce, 0x7f, 0x4b, 0x46, 0x08, 0x41, 0x51, 0x5c, 0x2c, 0x0e, 0x8b, 0xf8,
	0x46, 0xaf, 0xa0, 0xc4, 0x44, 0xe4, 0x44, 0x38, 0x6a, 0xed, 0x4f, 0x96, 0x2f, 0x15, 0x5b, 0x36,
	0xe3, 0xe0, 0x9a, 0x12, 0xca, 0x8d, 0x28, 0x66, 0x91, 0x17, 0x8a, 0x18, 0xad, 0x33, 0x32, 0x05,
	0xc4, 0x94, 0x50, 0x54, 0x87, 0x42, 0x44, 0x3d, 0x11, 0xbb, 0xaa, 0xc9, 0x3f, 0x51, 0x03, 0x2a,
	0x63, 0x3b, 0xc4, 0x53, 0x42, 0xe7, 0x32, 0x3c, 0xc9, 0xda, 0xf8, 0x0d, 0x94, 0x62, 0x7b, 0xa4,
	0x41, 0x79, 0xd8, 0xff, 0xa6, 0x7f, 0xfd, 0xae, 0x5f, 0xff, 0x11, 0x5f, 0x0c, 0x86, 0x9d, 0x4e,
	0x77, 0x30, 0xa8, 0xe7, 0xf8, 0xe2, 0xfc, 0xe4, 0xaa, 0x37, 0x34, 0xbb, 0xf5, 0x3c, 0xda, 0x85,
	0x4a, 0xe7, 0xa4, 0xdf, 0xe9, 0xf6, 0xba, 0x67, 0xf5, 0x82, 0xf1, 0x0a, 0x4a, 0xb2, 0x20, 0xf6,
	0xa0, 0x3a, 0xe8, 0x5c, 0x76, 0xcf, 0x86, 0x5c, 0x11, 0x6f, 0x70, 0x7b, 0x62, 0xde, 0x76, 0xcf,
	0xea, 0x39, 0xae, 0xeb, 0x5c, 0xbf, 0xbd, 0xe9, 0x75, 0xf9, 0x32, 0x6f, 0xfc, 0xb3, 0x00, 0xa0,
	0x4a, 0xaa, 0xd3, 0x43, 0x35, 0xc8, 0x27, 0x35, 0x94, 0x77, 0x1d, 0xf4, 0x65, 0x72, 0xeb, 0x38,
	0x54, 0xcf, 0x97, 0x6f, 0xbd, 0xb0, 0xcc, 0xde, 0x5c, 0x87, 0x32, 0x8b, 0x46, 0xdf, 0xe2, 0x71,
	0x28, 0x6b, 0x4a, 0x2d, 0x79, 0xee, 0xb8, 0xbd, 0x1b, 0x4c, 0xad, 0x90, 0xc8, 0xd0, 0x54, 0xa5,
	0xe4, 0x96, 0xa0, 0x17, 0xb0, 0xab, 0xd4, 0x13, 0x4a, 0x7c, 0x19, 0x24, 0x4d, 0xca, 0xce, 0x29,
	0xf1, 0xd1, 0x6b, 0x28, 0x8f, 0x29, 0xb6, 0x43, 0xec, 0x88, 0xd2, 0xd1, 0xda, 0x8d, 0x66, 0xdc,
	0x39, 0x4d, 0xd5, 0x39, 0xcd, 0x5b, 0xd5, 0x39, 0xa6, 0x82, 0xa2, 0x5f, 0x43, 0xc5, 0x27, 0x8e,
	0x3b, 0x71, 0x65, 0x41, 0x6d, 0x36, 0x4b, 0xb0, 0xa8, 0x05, 0x95, 0x90, 0xce, 0xad, 0x6f, 0xc9,
	0x88, 0xe9, 0x95, 0xa3, 0xc2, 0xb1, 0xd6, 0x3e, 0x7c, 0x28, 0xf5, 0x66, 0x39, 0x14, 0xbf, 0xcc,
	0xb8, 0x4f, 0xd2, 0xb8, 0x0f, 0xda, 0x55, 0xdf, 0xba, 0x31, 0xaf, 0x2f, 0x4c, 0x9e, 0xbd, 0x4d,
	0xa9, 0x7c, 0x0a, 0x07, 0x67, 0xe6, 0x1f, 0x2c, 0x73, 0xd8, 0xb7, 0xd2, 0x26, 0x05, 0x74, 0x00,
	0xfb, 0x4a, 0xa1, 0x4c, 0x8b, 0x69, 0xa1, 0xda, 0x62, 0xc7, 0xf8, 0x4b, 0x0e, 0x2a, 0x26, 0xbe,
	0x77, 0x99, 0x4b, 0x82, 0x95, 0x44, 0xea, 0x50, 0x76, 0x5c, 0x36, 0xf3, 0xec, 0xb9, 0xe4, 0x00,
	0xb5, 0x44, 0x47, 0xa0, 0x39, 0x98, 0x8d, 0xa9, 0x3b, 0x0b, 0x5d, 0x12, 0xc8, 0x6c, 0xa5, 0x45,
	0xa8, 0x09, 0x45, 0xce, 0x44, 0x22, 0x57, 0x9b, 0xa3, 0x26, 0x70, 0xaa, 0xea, 0x77, 0x92, 0xaa,
	0x37, 0xfe, 0x9b, 0x83, 0x5a, 0x52, 0x2b, 0x24, 0x98, 0xb8, 0x53, 0xf4, 0x53, 0xa8, 0xc5, 0xbc,
	0x34, 0x8a, 0xa6, 0x96, 0xe7, 0x06, 0xef, 0x25, 0x7e, 0x57, 0x48, 0x4f, 0xa3, 0x69, 0xcf, 0x0d,
	0xde, 0xa3, 0x97, 0xb0, 0x2f, 0xe9, 0x29, 0x81, 0xc5, 0x6c, 0xb1, 0x17, 0x8b, 0x15, 0xee, 0xe7,
	0x50, 0x97, 0xb8, 0x0f, 0x76, 0x88, 0xe9, 0xc4, 0xf6, 0x3c, 0x79, 0x79, 0x69, 0xff, 0x4e, 0x89,
	0x97, 0xd9, 0x32, 0x9f, 0x61, 0xcb, 0x36, 0x7c, 0xc4, 0xa2, 0xd9, 0x8c, 0xd0, 0x90, 0x59, 0xbe,
	0x1d, 0x44, 0xb6, 0x27, 0x68, 0x8a, 0x89, 0xb0, 0x54, 0xcc, 0x03, 0xa5, 0x7c, 0x2b, 0x74, 0xfc,
	0x3a, 0x8c, 0x53, 0x28, 0xbf, 0xb6, 0xf5, 0xc1, 0x0d, 0x1c, 0xf2, 0x41, 0x56, 0x34, 0x70, 0xd1,
	0x3b, 0x21, 0x31, 0xfe, 0x9e, 0x03, 0xe0, 0x4c, 0xd9, 0xb9, 0xb3, 0x83, 0x29, 0xde, 0x4c, 0xd7,
	0x8a, 0x6e, 0xf3, 0x8f, 0xd0, 0x2d, 0x82, 0x62, 0xc4, 0x30, 0x95, 0xe9, 0x12, 0xdf, 0xdf, 0x39,
	0x4f, 0x3a, 0x94, 0x7d, 0xcc, 0x98, 0x3d, 0xc5, 0x32, 0xf6, 0x6a, 0x69, 0xfc, 0x23, 0x07, 0xb5,
	0x41, 0x48, 0x39, 0x31, 0xcd, 0xb7, 0xf1, 0xba, 0x0d, 0x15, 0x26, 0xe1, 0xd2, 0xf3, 0x8f, 0x97,
	0x3d, 0x57, 0x9b, 0x99, 0x09, 0xee, 0x07, 0xbe, 0xc1, 0x7f, 0x0a, 0x00, 0x8b, 0x24, 0xad, 0xb4,
	0xc3, 0xc6, 0x22, 0x68, 0x40, 0x85, 0xca, 0x3e, 0x92, 0xde, 0x25, 0x6b, 0xf4, 0x29, 0x54, 0x29,
	0xfe, 0x53, 0x84, 0x59, 0x88, 0x69, 0x42, 0x5e, 0x4a, 0x90, 0xa2, 0xcb, 0x9d, 0x87, 0xe8, 0x72,
	0xe1, 0x50, 0x96, 0x2e, 0xbf, 0x4c, 0x46, 0x52, 0xe9, 0x11, 0xc3, 0xcc, 0x58, 0x7a, 0x03, 0xd5,
	0xe4, 0x95, 0xb0, 0x05, 0xad, 0x2d, 0xc0, 0xaa, 0x4b, 0x2b, 0x8b, 0xd9, 0xf4, 0x14, 0xca, 0x0e,
	0x9d, 0x5b, 0x34, 0x0a, 0xf4, 0xaa, 0x28, 0xf7, 0x92, 0x43, 0xe7, 0x66, 0x14, 0xa0, 0x1f, 0x43,
	0x25, 0x20, 0x16, 0xf6, 0x6d, 0xd7, 0xd3, 0x41, 0x68, 0xca, 0x01, 0xe9, 0xf2, 0x25, 0x6a, 0xc2,
	0x41, 0x40, 0x2c, 0x8a, 0x19, 0xf1, 0xee, 0xb1, 0x95, 0x84, 0x4d, 0x13, 0xa8, 0x27, 0x01, 0x31,
	0x63, 0x8d, 0xe2, 0x25, 0xa3, 0xb5, 0x76, 0xc6, 0x29, 0x22, 0xcb, 0xa5, 0x59, 0x32, 0x6f, 0xfc,
	0x32, 0x99, 0x6a, 0x1a, 0x94, 0x6f, 0xba, 0xfd, 0xb3, 0xab, 0xfe, 0xc5, 0x23, 0x33, 0xed, 0xdf,
	0x3b, 0x0b, 0xb6, 0x91, 0xb6, 0x27, 0xa0, 0xf9, 0x6e, 0xe0, 0x5a, 0x32, 0xc8, 0x39, 0x11, 0xa8,
	0xa3, 0x87, 0x87, 0xd9, 0xe2, 0x65, 0x65, 0x82, 0xbf, 0x78, 0x65, 0x7d, 0xbc, 0xf4, 0x6a, 0xa8,
	0x26, 0x19, 0x78, 0x0d, 0xa5, 0xb1, 0xa0, 0x34, 0x51, 0x2b, 0x5a, 0xfb, 0xd3, 0x35, 0x23, 0x52,
	0x60, 0x4c, 0x89, 0xe5, 0xcf, 0xa5, 0x49, 0xe4, 0x79, 0xd6, 0x9d, 0xcb, 0x42, 0x42, 0xe7, 0xd6,
	0xe2, 0x99, 0x50, 0xe3, 0xf2, 0xcb, 0x58, 0x3c, 0xa4, 0x1e, 0x27, 0x4a, 0x97, 0xb1, 0x08, 0x73,
	0x88, 0x35, 0xb2, 0x99, 0x2a, 0xf5, 0x5d, 0x21, 0x1d, 0x52, 0xef, 0xd4, 0x66, 0x18, 0x7d, 0x21,
	0x79, 0x23, 0x1e, 0x88, 0xfa, 0x2a, 0x6f, 0xc4, 0x6d, 0x2c, 0xd9, 0xe3, 0x4d, 0xaa, 0x5f, 0xcb,
	0x0f, 0x79, 0xbd, 0xdc, 0xfc, 0xa9, 0xae, 0xbd, 0x84, 0xc3, 0x80, 0xc4, 0x6f, 0x37, 0xec, 0x24,
	0xf9, 0x56, 0x93, 0x31, 0xd3, 0xf5, 0x2a, 0xeb, 0x26, 0x0a, 0x88, 0x78, 0xda, 0x61, 0x47, 0x89,
	0x18, 0xfa, 0x1a, 0x76, 0xd3, 0x0f, 0x46, 0x51, 0x72, 0x2b, 0x9e, 0x2f, 0x1e, 0x18, 0xa6, 0x96,
	0x7a, 0x46, 0xa2, 0x5f, 0x41, 0x35, 0x79, 0x43, 0x8a, 0x92, 0xdc, 0x64, 0x59, 0x51, 0x2f, 0x4b,
	0x7e, 0x26, 0xc5, 0x63, 0x75, 0x24, 0xd3, 0x35, 0xe1, 0xf5, 0x86, 0x33, 0x63, 0x74, 0xcc, 0xf3,
	0x5f, 0xc3, 0xee, 0xd2, 0x48, 0xd8, 0x7d, 0xc8, 0x78, 0xd1, 0xa9, 0xa6, 0xe6, 0xa7, 0x86, 0xc4,
	0x21, 0xec, 0x60, 0x4a, 0x09, 0xd5, 0xf7, 0x44, 0xf2, 0xe2, 0x05, 0xea, 0xc0, 0x7e, 0x78, 0x47,
	0x49, 0x18, 0xf2, 0x60, 0x46, 0x41, 0xe8, 0x7a, 0x7a, 0xed, 0xd1, 0x1e, 0xae, 0x25, 0x26, 0x43,
	0x6e, 0x61, 0x1c, 0xc0, 0x93, 0x0b, 0x1c, 0x87, 0x97, 0x32, 0x33, 0xe6, 0x22, 0xe3, 0x06, 0x50,
	0x5a, 0xc8, 0x66, 0x24, 0x60, 0x18, 0x7d, 0x05, 0xe5, 0x98, 0xe5, 0x78, 0x0b, 0x14, 0xb6, 0x6a,
	0x01, 0x65, 0x60, 0xbc, 0x82, 0xc3, 0x0b, 0x1c, 0xa6, 0x34, 0xf1, 0x49, 0x1b, 0x07, 0x83, 0xf1,
	0x3b, 0xf8, 0x28, 0x63, 0x24, 0x3d, 0x79, 0x93, 0x74, 0xd3, 0xb6, 0xbd, 0x28, 0xf1, 0x46, 0x0b,
	0xea, 0x17, 0x38, 0xfc, 0x0e, 0x3e, 0x5c, 0x89, 0xf8, 0x64, 0xce, 0x7f, 0x9d, 0x39, 0x7f, 0x4d,
	0xd7, 0x66, 0xce, 0x26, 0x50, 0x1b, 0xe0, 0x50, 0x8c, 0xe1, 0x2d, 0x4e, 0xde, 0x7a, 0x98, 0xa7,
	0xc6, 0x58, 0x71, 0x79, 0x8c, 0x5d, 0xc0, 0x7e, 0x72, 0xe0, 0xf7, 0xf2, 0xfc, 0xcf, 0x80, 0x06,
	0x3c, 0x08, 0x72, 0x0c, 0x6f, 0xe3, 0xfd, 0xff, 0x33, 0xd4, 0xd7, 0xdf, 0xe4, 0x1b, 0x38, 0x58,
	0x72, 0xe0, 0x7b, 0xdd, 0xe6, 0x3d, 0x3c, 0xed, 0x88, 0x67, 0x7d, 0xaa, 0xdd, 0xb6, 0xb9, 0x52,
	0x7a, 0xb2, 0xe7, 0x33, 0x93, 0x3d, 0x35, 0xfd, 0x0a, 0xe9, 0xe9, 0x67, 0x5c, 0x82, 0xbe, 0x7a,
	0x98, 0x74, 0xff, 0x0b, 0x28, 0x0a, 0x0a, 0xca, 0x3d, 0x48, 0xbb, 0x0b, 0xbc, 0x40, 0x19, 0xbf,
	0x80, 0x27, 0xc3, 0x40, 0x75, 0xef, 0x56, 0xb5, 0x7b, 0x08, 0x28, 0x6d, 0x11, 0x9f, 0xfa, 0xf9,
	0x57, 0x50, 0xe4, 0x25, 0xc1, 0x87, 0xa0, 0x39, 0xec, 0xf7, 0x53, 0x13, 0xf1, 0xfa, 0xe6, 0x46,
	0x4c, 0x44, 0x0d, 0xca, 0xf2, 0x0f, 0x42, 0x3d, 0xcf, 0x17, 0xd7, 0xe7, 0xe7, 0xbd, 0xab, 0x7e,
	0xb7, 0x5e, 0xf8, 0xbc, 0x09, 0x15, 0x95, 0x04, 0x54, 0x85, 0x9d, 0xd3, 0x93, 0xdb, 0xce, 0x65,
	0x6c, 0xdd, 0xb7, 0xe2, 0x45, 0x0e, 0x01, 0x94, 0x06, 0x57, 0xfd, 0x8b, 0x5e, 0xb7, 0x9e, 0x6f,
	0xff, 0xab, 0x08, 0xfb, 0x49, 0x16, 0x30, 0xbd, 0x77, 0xc7, 0x18, 0x5d, 0x03, 0x2c, 0xc8, 0x05,
	0x65, 0xde, 0x2a, 0x2b, 0x5c, 0xd4, 0x38, 0x5a, 0x0f, 0x90, 0x61, 0xfc, 0x3d, 0xec, 0x2d, 0xd1,
	0x04, 0x32, 0x56, 0x4c, 0x56, 0x88, 0xa7, 0xf1, 0xd9, 0x46, 0x8c, 0xdc, 0xb9, 0x07, 0xd5, 0xa4,
	0xf9, 0xd1, 0x4f, 0x56, 0x2c, 0x96, 0x77, 0x7c, 0xbe, 0x56, 0x2f, 0x77, 0x3b, 0x87, 0xb2, 0x6c,
	0x47, 0x94, 0x1d, 0x98, 0x4b, 0xb4, 0xd0, 0x78, 0xb6, 0x46, 0x2b, 0xf7, 0x31, 0x41, 0x4b, 0x35,
	0x03, 0x3a, 0x5a, 0x41, 0x67, 0x1a, 0xb5, 0xf1, 0x62, 0x03, 0x42, 0xee, 0x69, 0x43, 0x3d, 0x5b,
	0xa6, 0xe8, 0x67, 0xcb, 0x66, 0x6b, 0x7a, 0xa6, 0xf1, 0xf2, 0x31, 0x98, 0x3c, 0xe2, 0x1a, 0x60,
	0x51, 0x8d, 0xd9, 0xbc, 0xaf, 0x54, 0x76, 0x36, 0xef, 0xab, 0x85, 0x7c, 0xfa, 0xd9, 0x1f, 0x5f,
	0x4c, 0x49, 0x93, 0xbd, 0x77, 0xed, 0x26, 0xa1, 0xd3, 0x96, 0x1b, 0x4c, 0xa8, 0xdd, 0x52, 0x46,
	0xad, 0x29, 0x69, 0xd1, 0xd9, 0x78, 0x54, 0x12, 0x33, 0xf0, 0xd5, 0xff, 0x02, 0x00, 0x00, 0xff,
	0xff, 0xde, 0x16, 0x71, 0x3d, 0x38, 0x13, 0x00, 0x00,
}
