texttospeech

package
v0.0.0-...-0e82294 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 25, 2018 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var AudioEncoding_name = map[int32]string{
	0: "AUDIO_ENCODING_UNSPECIFIED",
	1: "LINEAR16",
	2: "MP3",
	3: "OGG_OPUS",
}
View Source
var AudioEncoding_value = map[string]int32{
	"AUDIO_ENCODING_UNSPECIFIED": 0,
	"LINEAR16":                   1,
	"MP3":                        2,
	"OGG_OPUS":                   3,
}
View Source
var SsmlVoiceGender_name = map[int32]string{
	0: "SSML_VOICE_GENDER_UNSPECIFIED",
	1: "MALE",
	2: "FEMALE",
	3: "NEUTRAL",
}
View Source
var SsmlVoiceGender_value = map[string]int32{
	"SSML_VOICE_GENDER_UNSPECIFIED": 0,
	"MALE":                          1,
	"FEMALE":                        2,
	"NEUTRAL":                       3,
}

Functions

func RegisterTextToSpeechServer

func RegisterTextToSpeechServer(s *grpc.Server, srv TextToSpeechServer)

Types

type AudioConfig

type AudioConfig struct {
	// Required. The format of the requested audio byte stream.
	AudioEncoding AudioEncoding `` /* 149-byte string literal not displayed */
	// Optional speaking rate/speed, in the range [0.25, 4.0]. 1.0 is the normal
	// native speed supported by the specific voice. 2.0 is twice as fast, and
	// 0.5 is half as fast. If unset(0.0), defaults to the native 1.0 speed. Any
	// other values < 0.25 or > 4.0 will return an error.
	SpeakingRate float64 `protobuf:"fixed64,2,opt,name=speaking_rate,json=speakingRate,proto3" json:"speaking_rate,omitempty"`
	// Optional speaking pitch, in the range [-20.0, 20.0]. 20 means increase 20
	// semitones from the original pitch. -20 means decrease 20 semitones from the
	// original pitch.
	Pitch float64 `protobuf:"fixed64,3,opt,name=pitch,proto3" json:"pitch,omitempty"`
	// Optional volume gain (in dB) of the normal native volume supported by the
	// specific voice, in the range [-96.0, 16.0]. If unset, or set to a value of
	// 0.0 (dB), will play at normal native signal amplitude. A value of -6.0 (dB)
	// will play at approximately half the amplitude of the normal native signal
	// amplitude. A value of +6.0 (dB) will play at approximately twice the
	// amplitude of the normal native signal amplitude. Strongly recommend not to
	// exceed +10 (dB) as there's usually no effective increase in loudness for
	// any value greater than that.
	VolumeGainDb float64 `protobuf:"fixed64,4,opt,name=volume_gain_db,json=volumeGainDb,proto3" json:"volume_gain_db,omitempty"`
	// The synthesis sample rate (in hertz) for this audio. Optional.  If this is
	// different from the voice's natural sample rate, then the synthesizer will
	// honor this request by converting to the desired sample rate (which might
	// result in worse audio quality), unless the specified sample rate is not
	// supported for the encoding chosen, in which case it will fail the request
	// and return [google.rpc.Code.INVALID_ARGUMENT][].
	SampleRateHertz      int32    `protobuf:"varint,5,opt,name=sample_rate_hertz,json=sampleRateHertz,proto3" json:"sample_rate_hertz,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

Description of audio data to be synthesized.

func (*AudioConfig) Descriptor

func (*AudioConfig) Descriptor() ([]byte, []int)

func (*AudioConfig) GetAudioEncoding

func (m *AudioConfig) GetAudioEncoding() AudioEncoding

func (*AudioConfig) GetPitch

func (m *AudioConfig) GetPitch() float64

func (*AudioConfig) GetSampleRateHertz

func (m *AudioConfig) GetSampleRateHertz() int32

func (*AudioConfig) GetSpeakingRate

func (m *AudioConfig) GetSpeakingRate() float64

func (*AudioConfig) GetVolumeGainDb

func (m *AudioConfig) GetVolumeGainDb() float64

func (*AudioConfig) ProtoMessage

func (*AudioConfig) ProtoMessage()

func (*AudioConfig) Reset

func (m *AudioConfig) Reset()

func (*AudioConfig) String

func (m *AudioConfig) String() string

func (*AudioConfig) XXX_DiscardUnknown

func (m *AudioConfig) XXX_DiscardUnknown()

func (*AudioConfig) XXX_Marshal

func (m *AudioConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*AudioConfig) XXX_Merge

func (m *AudioConfig) XXX_Merge(src proto.Message)

func (*AudioConfig) XXX_Size

func (m *AudioConfig) XXX_Size() int

func (*AudioConfig) XXX_Unmarshal

func (m *AudioConfig) XXX_Unmarshal(b []byte) error

type AudioEncoding

type AudioEncoding int32

Configuration to set up audio encoder. The encoding determines the output audio format that we'd like.

const (
	// Not specified. Will return result [google.rpc.Code.INVALID_ARGUMENT][].
	AudioEncoding_AUDIO_ENCODING_UNSPECIFIED AudioEncoding = 0
	// Uncompressed 16-bit signed little-endian samples (Linear PCM).
	// Audio content returned as LINEAR16 also contains a WAV header.
	AudioEncoding_LINEAR16 AudioEncoding = 1
	// MP3 audio.
	AudioEncoding_MP3 AudioEncoding = 2
	// Opus encoded audio wrapped in an ogg container. The result will be a
	// file which can be played natively on Android, and in browsers (at least
	// Chrome and Firefox). The quality of the encoding is considerably higher
	// than MP3 while using approximately the same bitrate.
	AudioEncoding_OGG_OPUS AudioEncoding = 3
)

func (AudioEncoding) EnumDescriptor

func (AudioEncoding) EnumDescriptor() ([]byte, []int)

func (AudioEncoding) String

func (x AudioEncoding) String() string

type ListVoicesRequest

type ListVoicesRequest struct {
	// Optional (but recommended)
	// [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tag. If
	// specified, the ListVoices call will only return voices that can be used to
	// synthesize this language_code. E.g. when specifying "en-NZ", you will get
	// supported "en-*" voices; when specifying "no", you will get supported
	// "no-*" (Norwegian) and "nb-*" (Norwegian Bokmal) voices; specifying "zh"
	// will also get supported "cmn-*" voices; specifying "zh-hk" will also get
	// supported "yue-*" voices.
	LanguageCode         string   `protobuf:"bytes,1,opt,name=language_code,json=languageCode,proto3" json:"language_code,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

The top-level message sent by the client for the `ListVoices` method.

func (*ListVoicesRequest) Descriptor

func (*ListVoicesRequest) Descriptor() ([]byte, []int)

func (*ListVoicesRequest) GetLanguageCode

func (m *ListVoicesRequest) GetLanguageCode() string

func (*ListVoicesRequest) ProtoMessage

func (*ListVoicesRequest) ProtoMessage()

func (*ListVoicesRequest) Reset

func (m *ListVoicesRequest) Reset()

func (*ListVoicesRequest) String

func (m *ListVoicesRequest) String() string

func (*ListVoicesRequest) XXX_DiscardUnknown

func (m *ListVoicesRequest) XXX_DiscardUnknown()

func (*ListVoicesRequest) XXX_Marshal

func (m *ListVoicesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*ListVoicesRequest) XXX_Merge

func (m *ListVoicesRequest) XXX_Merge(src proto.Message)

func (*ListVoicesRequest) XXX_Size

func (m *ListVoicesRequest) XXX_Size() int

func (*ListVoicesRequest) XXX_Unmarshal

func (m *ListVoicesRequest) XXX_Unmarshal(b []byte) error

type ListVoicesResponse

type ListVoicesResponse struct {
	// The list of voices.
	Voices               []*Voice `protobuf:"bytes,1,rep,name=voices,proto3" json:"voices,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

The message returned to the client by the `ListVoices` method.

func (*ListVoicesResponse) Descriptor

func (*ListVoicesResponse) Descriptor() ([]byte, []int)

func (*ListVoicesResponse) GetVoices

func (m *ListVoicesResponse) GetVoices() []*Voice

func (*ListVoicesResponse) ProtoMessage

func (*ListVoicesResponse) ProtoMessage()

func (*ListVoicesResponse) Reset

func (m *ListVoicesResponse) Reset()

func (*ListVoicesResponse) String

func (m *ListVoicesResponse) String() string

func (*ListVoicesResponse) XXX_DiscardUnknown

func (m *ListVoicesResponse) XXX_DiscardUnknown()

func (*ListVoicesResponse) XXX_Marshal

func (m *ListVoicesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*ListVoicesResponse) XXX_Merge

func (m *ListVoicesResponse) XXX_Merge(src proto.Message)

func (*ListVoicesResponse) XXX_Size

func (m *ListVoicesResponse) XXX_Size() int

func (*ListVoicesResponse) XXX_Unmarshal

func (m *ListVoicesResponse) XXX_Unmarshal(b []byte) error

type SsmlVoiceGender

type SsmlVoiceGender int32

Gender of the voice as described in [SSML voice element](https://www.w3.org/TR/speech-synthesis11/#edef_voice).

const (
	// An unspecified gender.
	// In VoiceSelectionParams, this means that the client doesn't care which
	// gender the selected voice will have. In the Voice field of
	// ListVoicesResponse, this may mean that the voice doesn't fit any of the
	// other categories in this enum, or that the gender of the voice isn't known.
	SsmlVoiceGender_SSML_VOICE_GENDER_UNSPECIFIED SsmlVoiceGender = 0
	// A male voice.
	SsmlVoiceGender_MALE SsmlVoiceGender = 1
	// A female voice.
	SsmlVoiceGender_FEMALE SsmlVoiceGender = 2
	// A gender-neutral voice.
	SsmlVoiceGender_NEUTRAL SsmlVoiceGender = 3
)

func (SsmlVoiceGender) EnumDescriptor

func (SsmlVoiceGender) EnumDescriptor() ([]byte, []int)

func (SsmlVoiceGender) String

func (x SsmlVoiceGender) String() string

type SynthesisInput

type SynthesisInput struct {
	// The input source, which is either plain text or SSML.
	//
	// Types that are valid to be assigned to InputSource:
	//	*SynthesisInput_Text
	//	*SynthesisInput_Ssml
	InputSource          isSynthesisInput_InputSource `protobuf_oneof:"input_source"`
	XXX_NoUnkeyedLiteral struct{}                     `json:"-"`
	XXX_unrecognized     []byte                       `json:"-"`
	XXX_sizecache        int32                        `json:"-"`
}

Contains text input to be synthesized. Either `text` or `ssml` must be supplied. Supplying both or neither returns [google.rpc.Code.INVALID_ARGUMENT][]. The input size is limited to 5000 characters.

func (*SynthesisInput) Descriptor

func (*SynthesisInput) Descriptor() ([]byte, []int)

func (*SynthesisInput) GetInputSource

func (m *SynthesisInput) GetInputSource() isSynthesisInput_InputSource

func (*SynthesisInput) GetSsml

func (m *SynthesisInput) GetSsml() string

func (*SynthesisInput) GetText

func (m *SynthesisInput) GetText() string

func (*SynthesisInput) ProtoMessage

func (*SynthesisInput) ProtoMessage()

func (*SynthesisInput) Reset

func (m *SynthesisInput) Reset()

func (*SynthesisInput) String

func (m *SynthesisInput) String() string

func (*SynthesisInput) XXX_DiscardUnknown

func (m *SynthesisInput) XXX_DiscardUnknown()

func (*SynthesisInput) XXX_Marshal

func (m *SynthesisInput) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*SynthesisInput) XXX_Merge

func (m *SynthesisInput) XXX_Merge(src proto.Message)

func (*SynthesisInput) XXX_OneofFuncs

func (*SynthesisInput) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{})

XXX_OneofFuncs is for the internal use of the proto package.

func (*SynthesisInput) XXX_Size

func (m *SynthesisInput) XXX_Size() int

func (*SynthesisInput) XXX_Unmarshal

func (m *SynthesisInput) XXX_Unmarshal(b []byte) error

type SynthesisInput_Ssml

type SynthesisInput_Ssml struct {
	Ssml string `protobuf:"bytes,2,opt,name=ssml,proto3,oneof"`
}

type SynthesisInput_Text

type SynthesisInput_Text struct {
	Text string `protobuf:"bytes,1,opt,name=text,proto3,oneof"`
}

type SynthesizeSpeechRequest

type SynthesizeSpeechRequest struct {
	// Required. The Synthesizer requires either plain text or SSML as input.
	Input *SynthesisInput `protobuf:"bytes,1,opt,name=input,proto3" json:"input,omitempty"`
	// Required. The desired voice of the synthesized audio.
	Voice *VoiceSelectionParams `protobuf:"bytes,2,opt,name=voice,proto3" json:"voice,omitempty"`
	// Required. The configuration of the synthesized audio.
	AudioConfig          *AudioConfig `protobuf:"bytes,3,opt,name=audio_config,json=audioConfig,proto3" json:"audio_config,omitempty"`
	XXX_NoUnkeyedLiteral struct{}     `json:"-"`
	XXX_unrecognized     []byte       `json:"-"`
	XXX_sizecache        int32        `json:"-"`
}

The top-level message sent by the client for the `SynthesizeSpeech` method.

func (*SynthesizeSpeechRequest) Descriptor

func (*SynthesizeSpeechRequest) Descriptor() ([]byte, []int)

func (*SynthesizeSpeechRequest) GetAudioConfig

func (m *SynthesizeSpeechRequest) GetAudioConfig() *AudioConfig

func (*SynthesizeSpeechRequest) GetInput

func (m *SynthesizeSpeechRequest) GetInput() *SynthesisInput

func (*SynthesizeSpeechRequest) GetVoice

func (*SynthesizeSpeechRequest) ProtoMessage

func (*SynthesizeSpeechRequest) ProtoMessage()

func (*SynthesizeSpeechRequest) Reset

func (m *SynthesizeSpeechRequest) Reset()

func (*SynthesizeSpeechRequest) String

func (m *SynthesizeSpeechRequest) String() string

func (*SynthesizeSpeechRequest) XXX_DiscardUnknown

func (m *SynthesizeSpeechRequest) XXX_DiscardUnknown()

func (*SynthesizeSpeechRequest) XXX_Marshal

func (m *SynthesizeSpeechRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*SynthesizeSpeechRequest) XXX_Merge

func (m *SynthesizeSpeechRequest) XXX_Merge(src proto.Message)

func (*SynthesizeSpeechRequest) XXX_Size

func (m *SynthesizeSpeechRequest) XXX_Size() int

func (*SynthesizeSpeechRequest) XXX_Unmarshal

func (m *SynthesizeSpeechRequest) XXX_Unmarshal(b []byte) error

type SynthesizeSpeechResponse

type SynthesizeSpeechResponse struct {
	// The audio data bytes encoded as specified in the request, including the
	// header (For LINEAR16 audio, we include the WAV header). Note: as
	// with all bytes fields, protobuffers use a pure binary representation,
	// whereas JSON representations use base64.
	AudioContent         []byte   `protobuf:"bytes,1,opt,name=audio_content,json=audioContent,proto3" json:"audio_content,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

The message returned to the client by the `SynthesizeSpeech` method.

func (*SynthesizeSpeechResponse) Descriptor

func (*SynthesizeSpeechResponse) Descriptor() ([]byte, []int)

func (*SynthesizeSpeechResponse) GetAudioContent

func (m *SynthesizeSpeechResponse) GetAudioContent() []byte

func (*SynthesizeSpeechResponse) ProtoMessage

func (*SynthesizeSpeechResponse) ProtoMessage()

func (*SynthesizeSpeechResponse) Reset

func (m *SynthesizeSpeechResponse) Reset()

func (*SynthesizeSpeechResponse) String

func (m *SynthesizeSpeechResponse) String() string

func (*SynthesizeSpeechResponse) XXX_DiscardUnknown

func (m *SynthesizeSpeechResponse) XXX_DiscardUnknown()

func (*SynthesizeSpeechResponse) XXX_Marshal

func (m *SynthesizeSpeechResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*SynthesizeSpeechResponse) XXX_Merge

func (m *SynthesizeSpeechResponse) XXX_Merge(src proto.Message)

func (*SynthesizeSpeechResponse) XXX_Size

func (m *SynthesizeSpeechResponse) XXX_Size() int

func (*SynthesizeSpeechResponse) XXX_Unmarshal

func (m *SynthesizeSpeechResponse) XXX_Unmarshal(b []byte) error

type TextToSpeechClient

type TextToSpeechClient interface {
	// Returns a list of [Voice][google.cloud.texttospeech.v1.Voice]
	// supported for synthesis.
	ListVoices(ctx context.Context, in *ListVoicesRequest, opts ...grpc.CallOption) (*ListVoicesResponse, error)
	// Synthesizes speech synchronously: receive results after all text input
	// has been processed.
	SynthesizeSpeech(ctx context.Context, in *SynthesizeSpeechRequest, opts ...grpc.CallOption) (*SynthesizeSpeechResponse, error)
}

TextToSpeechClient is the client API for TextToSpeech service.

For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.

func NewTextToSpeechClient

func NewTextToSpeechClient(cc *grpc.ClientConn) TextToSpeechClient

type TextToSpeechServer

type TextToSpeechServer interface {
	// Returns a list of [Voice][google.cloud.texttospeech.v1.Voice]
	// supported for synthesis.
	ListVoices(context.Context, *ListVoicesRequest) (*ListVoicesResponse, error)
	// Synthesizes speech synchronously: receive results after all text input
	// has been processed.
	SynthesizeSpeech(context.Context, *SynthesizeSpeechRequest) (*SynthesizeSpeechResponse, error)
}

TextToSpeechServer is the server API for TextToSpeech service.

type Voice

type Voice struct {
	// The languages that this voice supports, expressed as
	// [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tags (e.g.
	// "en-US", "es-419", "cmn-tw").
	LanguageCodes []string `protobuf:"bytes,1,rep,name=language_codes,json=languageCodes,proto3" json:"language_codes,omitempty"`
	// The name of this voice.  Each distinct voice has a unique name.
	Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
	// The gender of this voice.
	SsmlGender SsmlVoiceGender `` /* 142-byte string literal not displayed */
	// The natural sample rate (in hertz) for this voice.
	NaturalSampleRateHertz int32    `` /* 132-byte string literal not displayed */
	XXX_NoUnkeyedLiteral   struct{} `json:"-"`
	XXX_unrecognized       []byte   `json:"-"`
	XXX_sizecache          int32    `json:"-"`
}

Description of a voice supported by the TTS service.

func (*Voice) Descriptor

func (*Voice) Descriptor() ([]byte, []int)

func (*Voice) GetLanguageCodes

func (m *Voice) GetLanguageCodes() []string

func (*Voice) GetName

func (m *Voice) GetName() string

func (*Voice) GetNaturalSampleRateHertz

func (m *Voice) GetNaturalSampleRateHertz() int32

func (*Voice) GetSsmlGender

func (m *Voice) GetSsmlGender() SsmlVoiceGender

func (*Voice) ProtoMessage

func (*Voice) ProtoMessage()

func (*Voice) Reset

func (m *Voice) Reset()

func (*Voice) String

func (m *Voice) String() string

func (*Voice) XXX_DiscardUnknown

func (m *Voice) XXX_DiscardUnknown()

func (*Voice) XXX_Marshal

func (m *Voice) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*Voice) XXX_Merge

func (m *Voice) XXX_Merge(src proto.Message)

func (*Voice) XXX_Size

func (m *Voice) XXX_Size() int

func (*Voice) XXX_Unmarshal

func (m *Voice) XXX_Unmarshal(b []byte) error

type VoiceSelectionParams

type VoiceSelectionParams struct {
	// The language (and optionally also the region) of the voice expressed as a
	// [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tag, e.g.
	// "en-US". Required. This should not include a script tag (e.g. use
	// "cmn-cn" rather than "cmn-Hant-cn"), because the script will be inferred
	// from the input provided in the SynthesisInput.  The TTS service
	// will use this parameter to help choose an appropriate voice.  Note that
	// the TTS service may choose a voice with a slightly different language code
	// than the one selected; it may substitute a different region
	// (e.g. using en-US rather than en-CA if there isn't a Canadian voice
	// available), or even a different language, e.g. using "nb" (Norwegian
	// Bokmal) instead of "no" (Norwegian)".
	LanguageCode string `protobuf:"bytes,1,opt,name=language_code,json=languageCode,proto3" json:"language_code,omitempty"`
	// The name of the voice. Optional; if not set, the service will choose a
	// voice based on the other parameters such as language_code and gender.
	Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
	// The preferred gender of the voice. Optional; if not set, the service will
	// choose a voice based on the other parameters such as language_code and
	// name. Note that this is only a preference, not requirement; if a
	// voice of the appropriate gender is not available, the synthesizer should
	// substitute a voice with a different gender rather than failing the request.
	SsmlGender           SsmlVoiceGender `` /* 142-byte string literal not displayed */
	XXX_NoUnkeyedLiteral struct{}        `json:"-"`
	XXX_unrecognized     []byte          `json:"-"`
	XXX_sizecache        int32           `json:"-"`
}

Description of which voice to use for a synthesis request.

func (*VoiceSelectionParams) Descriptor

func (*VoiceSelectionParams) Descriptor() ([]byte, []int)

func (*VoiceSelectionParams) GetLanguageCode

func (m *VoiceSelectionParams) GetLanguageCode() string

func (*VoiceSelectionParams) GetName

func (m *VoiceSelectionParams) GetName() string

func (*VoiceSelectionParams) GetSsmlGender

func (m *VoiceSelectionParams) GetSsmlGender() SsmlVoiceGender

func (*VoiceSelectionParams) ProtoMessage

func (*VoiceSelectionParams) ProtoMessage()

func (*VoiceSelectionParams) Reset

func (m *VoiceSelectionParams) Reset()

func (*VoiceSelectionParams) String

func (m *VoiceSelectionParams) String() string

func (*VoiceSelectionParams) XXX_DiscardUnknown

func (m *VoiceSelectionParams) XXX_DiscardUnknown()

func (*VoiceSelectionParams) XXX_Marshal

func (m *VoiceSelectionParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*VoiceSelectionParams) XXX_Merge

func (m *VoiceSelectionParams) XXX_Merge(src proto.Message)

func (*VoiceSelectionParams) XXX_Size

func (m *VoiceSelectionParams) XXX_Size() int

func (*VoiceSelectionParams) XXX_Unmarshal

func (m *VoiceSelectionParams) XXX_Unmarshal(b []byte) error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL