xml

package
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: Jul 17, 2018 License: GPL-3.0 Imports: 10 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// GetType represents a 'get' IQ type.
	GetType = "get"

	// SetType represents a 'set' IQ type.
	SetType = "set"

	// ResultType represents a 'result' IQ type.
	ResultType = "result"
)
View Source
const (
	// NormalType represents a 'normal' message type.
	NormalType = "normal"

	// HeadlineType represents a 'headline' message type.
	HeadlineType = "headline"

	// ChatType represents a 'chat' message type.
	ChatType = "chat"

	// GroupChatType represents a 'groupchat' message type.
	GroupChatType = "groupchat"
)
View Source
const (
	// DefaultMode treats incoming elements as provided from raw byte reader.
	DefaultMode = ParsingMode(iota)

	// SocketStream treats incoming elements as provided from a socket transport.
	SocketStream

	// WebSocketStream treats incoming elements as provided from a websocket transport.
	WebSocketStream
)
View Source
const (
	// AvailableType represents an 'available' Presence type.
	AvailableType = ""

	// UnavailableType represents a 'unavailable' Presence type.
	UnavailableType = "unavailable"

	// SubscribeType represents a 'subscribe' Presence type.
	SubscribeType = "subscribe"

	// UnsubscribeType represents a 'unsubscribe' Presence type.
	UnsubscribeType = "unsubscribe"

	// SubscribedType represents a 'subscribed' Presence type.
	SubscribedType = "subscribed"

	// UnsubscribedType represents a 'unsubscribed' Presence type.
	UnsubscribedType = "unsubscribed"

	// ProbeType represents a 'probe' Presence type.
	ProbeType = "probe"
)
View Source
const ErrorType = "error"

ErrorType represents an 'error' stanza type.

Variables

View Source
var (
	// ErrBadRequest is returned by the stream when the  sender
	// has sent XML that is malformed or that cannot be processed.
	ErrBadRequest = newStanzaError(400, modifyErrorType, badRequestErrorReason)

	// ErrConflict is returned by the stream when access cannot be
	// granted because an existing resource or session exists with
	// the same name or address.
	ErrConflict = newStanzaError(409, cancelErrorType, conflictErrorReason)

	// ErrFeatureNotImplemented is returned by the stream when the feature
	// requested is not implemented by the server and therefore cannot be processed.
	ErrFeatureNotImplemented = newStanzaError(501, cancelErrorType, featureNotImplementedErrorReason)

	// ErrForbidden is returned by the stream when the requesting
	// entity does not possess the required permissions to perform the action.
	ErrForbidden = newStanzaError(403, authErrorType, forbiddenErrorReason)

	// ErrGone is returned by the stream when the recipient or server
	// can no longer be contacted at this address.
	ErrGone = newStanzaError(302, modifyErrorType, goneErrorReason)

	// ErrInternalServerError is returned by the stream when the server
	// could not process the stanza because of a misconfiguration
	// or an otherwise-undefined internal server error.
	ErrInternalServerError = newStanzaError(500, waitErrorType, internalServerErrorErrorReason)

	// ErrItemNotFound is returned by the stream when the addressed
	// JID or item requested cannot be found.
	ErrItemNotFound = newStanzaError(404, cancelErrorType, itemNotFoundErrorReason)

	// ErrJidMalformed is returned by the stream when the sending entity
	// has provided or communicated an XMPP address or aspect thereof that
	// does not adhere to the syntax defined in https://xmpp.org/rfcs/rfc3920.html#addressing.
	ErrJidMalformed = newStanzaError(400, modifyErrorType, jidMalformedErrorReason)

	// ErrNotAcceptable is returned by the stream when the server
	// understands the request but is refusing to process it because
	// it does not meet the defined criteria.
	ErrNotAcceptable = newStanzaError(406, modifyErrorType, notAcceptableErrorReason)

	// ErrNotAllowed is returned by the stream when the recipient
	// or server does not allow any entity to perform the action.
	ErrNotAllowed = newStanzaError(405, cancelErrorType, notAllowedErrorReason)

	// ErrNotAuthorized is returned by the stream when the sender
	// must provide proper credentials before being allowed to perform the action,
	// or has provided improper credentials.
	ErrNotAuthorized = newStanzaError(405, authErrorType, notAuthroizedErrorReason)

	// ErrPaymentRequired is returned by the stream when the requesting entity
	// is not authorized to access the requested service because payment is required.
	ErrPaymentRequired = newStanzaError(402, authErrorType, paymentRequiredErrorReason)

	// ErrRecipientUnavailable is returned by the stream when the intended
	// recipient is temporarily unavailable.
	ErrRecipientUnavailable = newStanzaError(404, waitErrorType, recipientUnavailableErrorReason)

	// ErrRedirect is returned by the stream when the recipient or server
	// is redirecting requests for this information to another entity, usually temporarily.
	ErrRedirect = newStanzaError(302, modifyErrorType, redirectErrorReason)

	// ErrRegistrationRequired is returned by the stream when the requesting entity
	// is not authorized to access the requested service because registration is required.
	ErrRegistrationRequired = newStanzaError(407, authErrorType, registrationRequiredErrorReason)

	// ErrRemoteServerNotFound is returned by the stream when a remote server
	// or service specified as part or all of the JID of the intended recipient does not exist.
	ErrRemoteServerNotFound = newStanzaError(404, cancelErrorType, remoteServerNotFoundErrorReason)

	// ErrRemoteServerTimeout is returned by the stream when a remote server
	// or service specified as part or all of the JID of the intended recipient
	// could not be contacted within a reasonable amount of time.
	ErrRemoteServerTimeout = newStanzaError(504, waitErrorType, remoteServerTimeoutErrorReason)

	// ErrResourceConstraint is returned by the stream when the server or recipient
	// lacks the system resources necessary to service the request.
	ErrResourceConstraint = newStanzaError(500, waitErrorType, resourceConstraintErrorReason)

	// ErrServiceUnavailable is returned by the stream when the server or recipient
	// does not currently provide the requested service.
	ErrServiceUnavailable = newStanzaError(503, cancelErrorType, serviceUnavailableErrorReason)

	// ErrSubscriptionRequired is returned by the stream when the requesting entity
	// is not authorized to access the requested service because a subscription is required.
	ErrSubscriptionRequired = newStanzaError(407, authErrorType, subscriptionRequiredErrorReason)

	// ErrUndefinedCondition is returned by the stream when the error condition
	// is not one of those defined by the other conditions in this list.
	ErrUndefinedCondition = newStanzaError(500, waitErrorType, undefinedConditionErrorReason)

	// ErrUnexpectedCondition is returned by the stream when the recipient or server
	// understood the request but was not expecting it at this time.
	ErrUnexpectedCondition = newStanzaError(400, waitErrorType, unexpectedConditionErrorReason)
)
View Source
var ErrStreamClosedByPeer = errors.New("xml: stream closed by peer")

ErrStreamClosedByPeer is returned by Parse when peer closes the stream.

View Source
var ErrTooLargeStanza = errors.New("xml: too large stanza")

ErrTooLargeStanza is returned by ReadElement when the size of the incoming stanza is too large.

Functions

This section is empty.

Types

type Attribute

type Attribute struct {
	Label string
	Value string
}

Attribute represents an XML node attribute (label=value).

type AttributeSet added in v0.2.0

type AttributeSet interface {
	Get(string) string
	Count() int
}

AttributeSet interface represents a read-only set of XML attributes.

type Element

type Element struct {
	// contains filtered or unexported fields
}

Element represents a generic and mutable XML node element.

func NewElementFromElement

func NewElementFromElement(elem XElement) *Element

NewElementFromElement creates a mutable XML XElement by copying an element.

func NewElementName

func NewElementName(name string) *Element

NewElementName creates a mutable XML XElement instance with a given name.

func NewElementNamespace

func NewElementNamespace(name, namespace string) *Element

NewElementNamespace creates a mutable XML XElement instance with a given name and namespace.

func NewErrorElementFromElement added in v0.2.0

func NewErrorElementFromElement(elem XElement, stanzaErr *StanzaError, errorElements []XElement) *Element

NewErrorElementFromElement returns a copy of an element of stanza error class.

func (*Element) AppendElement added in v0.2.0

func (e *Element) AppendElement(element XElement)

AppendElement appends a new sub element.

func (*Element) AppendElements added in v0.2.0

func (e *Element) AppendElements(elements []XElement)

AppendElements appends an array of sub elements.

func (*Element) Attributes

func (e *Element) Attributes() AttributeSet

Attributes returns XML node attribute value.

func (*Element) BadRequestError added in v0.2.0

func (el *Element) BadRequestError() XElement

BadRequestError returns an error copy of the element attaching 'bad-request' error sub element.

func (*Element) ClearElements added in v0.2.0

func (e *Element) ClearElements()

ClearElements removes all elements.

func (*Element) ConflictError added in v0.2.0

func (el *Element) ConflictError() XElement

ConflictError returns an error copy of the element attaching 'conflict' error sub element.

func (*Element) Delay added in v0.2.0

func (e *Element) Delay(from string, text string)

Delay attaches element's Delayed Delivery information.

func (*Element) Elements

func (e *Element) Elements() ElementSet

Elements returns all instance's child elements.

func (*Element) Error

func (e *Element) Error() XElement

Error returns element error sub element.

func (*Element) FeatureNotImplementedError added in v0.2.0

func (el *Element) FeatureNotImplementedError() XElement

FeatureNotImplementedError returns an error copy of the element attaching 'feature-not-implemented' error sub element.

func (*Element) ForbiddenError added in v0.2.0

func (el *Element) ForbiddenError() XElement

ForbiddenError returns an error copy of the element attaching 'forbidden' error sub element.

func (*Element) From

func (e *Element) From() string

From returns 'from' node attribute.

func (*Element) FromGob added in v0.2.0

func (e *Element) FromGob(dec *gob.Decoder)

FromGob deserializes an element node from it's gob binary representation.

func (*Element) GoneError added in v0.2.0

func (el *Element) GoneError() XElement

GoneError returns an error copy of the element attaching 'gone' error sub element.

func (*Element) ID

func (e *Element) ID() string

ID returns 'id' node attribute.

func (*Element) InternalServerError added in v0.2.0

func (el *Element) InternalServerError() XElement

InternalServerError returns an error copy of the element attaching 'internal-server-error' error sub element.

func (*Element) IsError added in v0.2.0

func (e *Element) IsError() bool

IsError returns true if element has a 'type' attribute of value 'error'.

func (*Element) IsStanza added in v0.3.0

func (e *Element) IsStanza() bool

IsStanza returns true if element is an XMPP stanza.

func (*Element) ItemNotFoundError added in v0.2.0

func (el *Element) ItemNotFoundError() XElement

ItemNotFoundError returns an error copy of the element attaching 'item-not-found' error sub element.

func (*Element) JidMalformedError added in v0.2.0

func (el *Element) JidMalformedError() XElement

JidMalformedError returns an error copy of the element attaching 'jid-malformed' error sub element.

func (*Element) Language

func (e *Element) Language() string

Language returns 'xml:lang' node attribute.

func (*Element) Name

func (e *Element) Name() string

Name returns XML node name.

func (*Element) Namespace

func (e *Element) Namespace() string

Namespace returns 'xmlns' node attribute.

func (*Element) NotAcceptableError added in v0.2.0

func (el *Element) NotAcceptableError() XElement

NotAcceptableError returns an error copy of the element attaching 'not-acceptable' error sub element.

func (*Element) NotAllowedError added in v0.2.0

func (el *Element) NotAllowedError() XElement

NotAllowedError returns an error copy of the element attaching 'not-allowed' error sub element.

func (*Element) NotAuthorizedError added in v0.2.0

func (el *Element) NotAuthorizedError() XElement

NotAuthorizedError returns an error copy of the element attaching 'not-authorized' error sub element.

func (*Element) PaymentRequiredError added in v0.2.0

func (el *Element) PaymentRequiredError() XElement

PaymentRequiredError returns an error copy of the element attaching 'payment-required' error sub element.

func (*Element) RecipientUnavailableError added in v0.2.0

func (el *Element) RecipientUnavailableError() XElement

RecipientUnavailableError returns an error copy of the element attaching 'recipient-unavailable' error sub element.

func (*Element) RedirectError added in v0.2.0

func (el *Element) RedirectError() XElement

RedirectError returns an error copy of the element attaching 'redirect' error sub element.

func (*Element) RegistrationRequiredError added in v0.2.0

func (el *Element) RegistrationRequiredError() XElement

RegistrationRequiredError returns an error copy of the element attaching 'registration-required' error sub element.

func (*Element) RemoteServerNotFoundError added in v0.2.0

func (el *Element) RemoteServerNotFoundError() XElement

RemoteServerNotFoundError returns an error copy of the element attaching 'remote-server-not-found' error sub element.

func (*Element) RemoteServerTimeoutError added in v0.2.0

func (el *Element) RemoteServerTimeoutError() XElement

RemoteServerTimeoutError returns an error copy of the element attaching 'remote-server-timeout' error sub element.

func (*Element) RemoveAttribute added in v0.2.0

func (e *Element) RemoveAttribute(label string)

RemoveAttribute removes an XML node attribute.

func (*Element) RemoveElements added in v0.2.0

func (e *Element) RemoveElements(name string)

RemoveElements removes all elements with a given name.

func (*Element) RemoveElementsNamespace added in v0.2.0

func (e *Element) RemoveElementsNamespace(name, namespace string)

RemoveElementsNamespace removes all elements with a given name and namespace.

func (*Element) ResourceConstraintError added in v0.2.0

func (el *Element) ResourceConstraintError() XElement

ResourceConstraintError returns an error copy of the element attaching 'resource-constraint' error sub element.

func (*Element) ServiceUnavailableError added in v0.2.0

func (el *Element) ServiceUnavailableError() XElement

ServiceUnavailableError returns an error copy of the element attaching 'service-unavailable' error sub element.

func (*Element) SetAttribute added in v0.2.0

func (e *Element) SetAttribute(label, value string)

SetAttribute sets an XML node attribute (label=value)

func (*Element) SetFrom added in v0.2.0

func (e *Element) SetFrom(from string)

SetFrom sets 'from' node attribute.

func (*Element) SetID added in v0.2.0

func (e *Element) SetID(identifier string)

SetID sets 'id' node attribute.

func (*Element) SetLanguage added in v0.2.0

func (e *Element) SetLanguage(language string)

SetLanguage sets 'xml:lang' node attribute.

func (*Element) SetName added in v0.2.0

func (e *Element) SetName(name string)

SetName sets XML node name.

func (*Element) SetNamespace added in v0.2.0

func (e *Element) SetNamespace(namespace string)

SetNamespace sets 'xmlns' node attribute.

func (*Element) SetText added in v0.2.0

func (e *Element) SetText(text string)

SetText sets XML node text value.

func (*Element) SetTo added in v0.2.0

func (e *Element) SetTo(to string)

SetTo sets 'to' node attribute.

func (*Element) SetType added in v0.2.0

func (e *Element) SetType(tp string)

SetType sets 'type' node attribute.

func (*Element) SetVersion added in v0.2.0

func (e *Element) SetVersion(version string)

SetVersion sets 'version' node attribute.

func (*Element) String added in v0.2.0

func (e *Element) String() string

String returns a string representation of the element.

func (*Element) SubscriptionRequiredError added in v0.2.0

func (el *Element) SubscriptionRequiredError() XElement

SubscriptionRequiredError returns an error copy of the element attaching 'subscription-required' error sub element.

func (*Element) Text

func (e *Element) Text() string

Text returns XML node text value. Returns an empty string if not set.

func (*Element) To

func (e *Element) To() string

To returns 'to' node attribute.

func (*Element) ToGob added in v0.2.0

func (e *Element) ToGob(enc *gob.Encoder)

ToGob serializes an element node to it's gob binary representation.

func (*Element) ToXML

func (e *Element) ToXML(w io.Writer, includeClosing bool)

ToXML serializes element to a raw XML representation. includeClosing determines if closing tag should be attached.

func (*Element) Type

func (e *Element) Type() string

Type returns 'type' node attribute.

func (*Element) UndefinedConditionError added in v0.2.0

func (el *Element) UndefinedConditionError() XElement

UndefinedConditionError returns an error copy of the element attaching 'undefined-condition' error sub element.

func (*Element) UnexpectedConditionError added in v0.2.0

func (el *Element) UnexpectedConditionError() XElement

UnexpectedConditionError returns an error copy of the element attaching 'unexpected-condition' error sub element.

func (*Element) Version

func (e *Element) Version() string

Version returns 'version' node attribute.

type ElementSet added in v0.2.0

type ElementSet interface {
	// Children returns all elements identified by name.
	// Returns an empty array if no elements are found.
	Children(name string) []XElement

	// Child returns first element identified by name.
	// Returns nil if no element is found.
	Child(name string) XElement

	// ChildrenNamespace returns all elements identified by name and namespace.
	// Returns an empty array if no elements are found.
	ChildrenNamespace(name, namespace string) []XElement

	// ChildNamespace returns first element identified by name and namespace.
	// Returns nil if no element is found.
	ChildNamespace(name, namespace string) XElement

	// All returns a list of all child nodes.
	All() []XElement

	// Count returns child elements count.
	Count() int
}

ElementSet interface represents a read-only set of XML sub elements.

type IQ

type IQ struct {
	Element
	// contains filtered or unexported fields
}

IQ type represents an <iq> element. All incoming <iq> elements providing from the stream will automatically be converted to IQ objects.

func NewIQFromElement

func NewIQFromElement(e XElement, from *jid.JID, to *jid.JID) (*IQ, error)

NewIQFromElement creates an IQ object from XElement.

func NewIQType

func NewIQType(identifier string, iqType string) *IQ

NewIQType creates and returns a new IQ element.

func (*IQ) FromJID

func (iq *IQ) FromJID() *jid.JID

FromJID returns presence 'from' JID value.

func (*IQ) IsGet

func (iq *IQ) IsGet() bool

IsGet returns true if this is a 'get' type IQ.

func (*IQ) IsResult

func (iq *IQ) IsResult() bool

IsResult returns true if this is a 'result' type IQ.

func (*IQ) IsSet

func (iq *IQ) IsSet() bool

IsSet returns true if this is a 'set' type IQ.

func (*IQ) ResultIQ

func (iq *IQ) ResultIQ() *IQ

ResultIQ returns the instance associated result IQ.

func (*IQ) SetFromJID

func (iq *IQ) SetFromJID(from *jid.JID)

SetFromJID sets the IQ 'from' JID value.

func (*IQ) SetToJID

func (iq *IQ) SetToJID(to *jid.JID)

SetToJID sets the IQ 'to' JID value.

func (*IQ) ToJID

func (iq *IQ) ToJID() *jid.JID

ToJID returns iq 'from' JID value.

type Message

type Message struct {
	Element
	// contains filtered or unexported fields
}

Message type represents a <message> element. All incoming <message> elements providing from the stream will automatically be converted to Message objects.

func NewMessageFromElement

func NewMessageFromElement(e XElement, from *jid.JID, to *jid.JID) (*Message, error)

NewMessageFromElement creates a Message object from XElement.

func NewMessageType

func NewMessageType(identifier string, messageType string) *Message

NewMessageType creates and returns a new Message element.

func (*Message) FromJID

func (m *Message) FromJID() *jid.JID

FromJID returns message 'from' JID value.

func (*Message) IsChat

func (m *Message) IsChat() bool

IsChat returns true if this is a 'chat' type Message.

func (*Message) IsGroupChat

func (m *Message) IsGroupChat() bool

IsGroupChat returns true if this is a 'groupchat' type Message.

func (*Message) IsHeadline

func (m *Message) IsHeadline() bool

IsHeadline returns true if this is a 'headline' type Message.

func (*Message) IsMessageWithBody

func (m *Message) IsMessageWithBody() bool

IsMessageWithBody returns true if the message has a body sub element.

func (*Message) IsNormal

func (m *Message) IsNormal() bool

IsNormal returns true if this is a 'normal' type Message.

func (*Message) SetFromJID

func (m *Message) SetFromJID(from *jid.JID)

SetFromJID sets the message 'from' JID value.

func (*Message) SetToJID

func (m *Message) SetToJID(to *jid.JID)

SetToJID sets the message 'to' JID value.

func (*Message) ToJID

func (m *Message) ToJID() *jid.JID

ToJID returns message 'to' JID value.

type Parser

type Parser struct {
	// contains filtered or unexported fields
}

Parser parses arbitrary XML input and builds an array with the structure of all tag and data elements.

func NewParser

func NewParser(reader io.Reader, mode ParsingMode, maxStanzaSize int) *Parser

NewParser creates an empty Parser instance.

func (*Parser) ParseElement

func (p *Parser) ParseElement() (XElement, error)

ParseElement parses next available XML element from reader.

type ParsingMode added in v0.3.0

type ParsingMode int

ParsingMode defines the way in which special parsed element should be considered or not according to the reader nature.

type Presence

type Presence struct {
	Element
	// contains filtered or unexported fields
}

Presence type represents an <presence> element. All incoming <presence> elements providing from the stream will automatically be converted to Presence objects.

func NewPresence

func NewPresence(from *jid.JID, to *jid.JID, presenceType string) *Presence

NewPresence creates and returns a new Presence element.

func NewPresenceFromElement

func NewPresenceFromElement(e XElement, from *jid.JID, to *jid.JID) (*Presence, error)

NewPresenceFromElement creates a Presence object from XElement.

func (*Presence) FromJID

func (p *Presence) FromJID() *jid.JID

FromJID returns presence 'from' JID value.

func (*Presence) IsAvailable

func (p *Presence) IsAvailable() bool

IsAvailable returns true if this is an 'available' type Presence.

func (*Presence) IsProbe added in v0.3.0

func (p *Presence) IsProbe() bool

IsProbe returns true if this is an 'probe' type Presence.

func (*Presence) IsSubscribe

func (p *Presence) IsSubscribe() bool

IsSubscribe returns true if this is a 'subscribe' type Presence.

func (*Presence) IsSubscribed

func (p *Presence) IsSubscribed() bool

IsSubscribed returns true if this is a 'subscribed' type Presence.

func (*Presence) IsUnavailable

func (p *Presence) IsUnavailable() bool

IsUnavailable returns true if this is an 'unavailable' type Presence.

func (*Presence) IsUnsubscribe

func (p *Presence) IsUnsubscribe() bool

IsUnsubscribe returns true if this is an 'unsubscribe' type Presence.

func (*Presence) IsUnsubscribed

func (p *Presence) IsUnsubscribed() bool

IsUnsubscribed returns true if this is an 'unsubscribed' type Presence.

func (*Presence) Priority

func (p *Presence) Priority() int8

Priority returns presence stanza priority value.

func (*Presence) SetFromJID

func (p *Presence) SetFromJID(from *jid.JID)

SetFromJID sets the presence 'from' JID value.

func (*Presence) SetToJID

func (p *Presence) SetToJID(to *jid.JID)

SetToJID sets the presence 'to' JID value.

func (*Presence) ShowState

func (p *Presence) ShowState() ShowState

ShowState returns presence stanza show state.

func (*Presence) Status added in v0.2.0

func (p *Presence) Status() string

Status returns presence stanza default status.

func (*Presence) ToJID

func (p *Presence) ToJID() *jid.JID

ToJID returns presence 'to' JID value.

type ShowState

type ShowState int

ShowState represents Presence show state.

const (
	// AvailableShowState represents 'available' Presence show state.
	AvailableShowState ShowState = iota

	// AwayShowState represents 'away' Presence show state.
	AwayShowState

	// ChatShowState represents 'chat' Presence show state.
	ChatShowState

	// DoNotDisturbShowState represents 'dnd' Presence show state.
	DoNotDisturbShowState

	// ExtendedAwaysShowState represents 'xa' Presence show state.
	ExtendedAwaysShowState
)

type Stanza added in v0.2.0

type Stanza interface {
	XElement
	FromJID() *jid.JID
	ToJID() *jid.JID
}

Stanza represents an XML stanza.

type StanzaError

type StanzaError struct {
	// contains filtered or unexported fields
}

StanzaError represents a stanza "error" element.

func (*StanzaError) Element

func (se *StanzaError) Element() *Element

Element returns StanzaError equivalent XML element.

func (*StanzaError) Error

func (se *StanzaError) Error() string

Error satisfies error interface.

type XElement added in v0.2.0

type XElement interface {
	fmt.Stringer

	Name() string
	Attributes() AttributeSet
	Elements() ElementSet

	Text() string

	ID() string
	Namespace() string
	Language() string
	Version() string
	From() string
	To() string
	Type() string

	IsStanza() bool
	IsError() bool

	Error() XElement

	ToXML(w io.Writer, includeClosing bool)
	ToGob(enc *gob.Encoder)
}

XElement represents a generic XML node element.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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