diff --git a/bridge/whatsapp/handlers.go b/bridge/whatsapp/handlers.go index bac886d3..1be9b5e3 100644 --- a/bridge/whatsapp/handlers.go +++ b/bridge/whatsapp/handlers.go @@ -4,104 +4,126 @@ import ( "fmt" "mime" "strings" + "time" "github.com/42wim/matterbridge/bridge/config" "github.com/42wim/matterbridge/bridge/helper" - - "go.mau.fi/whatsmeow/binary/proto" - "go.mau.fi/whatsmeow/types" - "go.mau.fi/whatsmeow/types/events" + "github.com/Rhymen/go-whatsapp" + "github.com/jpillora/backoff" ) -// nolint:gocritic -func (b *Bwhatsapp) eventHandler(evt interface{}) { - switch e := evt.(type) { - case *events.Message: - b.handleMessage(e) - } -} +/* +Implement handling messages coming from WhatsApp +Check: +- https://github.com/Rhymen/go-whatsapp#add-message-handlers +- https://github.com/Rhymen/go-whatsapp/blob/master/handler.go +- https://github.com/tulir/mautrix-whatsapp/tree/master/whatsapp-ext for more advanced command handling +*/ -func (b *Bwhatsapp) handleMessage(message *events.Message) { - msg := message.Message - switch { - case msg == nil, message.Info.IsFromMe, message.Info.Timestamp.Before(b.startedAt): +// HandleError received from WhatsApp +func (b *Bwhatsapp) HandleError(err error) { + // ignore received invalid data errors. https://github.com/42wim/matterbridge/issues/843 + // ignore tag 174 errors. https://github.com/42wim/matterbridge/issues/1094 + if strings.Contains(err.Error(), "error processing data: received invalid data") || + strings.Contains(err.Error(), "invalid string with tag 174") { return } - b.Log.Infof("Receiving message %#v", msg) - - switch { - case msg.Conversation != nil || msg.ExtendedTextMessage != nil: - b.handleTextMessage(message.Info, msg) - case msg.VideoMessage != nil: - b.handleVideoMessage(message) - case msg.AudioMessage != nil: - b.handleAudioMessage(message) - case msg.DocumentMessage != nil: - b.handleDocumentMessage(message) - case msg.ImageMessage != nil: - b.handleImageMessage(message) + switch err.(type) { + case *whatsapp.ErrConnectionClosed, *whatsapp.ErrConnectionFailed: + b.reconnect(err) + default: + switch err { + case whatsapp.ErrConnectionTimeout: + b.reconnect(err) + default: + b.Log.Errorf("%v", err) + } } } -// nolint:funlen -func (b *Bwhatsapp) handleTextMessage(messageInfo types.MessageInfo, msg *proto.Message) { - senderJID := messageInfo.Sender - channel := messageInfo.Chat +func (b *Bwhatsapp) reconnect(err error) { + bf := &backoff.Backoff{ + Min: time.Second, + Max: 5 * time.Minute, + Jitter: true, + } - senderName := b.getSenderName(messageInfo.Sender) + for { + d := bf.Duration() + + b.Log.Errorf("Connection failed, underlying error: %v", err) + b.Log.Infof("Waiting %s...", d) + + time.Sleep(d) + + b.Log.Info("Reconnecting...") + + err := b.conn.Restore() + if err == nil { + bf.Reset() + b.startedAt = uint64(time.Now().Unix()) + + return + } + } +} + +// HandleTextMessage sent from WhatsApp, relay it to the brige +func (b *Bwhatsapp) HandleTextMessage(message whatsapp.TextMessage) { + if message.Info.FromMe { + return + } + // whatsapp sends last messages to show context , cut them + if message.Info.Timestamp < b.startedAt { + return + } + + groupJID := message.Info.RemoteJid + senderJID := message.Info.SenderJid + + if len(senderJID) == 0 { + if message.Info.Source != nil && message.Info.Source.Participant != nil { + senderJID = *message.Info.Source.Participant + } + } + + // translate sender's JID to the nicest username we can get + senderName := b.getSenderName(senderJID) if senderName == "" { senderName = "Someone" // don't expose telephone number } - if msg.GetExtendedTextMessage() == nil && msg.GetConversation() == "" { - b.Log.Debugf("message without text content? %#v", msg) - return - } + extText := message.Info.Source.Message.ExtendedTextMessage + if extText != nil && extText.ContextInfo != nil && extText.ContextInfo.MentionedJid != nil { + // handle user mentions + for _, mentionedJID := range extText.ContextInfo.MentionedJid { + numberAndSuffix := strings.SplitN(mentionedJID, "@", 2) - var text string - - // nolint:nestif - if msg.GetExtendedTextMessage() == nil { - text = msg.GetConversation() - } else { - text = msg.GetExtendedTextMessage().GetText() - ci := msg.GetExtendedTextMessage().GetContextInfo() - - if senderJID == (types.JID{}) && ci.Participant != nil { - senderJID = types.NewJID(ci.GetParticipant(), types.DefaultUserServer) - } - - if ci.MentionedJid != nil { - // handle user mentions - for _, mentionedJID := range ci.MentionedJid { - numberAndSuffix := strings.SplitN(mentionedJID, "@", 2) - - // mentions comes as telephone numbers and we don't want to expose it to other bridges - // replace it with something more meaninful to others - mention := b.getSenderNotify(types.NewJID(numberAndSuffix[0], types.DefaultUserServer)) - if mention == "" { - mention = "someone" - } - - text = strings.Replace(text, "@"+numberAndSuffix[0], "@"+mention, 1) + // mentions comes as telephone numbers and we don't want to expose it to other bridges + // replace it with something more meaninful to others + mention := b.getSenderNotify(numberAndSuffix[0] + "@s.whatsapp.net") + if mention == "" { + mention = "someone" } + + message.Text = strings.Replace(message.Text, "@"+numberAndSuffix[0], "@"+mention, 1) } } rmsg := config.Message{ - UserID: senderJID.String(), + UserID: senderJID, Username: senderName, - Text: text, - Channel: channel.String(), + Text: message.Text, + Channel: groupJID, Account: b.Account, Protocol: b.Protocol, Extra: make(map[string][]interface{}), - // ParentID: TODO, // TODO handle thread replies // map from Info.QuotedMessageID string - ID: messageInfo.ID, + // ParentID: TODO, // TODO handle thread replies // map from Info.QuotedMessageID string + ID: message.Info.Id, } - if avatarURL, exists := b.userAvatars[senderJID.String()]; exists { + if avatarURL, exists := b.userAvatars[senderJID]; exists { rmsg.Avatar = avatarURL } @@ -112,32 +134,36 @@ func (b *Bwhatsapp) handleTextMessage(messageInfo types.MessageInfo, msg *proto. } // HandleImageMessage sent from WhatsApp, relay it to the brige -func (b *Bwhatsapp) handleImageMessage(msg *events.Message) { - imsg := msg.Message.GetImageMessage() +func (b *Bwhatsapp) HandleImageMessage(message whatsapp.ImageMessage) { + if message.Info.FromMe || message.Info.Timestamp < b.startedAt { + return + } - senderJID := msg.Info.Sender - senderName := b.getSenderName(senderJID) - ci := imsg.GetContextInfo() + senderJID := message.Info.SenderJid + if len(message.Info.SenderJid) == 0 && message.Info.Source != nil && message.Info.Source.Participant != nil { + senderJID = *message.Info.Source.Participant + } - if senderJID == (types.JID{}) && ci.Participant != nil { - senderJID = types.NewJID(ci.GetParticipant(), types.DefaultUserServer) + senderName := b.getSenderName(message.Info.SenderJid) + if senderName == "" { + senderName = "Someone" // don't expose telephone number } rmsg := config.Message{ - UserID: senderJID.String(), + UserID: senderJID, Username: senderName, - Channel: msg.Info.Chat.String(), + Channel: message.Info.RemoteJid, Account: b.Account, Protocol: b.Protocol, Extra: make(map[string][]interface{}), - ID: msg.Info.ID, + ID: message.Info.Id, } - if avatarURL, exists := b.userAvatars[senderJID.String()]; exists { + if avatarURL, exists := b.userAvatars[senderJID]; exists { rmsg.Avatar = avatarURL } - fileExt, err := mime.ExtensionsByType(imsg.GetMimetype()) + fileExt, err := mime.ExtensionsByType(message.Type) if err != nil { b.Log.Errorf("Mimetype detection error: %s", err) @@ -154,11 +180,11 @@ func (b *Bwhatsapp) handleImageMessage(msg *events.Message) { fileExt[0] = ".jpg" } - filename := fmt.Sprintf("%v%v", msg.Info.ID, fileExt[0]) + filename := fmt.Sprintf("%v%v", message.Info.Id, fileExt[0]) - b.Log.Debugf("Trying to download %s with type %s", filename, imsg.GetMimetype()) + b.Log.Debugf("Trying to download %s with type %s", filename, message.Type) - data, err := b.wc.Download(imsg) + data, err := message.Download() if err != nil { b.Log.Errorf("Download image failed: %s", err) @@ -166,7 +192,7 @@ func (b *Bwhatsapp) handleImageMessage(msg *events.Message) { } // Move file to bridge storage - helper.HandleDownloadData(b.Log, &rmsg, filename, imsg.GetCaption(), "", &data, b.General) + helper.HandleDownloadData(b.Log, &rmsg, filename, message.Caption, "", &data, b.General) b.Log.Debugf("<= Sending message from %s on %s to gateway", senderJID, b.Account) b.Log.Debugf("<= Message is %#v", rmsg) @@ -175,32 +201,36 @@ func (b *Bwhatsapp) handleImageMessage(msg *events.Message) { } // HandleVideoMessage downloads video messages -func (b *Bwhatsapp) handleVideoMessage(msg *events.Message) { - imsg := msg.Message.GetVideoMessage() +func (b *Bwhatsapp) HandleVideoMessage(message whatsapp.VideoMessage) { + if message.Info.FromMe || message.Info.Timestamp < b.startedAt { + return + } - senderJID := msg.Info.Sender - senderName := b.getSenderName(senderJID) - ci := imsg.GetContextInfo() + senderJID := message.Info.SenderJid + if len(message.Info.SenderJid) == 0 && message.Info.Source != nil && message.Info.Source.Participant != nil { + senderJID = *message.Info.Source.Participant + } - if senderJID == (types.JID{}) && ci.Participant != nil { - senderJID = types.NewJID(ci.GetParticipant(), types.DefaultUserServer) + senderName := b.getSenderName(message.Info.SenderJid) + if senderName == "" { + senderName = "Someone" // don't expose telephone number } rmsg := config.Message{ - UserID: senderJID.String(), + UserID: senderJID, Username: senderName, - Channel: msg.Info.Chat.String(), + Channel: message.Info.RemoteJid, Account: b.Account, Protocol: b.Protocol, Extra: make(map[string][]interface{}), - ID: msg.Info.ID, + ID: message.Info.Id, } - if avatarURL, exists := b.userAvatars[senderJID.String()]; exists { + if avatarURL, exists := b.userAvatars[senderJID]; exists { rmsg.Avatar = avatarURL } - fileExt, err := mime.ExtensionsByType(imsg.GetMimetype()) + fileExt, err := mime.ExtensionsByType(message.Type) if err != nil { b.Log.Errorf("Mimetype detection error: %s", err) @@ -211,11 +241,11 @@ func (b *Bwhatsapp) handleVideoMessage(msg *events.Message) { fileExt = append(fileExt, ".mp4") } - filename := fmt.Sprintf("%v%v", msg.Info.ID, fileExt[0]) + filename := fmt.Sprintf("%v%v", message.Info.Id, fileExt[0]) - b.Log.Debugf("Trying to download %s with size %#v and type %s", filename, imsg.GetFileLength(), imsg.GetMimetype()) + b.Log.Debugf("Trying to download %s with size %#v and type %s", filename, message.Length, message.Type) - data, err := b.wc.Download(imsg) + data, err := message.Download() if err != nil { b.Log.Errorf("Download video failed: %s", err) @@ -223,7 +253,7 @@ func (b *Bwhatsapp) handleVideoMessage(msg *events.Message) { } // Move file to bridge storage - helper.HandleDownloadData(b.Log, &rmsg, filename, imsg.GetCaption(), "", &data, b.General) + helper.HandleDownloadData(b.Log, &rmsg, filename, message.Caption, "", &data, b.General) b.Log.Debugf("<= Sending message from %s on %s to gateway", senderJID, b.Account) b.Log.Debugf("<= Message is %#v", rmsg) @@ -232,32 +262,36 @@ func (b *Bwhatsapp) handleVideoMessage(msg *events.Message) { } // HandleAudioMessage downloads audio messages -func (b *Bwhatsapp) handleAudioMessage(msg *events.Message) { - imsg := msg.Message.GetAudioMessage() +func (b *Bwhatsapp) HandleAudioMessage(message whatsapp.AudioMessage) { + if message.Info.FromMe || message.Info.Timestamp < b.startedAt { + return + } - senderJID := msg.Info.Sender - senderName := b.getSenderName(senderJID) - ci := imsg.GetContextInfo() + senderJID := message.Info.SenderJid + if len(message.Info.SenderJid) == 0 && message.Info.Source != nil && message.Info.Source.Participant != nil { + senderJID = *message.Info.Source.Participant + } - if senderJID == (types.JID{}) && ci.Participant != nil { - senderJID = types.NewJID(ci.GetParticipant(), types.DefaultUserServer) + senderName := b.getSenderName(message.Info.SenderJid) + if senderName == "" { + senderName = "Someone" // don't expose telephone number } rmsg := config.Message{ - UserID: senderJID.String(), + UserID: senderJID, Username: senderName, - Channel: msg.Info.Chat.String(), + Channel: message.Info.RemoteJid, Account: b.Account, Protocol: b.Protocol, Extra: make(map[string][]interface{}), - ID: msg.Info.ID, + ID: message.Info.Id, } - if avatarURL, exists := b.userAvatars[senderJID.String()]; exists { + if avatarURL, exists := b.userAvatars[senderJID]; exists { rmsg.Avatar = avatarURL } - fileExt, err := mime.ExtensionsByType(imsg.GetMimetype()) + fileExt, err := mime.ExtensionsByType(message.Type) if err != nil { b.Log.Errorf("Mimetype detection error: %s", err) @@ -268,13 +302,13 @@ func (b *Bwhatsapp) handleAudioMessage(msg *events.Message) { fileExt = append(fileExt, ".ogg") } - filename := fmt.Sprintf("%v%v", msg.Info.ID, fileExt[0]) + filename := fmt.Sprintf("%v%v", message.Info.Id, fileExt[0]) - b.Log.Debugf("Trying to download %s with size %#v and type %s", filename, imsg.GetFileLength(), imsg.GetMimetype()) + b.Log.Debugf("Trying to download %s with size %#v and type %s", filename, message.Length, message.Type) - data, err := b.wc.Download(imsg) + data, err := message.Download() if err != nil { - b.Log.Errorf("Download video failed: %s", err) + b.Log.Errorf("Download audio failed: %s", err) return } @@ -289,43 +323,47 @@ func (b *Bwhatsapp) handleAudioMessage(msg *events.Message) { } // HandleDocumentMessage downloads documents -func (b *Bwhatsapp) handleDocumentMessage(msg *events.Message) { - imsg := msg.Message.GetDocumentMessage() +func (b *Bwhatsapp) HandleDocumentMessage(message whatsapp.DocumentMessage) { + if message.Info.FromMe || message.Info.Timestamp < b.startedAt { + return + } - senderJID := msg.Info.Sender - senderName := b.getSenderName(senderJID) - ci := imsg.GetContextInfo() + senderJID := message.Info.SenderJid + if len(message.Info.SenderJid) == 0 && message.Info.Source != nil && message.Info.Source.Participant != nil { + senderJID = *message.Info.Source.Participant + } - if senderJID == (types.JID{}) && ci.Participant != nil { - senderJID = types.NewJID(ci.GetParticipant(), types.DefaultUserServer) + senderName := b.getSenderName(message.Info.SenderJid) + if senderName == "" { + senderName = "Someone" // don't expose telephone number } rmsg := config.Message{ - UserID: senderJID.String(), + UserID: senderJID, Username: senderName, - Channel: msg.Info.Chat.String(), + Channel: message.Info.RemoteJid, Account: b.Account, Protocol: b.Protocol, Extra: make(map[string][]interface{}), - ID: msg.Info.ID, + ID: message.Info.Id, } - if avatarURL, exists := b.userAvatars[senderJID.String()]; exists { + if avatarURL, exists := b.userAvatars[senderJID]; exists { rmsg.Avatar = avatarURL } - fileExt, err := mime.ExtensionsByType(imsg.GetMimetype()) + fileExt, err := mime.ExtensionsByType(message.Type) if err != nil { b.Log.Errorf("Mimetype detection error: %s", err) return } - filename := fmt.Sprintf("%v", imsg.GetFileName()) + filename := fmt.Sprintf("%v", message.FileName) - b.Log.Debugf("Trying to download %s with extension %s and type %s", filename, fileExt, imsg.GetMimetype()) + b.Log.Debugf("Trying to download %s with extension %s and type %s", filename, fileExt, message.Type) - data, err := b.wc.Download(imsg) + data, err := message.Download() if err != nil { b.Log.Errorf("Download document message failed: %s", err) diff --git a/bridge/whatsapp/helpers.go b/bridge/whatsapp/helpers.go index b32372c5..e424387d 100644 --- a/bridge/whatsapp/helpers.go +++ b/bridge/whatsapp/helpers.go @@ -1,12 +1,15 @@ package bwhatsapp import ( + "encoding/gob" + "encoding/json" + "errors" "fmt" + "os" "strings" - "go.mau.fi/whatsmeow/store" - "go.mau.fi/whatsmeow/store/sqlstore" - "go.mau.fi/whatsmeow/types" + qrcodeTerminal "github.com/Baozisoftware/qrcode-terminal-go" + "github.com/Rhymen/go-whatsapp" ) type ProfilePicInfo struct { @@ -15,71 +18,141 @@ type ProfilePicInfo struct { Status int16 `json:"status"` } -func (b *Bwhatsapp) getSenderName(senderJid types.JID) string { - if sender, exists := b.contacts[senderJid]; exists { - if sender.FullName != "" { - return sender.FullName +func qrFromTerminal(invert bool) chan string { + qr := make(chan string) + + go func() { + terminal := qrcodeTerminal.New() + + if invert { + terminal = qrcodeTerminal.New2(qrcodeTerminal.ConsoleColors.BrightWhite, qrcodeTerminal.ConsoleColors.BrightBlack, qrcodeTerminal.QRCodeRecoveryLevels.Medium) + } + + terminal.Get(<-qr).Print() + }() + + return qr +} + +func (b *Bwhatsapp) readSession() (whatsapp.Session, error) { + session := whatsapp.Session{} + sessionFile := b.Config.GetString(sessionFile) + + if sessionFile == "" { + return session, errors.New("if you won't set SessionFile then you will need to scan QR code on every restart") + } + + file, err := os.Open(sessionFile) + if err != nil { + return session, err + } + + defer file.Close() + + decoder := gob.NewDecoder(file) + + return session, decoder.Decode(&session) +} + +func (b *Bwhatsapp) writeSession(session whatsapp.Session) error { + sessionFile := b.Config.GetString(sessionFile) + + if sessionFile == "" { + // we already sent a warning while starting the bridge, so let's be quiet here + return nil + } + + file, err := os.Create(sessionFile) + if err != nil { + return err + } + + defer file.Close() + + encoder := gob.NewEncoder(file) + + return encoder.Encode(session) +} + +func (b *Bwhatsapp) restoreSession() (*whatsapp.Session, error) { + session, err := b.readSession() + if err != nil { + b.Log.Warn(err.Error()) + } + + b.Log.Debugln("Restoring WhatsApp session..") + + session, err = b.conn.RestoreWithSession(session) + if err != nil { + // restore session connection timed out (I couldn't get over it without logging in again) + return nil, errors.New("failed to restore session: " + err.Error()) + } + + b.Log.Debugln("Session restored successfully!") + + return &session, nil +} + +func (b *Bwhatsapp) getSenderName(senderJid string) string { + if sender, exists := b.users[senderJid]; exists { + if sender.Name != "" { + return sender.Name } // if user is not in phone contacts // it is the most obvious scenario unless you sync your phone contacts with some remote updated source // users can change it in their WhatsApp settings -> profile -> click on Avatar - if sender.PushName != "" { - return sender.PushName + if sender.Notify != "" { + return sender.Notify } - if sender.FirstName != "" { - return sender.FirstName + if sender.Short != "" { + return sender.Short } } // try to reload this contact - if _, err := b.wc.Store.Contacts.GetAllContacts(); err != nil { - b.Log.Errorf("error on update of contacts: %v", err) - } - - allcontacts, err := b.wc.Store.Contacts.GetAllContacts() + _, err := b.conn.Contacts() if err != nil { b.Log.Errorf("error on update of contacts: %v", err) } - if len(allcontacts) > 0 { - b.contacts = allcontacts - } + if contact, exists := b.conn.Store.Contacts[senderJid]; exists { + // Add it to the user map + b.users[senderJid] = contact - if sender, exists := b.contacts[senderJid]; exists { - if sender.FullName != "" { - return sender.FullName + if contact.Name != "" { + return contact.Name } // if user is not in phone contacts - // it is the most obvious scenario unless you sync your phone contacts with some remote updated source - // users can change it in their WhatsApp settings -> profile -> click on Avatar - if sender.PushName != "" { - return sender.PushName - } - - if sender.FirstName != "" { - return sender.FirstName - } - } - - return "Someone" -} - -func (b *Bwhatsapp) getSenderNotify(senderJid types.JID) string { - if sender, exists := b.contacts[senderJid]; exists { - return sender.PushName + // same as above + return contact.Notify } return "" } -func (b *Bwhatsapp) GetProfilePicThumb(jid string) (*types.ProfilePictureInfo, error) { - pjid, _ := types.ParseJID(jid) - info, err := b.wc.GetProfilePictureInfo(pjid, true) +func (b *Bwhatsapp) getSenderNotify(senderJid string) string { + if sender, exists := b.users[senderJid]; exists { + return sender.Notify + } + + return "" +} + +func (b *Bwhatsapp) GetProfilePicThumb(jid string) (*ProfilePicInfo, error) { + data, err := b.conn.GetProfilePicThumb(jid) if err != nil { return nil, fmt.Errorf("failed to get avatar: %v", err) } + content := <-data + info := &ProfilePicInfo{} + + err = json.Unmarshal([]byte(content), info) + if err != nil { + return info, fmt.Errorf("failed to unmarshal avatar info: %v", err) + } + return info, nil } @@ -88,19 +161,3 @@ func isGroupJid(identifier string) bool { strings.HasSuffix(identifier, "@temp") || strings.HasSuffix(identifier, "@broadcast") } - -func (b *Bwhatsapp) getDevice() (*store.Device, error) { - device := &store.Device{} - - storeContainer, err := sqlstore.New("sqlite", "file:"+b.Config.GetString("sessionfile")+".db?_foreign_keys=on&_pragma=busy_timeout=10000", nil) - if err != nil { - return device, fmt.Errorf("failed to connect to database: %v", err) - } - - device, err = storeContainer.GetFirstDevice() - if err != nil { - return device, fmt.Errorf("failed to get device: %v", err) - } - - return device, nil -} diff --git a/bridge/whatsapp/whatsapp.go b/bridge/whatsapp/whatsapp.go index 2ba39c14..ba0ede64 100644 --- a/bridge/whatsapp/whatsapp.go +++ b/bridge/whatsapp/whatsapp.go @@ -1,41 +1,38 @@ package bwhatsapp import ( - "context" + "bytes" + "crypto/rand" + "encoding/hex" "errors" "fmt" "mime" "os" "path/filepath" + "strings" "time" "github.com/42wim/matterbridge/bridge" "github.com/42wim/matterbridge/bridge/config" - "github.com/mdp/qrterminal" - - "go.mau.fi/whatsmeow" - "go.mau.fi/whatsmeow/binary/proto" - "go.mau.fi/whatsmeow/types" - waLog "go.mau.fi/whatsmeow/util/log" - - goproto "google.golang.org/protobuf/proto" - - _ "modernc.org/sqlite" // needed for sqlite + "github.com/Rhymen/go-whatsapp" ) const ( // Account config parameters - cfgNumber = "Number" + cfgNumber = "Number" + qrOnWhiteTerminal = "QrOnWhiteTerminal" + sessionFile = "SessionFile" ) // Bwhatsapp Bridge structure keeping all the information needed for relying type Bwhatsapp struct { *bridge.Config - startedAt time.Time - wc *whatsmeow.Client - contacts map[types.JID]types.ContactInfo - users map[string]types.ContactInfo + session *whatsapp.Session + conn *whatsapp.Conn + startedAt uint64 + + users map[string]whatsapp.Contact userAvatars map[string]string } @@ -50,7 +47,7 @@ func New(cfg *bridge.Config) bridge.Bridger { b := &Bwhatsapp{ Config: cfg, - users: make(map[string]types.ContactInfo), + users: make(map[string]whatsapp.Contact), userAvatars: make(map[string]string), } @@ -59,92 +56,101 @@ func New(cfg *bridge.Config) bridge.Bridger { // Connect to WhatsApp. Required implementation of the Bridger interface func (b *Bwhatsapp) Connect() error { - device, err := b.getDevice() - if err != nil { - return err - } - number := b.GetString(cfgNumber) if number == "" { return errors.New("whatsapp's telephone number need to be configured") } b.Log.Debugln("Connecting to WhatsApp..") - - b.wc = whatsmeow.NewClient(device, waLog.Stdout("Client", "INFO", true)) - b.wc.AddEventHandler(b.eventHandler) - - firstlogin := false - var qrChan <-chan whatsmeow.QRChannelItem - if b.wc.Store.ID == nil { - firstlogin = true - qrChan, err = b.wc.GetQRChannel(context.Background()) - if err != nil && !errors.Is(err, whatsmeow.ErrQRStoreContainsID) { - return errors.New("failed to to get QR channel:" + err.Error()) - } - } - - err = b.wc.Connect() + conn, err := whatsapp.NewConn(20 * time.Second) if err != nil { return errors.New("failed to connect to WhatsApp: " + err.Error()) } - if b.wc.Store.ID == nil { - for evt := range qrChan { - if evt.Event == "code" { - qrterminal.GenerateHalfBlock(evt.Code, qrterminal.L, os.Stdout) - } else { - b.Log.Infof("QR channel result: %s", evt.Event) - } - } - } + b.conn = conn - // disconnect and reconnect on our first login/pairing - // for some reason the GetJoinedGroups in JoinChannel doesn't work on first login - if firstlogin { - b.wc.Disconnect() - time.Sleep(time.Second) + b.conn.AddHandler(b) + b.Log.Debugln("WhatsApp connection successful") - err = b.wc.Connect() - if err != nil { - return errors.New("failed to connect to WhatsApp: " + err.Error()) - } - } - - b.Log.Infoln("WhatsApp connection successful") - - b.contacts, err = b.wc.Store.Contacts.GetAllContacts() + // load existing session in order to keep it between restarts + b.session, err = b.restoreSession() if err != nil { - return errors.New("failed to get contacts: " + err.Error()) + b.Log.Warn(err.Error()) } - b.startedAt = time.Now() + // login to a new session + if b.session == nil { + if err = b.Login(); err != nil { + return err + } + } + + b.startedAt = uint64(time.Now().Unix()) + + _, err = b.conn.Contacts() + if err != nil { + return fmt.Errorf("error on update of contacts: %v", err) + } + + // see https://github.com/Rhymen/go-whatsapp/issues/137#issuecomment-480316013 + for len(b.conn.Store.Contacts) == 0 { + b.conn.Contacts() // nolint:errcheck + + <-time.After(1 * time.Second) + } // map all the users - for id, contact := range b.contacts { - if !isGroupJid(id.String()) && id.String() != "status@broadcast" { + for id, contact := range b.conn.Store.Contacts { + if !isGroupJid(id) && id != "status@broadcast" { // it is user - b.users[id.String()] = contact + b.users[id] = contact } } // get user avatar asynchronously - b.Log.Info("Getting user avatars..") + go func() { + b.Log.Debug("Getting user avatars..") - for jid := range b.users { - info, err := b.GetProfilePicThumb(jid) - if err != nil { - b.Log.Warnf("Could not get profile photo of %s: %v", jid, err) - } else { - b.Lock() - if info != nil { + for jid := range b.users { + info, err := b.GetProfilePicThumb(jid) + if err != nil { + b.Log.Warnf("Could not get profile photo of %s: %v", jid, err) + } else { + b.Lock() b.userAvatars[jid] = info.URL + b.Unlock() } - b.Unlock() } + + b.Log.Debug("Finished getting avatars..") + }() + + return nil +} + +// Login to WhatsApp creating a new session. This will require to scan a QR code on your mobile device +func (b *Bwhatsapp) Login() error { + b.Log.Debugln("Logging in..") + + invert := b.GetBool(qrOnWhiteTerminal) // false is the default + qrChan := qrFromTerminal(invert) + + session, err := b.conn.Login(qrChan) + if err != nil { + b.Log.Warnln("Failed to log in:", err) + + return err } - b.Log.Info("Finished getting avatars..") + b.session = &session + + b.Log.Infof("Logged into session: %#v", session) + b.Log.Infof("Connection: %#v", b.conn) + + err = b.writeSession(session) + if err != nil { + fmt.Fprintf(os.Stderr, "error saving session: %v\n", err) + } return nil } @@ -152,8 +158,8 @@ func (b *Bwhatsapp) Connect() error { // Disconnect is called while reconnecting to the bridge // Required implementation of the Bridger interface func (b *Bwhatsapp) Disconnect() error { - b.wc.Disconnect() - + // We could Logout, but that would close the session completely and would require a new QR code scan + // https://github.com/Rhymen/go-whatsapp/blob/c31092027237441cffba1b9cb148eadf7c83c3d2/session.go#L377-L381 return nil } @@ -163,118 +169,111 @@ func (b *Bwhatsapp) Disconnect() error { func (b *Bwhatsapp) JoinChannel(channel config.ChannelInfo) error { byJid := isGroupJid(channel.Name) - groups, err := b.wc.GetJoinedGroups() - if err != nil { - return err + // see https://github.com/Rhymen/go-whatsapp/issues/137#issuecomment-480316013 + for len(b.conn.Store.Contacts) == 0 { + b.conn.Contacts() // nolint:errcheck + <-time.After(1 * time.Second) } // verify if we are member of the given group if byJid { - gJID, err := types.ParseJID(channel.Name) - if err != nil { - return err + // channel.Name specifies static group jID, not the name + if _, exists := b.conn.Store.Contacts[channel.Name]; !exists { + return fmt.Errorf("account doesn't belong to group with jid %s", channel.Name) } - for _, group := range groups { - if group.JID == gJID { - return nil - } + return nil + } + + // channel.Name specifies group name that might change, warn about it + var jids []string + for id, contact := range b.conn.Store.Contacts { + if isGroupJid(id) && contact.Name == channel.Name { + jids = append(jids, id) } } - foundGroups := []string{} - - for _, group := range groups { - if group.Name == channel.Name { - foundGroups = append(foundGroups, group.Name) - } - } - - switch len(foundGroups) { + switch len(jids) { case 0: // didn't match any group - print out possibilites - for _, group := range groups { - b.Log.Infof("%s %s", group.JID, group.Name) + for id, contact := range b.conn.Store.Contacts { + if isGroupJid(id) { + b.Log.Infof("%s %s", contact.Jid, contact.Name) + } } + return fmt.Errorf("please specify group's JID from the list above instead of the name '%s'", channel.Name) case 1: - return fmt.Errorf("group name might change. Please configure gateway with channel=\"%v\" instead of channel=\"%v\"", foundGroups[0], channel.Name) + return fmt.Errorf("group name might change. Please configure gateway with channel=\"%v\" instead of channel=\"%v\"", jids[0], channel.Name) default: - return fmt.Errorf("there is more than one group with name '%s'. Please specify one of JIDs as channel name: %v", channel.Name, foundGroups) + return fmt.Errorf("there is more than one group with name '%s'. Please specify one of JIDs as channel name: %v", channel.Name, jids) } } // Post a document message from the bridge to WhatsApp func (b *Bwhatsapp) PostDocumentMessage(msg config.Message, filetype string) (string, error) { - groupJID, _ := types.ParseJID(msg.Channel) - fi := msg.Extra["file"][0].(config.FileInfo) - resp, err := b.wc.Upload(context.Background(), *fi.Data, whatsmeow.MediaDocument) - if err != nil { - return "", err - } - // Post document message - var message proto.Message - - message.DocumentMessage = &proto.DocumentMessage{ - Title: &fi.Name, - FileName: &fi.Name, - Mimetype: &filetype, - MediaKey: resp.MediaKey, - FileEncSha256: resp.FileEncSHA256, - FileSha256: resp.FileSHA256, - FileLength: goproto.Uint64(resp.FileLength), - Url: &resp.URL, + message := whatsapp.DocumentMessage{ + Info: whatsapp.MessageInfo{ + RemoteJid: msg.Channel, + }, + Title: fi.Name, + FileName: fi.Name, + Type: filetype, + Content: bytes.NewReader(*fi.Data), } b.Log.Debugf("=> Sending %#v", msg) - ID := whatsmeow.GenerateMessageID() - _, err = b.wc.SendMessage(groupJID, ID, &message) + // create message ID + // TODO follow and act if https://github.com/Rhymen/go-whatsapp/issues/101 implemented + idBytes := make([]byte, 10) + if _, err := rand.Read(idBytes); err != nil { + b.Log.Warn(err.Error()) + } - return ID, err + message.Info.Id = strings.ToUpper(hex.EncodeToString(idBytes)) + _, err := b.conn.Send(message) + + return message.Info.Id, err } // Post an image message from the bridge to WhatsApp // Handle, for sure image/jpeg, image/png and image/gif MIME types func (b *Bwhatsapp) PostImageMessage(msg config.Message, filetype string) (string, error) { - groupJID, _ := types.ParseJID(msg.Channel) - fi := msg.Extra["file"][0].(config.FileInfo) - caption := msg.Username + fi.Comment - - resp, err := b.wc.Upload(context.Background(), *fi.Data, whatsmeow.MediaImage) - if err != nil { - return "", err - } - - var message proto.Message - - message.ImageMessage = &proto.ImageMessage{ - Mimetype: &filetype, - Caption: &caption, - MediaKey: resp.MediaKey, - FileEncSha256: resp.FileEncSHA256, - FileSha256: resp.FileSHA256, - FileLength: goproto.Uint64(resp.FileLength), - Url: &resp.URL, + // Post image message + message := whatsapp.ImageMessage{ + Info: whatsapp.MessageInfo{ + RemoteJid: msg.Channel, + }, + Type: filetype, + Caption: msg.Username + fi.Comment, + Content: bytes.NewReader(*fi.Data), } b.Log.Debugf("=> Sending %#v", msg) - ID := whatsmeow.GenerateMessageID() - _, err = b.wc.SendMessage(groupJID, ID, &message) + // create message ID + // TODO follow and act if https://github.com/Rhymen/go-whatsapp/issues/101 implemented + idBytes := make([]byte, 10) + if _, err := rand.Read(idBytes); err != nil { + b.Log.Warn(err.Error()) + } - return ID, err + message.Info.Id = strings.ToUpper(hex.EncodeToString(idBytes)) + _, err := b.conn.Send(message) + + return message.Info.Id, err } // Send a message from the bridge to WhatsApp +// Required implementation of the Bridger interface +// https://github.com/42wim/matterbridge/blob/2cfd880cdb0df29771bf8f31df8d990ab897889d/bridge/bridge.go#L11-L16 func (b *Bwhatsapp) Send(msg config.Message) (string, error) { - groupJID, _ := types.ParseJID(msg.Channel) - b.Log.Debugf("=> Receiving %#v", msg) // Delete message @@ -285,7 +284,7 @@ func (b *Bwhatsapp) Send(msg config.Message) (string, error) { return "", nil } - _, err := b.wc.RevokeMessage(groupJID, msg.ID) + _, err := b.conn.RevokeMessage(msg.Channel, msg.ID, true) return "", err } @@ -318,14 +317,20 @@ func (b *Bwhatsapp) Send(msg config.Message) (string, error) { } } - text := msg.Username + msg.Text + // Post text message + message := whatsapp.TextMessage{ + Info: whatsapp.MessageInfo{ + RemoteJid: msg.Channel, // which equals to group id + }, + Text: msg.Username + msg.Text, + } - var message proto.Message + b.Log.Debugf("=> Sending %#v", msg) - message.Conversation = &text - - ID := whatsmeow.GenerateMessageID() - _, err := b.wc.SendMessage(groupJID, ID, &message) - - return ID, err + return b.conn.Send(message) } + +// TODO do we want that? to allow login with QR code from a bridged channel? https://github.com/tulir/mautrix-whatsapp/blob/513eb18e2d59bada0dd515ee1abaaf38a3bfe3d5/commands.go#L76 +//func (b *Bwhatsapp) Command(cmd string) string { +// return "" +//} diff --git a/bridge/whatsappmulti/handlers.go b/bridge/whatsappmulti/handlers.go new file mode 100644 index 00000000..c6b96a5e --- /dev/null +++ b/bridge/whatsappmulti/handlers.go @@ -0,0 +1,344 @@ +// +build whatsappmulti + +package bwhatsapp + +import ( + "fmt" + "mime" + "strings" + + "github.com/42wim/matterbridge/bridge/config" + "github.com/42wim/matterbridge/bridge/helper" + + "go.mau.fi/whatsmeow/binary/proto" + "go.mau.fi/whatsmeow/types" + "go.mau.fi/whatsmeow/types/events" +) + +// nolint:gocritic +func (b *Bwhatsapp) eventHandler(evt interface{}) { + switch e := evt.(type) { + case *events.Message: + b.handleMessage(e) + } +} + +func (b *Bwhatsapp) handleMessage(message *events.Message) { + msg := message.Message + switch { + case msg == nil, message.Info.IsFromMe, message.Info.Timestamp.Before(b.startedAt): + return + } + + b.Log.Infof("Receiving message %#v", msg) + + switch { + case msg.Conversation != nil || msg.ExtendedTextMessage != nil: + b.handleTextMessage(message.Info, msg) + case msg.VideoMessage != nil: + b.handleVideoMessage(message) + case msg.AudioMessage != nil: + b.handleAudioMessage(message) + case msg.DocumentMessage != nil: + b.handleDocumentMessage(message) + case msg.ImageMessage != nil: + b.handleImageMessage(message) + } +} + +// nolint:funlen +func (b *Bwhatsapp) handleTextMessage(messageInfo types.MessageInfo, msg *proto.Message) { + senderJID := messageInfo.Sender + channel := messageInfo.Chat + + senderName := b.getSenderName(messageInfo.Sender) + if senderName == "" { + senderName = "Someone" // don't expose telephone number + } + + if msg.GetExtendedTextMessage() == nil && msg.GetConversation() == "" { + b.Log.Debugf("message without text content? %#v", msg) + return + } + + var text string + + // nolint:nestif + if msg.GetExtendedTextMessage() == nil { + text = msg.GetConversation() + } else { + text = msg.GetExtendedTextMessage().GetText() + ci := msg.GetExtendedTextMessage().GetContextInfo() + + if senderJID == (types.JID{}) && ci.Participant != nil { + senderJID = types.NewJID(ci.GetParticipant(), types.DefaultUserServer) + } + + if ci.MentionedJid != nil { + // handle user mentions + for _, mentionedJID := range ci.MentionedJid { + numberAndSuffix := strings.SplitN(mentionedJID, "@", 2) + + // mentions comes as telephone numbers and we don't want to expose it to other bridges + // replace it with something more meaninful to others + mention := b.getSenderNotify(types.NewJID(numberAndSuffix[0], types.DefaultUserServer)) + if mention == "" { + mention = "someone" + } + + text = strings.Replace(text, "@"+numberAndSuffix[0], "@"+mention, 1) + } + } + } + + rmsg := config.Message{ + UserID: senderJID.String(), + Username: senderName, + Text: text, + Channel: channel.String(), + Account: b.Account, + Protocol: b.Protocol, + Extra: make(map[string][]interface{}), + // ParentID: TODO, // TODO handle thread replies // map from Info.QuotedMessageID string + ID: messageInfo.ID, + } + + if avatarURL, exists := b.userAvatars[senderJID.String()]; exists { + rmsg.Avatar = avatarURL + } + + b.Log.Debugf("<= Sending message from %s on %s to gateway", senderJID, b.Account) + b.Log.Debugf("<= Message is %#v", rmsg) + + b.Remote <- rmsg +} + +// HandleImageMessage sent from WhatsApp, relay it to the brige +func (b *Bwhatsapp) handleImageMessage(msg *events.Message) { + imsg := msg.Message.GetImageMessage() + + senderJID := msg.Info.Sender + senderName := b.getSenderName(senderJID) + ci := imsg.GetContextInfo() + + if senderJID == (types.JID{}) && ci.Participant != nil { + senderJID = types.NewJID(ci.GetParticipant(), types.DefaultUserServer) + } + + rmsg := config.Message{ + UserID: senderJID.String(), + Username: senderName, + Channel: msg.Info.Chat.String(), + Account: b.Account, + Protocol: b.Protocol, + Extra: make(map[string][]interface{}), + ID: msg.Info.ID, + } + + if avatarURL, exists := b.userAvatars[senderJID.String()]; exists { + rmsg.Avatar = avatarURL + } + + fileExt, err := mime.ExtensionsByType(imsg.GetMimetype()) + if err != nil { + b.Log.Errorf("Mimetype detection error: %s", err) + + return + } + + // rename .jfif to .jpg https://github.com/42wim/matterbridge/issues/1292 + if fileExt[0] == ".jfif" { + fileExt[0] = ".jpg" + } + + // rename .jpe to .jpg https://github.com/42wim/matterbridge/issues/1463 + if fileExt[0] == ".jpe" { + fileExt[0] = ".jpg" + } + + filename := fmt.Sprintf("%v%v", msg.Info.ID, fileExt[0]) + + b.Log.Debugf("Trying to download %s with type %s", filename, imsg.GetMimetype()) + + data, err := b.wc.Download(imsg) + if err != nil { + b.Log.Errorf("Download image failed: %s", err) + + return + } + + // Move file to bridge storage + helper.HandleDownloadData(b.Log, &rmsg, filename, imsg.GetCaption(), "", &data, b.General) + + b.Log.Debugf("<= Sending message from %s on %s to gateway", senderJID, b.Account) + b.Log.Debugf("<= Message is %#v", rmsg) + + b.Remote <- rmsg +} + +// HandleVideoMessage downloads video messages +func (b *Bwhatsapp) handleVideoMessage(msg *events.Message) { + imsg := msg.Message.GetVideoMessage() + + senderJID := msg.Info.Sender + senderName := b.getSenderName(senderJID) + ci := imsg.GetContextInfo() + + if senderJID == (types.JID{}) && ci.Participant != nil { + senderJID = types.NewJID(ci.GetParticipant(), types.DefaultUserServer) + } + + rmsg := config.Message{ + UserID: senderJID.String(), + Username: senderName, + Channel: msg.Info.Chat.String(), + Account: b.Account, + Protocol: b.Protocol, + Extra: make(map[string][]interface{}), + ID: msg.Info.ID, + } + + if avatarURL, exists := b.userAvatars[senderJID.String()]; exists { + rmsg.Avatar = avatarURL + } + + fileExt, err := mime.ExtensionsByType(imsg.GetMimetype()) + if err != nil { + b.Log.Errorf("Mimetype detection error: %s", err) + + return + } + + if len(fileExt) == 0 { + fileExt = append(fileExt, ".mp4") + } + + filename := fmt.Sprintf("%v%v", msg.Info.ID, fileExt[0]) + + b.Log.Debugf("Trying to download %s with size %#v and type %s", filename, imsg.GetFileLength(), imsg.GetMimetype()) + + data, err := b.wc.Download(imsg) + if err != nil { + b.Log.Errorf("Download video failed: %s", err) + + return + } + + // Move file to bridge storage + helper.HandleDownloadData(b.Log, &rmsg, filename, imsg.GetCaption(), "", &data, b.General) + + b.Log.Debugf("<= Sending message from %s on %s to gateway", senderJID, b.Account) + b.Log.Debugf("<= Message is %#v", rmsg) + + b.Remote <- rmsg +} + +// HandleAudioMessage downloads audio messages +func (b *Bwhatsapp) handleAudioMessage(msg *events.Message) { + imsg := msg.Message.GetAudioMessage() + + senderJID := msg.Info.Sender + senderName := b.getSenderName(senderJID) + ci := imsg.GetContextInfo() + + if senderJID == (types.JID{}) && ci.Participant != nil { + senderJID = types.NewJID(ci.GetParticipant(), types.DefaultUserServer) + } + + rmsg := config.Message{ + UserID: senderJID.String(), + Username: senderName, + Channel: msg.Info.Chat.String(), + Account: b.Account, + Protocol: b.Protocol, + Extra: make(map[string][]interface{}), + ID: msg.Info.ID, + } + + if avatarURL, exists := b.userAvatars[senderJID.String()]; exists { + rmsg.Avatar = avatarURL + } + + fileExt, err := mime.ExtensionsByType(imsg.GetMimetype()) + if err != nil { + b.Log.Errorf("Mimetype detection error: %s", err) + + return + } + + if len(fileExt) == 0 { + fileExt = append(fileExt, ".ogg") + } + + filename := fmt.Sprintf("%v%v", msg.Info.ID, fileExt[0]) + + b.Log.Debugf("Trying to download %s with size %#v and type %s", filename, imsg.GetFileLength(), imsg.GetMimetype()) + + data, err := b.wc.Download(imsg) + if err != nil { + b.Log.Errorf("Download video failed: %s", err) + + return + } + + // Move file to bridge storage + helper.HandleDownloadData(b.Log, &rmsg, filename, "audio message", "", &data, b.General) + + b.Log.Debugf("<= Sending message from %s on %s to gateway", senderJID, b.Account) + b.Log.Debugf("<= Message is %#v", rmsg) + + b.Remote <- rmsg +} + +// HandleDocumentMessage downloads documents +func (b *Bwhatsapp) handleDocumentMessage(msg *events.Message) { + imsg := msg.Message.GetDocumentMessage() + + senderJID := msg.Info.Sender + senderName := b.getSenderName(senderJID) + ci := imsg.GetContextInfo() + + if senderJID == (types.JID{}) && ci.Participant != nil { + senderJID = types.NewJID(ci.GetParticipant(), types.DefaultUserServer) + } + + rmsg := config.Message{ + UserID: senderJID.String(), + Username: senderName, + Channel: msg.Info.Chat.String(), + Account: b.Account, + Protocol: b.Protocol, + Extra: make(map[string][]interface{}), + ID: msg.Info.ID, + } + + if avatarURL, exists := b.userAvatars[senderJID.String()]; exists { + rmsg.Avatar = avatarURL + } + + fileExt, err := mime.ExtensionsByType(imsg.GetMimetype()) + if err != nil { + b.Log.Errorf("Mimetype detection error: %s", err) + + return + } + + filename := fmt.Sprintf("%v", imsg.GetFileName()) + + b.Log.Debugf("Trying to download %s with extension %s and type %s", filename, fileExt, imsg.GetMimetype()) + + data, err := b.wc.Download(imsg) + if err != nil { + b.Log.Errorf("Download document message failed: %s", err) + + return + } + + // Move file to bridge storage + helper.HandleDownloadData(b.Log, &rmsg, filename, "document", "", &data, b.General) + + b.Log.Debugf("<= Sending message from %s on %s to gateway", senderJID, b.Account) + b.Log.Debugf("<= Message is %#v", rmsg) + + b.Remote <- rmsg +} diff --git a/bridge/whatsappmulti/helpers.go b/bridge/whatsappmulti/helpers.go new file mode 100644 index 00000000..a7cc5c98 --- /dev/null +++ b/bridge/whatsappmulti/helpers.go @@ -0,0 +1,108 @@ +// +build whatsappmulti + +package bwhatsapp + +import ( + "fmt" + "strings" + + "go.mau.fi/whatsmeow/store" + "go.mau.fi/whatsmeow/store/sqlstore" + "go.mau.fi/whatsmeow/types" +) + +type ProfilePicInfo struct { + URL string `json:"eurl"` + Tag string `json:"tag"` + Status int16 `json:"status"` +} + +func (b *Bwhatsapp) getSenderName(senderJid types.JID) string { + if sender, exists := b.contacts[senderJid]; exists { + if sender.FullName != "" { + return sender.FullName + } + // if user is not in phone contacts + // it is the most obvious scenario unless you sync your phone contacts with some remote updated source + // users can change it in their WhatsApp settings -> profile -> click on Avatar + if sender.PushName != "" { + return sender.PushName + } + + if sender.FirstName != "" { + return sender.FirstName + } + } + + // try to reload this contact + if _, err := b.wc.Store.Contacts.GetAllContacts(); err != nil { + b.Log.Errorf("error on update of contacts: %v", err) + } + + allcontacts, err := b.wc.Store.Contacts.GetAllContacts() + if err != nil { + b.Log.Errorf("error on update of contacts: %v", err) + } + + if len(allcontacts) > 0 { + b.contacts = allcontacts + } + + if sender, exists := b.contacts[senderJid]; exists { + if sender.FullName != "" { + return sender.FullName + } + // if user is not in phone contacts + // it is the most obvious scenario unless you sync your phone contacts with some remote updated source + // users can change it in their WhatsApp settings -> profile -> click on Avatar + if sender.PushName != "" { + return sender.PushName + } + + if sender.FirstName != "" { + return sender.FirstName + } + } + + return "Someone" +} + +func (b *Bwhatsapp) getSenderNotify(senderJid types.JID) string { + if sender, exists := b.contacts[senderJid]; exists { + return sender.PushName + } + + return "" +} + +func (b *Bwhatsapp) GetProfilePicThumb(jid string) (*types.ProfilePictureInfo, error) { + pjid, _ := types.ParseJID(jid) + info, err := b.wc.GetProfilePictureInfo(pjid, true) + if err != nil { + return nil, fmt.Errorf("failed to get avatar: %v", err) + } + + return info, nil +} + +func isGroupJid(identifier string) bool { + return strings.HasSuffix(identifier, "@g.us") || + strings.HasSuffix(identifier, "@temp") || + strings.HasSuffix(identifier, "@broadcast") +} + +func (b *Bwhatsapp) getDevice() (*store.Device, error) { + device := &store.Device{} + + storeContainer, err := sqlstore.New("sqlite", "file:"+b.Config.GetString("sessionfile")+".db?_foreign_keys=on&_pragma=busy_timeout=10000", nil) + if err != nil { + return device, fmt.Errorf("failed to connect to database: %v", err) + } + + device, err = storeContainer.GetFirstDevice() + if err != nil { + return device, fmt.Errorf("failed to get device: %v", err) + } + + return device, nil +} diff --git a/bridge/whatsappmulti/whatsapp.go b/bridge/whatsappmulti/whatsapp.go new file mode 100644 index 00000000..6b514451 --- /dev/null +++ b/bridge/whatsappmulti/whatsapp.go @@ -0,0 +1,333 @@ +// +build whatsappmulti + +package bwhatsapp + +import ( + "context" + "errors" + "fmt" + "mime" + "os" + "path/filepath" + "time" + + "github.com/42wim/matterbridge/bridge" + "github.com/42wim/matterbridge/bridge/config" + "github.com/mdp/qrterminal" + + "go.mau.fi/whatsmeow" + "go.mau.fi/whatsmeow/binary/proto" + "go.mau.fi/whatsmeow/types" + waLog "go.mau.fi/whatsmeow/util/log" + + goproto "google.golang.org/protobuf/proto" + + _ "modernc.org/sqlite" // needed for sqlite +) + +const ( + // Account config parameters + cfgNumber = "Number" +) + +// Bwhatsapp Bridge structure keeping all the information needed for relying +type Bwhatsapp struct { + *bridge.Config + + startedAt time.Time + wc *whatsmeow.Client + contacts map[types.JID]types.ContactInfo + users map[string]types.ContactInfo + userAvatars map[string]string +} + +// New Create a new WhatsApp bridge. This will be called for each [whatsapp.] entry you have in the config file +func New(cfg *bridge.Config) bridge.Bridger { + number := cfg.GetString(cfgNumber) + + if number == "" { + cfg.Log.Fatalf("Missing configuration for WhatsApp bridge: Number") + } + + b := &Bwhatsapp{ + Config: cfg, + + users: make(map[string]types.ContactInfo), + userAvatars: make(map[string]string), + } + + return b +} + +// Connect to WhatsApp. Required implementation of the Bridger interface +func (b *Bwhatsapp) Connect() error { + device, err := b.getDevice() + if err != nil { + return err + } + + number := b.GetString(cfgNumber) + if number == "" { + return errors.New("whatsapp's telephone number need to be configured") + } + + b.Log.Debugln("Connecting to WhatsApp..") + + b.wc = whatsmeow.NewClient(device, waLog.Stdout("Client", "INFO", true)) + b.wc.AddEventHandler(b.eventHandler) + + firstlogin := false + var qrChan <-chan whatsmeow.QRChannelItem + if b.wc.Store.ID == nil { + firstlogin = true + qrChan, err = b.wc.GetQRChannel(context.Background()) + if err != nil && !errors.Is(err, whatsmeow.ErrQRStoreContainsID) { + return errors.New("failed to to get QR channel:" + err.Error()) + } + } + + err = b.wc.Connect() + if err != nil { + return errors.New("failed to connect to WhatsApp: " + err.Error()) + } + + if b.wc.Store.ID == nil { + for evt := range qrChan { + if evt.Event == "code" { + qrterminal.GenerateHalfBlock(evt.Code, qrterminal.L, os.Stdout) + } else { + b.Log.Infof("QR channel result: %s", evt.Event) + } + } + } + + // disconnect and reconnect on our first login/pairing + // for some reason the GetJoinedGroups in JoinChannel doesn't work on first login + if firstlogin { + b.wc.Disconnect() + time.Sleep(time.Second) + + err = b.wc.Connect() + if err != nil { + return errors.New("failed to connect to WhatsApp: " + err.Error()) + } + } + + b.Log.Infoln("WhatsApp connection successful") + + b.contacts, err = b.wc.Store.Contacts.GetAllContacts() + if err != nil { + return errors.New("failed to get contacts: " + err.Error()) + } + + b.startedAt = time.Now() + + // map all the users + for id, contact := range b.contacts { + if !isGroupJid(id.String()) && id.String() != "status@broadcast" { + // it is user + b.users[id.String()] = contact + } + } + + // get user avatar asynchronously + b.Log.Info("Getting user avatars..") + + for jid := range b.users { + info, err := b.GetProfilePicThumb(jid) + if err != nil { + b.Log.Warnf("Could not get profile photo of %s: %v", jid, err) + } else { + b.Lock() + if info != nil { + b.userAvatars[jid] = info.URL + } + b.Unlock() + } + } + + b.Log.Info("Finished getting avatars..") + + return nil +} + +// Disconnect is called while reconnecting to the bridge +// Required implementation of the Bridger interface +func (b *Bwhatsapp) Disconnect() error { + b.wc.Disconnect() + + return nil +} + +// JoinChannel Join a WhatsApp group specified in gateway config as channel='number-id@g.us' or channel='Channel name' +// Required implementation of the Bridger interface +// https://github.com/42wim/matterbridge/blob/2cfd880cdb0df29771bf8f31df8d990ab897889d/bridge/bridge.go#L11-L16 +func (b *Bwhatsapp) JoinChannel(channel config.ChannelInfo) error { + byJid := isGroupJid(channel.Name) + + groups, err := b.wc.GetJoinedGroups() + if err != nil { + return err + } + + // verify if we are member of the given group + if byJid { + gJID, err := types.ParseJID(channel.Name) + if err != nil { + return err + } + + for _, group := range groups { + if group.JID == gJID { + return nil + } + } + } + + foundGroups := []string{} + + for _, group := range groups { + if group.Name == channel.Name { + foundGroups = append(foundGroups, group.Name) + } + } + + switch len(foundGroups) { + case 0: + // didn't match any group - print out possibilites + for _, group := range groups { + b.Log.Infof("%s %s", group.JID, group.Name) + } + return fmt.Errorf("please specify group's JID from the list above instead of the name '%s'", channel.Name) + case 1: + return fmt.Errorf("group name might change. Please configure gateway with channel=\"%v\" instead of channel=\"%v\"", foundGroups[0], channel.Name) + default: + return fmt.Errorf("there is more than one group with name '%s'. Please specify one of JIDs as channel name: %v", channel.Name, foundGroups) + } +} + +// Post a document message from the bridge to WhatsApp +func (b *Bwhatsapp) PostDocumentMessage(msg config.Message, filetype string) (string, error) { + groupJID, _ := types.ParseJID(msg.Channel) + + fi := msg.Extra["file"][0].(config.FileInfo) + + resp, err := b.wc.Upload(context.Background(), *fi.Data, whatsmeow.MediaDocument) + if err != nil { + return "", err + } + + // Post document message + var message proto.Message + + message.DocumentMessage = &proto.DocumentMessage{ + Title: &fi.Name, + FileName: &fi.Name, + Mimetype: &filetype, + MediaKey: resp.MediaKey, + FileEncSha256: resp.FileEncSHA256, + FileSha256: resp.FileSHA256, + FileLength: goproto.Uint64(resp.FileLength), + Url: &resp.URL, + } + + b.Log.Debugf("=> Sending %#v", msg) + + ID := whatsmeow.GenerateMessageID() + _, err = b.wc.SendMessage(groupJID, ID, &message) + + return ID, err +} + +// Post an image message from the bridge to WhatsApp +// Handle, for sure image/jpeg, image/png and image/gif MIME types +func (b *Bwhatsapp) PostImageMessage(msg config.Message, filetype string) (string, error) { + groupJID, _ := types.ParseJID(msg.Channel) + + fi := msg.Extra["file"][0].(config.FileInfo) + + caption := msg.Username + fi.Comment + + resp, err := b.wc.Upload(context.Background(), *fi.Data, whatsmeow.MediaImage) + if err != nil { + return "", err + } + + var message proto.Message + + message.ImageMessage = &proto.ImageMessage{ + Mimetype: &filetype, + Caption: &caption, + MediaKey: resp.MediaKey, + FileEncSha256: resp.FileEncSHA256, + FileSha256: resp.FileSHA256, + FileLength: goproto.Uint64(resp.FileLength), + Url: &resp.URL, + } + + b.Log.Debugf("=> Sending %#v", msg) + + ID := whatsmeow.GenerateMessageID() + _, err = b.wc.SendMessage(groupJID, ID, &message) + + return ID, err +} + +// Send a message from the bridge to WhatsApp +func (b *Bwhatsapp) Send(msg config.Message) (string, error) { + groupJID, _ := types.ParseJID(msg.Channel) + + b.Log.Debugf("=> Receiving %#v", msg) + + // Delete message + if msg.Event == config.EventMsgDelete { + if msg.ID == "" { + // No message ID in case action is executed on a message sent before the bridge was started + // and then the bridge cache doesn't have this message ID mapped + return "", nil + } + + _, err := b.wc.RevokeMessage(groupJID, msg.ID) + + return "", err + } + + // Edit message + if msg.ID != "" { + b.Log.Debugf("updating message with id %s", msg.ID) + + if b.GetString("editsuffix") != "" { + msg.Text += b.GetString("EditSuffix") + } else { + msg.Text += " (edited)" + } + } + + // Handle Upload a file + if msg.Extra["file"] != nil { + fi := msg.Extra["file"][0].(config.FileInfo) + filetype := mime.TypeByExtension(filepath.Ext(fi.Name)) + + b.Log.Debugf("Extra file is %#v", filetype) + + // TODO: add different types + // TODO: add webp conversion + switch filetype { + case "image/jpeg", "image/png", "image/gif": + return b.PostImageMessage(msg, filetype) + default: + return b.PostDocumentMessage(msg, filetype) + } + } + + text := msg.Username + msg.Text + + var message proto.Message + + message.Conversation = &text + + ID := whatsmeow.GenerateMessageID() + _, err := b.wc.SendMessage(groupJID, ID, &message) + + return ID, err +} diff --git a/gateway/bridgemap/bwhatsapp.go b/gateway/bridgemap/bwhatsapp.go index ef6d6f73..e7b72b0f 100644 --- a/gateway/bridgemap/bwhatsapp.go +++ b/gateway/bridgemap/bwhatsapp.go @@ -1,4 +1,5 @@ // +build !nowhatsapp +// +build !whatsappmulti package bridgemap diff --git a/gateway/bridgemap/bwhatsappmulti.go b/gateway/bridgemap/bwhatsappmulti.go new file mode 100644 index 00000000..055c6da2 --- /dev/null +++ b/gateway/bridgemap/bwhatsappmulti.go @@ -0,0 +1,11 @@ +// +build whatsappmulti + +package bridgemap + +import ( + bwhatsapp "github.com/42wim/matterbridge/bridge/whatsappmulti" +) + +func init() { + FullMap["whatsapp"] = bwhatsapp.New +} diff --git a/go.mod b/go.mod index 53f9a53e..edb70a5d 100644 --- a/go.mod +++ b/go.mod @@ -2,8 +2,10 @@ module github.com/42wim/matterbridge require ( github.com/42wim/go-gitter v0.0.0-20170828205020-017310c2d557 + github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f github.com/Benau/tgsconverter v0.0.0-20210809170556-99f4a4f6337f github.com/Philipp15b/go-steam v1.0.1-0.20200727090957-6ae9b3c0a560 + github.com/Rhymen/go-whatsapp v0.1.2-0.20211102134409-31a2e740845c github.com/SevereCloud/vksdk/v2 v2.13.1 github.com/bwmarrin/discordgo v0.24.0 github.com/d5/tengo/v2 v2.10.1 @@ -110,6 +112,7 @@ require ( github.com/rivo/uniseg v0.2.0 // indirect github.com/shazow/rateio v0.0.0-20200113175441-4461efc8bdc4 // indirect github.com/sizeofint/webpanimation v0.0.0-20210809145948-1d2b32119882 // indirect + github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9 // indirect github.com/spf13/afero v1.6.0 // indirect github.com/spf13/cast v1.4.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect diff --git a/go.sum b/go.sum index 5368c48b..5bd03002 100644 --- a/go.sum +++ b/go.sum @@ -90,6 +90,8 @@ github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935 github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= +github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f h1:2dk3eOnYllh+wUOuDhOoC2vUVoJF/5z478ryJ+wzEII= +github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f/go.mod h1:4a58ifQTEe2uwwsaqbh3i2un5/CBPg+At/qHpt18Tmk= github.com/Benau/go_rlottie v0.0.0-20210807002906-98c1b2421989 h1:+wrfJITuBoQOE6ST4k3c4EortNVQXVhfAbwt0M/j0+Y= github.com/Benau/go_rlottie v0.0.0-20210807002906-98c1b2421989/go.mod h1:aDWSWjsayFyGTvHZH3v4ijGXEBe51xcEkAK+NUWeOeo= github.com/Benau/tgsconverter v0.0.0-20210809170556-99f4a4f6337f h1:aUkwZDEMJIGRcWlSDifSLoKG37UCOH/DPeG52/xwois= @@ -144,6 +146,8 @@ github.com/PuerkitoBio/goquery v1.7.0/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBK github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/Rhymen/go-whatsapp v0.1.2-0.20211102134409-31a2e740845c h1:4mIZQXKYBymQ9coA82nNyG/CjicMNLBZ8cPVrhNUM3g= +github.com/Rhymen/go-whatsapp v0.1.2-0.20211102134409-31a2e740845c/go.mod h1:DNSFRLFDFIqm2+0aJzSOVfn25020vldM4SRqz6YtLgI= github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo= github.com/RoaringBitmap/roaring v0.8.0/go.mod h1:jdT9ykXwHFNdJbEtxePexlFYH9LXucApeS0/+/g+p1I= github.com/RoaringBitmap/roaring v0.9.4/go.mod h1:icnadbWcNyfEHlYdr+tDlOTih1Bf/h+rzPpv4sbomAA= @@ -1497,6 +1501,8 @@ github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sizeofint/webpanimation v0.0.0-20210809145948-1d2b32119882 h1:A7o8tOERTtpD/poS+2VoassCjXpjHn916luXbf5QKD0= github.com/sizeofint/webpanimation v0.0.0-20210809145948-1d2b32119882/go.mod h1:5IwJoz9Pw7JsrCN4/skkxUtSWT7myuUPLhCgv6Q5vvQ= +github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9 h1:lpEzuenPuO1XNTeikEmvqYFcU37GVLl8SRNblzyvGBE= +github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9/go.mod h1:PLPIyL7ikehBD1OAjmKKiOEhbvWyHGaNDjquXMcYABo= github.com/slack-go/slack v0.10.2 h1:KMN/h2sgUninHXvQI8PrR/PHBUuWp2NPvz2Kr66tki4= github.com/slack-go/slack v0.10.2/go.mod h1:5FLdBRv7VW/d9EBxx/eEktOptWygbA9K2QK/KW7ds1s= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= diff --git a/vendor/github.com/Baozisoftware/qrcode-terminal-go/.gitignore b/vendor/github.com/Baozisoftware/qrcode-terminal-go/.gitignore new file mode 100644 index 00000000..daf913b1 --- /dev/null +++ b/vendor/github.com/Baozisoftware/qrcode-terminal-go/.gitignore @@ -0,0 +1,24 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof diff --git a/vendor/github.com/Baozisoftware/qrcode-terminal-go/LICENSE b/vendor/github.com/Baozisoftware/qrcode-terminal-go/LICENSE new file mode 100644 index 00000000..72223a6e --- /dev/null +++ b/vendor/github.com/Baozisoftware/qrcode-terminal-go/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2017, Baozisoftware +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/Baozisoftware/qrcode-terminal-go/README.md b/vendor/github.com/Baozisoftware/qrcode-terminal-go/README.md new file mode 100644 index 00000000..40e850ad --- /dev/null +++ b/vendor/github.com/Baozisoftware/qrcode-terminal-go/README.md @@ -0,0 +1,39 @@ + +# qrcode-terminal-go +QRCode terminal for golang. + +# Example +```go +package main + +import "github.com/Baozisoftware/qrcode-terminal-go" + +func main() { + Test1() + Test2() +} + +func Test1(){ + content := "Hello, δΈ–η•Œ" + obj := qrcodeTerminal.New() + obj.Get(content).Print() +} + +func Test2(){ + content := "https://github.com/Baozisoftware/qrcode-terminal-go" + obj := qrcodeTerminal.New2(qrcodeTerminal.ConsoleColors.BrightBlue,qrcodeTerminal.ConsoleColors.BrightGreen,qrcodeTerminal.QRCodeRecoveryLevels.Low) + obj.Get([]byte(content)).Print() +} +``` + +## Screenshots +### Windows XP +![winxp](https://github.com/Baozisoftware/qrcode-terminal-go/blob/master/screenshots/winxp.png) +### Windows 7 +![win7](https://github.com/Baozisoftware/qrcode-terminal-go/blob/master/screenshots/win7.png) +### Windows 10 +![win10](https://github.com/Baozisoftware/qrcode-terminal-go/blob/master/screenshots/win10.png) +### Ubuntu +![ubuntu](https://github.com/Baozisoftware/qrcode-terminal-go/blob/master/screenshots/ubuntu.png) +### macOS +![macos](https://github.com/Baozisoftware/qrcode-terminal-go/blob/master/screenshots/macos.png) diff --git a/vendor/github.com/Baozisoftware/qrcode-terminal-go/qrcodeTerminal.go b/vendor/github.com/Baozisoftware/qrcode-terminal-go/qrcodeTerminal.go new file mode 100644 index 00000000..6d0f64f3 --- /dev/null +++ b/vendor/github.com/Baozisoftware/qrcode-terminal-go/qrcodeTerminal.go @@ -0,0 +1,155 @@ +package qrcodeTerminal + +import ( + "fmt" + + "github.com/skip2/go-qrcode" + "github.com/mattn/go-colorable" + "image/png" + nbytes "bytes" +) + +type consoleColor string +type consoleColors struct { + NormalBlack consoleColor + NormalRed consoleColor + NormalGreen consoleColor + NormalYellow consoleColor + NormalBlue consoleColor + NormalMagenta consoleColor + NormalCyan consoleColor + NormalWhite consoleColor + BrightBlack consoleColor + BrightRed consoleColor + BrightGreen consoleColor + BrightYellow consoleColor + BrightBlue consoleColor + BrightMagenta consoleColor + BrightCyan consoleColor + BrightWhite consoleColor +} +type qrcodeRecoveryLevel qrcode.RecoveryLevel +type qrcodeRecoveryLevels struct { + Low qrcodeRecoveryLevel + Medium qrcodeRecoveryLevel + High qrcodeRecoveryLevel + Highest qrcodeRecoveryLevel +} + +var ( + ConsoleColors consoleColors = consoleColors{ + NormalBlack: "\033[38;5;0m \033[0m", + NormalRed: "\033[38;5;1m \033[0m", + NormalGreen: "\033[38;5;2m \033[0m", + NormalYellow: "\033[38;5;3m \033[0m", + NormalBlue: "\033[38;5;4m \033[0m", + NormalMagenta: "\033[38;5;5m \033[0m", + NormalCyan: "\033[38;5;6m \033[0m", + NormalWhite: "\033[38;5;7m \033[0m", + BrightBlack: "\033[48;5;0m \033[0m", + BrightRed: "\033[48;5;1m \033[0m", + BrightGreen: "\033[48;5;2m \033[0m", + BrightYellow: "\033[48;5;3m \033[0m", + BrightBlue: "\033[48;5;4m \033[0m", + BrightMagenta: "\033[48;5;5m \033[0m", + BrightCyan: "\033[48;5;6m \033[0m", + BrightWhite: "\033[48;5;7m \033[0m"} + QRCodeRecoveryLevels = qrcodeRecoveryLevels{ + Low: qrcodeRecoveryLevel(qrcode.Low), + Medium: qrcodeRecoveryLevel(qrcode.Medium), + High: qrcodeRecoveryLevel(qrcode.High), + Highest: qrcodeRecoveryLevel(qrcode.Highest)} +) + +type QRCodeString string + +func (v *QRCodeString) Print() { + fmt.Fprint(outer, *v) +} + +type qrcodeTerminal struct { + front consoleColor + back consoleColor + level qrcodeRecoveryLevel +} + +func (v *qrcodeTerminal) Get(content interface{}) (result *QRCodeString) { + var qr *qrcode.QRCode + var err error + if t, ok := content.(string); ok { + qr, err = qrcode.New(t, qrcode.RecoveryLevel(v.level)) + } else if t, ok := content.([]byte); ok { + qr, err = qrcode.New(string(t), qrcode.RecoveryLevel(v.level)) + } + if qr != nil && err == nil { + data := qr.Bitmap() + result = v.getQRCodeString(data) + } + return +} + +func (v *qrcodeTerminal) Get2(bytes []byte) (result *QRCodeString) { + data, err := parseQR(bytes) + if err == nil { + result = v.getQRCodeString(data) + } + return +} + +func New2(front, back consoleColor, level qrcodeRecoveryLevel) *qrcodeTerminal { + obj := qrcodeTerminal{front: front, back: back, level: level} + return &obj +} + +func New() *qrcodeTerminal { + front, back, level := ConsoleColors.BrightBlack, ConsoleColors.BrightWhite, QRCodeRecoveryLevels.Medium + return New2(front, back, level) +} + +func (v *qrcodeTerminal) getQRCodeString(data [][]bool) (result *QRCodeString) { + str := "" + for ir, row := range data { + lr := len(row) + if ir == 0 || ir == 1 || ir == 2 || + ir == lr-1 || ir == lr-2 || ir == lr-3 { + continue + } + for ic, col := range row { + lc := len(data) + if ic == 0 || ic == 1 || ic == 2 || + ic == lc-1 || ic == lc-2 || ic == lc-3 { + continue + } + if col { + str += fmt.Sprint(v.front) + } else { + str += fmt.Sprint(v.back) + } + } + str += fmt.Sprintln() + } + obj := QRCodeString(str) + result = &obj + return +} + +func parseQR(bytes []byte) (data [][]bool, err error) { + r := nbytes.NewReader(bytes) + img, err := png.Decode(r) + if err == nil { + rect := img.Bounds() + mx, my := rect.Max.X, rect.Max.Y + data = make([][]bool, mx) + for x := 0; x < mx; x++ { + data[x] = make([]bool, my) + for y := 0; y < my; y++ { + c := img.At(x, y) + r, _, _, _ := c.RGBA() + data[x][y] = r == 0 + } + } + } + return +} + +var outer = colorable.NewColorableStdout() diff --git a/vendor/github.com/Rhymen/go-whatsapp/.gitignore b/vendor/github.com/Rhymen/go-whatsapp/.gitignore new file mode 100644 index 00000000..b553f0fd --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/.gitignore @@ -0,0 +1,3 @@ +.idea/ +docs/ +build/ diff --git a/vendor/github.com/Rhymen/go-whatsapp/LICENSE b/vendor/github.com/Rhymen/go-whatsapp/LICENSE new file mode 100644 index 00000000..b442934b --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/Rhymen/go-whatsapp/README.md b/vendor/github.com/Rhymen/go-whatsapp/README.md new file mode 100644 index 00000000..ea66f5bb --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/README.md @@ -0,0 +1,139 @@ +# go-whatsapp +Package rhymen/go-whatsapp implements the WhatsApp Web API to provide a clean interface for developers. Big thanks to all contributors of the [sigalor/whatsapp-web-reveng](https://github.com/sigalor/whatsapp-web-reveng) project. The official WhatsApp Business API was released in August 2018. You can check it out [here](https://www.whatsapp.com/business/api). + +## Installation +```sh +go get github.com/Rhymen/go-whatsapp +``` + +## Usage +### Creating a connection +```go +import ( + whatsapp "github.com/Rhymen/go-whatsapp" +) + +wac, err := whatsapp.NewConn(20 * time.Second) +``` +The duration passed to the NewConn function is used to timeout login requests. If you have a bad internet connection use a higher timeout value. This function only creates a websocket connection, it does not handle authentication. + +### Login +```go +qrChan := make(chan string) +go func() { + fmt.Printf("qr code: %v\n", <-qrChan) + //show qr code or save it somewhere to scan +}() +sess, err := wac.Login(qrChan) +``` +The authentication process requires you to scan the qr code, that is send through the channel, with the device you are using whatsapp on. The session struct that is returned can be saved and used to restore the login without scanning the qr code again. The qr code has a ttl of 20 seconds and the login function throws a timeout err if the time has passed or any other request fails. + +### Restore +```go +newSess, err := wac.RestoreWithSession(sess) +``` +The restore function needs a valid session and returns the new session that was created. + +### Add message handlers +```go +type myHandler struct{} + +func (myHandler) HandleError(err error) { + fmt.Fprintf(os.Stderr, "%v", err) +} + +func (myHandler) HandleTextMessage(message whatsapp.TextMessage) { + fmt.Println(message) +} + +func (myHandler) HandleImageMessage(message whatsapp.ImageMessage) { + fmt.Println(message) +} + +func (myHandler) HandleDocumentMessage(message whatsapp.DocumentMessage) { + fmt.Println(message) +} + +func (myHandler) HandleVideoMessage(message whatsapp.VideoMessage) { + fmt.Println(message) +} + +func (myHandler) HandleAudioMessage(message whatsapp.AudioMessage){ + fmt.Println(message) +} + +func (myHandler) HandleJsonMessage(message string) { + fmt.Println(message) +} + +func (myHandler) HandleContactMessage(message whatsapp.ContactMessage) { + fmt.Println(message) +} + +func (myHandler) HandleBatteryMessage(message whatsapp.BatteryMessage) { + fmt.Println(message) +} + +func (myHandler) HandleNewContact(contact whatsapp.Contact) { + fmt.Println(contact) +} + +wac.AddHandler(myHandler{}) +``` +The message handlers are all optional, you don't need to implement anything but the error handler to implement the interface. The ImageMessage, VideoMessage, AudioMessage and DocumentMessage provide a Download function to get the media data. + +### Sending text messages +```go +text := whatsapp.TextMessage{ + Info: whatsapp.MessageInfo{ + RemoteJid: "0123456789@s.whatsapp.net", + }, + Text: "Hello Whatsapp", +} + +err := wac.Send(text) +``` + +### Sending Contact Messages +```go +contactMessage := whatsapp.ContactMessage{ + Info: whatsapp.MessageInfo{ + RemoteJid: "0123456789@s.whatsapp.net", + }, + DisplayName: "Luke Skylwallker", + Vcard: "BEGIN:VCARD\nVERSION:3.0\nN:Skyllwalker;Luke;;\nFN:Luke Skywallker\nitem1.TEL;waid=0123456789:+1 23 456789789\nitem1.X-ABLabel:Mobile\nEND:VCARD", + } + +id, error := client.WaConn.Send(contactMessage) +``` + + +The message will be send over the websocket. The attributes seen above are the required ones. All other relevant attributes (id, timestamp, fromMe, status) are set if they are missing in the struct. For the time being we only support text messages, but other types are planned for the near future. + +## Legal +This code is in no way affiliated with, authorized, maintained, sponsored or endorsed by WhatsApp or any of its +affiliates or subsidiaries. This is an independent and unofficial software. Use at your own risk. + +## License + +The MIT License (MIT) + +Copyright (c) 2018 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/Rhymen/go-whatsapp/binary/decoder.go b/vendor/github.com/Rhymen/go-whatsapp/binary/decoder.go new file mode 100644 index 00000000..95da606c --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/binary/decoder.go @@ -0,0 +1,388 @@ +package binary + +import ( + "fmt" + "github.com/Rhymen/go-whatsapp/binary/token" + "io" + "strconv" +) + +type binaryDecoder struct { + data []byte + index int +} + +func NewDecoder(data []byte) *binaryDecoder { + return &binaryDecoder{data, 0} +} + +func (r *binaryDecoder) checkEOS(length int) error { + if r.index+length > len(r.data) { + return io.EOF + } + + return nil +} + +func (r *binaryDecoder) readByte() (byte, error) { + if err := r.checkEOS(1); err != nil { + return 0, err + } + + b := r.data[r.index] + r.index++ + + return b, nil +} + +func (r *binaryDecoder) readIntN(n int, littleEndian bool) (int, error) { + if err := r.checkEOS(n); err != nil { + return 0, err + } + + var ret int + + for i := 0; i < n; i++ { + var curShift int + if littleEndian { + curShift = i + } else { + curShift = n - i - 1 + } + ret |= int(r.data[r.index+i]) << uint(curShift*8) + } + + r.index += n + return ret, nil +} + +func (r *binaryDecoder) readInt8(littleEndian bool) (int, error) { + return r.readIntN(1, littleEndian) +} + +func (r *binaryDecoder) readInt16(littleEndian bool) (int, error) { + return r.readIntN(2, littleEndian) +} + +func (r *binaryDecoder) readInt20() (int, error) { + if err := r.checkEOS(3); err != nil { + return 0, err + } + + ret := ((int(r.data[r.index]) & 15) << 16) + (int(r.data[r.index+1]) << 8) + int(r.data[r.index+2]) + r.index += 3 + return ret, nil +} + +func (r *binaryDecoder) readInt32(littleEndian bool) (int, error) { + return r.readIntN(4, littleEndian) +} + +func (r *binaryDecoder) readInt64(littleEndian bool) (int, error) { + return r.readIntN(8, littleEndian) +} + +func (r *binaryDecoder) readPacked8(tag int) (string, error) { + startByte, err := r.readByte() + if err != nil { + return "", err + } + + ret := "" + + for i := 0; i < int(startByte&127); i++ { + currByte, err := r.readByte() + if err != nil { + return "", err + } + + lower, err := unpackByte(tag, currByte&0xF0>>4) + if err != nil { + return "", err + } + + upper, err := unpackByte(tag, currByte&0x0F) + if err != nil { + return "", err + } + + ret += lower + upper + } + + if startByte>>7 != 0 { + ret = ret[:len(ret)-1] + } + return ret, nil +} + +func unpackByte(tag int, value byte) (string, error) { + switch tag { + case token.NIBBLE_8: + return unpackNibble(value) + case token.HEX_8: + return unpackHex(value) + default: + return "", fmt.Errorf("unpackByte with unknown tag %d", tag) + } +} + +func unpackNibble(value byte) (string, error) { + switch { + case value < 0 || value > 15: + return "", fmt.Errorf("unpackNibble with value %d", value) + case value == 10: + return "-", nil + case value == 11: + return ".", nil + case value == 15: + return "\x00", nil + default: + return strconv.Itoa(int(value)), nil + } +} + +func unpackHex(value byte) (string, error) { + switch { + case value < 0 || value > 15: + return "", fmt.Errorf("unpackHex with value %d", value) + case value < 10: + return strconv.Itoa(int(value)), nil + default: + return string('A' + value - 10), nil + } +} + +func (r *binaryDecoder) readListSize(tag int) (int, error) { + switch tag { + case token.LIST_EMPTY: + return 0, nil + case token.LIST_8: + return r.readInt8(false) + case token.LIST_16: + return r.readInt16(false) + default: + return 0, fmt.Errorf("readListSize with unknown tag %d at position %d", tag, r.index) + } +} + +func (r *binaryDecoder) readString(tag int) (string, error) { + switch { + case tag >= 3 && tag <= len(token.SingleByteTokens): + tok, err := token.GetSingleToken(tag) + if err != nil { + return "", err + } + + if tok == "s.whatsapp.net" { + tok = "c.us" + } + + return tok, nil + case tag == token.DICTIONARY_0 || tag == token.DICTIONARY_1 || tag == token.DICTIONARY_2 || tag == token.DICTIONARY_3: + i, err := r.readInt8(false) + if err != nil { + return "", err + } + + return token.GetDoubleToken(tag-token.DICTIONARY_0, i) + case tag == token.LIST_EMPTY: + return "", nil + case tag == token.BINARY_8: + length, err := r.readInt8(false) + if err != nil { + return "", err + } + + return r.readStringFromChars(length) + case tag == token.BINARY_20: + length, err := r.readInt20() + if err != nil { + return "", err + } + + return r.readStringFromChars(length) + case tag == token.BINARY_32: + length, err := r.readInt32(false) + if err != nil { + return "", err + } + + return r.readStringFromChars(length) + case tag == token.JID_PAIR: + b, err := r.readByte() + if err != nil { + return "", err + } + i, err := r.readString(int(b)) + if err != nil { + return "", err + } + + b, err = r.readByte() + if err != nil { + return "", err + } + j, err := r.readString(int(b)) + if err != nil { + return "", err + } + + if i == "" || j == "" { + return "", fmt.Errorf("invalid jid pair: %s - %s", i, j) + } + + return i + "@" + j, nil + case tag == token.NIBBLE_8 || tag == token.HEX_8: + return r.readPacked8(tag) + default: + return "", fmt.Errorf("invalid string with tag %d", tag) + } +} + +func (r *binaryDecoder) readStringFromChars(length int) (string, error) { + if err := r.checkEOS(length); err != nil { + return "", err + } + + ret := r.data[r.index : r.index+length] + r.index += length + + return string(ret), nil +} + +func (r *binaryDecoder) readAttributes(n int) (map[string]string, error) { + if n == 0 { + return nil, nil + } + + ret := make(map[string]string) + for i := 0; i < n; i++ { + idx, err := r.readInt8(false) + if err != nil { + return nil, err + } + + index, err := r.readString(idx) + if err != nil { + return nil, err + } + + idx, err = r.readInt8(false) + if err != nil { + return nil, err + } + + ret[index], err = r.readString(idx) + if err != nil { + return nil, err + } + } + + return ret, nil +} + +func (r *binaryDecoder) readList(tag int) ([]Node, error) { + size, err := r.readListSize(tag) + if err != nil { + return nil, err + } + + ret := make([]Node, size) + for i := 0; i < size; i++ { + n, err := r.ReadNode() + + if err != nil { + return nil, err + } + + ret[i] = *n + } + + return ret, nil +} + +func (r *binaryDecoder) ReadNode() (*Node, error) { + ret := &Node{} + + size, err := r.readInt8(false) + if err != nil { + return nil, err + } + listSize, err := r.readListSize(size) + if err != nil { + return nil, err + } + + descrTag, err := r.readInt8(false) + if descrTag == token.STREAM_END { + return nil, fmt.Errorf("unexpected stream end") + } + ret.Description, err = r.readString(descrTag) + if err != nil { + return nil, err + } + if listSize == 0 || ret.Description == "" { + return nil, fmt.Errorf("invalid Node") + } + + ret.Attributes, err = r.readAttributes((listSize - 1) >> 1) + if err != nil { + return nil, err + } + + if listSize%2 == 1 { + return ret, nil + } + + tag, err := r.readInt8(false) + if err != nil { + return nil, err + } + + switch tag { + case token.LIST_EMPTY, token.LIST_8, token.LIST_16: + ret.Content, err = r.readList(tag) + case token.BINARY_8: + size, err = r.readInt8(false) + if err != nil { + return nil, err + } + + ret.Content, err = r.readBytes(size) + case token.BINARY_20: + size, err = r.readInt20() + if err != nil { + return nil, err + } + + ret.Content, err = r.readBytes(size) + case token.BINARY_32: + size, err = r.readInt32(false) + if err != nil { + return nil, err + } + + ret.Content, err = r.readBytes(size) + default: + ret.Content, err = r.readString(tag) + } + + if err != nil { + return nil, err + } + return ret, nil +} + +func (r *binaryDecoder) readBytes(n int) ([]byte, error) { + ret := make([]byte, n) + var err error + + for i := range ret { + ret[i], err = r.readByte() + if err != nil { + return nil, err + } + } + + return ret, nil +} diff --git a/vendor/github.com/Rhymen/go-whatsapp/binary/encoder.go b/vendor/github.com/Rhymen/go-whatsapp/binary/encoder.go new file mode 100644 index 00000000..59003e7a --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/binary/encoder.go @@ -0,0 +1,351 @@ +package binary + +import ( + "fmt" + "github.com/Rhymen/go-whatsapp/binary/token" + "math" + "strconv" + "strings" +) + +type binaryEncoder struct { + data []byte +} + +func NewEncoder() *binaryEncoder { + return &binaryEncoder{make([]byte, 0)} +} + +func (w *binaryEncoder) GetData() []byte { + return w.data +} + +func (w *binaryEncoder) pushByte(b byte) { + w.data = append(w.data, b) +} + +func (w *binaryEncoder) pushBytes(bytes []byte) { + w.data = append(w.data, bytes...) +} + +func (w *binaryEncoder) pushIntN(value, n int, littleEndian bool) { + for i := 0; i < n; i++ { + var curShift int + if littleEndian { + curShift = i + } else { + curShift = n - i - 1 + } + w.pushByte(byte((value >> uint(curShift*8)) & 0xFF)) + } +} + +func (w *binaryEncoder) pushInt20(value int) { + w.pushBytes([]byte{byte((value >> 16) & 0x0F), byte((value >> 8) & 0xFF), byte(value & 0xFF)}) +} + +func (w *binaryEncoder) pushInt8(value int) { + w.pushIntN(value, 1, false) +} + +func (w *binaryEncoder) pushInt16(value int) { + w.pushIntN(value, 2, false) +} + +func (w *binaryEncoder) pushInt32(value int) { + w.pushIntN(value, 4, false) +} + +func (w *binaryEncoder) pushInt64(value int) { + w.pushIntN(value, 8, false) +} + +func (w *binaryEncoder) pushString(value string) { + w.pushBytes([]byte(value)) +} + +func (w *binaryEncoder) writeByteLength(length int) error { + if length > math.MaxInt32 { + return fmt.Errorf("length is too large: %d", length) + } else if length >= (1 << 20) { + w.pushByte(token.BINARY_32) + w.pushInt32(length) + } else if length >= 256 { + w.pushByte(token.BINARY_20) + w.pushInt20(length) + } else { + w.pushByte(token.BINARY_8) + w.pushInt8(length) + } + + return nil +} + +func (w *binaryEncoder) WriteNode(n Node) error { + numAttributes := 0 + if n.Attributes != nil { + numAttributes = len(n.Attributes) + } + + hasContent := 0 + if n.Content != nil { + hasContent = 1 + } + + w.writeListStart(2*numAttributes + 1 + hasContent) + if err := w.writeString(n.Description, false); err != nil { + return err + } + + if err := w.writeAttributes(n.Attributes); err != nil { + return err + } + + if err := w.writeChildren(n.Content); err != nil { + return err + } + + return nil +} + +func (w *binaryEncoder) writeString(tok string, i bool) error { + if !i && tok == "c.us" { + if err := w.writeToken(token.IndexOfSingleToken("s.whatsapp.net")); err != nil { + return err + } + return nil + } + + tokenIndex := token.IndexOfSingleToken(tok) + if tokenIndex == -1 { + jidSepIndex := strings.Index(tok, "@") + if jidSepIndex < 1 { + w.writeStringRaw(tok) + } else { + w.writeJid(tok[:jidSepIndex], tok[jidSepIndex+1:]) + } + } else { + if tokenIndex < token.SINGLE_BYTE_MAX { + if err := w.writeToken(tokenIndex); err != nil { + return err + } + } else { + singleByteOverflow := tokenIndex - token.SINGLE_BYTE_MAX + dictionaryIndex := singleByteOverflow >> 8 + if dictionaryIndex < 0 || dictionaryIndex > 3 { + return fmt.Errorf("double byte dictionary token out of range: %v", tok) + } + if err := w.writeToken(token.DICTIONARY_0 + dictionaryIndex); err != nil { + return err + } + if err := w.writeToken(singleByteOverflow % 256); err != nil { + return err + } + } + } + + return nil +} + +func (w *binaryEncoder) writeStringRaw(value string) error { + if err := w.writeByteLength(len(value)); err != nil { + return err + } + + w.pushString(value) + + return nil +} + +func (w *binaryEncoder) writeJid(jidLeft, jidRight string) error { + w.pushByte(token.JID_PAIR) + + if jidLeft != "" { + if err := w.writePackedBytes(jidLeft); err != nil { + return err + } + } else { + if err := w.writeToken(token.LIST_EMPTY); err != nil { + return err + } + } + + if err := w.writeString(jidRight, false); err != nil { + return err + } + + return nil +} + +func (w *binaryEncoder) writeToken(tok int) error { + if tok < len(token.SingleByteTokens) { + w.pushByte(byte(tok)) + } else if tok <= 500 { + return fmt.Errorf("invalid token: %d", tok) + } + + return nil +} + +func (w *binaryEncoder) writeAttributes(attributes map[string]string) error { + if attributes == nil { + return nil + } + + for key, val := range attributes { + if val == "" { + continue + } + + if err := w.writeString(key, false); err != nil { + return err + } + + if err := w.writeString(val, false); err != nil { + return err + } + } + + return nil +} + +func (w *binaryEncoder) writeChildren(children interface{}) error { + if children == nil { + return nil + } + + switch childs := children.(type) { + case string: + if err := w.writeString(childs, true); err != nil { + return err + } + case []byte: + if err := w.writeByteLength(len(childs)); err != nil { + return err + } + + w.pushBytes(childs) + case []Node: + w.writeListStart(len(childs)) + for _, n := range childs { + if err := w.WriteNode(n); err != nil { + return err + } + } + default: + return fmt.Errorf("cannot write child of type: %T", children) + } + + return nil +} + +func (w *binaryEncoder) writeListStart(listSize int) { + if listSize == 0 { + w.pushByte(byte(token.LIST_EMPTY)) + } else if listSize < 256 { + w.pushByte(byte(token.LIST_8)) + w.pushInt8(listSize) + } else { + w.pushByte(byte(token.LIST_16)) + w.pushInt16(listSize) + } +} + +func (w *binaryEncoder) writePackedBytes(value string) error { + if err := w.writePackedBytesImpl(value, token.NIBBLE_8); err != nil { + if err := w.writePackedBytesImpl(value, token.HEX_8); err != nil { + return err + } + } + + return nil +} + +func (w *binaryEncoder) writePackedBytesImpl(value string, dataType int) error { + numBytes := len(value) + if numBytes > token.PACKED_MAX { + return fmt.Errorf("too many bytes to pack: %d", numBytes) + } + + w.pushByte(byte(dataType)) + + x := 0 + if numBytes%2 != 0 { + x = 128 + } + w.pushByte(byte(x | int(math.Ceil(float64(numBytes)/2.0)))) + for i, l := 0, numBytes/2; i < l; i++ { + b, err := w.packBytePair(dataType, value[2*i:2*i+1], value[2*i+1:2*i+2]) + if err != nil { + return err + } + + w.pushByte(byte(b)) + } + + if (numBytes % 2) != 0 { + b, err := w.packBytePair(dataType, value[numBytes-1:], "\x00") + if err != nil { + return err + } + + w.pushByte(byte(b)) + } + + return nil +} + +func (w *binaryEncoder) packBytePair(packType int, part1, part2 string) (int, error) { + if packType == token.NIBBLE_8 { + n1, err := packNibble(part1) + if err != nil { + return 0, err + } + + n2, err := packNibble(part2) + if err != nil { + return 0, err + } + + return (n1 << 4) | n2, nil + } else if packType == token.HEX_8 { + n1, err := packHex(part1) + if err != nil { + return 0, err + } + + n2, err := packHex(part2) + if err != nil { + return 0, err + } + + return (n1 << 4) | n2, nil + } else { + return 0, fmt.Errorf("invalid pack type (%d) for byte pair: %s / %s", packType, part1, part2) + } +} + +func packNibble(value string) (int, error) { + if value >= "0" && value <= "9" { + return strconv.Atoi(value) + } else if value == "-" { + return 10, nil + } else if value == "." { + return 11, nil + } else if value == "\x00" { + return 15, nil + } + + return 0, fmt.Errorf("invalid string to pack as nibble: %v", value) +} + +func packHex(value string) (int, error) { + if (value >= "0" && value <= "9") || (value >= "A" && value <= "F") || (value >= "a" && value <= "f") { + d, err := strconv.ParseInt(value, 16, 0) + return int(d), err + } else if value == "\x00" { + return 15, nil + } + + return 0, fmt.Errorf("invalid string to pack as hex: %v", value) +} diff --git a/vendor/github.com/Rhymen/go-whatsapp/binary/node.go b/vendor/github.com/Rhymen/go-whatsapp/binary/node.go new file mode 100644 index 00000000..66b28d88 --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/binary/node.go @@ -0,0 +1,106 @@ +package binary + +import ( + "fmt" + pb "github.com/Rhymen/go-whatsapp/binary/proto" + "github.com/golang/protobuf/proto" +) + +type Node struct { + Description string + Attributes map[string]string + Content interface{} +} + +func Marshal(n Node) ([]byte, error) { + if n.Attributes != nil && n.Content != nil { + a, err := marshalMessageArray(n.Content.([]interface{})) + if err != nil { + return nil, err + } + n.Content = a + } + + w := NewEncoder() + if err := w.WriteNode(n); err != nil { + return nil, err + } + + return w.GetData(), nil +} + +func marshalMessageArray(messages []interface{}) ([]Node, error) { + ret := make([]Node, len(messages)) + + for i, m := range messages { + if wmi, ok := m.(*pb.WebMessageInfo); ok { + b, err := marshalWebMessageInfo(wmi) + if err != nil { + return nil, nil + } + ret[i] = Node{"message", nil, b} + } else { + ret[i], ok = m.(Node) + if !ok { + return nil, fmt.Errorf("invalid Node") + } + } + } + + return ret, nil +} + +func marshalWebMessageInfo(p *pb.WebMessageInfo) ([]byte, error) { + b, err := proto.Marshal(p) + if err != nil { + return nil, err + } + return b, nil +} + +func Unmarshal(data []byte) (*Node, error) { + r := NewDecoder(data) + n, err := r.ReadNode() + if err != nil { + return nil, err + } + + if n != nil && n.Attributes != nil && n.Content != nil { + nContent, ok := n.Content.([]Node) + if ok { + n.Content, err = unmarshalMessageArray(nContent) + if err != nil { + return nil, err + } + } + } + + return n, nil +} + +func unmarshalMessageArray(messages []Node) ([]interface{}, error) { + ret := make([]interface{}, len(messages)) + + for i, msg := range messages { + if msg.Description == "message" { + info, err := unmarshalWebMessageInfo(msg.Content.([]byte)) + if err != nil { + return nil, err + } + ret[i] = info + } else { + ret[i] = msg + } + } + + return ret, nil +} + +func unmarshalWebMessageInfo(msg []byte) (*pb.WebMessageInfo, error) { + message := &pb.WebMessageInfo{} + err := proto.Unmarshal(msg, message) + if err != nil { + return nil, err + } + return message, nil +} diff --git a/vendor/github.com/Rhymen/go-whatsapp/binary/proto/def.pb.go b/vendor/github.com/Rhymen/go-whatsapp/binary/proto/def.pb.go new file mode 100644 index 00000000..2e473b73 --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/binary/proto/def.pb.go @@ -0,0 +1,12807 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0-devel +// protoc v3.12.3 +// source: def.proto + +package proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type AdReplyInfo_AdReplyInfoMediaType int32 + +const ( + AdReplyInfo_NONE AdReplyInfo_AdReplyInfoMediaType = 0 + AdReplyInfo_IMAGE AdReplyInfo_AdReplyInfoMediaType = 1 + AdReplyInfo_VIDEO AdReplyInfo_AdReplyInfoMediaType = 2 +) + +// Enum value maps for AdReplyInfo_AdReplyInfoMediaType. +var ( + AdReplyInfo_AdReplyInfoMediaType_name = map[int32]string{ + 0: "NONE", + 1: "IMAGE", + 2: "VIDEO", + } + AdReplyInfo_AdReplyInfoMediaType_value = map[string]int32{ + "NONE": 0, + "IMAGE": 1, + "VIDEO": 2, + } +) + +func (x AdReplyInfo_AdReplyInfoMediaType) Enum() *AdReplyInfo_AdReplyInfoMediaType { + p := new(AdReplyInfo_AdReplyInfoMediaType) + *p = x + return p +} + +func (x AdReplyInfo_AdReplyInfoMediaType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (AdReplyInfo_AdReplyInfoMediaType) Descriptor() protoreflect.EnumDescriptor { + return file_def_proto_enumTypes[0].Descriptor() +} + +func (AdReplyInfo_AdReplyInfoMediaType) Type() protoreflect.EnumType { + return &file_def_proto_enumTypes[0] +} + +func (x AdReplyInfo_AdReplyInfoMediaType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *AdReplyInfo_AdReplyInfoMediaType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = AdReplyInfo_AdReplyInfoMediaType(num) + return nil +} + +// Deprecated: Use AdReplyInfo_AdReplyInfoMediaType.Descriptor instead. +func (AdReplyInfo_AdReplyInfoMediaType) EnumDescriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{14, 0} +} + +type ExternalAdReplyInfo_ExternalAdReplyInfoMediaType int32 + +const ( + ExternalAdReplyInfo_NONE ExternalAdReplyInfo_ExternalAdReplyInfoMediaType = 0 + ExternalAdReplyInfo_IMAGE ExternalAdReplyInfo_ExternalAdReplyInfoMediaType = 1 + ExternalAdReplyInfo_VIDEO ExternalAdReplyInfo_ExternalAdReplyInfoMediaType = 2 +) + +// Enum value maps for ExternalAdReplyInfo_ExternalAdReplyInfoMediaType. +var ( + ExternalAdReplyInfo_ExternalAdReplyInfoMediaType_name = map[int32]string{ + 0: "NONE", + 1: "IMAGE", + 2: "VIDEO", + } + ExternalAdReplyInfo_ExternalAdReplyInfoMediaType_value = map[string]int32{ + "NONE": 0, + "IMAGE": 1, + "VIDEO": 2, + } +) + +func (x ExternalAdReplyInfo_ExternalAdReplyInfoMediaType) Enum() *ExternalAdReplyInfo_ExternalAdReplyInfoMediaType { + p := new(ExternalAdReplyInfo_ExternalAdReplyInfoMediaType) + *p = x + return p +} + +func (x ExternalAdReplyInfo_ExternalAdReplyInfoMediaType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ExternalAdReplyInfo_ExternalAdReplyInfoMediaType) Descriptor() protoreflect.EnumDescriptor { + return file_def_proto_enumTypes[1].Descriptor() +} + +func (ExternalAdReplyInfo_ExternalAdReplyInfoMediaType) Type() protoreflect.EnumType { + return &file_def_proto_enumTypes[1] +} + +func (x ExternalAdReplyInfo_ExternalAdReplyInfoMediaType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *ExternalAdReplyInfo_ExternalAdReplyInfoMediaType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = ExternalAdReplyInfo_ExternalAdReplyInfoMediaType(num) + return nil +} + +// Deprecated: Use ExternalAdReplyInfo_ExternalAdReplyInfoMediaType.Descriptor instead. +func (ExternalAdReplyInfo_ExternalAdReplyInfoMediaType) EnumDescriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{15, 0} +} + +type InvoiceMessage_InvoiceMessageAttachmentType int32 + +const ( + InvoiceMessage_IMAGE InvoiceMessage_InvoiceMessageAttachmentType = 0 + InvoiceMessage_PDF InvoiceMessage_InvoiceMessageAttachmentType = 1 +) + +// Enum value maps for InvoiceMessage_InvoiceMessageAttachmentType. +var ( + InvoiceMessage_InvoiceMessageAttachmentType_name = map[int32]string{ + 0: "IMAGE", + 1: "PDF", + } + InvoiceMessage_InvoiceMessageAttachmentType_value = map[string]int32{ + "IMAGE": 0, + "PDF": 1, + } +) + +func (x InvoiceMessage_InvoiceMessageAttachmentType) Enum() *InvoiceMessage_InvoiceMessageAttachmentType { + p := new(InvoiceMessage_InvoiceMessageAttachmentType) + *p = x + return p +} + +func (x InvoiceMessage_InvoiceMessageAttachmentType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (InvoiceMessage_InvoiceMessageAttachmentType) Descriptor() protoreflect.EnumDescriptor { + return file_def_proto_enumTypes[2].Descriptor() +} + +func (InvoiceMessage_InvoiceMessageAttachmentType) Type() protoreflect.EnumType { + return &file_def_proto_enumTypes[2] +} + +func (x InvoiceMessage_InvoiceMessageAttachmentType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *InvoiceMessage_InvoiceMessageAttachmentType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = InvoiceMessage_InvoiceMessageAttachmentType(num) + return nil +} + +// Deprecated: Use InvoiceMessage_InvoiceMessageAttachmentType.Descriptor instead. +func (InvoiceMessage_InvoiceMessageAttachmentType) EnumDescriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{19, 0} +} + +type ExtendedTextMessage_ExtendedTextMessageFontType int32 + +const ( + ExtendedTextMessage_SANS_SERIF ExtendedTextMessage_ExtendedTextMessageFontType = 0 + ExtendedTextMessage_SERIF ExtendedTextMessage_ExtendedTextMessageFontType = 1 + ExtendedTextMessage_NORICAN_REGULAR ExtendedTextMessage_ExtendedTextMessageFontType = 2 + ExtendedTextMessage_BRYNDAN_WRITE ExtendedTextMessage_ExtendedTextMessageFontType = 3 + ExtendedTextMessage_BEBASNEUE_REGULAR ExtendedTextMessage_ExtendedTextMessageFontType = 4 + ExtendedTextMessage_OSWALD_HEAVY ExtendedTextMessage_ExtendedTextMessageFontType = 5 +) + +// Enum value maps for ExtendedTextMessage_ExtendedTextMessageFontType. +var ( + ExtendedTextMessage_ExtendedTextMessageFontType_name = map[int32]string{ + 0: "SANS_SERIF", + 1: "SERIF", + 2: "NORICAN_REGULAR", + 3: "BRYNDAN_WRITE", + 4: "BEBASNEUE_REGULAR", + 5: "OSWALD_HEAVY", + } + ExtendedTextMessage_ExtendedTextMessageFontType_value = map[string]int32{ + "SANS_SERIF": 0, + "SERIF": 1, + "NORICAN_REGULAR": 2, + "BRYNDAN_WRITE": 3, + "BEBASNEUE_REGULAR": 4, + "OSWALD_HEAVY": 5, + } +) + +func (x ExtendedTextMessage_ExtendedTextMessageFontType) Enum() *ExtendedTextMessage_ExtendedTextMessageFontType { + p := new(ExtendedTextMessage_ExtendedTextMessageFontType) + *p = x + return p +} + +func (x ExtendedTextMessage_ExtendedTextMessageFontType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ExtendedTextMessage_ExtendedTextMessageFontType) Descriptor() protoreflect.EnumDescriptor { + return file_def_proto_enumTypes[3].Descriptor() +} + +func (ExtendedTextMessage_ExtendedTextMessageFontType) Type() protoreflect.EnumType { + return &file_def_proto_enumTypes[3] +} + +func (x ExtendedTextMessage_ExtendedTextMessageFontType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *ExtendedTextMessage_ExtendedTextMessageFontType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = ExtendedTextMessage_ExtendedTextMessageFontType(num) + return nil +} + +// Deprecated: Use ExtendedTextMessage_ExtendedTextMessageFontType.Descriptor instead. +func (ExtendedTextMessage_ExtendedTextMessageFontType) EnumDescriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{22, 0} +} + +type ExtendedTextMessage_ExtendedTextMessagePreviewType int32 + +const ( + ExtendedTextMessage_NONE ExtendedTextMessage_ExtendedTextMessagePreviewType = 0 + ExtendedTextMessage_VIDEO ExtendedTextMessage_ExtendedTextMessagePreviewType = 1 +) + +// Enum value maps for ExtendedTextMessage_ExtendedTextMessagePreviewType. +var ( + ExtendedTextMessage_ExtendedTextMessagePreviewType_name = map[int32]string{ + 0: "NONE", + 1: "VIDEO", + } + ExtendedTextMessage_ExtendedTextMessagePreviewType_value = map[string]int32{ + "NONE": 0, + "VIDEO": 1, + } +) + +func (x ExtendedTextMessage_ExtendedTextMessagePreviewType) Enum() *ExtendedTextMessage_ExtendedTextMessagePreviewType { + p := new(ExtendedTextMessage_ExtendedTextMessagePreviewType) + *p = x + return p +} + +func (x ExtendedTextMessage_ExtendedTextMessagePreviewType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ExtendedTextMessage_ExtendedTextMessagePreviewType) Descriptor() protoreflect.EnumDescriptor { + return file_def_proto_enumTypes[4].Descriptor() +} + +func (ExtendedTextMessage_ExtendedTextMessagePreviewType) Type() protoreflect.EnumType { + return &file_def_proto_enumTypes[4] +} + +func (x ExtendedTextMessage_ExtendedTextMessagePreviewType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *ExtendedTextMessage_ExtendedTextMessagePreviewType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = ExtendedTextMessage_ExtendedTextMessagePreviewType(num) + return nil +} + +// Deprecated: Use ExtendedTextMessage_ExtendedTextMessagePreviewType.Descriptor instead. +func (ExtendedTextMessage_ExtendedTextMessagePreviewType) EnumDescriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{22, 1} +} + +type VideoMessage_VideoMessageAttribution int32 + +const ( + VideoMessage_NONE VideoMessage_VideoMessageAttribution = 0 + VideoMessage_GIPHY VideoMessage_VideoMessageAttribution = 1 + VideoMessage_TENOR VideoMessage_VideoMessageAttribution = 2 +) + +// Enum value maps for VideoMessage_VideoMessageAttribution. +var ( + VideoMessage_VideoMessageAttribution_name = map[int32]string{ + 0: "NONE", + 1: "GIPHY", + 2: "TENOR", + } + VideoMessage_VideoMessageAttribution_value = map[string]int32{ + "NONE": 0, + "GIPHY": 1, + "TENOR": 2, + } +) + +func (x VideoMessage_VideoMessageAttribution) Enum() *VideoMessage_VideoMessageAttribution { + p := new(VideoMessage_VideoMessageAttribution) + *p = x + return p +} + +func (x VideoMessage_VideoMessageAttribution) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (VideoMessage_VideoMessageAttribution) Descriptor() protoreflect.EnumDescriptor { + return file_def_proto_enumTypes[5].Descriptor() +} + +func (VideoMessage_VideoMessageAttribution) Type() protoreflect.EnumType { + return &file_def_proto_enumTypes[5] +} + +func (x VideoMessage_VideoMessageAttribution) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *VideoMessage_VideoMessageAttribution) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = VideoMessage_VideoMessageAttribution(num) + return nil +} + +// Deprecated: Use VideoMessage_VideoMessageAttribution.Descriptor instead. +func (VideoMessage_VideoMessageAttribution) EnumDescriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{25, 0} +} + +type ProtocolMessage_ProtocolMessageType int32 + +const ( + ProtocolMessage_REVOKE ProtocolMessage_ProtocolMessageType = 0 + ProtocolMessage_EPHEMERAL_SETTING ProtocolMessage_ProtocolMessageType = 3 + ProtocolMessage_EPHEMERAL_SYNC_RESPONSE ProtocolMessage_ProtocolMessageType = 4 + ProtocolMessage_HISTORY_SYNC_NOTIFICATION ProtocolMessage_ProtocolMessageType = 5 + ProtocolMessage_APP_STATE_SYNC_KEY_SHARE ProtocolMessage_ProtocolMessageType = 6 + ProtocolMessage_APP_STATE_SYNC_KEY_REQUEST ProtocolMessage_ProtocolMessageType = 7 + ProtocolMessage_MSG_FANOUT_BACKFILL_REQUEST ProtocolMessage_ProtocolMessageType = 8 + ProtocolMessage_INITIAL_SECURITY_NOTIFICATION_SETTING_SYNC ProtocolMessage_ProtocolMessageType = 9 + ProtocolMessage_APP_STATE_FATAL_EXCEPTION_NOTIFICATION ProtocolMessage_ProtocolMessageType = 10 +) + +// Enum value maps for ProtocolMessage_ProtocolMessageType. +var ( + ProtocolMessage_ProtocolMessageType_name = map[int32]string{ + 0: "REVOKE", + 3: "EPHEMERAL_SETTING", + 4: "EPHEMERAL_SYNC_RESPONSE", + 5: "HISTORY_SYNC_NOTIFICATION", + 6: "APP_STATE_SYNC_KEY_SHARE", + 7: "APP_STATE_SYNC_KEY_REQUEST", + 8: "MSG_FANOUT_BACKFILL_REQUEST", + 9: "INITIAL_SECURITY_NOTIFICATION_SETTING_SYNC", + 10: "APP_STATE_FATAL_EXCEPTION_NOTIFICATION", + } + ProtocolMessage_ProtocolMessageType_value = map[string]int32{ + "REVOKE": 0, + "EPHEMERAL_SETTING": 3, + "EPHEMERAL_SYNC_RESPONSE": 4, + "HISTORY_SYNC_NOTIFICATION": 5, + "APP_STATE_SYNC_KEY_SHARE": 6, + "APP_STATE_SYNC_KEY_REQUEST": 7, + "MSG_FANOUT_BACKFILL_REQUEST": 8, + "INITIAL_SECURITY_NOTIFICATION_SETTING_SYNC": 9, + "APP_STATE_FATAL_EXCEPTION_NOTIFICATION": 10, + } +) + +func (x ProtocolMessage_ProtocolMessageType) Enum() *ProtocolMessage_ProtocolMessageType { + p := new(ProtocolMessage_ProtocolMessageType) + *p = x + return p +} + +func (x ProtocolMessage_ProtocolMessageType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ProtocolMessage_ProtocolMessageType) Descriptor() protoreflect.EnumDescriptor { + return file_def_proto_enumTypes[6].Descriptor() +} + +func (ProtocolMessage_ProtocolMessageType) Type() protoreflect.EnumType { + return &file_def_proto_enumTypes[6] +} + +func (x ProtocolMessage_ProtocolMessageType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *ProtocolMessage_ProtocolMessageType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = ProtocolMessage_ProtocolMessageType(num) + return nil +} + +// Deprecated: Use ProtocolMessage_ProtocolMessageType.Descriptor instead. +func (ProtocolMessage_ProtocolMessageType) EnumDescriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{28, 0} +} + +type HistorySyncNotification_HistorySyncNotificationHistorySyncType int32 + +const ( + HistorySyncNotification_INITIAL_BOOTSTRAP HistorySyncNotification_HistorySyncNotificationHistorySyncType = 0 + HistorySyncNotification_INITIAL_STATUS_V3 HistorySyncNotification_HistorySyncNotificationHistorySyncType = 1 + HistorySyncNotification_FULL HistorySyncNotification_HistorySyncNotificationHistorySyncType = 2 + HistorySyncNotification_RECENT HistorySyncNotification_HistorySyncNotificationHistorySyncType = 3 + HistorySyncNotification_PUSH_NAME HistorySyncNotification_HistorySyncNotificationHistorySyncType = 4 +) + +// Enum value maps for HistorySyncNotification_HistorySyncNotificationHistorySyncType. +var ( + HistorySyncNotification_HistorySyncNotificationHistorySyncType_name = map[int32]string{ + 0: "INITIAL_BOOTSTRAP", + 1: "INITIAL_STATUS_V3", + 2: "FULL", + 3: "RECENT", + 4: "PUSH_NAME", + } + HistorySyncNotification_HistorySyncNotificationHistorySyncType_value = map[string]int32{ + "INITIAL_BOOTSTRAP": 0, + "INITIAL_STATUS_V3": 1, + "FULL": 2, + "RECENT": 3, + "PUSH_NAME": 4, + } +) + +func (x HistorySyncNotification_HistorySyncNotificationHistorySyncType) Enum() *HistorySyncNotification_HistorySyncNotificationHistorySyncType { + p := new(HistorySyncNotification_HistorySyncNotificationHistorySyncType) + *p = x + return p +} + +func (x HistorySyncNotification_HistorySyncNotificationHistorySyncType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (HistorySyncNotification_HistorySyncNotificationHistorySyncType) Descriptor() protoreflect.EnumDescriptor { + return file_def_proto_enumTypes[7].Descriptor() +} + +func (HistorySyncNotification_HistorySyncNotificationHistorySyncType) Type() protoreflect.EnumType { + return &file_def_proto_enumTypes[7] +} + +func (x HistorySyncNotification_HistorySyncNotificationHistorySyncType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *HistorySyncNotification_HistorySyncNotificationHistorySyncType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = HistorySyncNotification_HistorySyncNotificationHistorySyncType(num) + return nil +} + +// Deprecated: Use HistorySyncNotification_HistorySyncNotificationHistorySyncType.Descriptor instead. +func (HistorySyncNotification_HistorySyncNotificationHistorySyncType) EnumDescriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{29, 0} +} + +type HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType int32 + +const ( + HSMDateTimeComponent_MONDAY HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType = 1 + HSMDateTimeComponent_TUESDAY HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType = 2 + HSMDateTimeComponent_WEDNESDAY HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType = 3 + HSMDateTimeComponent_THURSDAY HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType = 4 + HSMDateTimeComponent_FRIDAY HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType = 5 + HSMDateTimeComponent_SATURDAY HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType = 6 + HSMDateTimeComponent_SUNDAY HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType = 7 +) + +// Enum value maps for HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType. +var ( + HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType_name = map[int32]string{ + 1: "MONDAY", + 2: "TUESDAY", + 3: "WEDNESDAY", + 4: "THURSDAY", + 5: "FRIDAY", + 6: "SATURDAY", + 7: "SUNDAY", + } + HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType_value = map[string]int32{ + "MONDAY": 1, + "TUESDAY": 2, + "WEDNESDAY": 3, + "THURSDAY": 4, + "FRIDAY": 5, + "SATURDAY": 6, + "SUNDAY": 7, + } +) + +func (x HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType) Enum() *HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType { + p := new(HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType) + *p = x + return p +} + +func (x HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType) Descriptor() protoreflect.EnumDescriptor { + return file_def_proto_enumTypes[8].Descriptor() +} + +func (HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType) Type() protoreflect.EnumType { + return &file_def_proto_enumTypes[8] +} + +func (x HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType(num) + return nil +} + +// Deprecated: Use HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType.Descriptor instead. +func (HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType) EnumDescriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{40, 0} +} + +type HSMDateTimeComponent_HSMDateTimeComponentCalendarType int32 + +const ( + HSMDateTimeComponent_GREGORIAN HSMDateTimeComponent_HSMDateTimeComponentCalendarType = 1 + HSMDateTimeComponent_SOLAR_HIJRI HSMDateTimeComponent_HSMDateTimeComponentCalendarType = 2 +) + +// Enum value maps for HSMDateTimeComponent_HSMDateTimeComponentCalendarType. +var ( + HSMDateTimeComponent_HSMDateTimeComponentCalendarType_name = map[int32]string{ + 1: "GREGORIAN", + 2: "SOLAR_HIJRI", + } + HSMDateTimeComponent_HSMDateTimeComponentCalendarType_value = map[string]int32{ + "GREGORIAN": 1, + "SOLAR_HIJRI": 2, + } +) + +func (x HSMDateTimeComponent_HSMDateTimeComponentCalendarType) Enum() *HSMDateTimeComponent_HSMDateTimeComponentCalendarType { + p := new(HSMDateTimeComponent_HSMDateTimeComponentCalendarType) + *p = x + return p +} + +func (x HSMDateTimeComponent_HSMDateTimeComponentCalendarType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (HSMDateTimeComponent_HSMDateTimeComponentCalendarType) Descriptor() protoreflect.EnumDescriptor { + return file_def_proto_enumTypes[9].Descriptor() +} + +func (HSMDateTimeComponent_HSMDateTimeComponentCalendarType) Type() protoreflect.EnumType { + return &file_def_proto_enumTypes[9] +} + +func (x HSMDateTimeComponent_HSMDateTimeComponentCalendarType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *HSMDateTimeComponent_HSMDateTimeComponentCalendarType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = HSMDateTimeComponent_HSMDateTimeComponentCalendarType(num) + return nil +} + +// Deprecated: Use HSMDateTimeComponent_HSMDateTimeComponentCalendarType.Descriptor instead. +func (HSMDateTimeComponent_HSMDateTimeComponentCalendarType) EnumDescriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{40, 1} +} + +type OrderMessage_OrderMessageOrderStatus int32 + +const ( + OrderMessage_INQUIRY OrderMessage_OrderMessageOrderStatus = 1 +) + +// Enum value maps for OrderMessage_OrderMessageOrderStatus. +var ( + OrderMessage_OrderMessageOrderStatus_name = map[int32]string{ + 1: "INQUIRY", + } + OrderMessage_OrderMessageOrderStatus_value = map[string]int32{ + "INQUIRY": 1, + } +) + +func (x OrderMessage_OrderMessageOrderStatus) Enum() *OrderMessage_OrderMessageOrderStatus { + p := new(OrderMessage_OrderMessageOrderStatus) + *p = x + return p +} + +func (x OrderMessage_OrderMessageOrderStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (OrderMessage_OrderMessageOrderStatus) Descriptor() protoreflect.EnumDescriptor { + return file_def_proto_enumTypes[10].Descriptor() +} + +func (OrderMessage_OrderMessageOrderStatus) Type() protoreflect.EnumType { + return &file_def_proto_enumTypes[10] +} + +func (x OrderMessage_OrderMessageOrderStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *OrderMessage_OrderMessageOrderStatus) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = OrderMessage_OrderMessageOrderStatus(num) + return nil +} + +// Deprecated: Use OrderMessage_OrderMessageOrderStatus.Descriptor instead. +func (OrderMessage_OrderMessageOrderStatus) EnumDescriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{58, 0} +} + +type OrderMessage_OrderMessageOrderSurface int32 + +const ( + OrderMessage_CATALOG OrderMessage_OrderMessageOrderSurface = 1 +) + +// Enum value maps for OrderMessage_OrderMessageOrderSurface. +var ( + OrderMessage_OrderMessageOrderSurface_name = map[int32]string{ + 1: "CATALOG", + } + OrderMessage_OrderMessageOrderSurface_value = map[string]int32{ + "CATALOG": 1, + } +) + +func (x OrderMessage_OrderMessageOrderSurface) Enum() *OrderMessage_OrderMessageOrderSurface { + p := new(OrderMessage_OrderMessageOrderSurface) + *p = x + return p +} + +func (x OrderMessage_OrderMessageOrderSurface) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (OrderMessage_OrderMessageOrderSurface) Descriptor() protoreflect.EnumDescriptor { + return file_def_proto_enumTypes[11].Descriptor() +} + +func (OrderMessage_OrderMessageOrderSurface) Type() protoreflect.EnumType { + return &file_def_proto_enumTypes[11] +} + +func (x OrderMessage_OrderMessageOrderSurface) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *OrderMessage_OrderMessageOrderSurface) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = OrderMessage_OrderMessageOrderSurface(num) + return nil +} + +// Deprecated: Use OrderMessage_OrderMessageOrderSurface.Descriptor instead. +func (OrderMessage_OrderMessageOrderSurface) EnumDescriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{58, 1} +} + +type ListMessage_ListMessageListType int32 + +const ( + ListMessage_UNKNOWN ListMessage_ListMessageListType = 0 + ListMessage_SINGLE_SELECT ListMessage_ListMessageListType = 1 +) + +// Enum value maps for ListMessage_ListMessageListType. +var ( + ListMessage_ListMessageListType_name = map[int32]string{ + 0: "UNKNOWN", + 1: "SINGLE_SELECT", + } + ListMessage_ListMessageListType_value = map[string]int32{ + "UNKNOWN": 0, + "SINGLE_SELECT": 1, + } +) + +func (x ListMessage_ListMessageListType) Enum() *ListMessage_ListMessageListType { + p := new(ListMessage_ListMessageListType) + *p = x + return p +} + +func (x ListMessage_ListMessageListType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ListMessage_ListMessageListType) Descriptor() protoreflect.EnumDescriptor { + return file_def_proto_enumTypes[12].Descriptor() +} + +func (ListMessage_ListMessageListType) Type() protoreflect.EnumType { + return &file_def_proto_enumTypes[12] +} + +func (x ListMessage_ListMessageListType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *ListMessage_ListMessageListType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = ListMessage_ListMessageListType(num) + return nil +} + +// Deprecated: Use ListMessage_ListMessageListType.Descriptor instead. +func (ListMessage_ListMessageListType) EnumDescriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{61, 0} +} + +type ListResponseMessage_ListResponseMessageListType int32 + +const ( + ListResponseMessage_UNKNOWN ListResponseMessage_ListResponseMessageListType = 0 + ListResponseMessage_SINGLE_SELECT ListResponseMessage_ListResponseMessageListType = 1 +) + +// Enum value maps for ListResponseMessage_ListResponseMessageListType. +var ( + ListResponseMessage_ListResponseMessageListType_name = map[int32]string{ + 0: "UNKNOWN", + 1: "SINGLE_SELECT", + } + ListResponseMessage_ListResponseMessageListType_value = map[string]int32{ + "UNKNOWN": 0, + "SINGLE_SELECT": 1, + } +) + +func (x ListResponseMessage_ListResponseMessageListType) Enum() *ListResponseMessage_ListResponseMessageListType { + p := new(ListResponseMessage_ListResponseMessageListType) + *p = x + return p +} + +func (x ListResponseMessage_ListResponseMessageListType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ListResponseMessage_ListResponseMessageListType) Descriptor() protoreflect.EnumDescriptor { + return file_def_proto_enumTypes[13].Descriptor() +} + +func (ListResponseMessage_ListResponseMessageListType) Type() protoreflect.EnumType { + return &file_def_proto_enumTypes[13] +} + +func (x ListResponseMessage_ListResponseMessageListType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *ListResponseMessage_ListResponseMessageListType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = ListResponseMessage_ListResponseMessageListType(num) + return nil +} + +// Deprecated: Use ListResponseMessage_ListResponseMessageListType.Descriptor instead. +func (ListResponseMessage_ListResponseMessageListType) EnumDescriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{63, 0} +} + +type Button_ButtonType int32 + +const ( + Button_UNKNOWN Button_ButtonType = 0 + Button_RESPONSE Button_ButtonType = 1 +) + +// Enum value maps for Button_ButtonType. +var ( + Button_ButtonType_name = map[int32]string{ + 0: "UNKNOWN", + 1: "RESPONSE", + } + Button_ButtonType_value = map[string]int32{ + "UNKNOWN": 0, + "RESPONSE": 1, + } +) + +func (x Button_ButtonType) Enum() *Button_ButtonType { + p := new(Button_ButtonType) + *p = x + return p +} + +func (x Button_ButtonType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Button_ButtonType) Descriptor() protoreflect.EnumDescriptor { + return file_def_proto_enumTypes[14].Descriptor() +} + +func (Button_ButtonType) Type() protoreflect.EnumType { + return &file_def_proto_enumTypes[14] +} + +func (x Button_ButtonType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *Button_ButtonType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = Button_ButtonType(num) + return nil +} + +// Deprecated: Use Button_ButtonType.Descriptor instead. +func (Button_ButtonType) EnumDescriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{69, 0} +} + +type ButtonsMessage_ButtonsMessageHeaderType int32 + +const ( + ButtonsMessage_UNKNOWN ButtonsMessage_ButtonsMessageHeaderType = 0 + ButtonsMessage_EMPTY ButtonsMessage_ButtonsMessageHeaderType = 1 + ButtonsMessage_TEXT ButtonsMessage_ButtonsMessageHeaderType = 2 + ButtonsMessage_DOCUMENT ButtonsMessage_ButtonsMessageHeaderType = 3 + ButtonsMessage_IMAGE ButtonsMessage_ButtonsMessageHeaderType = 4 + ButtonsMessage_VIDEO ButtonsMessage_ButtonsMessageHeaderType = 5 + ButtonsMessage_LOCATION ButtonsMessage_ButtonsMessageHeaderType = 6 +) + +// Enum value maps for ButtonsMessage_ButtonsMessageHeaderType. +var ( + ButtonsMessage_ButtonsMessageHeaderType_name = map[int32]string{ + 0: "UNKNOWN", + 1: "EMPTY", + 2: "TEXT", + 3: "DOCUMENT", + 4: "IMAGE", + 5: "VIDEO", + 6: "LOCATION", + } + ButtonsMessage_ButtonsMessageHeaderType_value = map[string]int32{ + "UNKNOWN": 0, + "EMPTY": 1, + "TEXT": 2, + "DOCUMENT": 3, + "IMAGE": 4, + "VIDEO": 5, + "LOCATION": 6, + } +) + +func (x ButtonsMessage_ButtonsMessageHeaderType) Enum() *ButtonsMessage_ButtonsMessageHeaderType { + p := new(ButtonsMessage_ButtonsMessageHeaderType) + *p = x + return p +} + +func (x ButtonsMessage_ButtonsMessageHeaderType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ButtonsMessage_ButtonsMessageHeaderType) Descriptor() protoreflect.EnumDescriptor { + return file_def_proto_enumTypes[15].Descriptor() +} + +func (ButtonsMessage_ButtonsMessageHeaderType) Type() protoreflect.EnumType { + return &file_def_proto_enumTypes[15] +} + +func (x ButtonsMessage_ButtonsMessageHeaderType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *ButtonsMessage_ButtonsMessageHeaderType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = ButtonsMessage_ButtonsMessageHeaderType(num) + return nil +} + +// Deprecated: Use ButtonsMessage_ButtonsMessageHeaderType.Descriptor instead. +func (ButtonsMessage_ButtonsMessageHeaderType) EnumDescriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{70, 0} +} + +type ButtonsResponseMessage_ButtonsResponseMessageType int32 + +const ( + ButtonsResponseMessage_UNKNOWN ButtonsResponseMessage_ButtonsResponseMessageType = 0 + ButtonsResponseMessage_DISPLAY_TEXT ButtonsResponseMessage_ButtonsResponseMessageType = 1 +) + +// Enum value maps for ButtonsResponseMessage_ButtonsResponseMessageType. +var ( + ButtonsResponseMessage_ButtonsResponseMessageType_name = map[int32]string{ + 0: "UNKNOWN", + 1: "DISPLAY_TEXT", + } + ButtonsResponseMessage_ButtonsResponseMessageType_value = map[string]int32{ + "UNKNOWN": 0, + "DISPLAY_TEXT": 1, + } +) + +func (x ButtonsResponseMessage_ButtonsResponseMessageType) Enum() *ButtonsResponseMessage_ButtonsResponseMessageType { + p := new(ButtonsResponseMessage_ButtonsResponseMessageType) + *p = x + return p +} + +func (x ButtonsResponseMessage_ButtonsResponseMessageType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ButtonsResponseMessage_ButtonsResponseMessageType) Descriptor() protoreflect.EnumDescriptor { + return file_def_proto_enumTypes[16].Descriptor() +} + +func (ButtonsResponseMessage_ButtonsResponseMessageType) Type() protoreflect.EnumType { + return &file_def_proto_enumTypes[16] +} + +func (x ButtonsResponseMessage_ButtonsResponseMessageType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *ButtonsResponseMessage_ButtonsResponseMessageType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = ButtonsResponseMessage_ButtonsResponseMessageType(num) + return nil +} + +// Deprecated: Use ButtonsResponseMessage_ButtonsResponseMessageType.Descriptor instead. +func (ButtonsResponseMessage_ButtonsResponseMessageType) EnumDescriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{71, 0} +} + +type WebFeatures_WebFeaturesFlag int32 + +const ( + WebFeatures_NOT_STARTED WebFeatures_WebFeaturesFlag = 0 + WebFeatures_FORCE_UPGRADE WebFeatures_WebFeaturesFlag = 1 + WebFeatures_DEVELOPMENT WebFeatures_WebFeaturesFlag = 2 + WebFeatures_PRODUCTION WebFeatures_WebFeaturesFlag = 3 +) + +// Enum value maps for WebFeatures_WebFeaturesFlag. +var ( + WebFeatures_WebFeaturesFlag_name = map[int32]string{ + 0: "NOT_STARTED", + 1: "FORCE_UPGRADE", + 2: "DEVELOPMENT", + 3: "PRODUCTION", + } + WebFeatures_WebFeaturesFlag_value = map[string]int32{ + "NOT_STARTED": 0, + "FORCE_UPGRADE": 1, + "DEVELOPMENT": 2, + "PRODUCTION": 3, + } +) + +func (x WebFeatures_WebFeaturesFlag) Enum() *WebFeatures_WebFeaturesFlag { + p := new(WebFeatures_WebFeaturesFlag) + *p = x + return p +} + +func (x WebFeatures_WebFeaturesFlag) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (WebFeatures_WebFeaturesFlag) Descriptor() protoreflect.EnumDescriptor { + return file_def_proto_enumTypes[17].Descriptor() +} + +func (WebFeatures_WebFeaturesFlag) Type() protoreflect.EnumType { + return &file_def_proto_enumTypes[17] +} + +func (x WebFeatures_WebFeaturesFlag) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *WebFeatures_WebFeaturesFlag) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = WebFeatures_WebFeaturesFlag(num) + return nil +} + +// Deprecated: Use WebFeatures_WebFeaturesFlag.Descriptor instead. +func (WebFeatures_WebFeaturesFlag) EnumDescriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{74, 0} +} + +type PaymentInfo_PaymentInfoCurrency int32 + +const ( + PaymentInfo_UNKNOWN_CURRENCY PaymentInfo_PaymentInfoCurrency = 0 + PaymentInfo_INR PaymentInfo_PaymentInfoCurrency = 1 +) + +// Enum value maps for PaymentInfo_PaymentInfoCurrency. +var ( + PaymentInfo_PaymentInfoCurrency_name = map[int32]string{ + 0: "UNKNOWN_CURRENCY", + 1: "INR", + } + PaymentInfo_PaymentInfoCurrency_value = map[string]int32{ + "UNKNOWN_CURRENCY": 0, + "INR": 1, + } +) + +func (x PaymentInfo_PaymentInfoCurrency) Enum() *PaymentInfo_PaymentInfoCurrency { + p := new(PaymentInfo_PaymentInfoCurrency) + *p = x + return p +} + +func (x PaymentInfo_PaymentInfoCurrency) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (PaymentInfo_PaymentInfoCurrency) Descriptor() protoreflect.EnumDescriptor { + return file_def_proto_enumTypes[18].Descriptor() +} + +func (PaymentInfo_PaymentInfoCurrency) Type() protoreflect.EnumType { + return &file_def_proto_enumTypes[18] +} + +func (x PaymentInfo_PaymentInfoCurrency) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *PaymentInfo_PaymentInfoCurrency) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = PaymentInfo_PaymentInfoCurrency(num) + return nil +} + +// Deprecated: Use PaymentInfo_PaymentInfoCurrency.Descriptor instead. +func (PaymentInfo_PaymentInfoCurrency) EnumDescriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{77, 0} +} + +type PaymentInfo_PaymentInfoStatus int32 + +const ( + PaymentInfo_UNKNOWN_STATUS PaymentInfo_PaymentInfoStatus = 0 + PaymentInfo_PROCESSING PaymentInfo_PaymentInfoStatus = 1 + PaymentInfo_SENT PaymentInfo_PaymentInfoStatus = 2 + PaymentInfo_NEED_TO_ACCEPT PaymentInfo_PaymentInfoStatus = 3 + PaymentInfo_COMPLETE PaymentInfo_PaymentInfoStatus = 4 + PaymentInfo_COULD_NOT_COMPLETE PaymentInfo_PaymentInfoStatus = 5 + PaymentInfo_REFUNDED PaymentInfo_PaymentInfoStatus = 6 + PaymentInfo_EXPIRED PaymentInfo_PaymentInfoStatus = 7 + PaymentInfo_REJECTED PaymentInfo_PaymentInfoStatus = 8 + PaymentInfo_CANCELLED PaymentInfo_PaymentInfoStatus = 9 + PaymentInfo_WAITING_FOR_PAYER PaymentInfo_PaymentInfoStatus = 10 + PaymentInfo_WAITING PaymentInfo_PaymentInfoStatus = 11 +) + +// Enum value maps for PaymentInfo_PaymentInfoStatus. +var ( + PaymentInfo_PaymentInfoStatus_name = map[int32]string{ + 0: "UNKNOWN_STATUS", + 1: "PROCESSING", + 2: "SENT", + 3: "NEED_TO_ACCEPT", + 4: "COMPLETE", + 5: "COULD_NOT_COMPLETE", + 6: "REFUNDED", + 7: "EXPIRED", + 8: "REJECTED", + 9: "CANCELLED", + 10: "WAITING_FOR_PAYER", + 11: "WAITING", + } + PaymentInfo_PaymentInfoStatus_value = map[string]int32{ + "UNKNOWN_STATUS": 0, + "PROCESSING": 1, + "SENT": 2, + "NEED_TO_ACCEPT": 3, + "COMPLETE": 4, + "COULD_NOT_COMPLETE": 5, + "REFUNDED": 6, + "EXPIRED": 7, + "REJECTED": 8, + "CANCELLED": 9, + "WAITING_FOR_PAYER": 10, + "WAITING": 11, + } +) + +func (x PaymentInfo_PaymentInfoStatus) Enum() *PaymentInfo_PaymentInfoStatus { + p := new(PaymentInfo_PaymentInfoStatus) + *p = x + return p +} + +func (x PaymentInfo_PaymentInfoStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (PaymentInfo_PaymentInfoStatus) Descriptor() protoreflect.EnumDescriptor { + return file_def_proto_enumTypes[19].Descriptor() +} + +func (PaymentInfo_PaymentInfoStatus) Type() protoreflect.EnumType { + return &file_def_proto_enumTypes[19] +} + +func (x PaymentInfo_PaymentInfoStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *PaymentInfo_PaymentInfoStatus) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = PaymentInfo_PaymentInfoStatus(num) + return nil +} + +// Deprecated: Use PaymentInfo_PaymentInfoStatus.Descriptor instead. +func (PaymentInfo_PaymentInfoStatus) EnumDescriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{77, 1} +} + +type PaymentInfo_PaymentInfoTxnStatus int32 + +const ( + PaymentInfo_UNKNOWN PaymentInfo_PaymentInfoTxnStatus = 0 + PaymentInfo_PENDING_SETUP PaymentInfo_PaymentInfoTxnStatus = 1 + PaymentInfo_PENDING_RECEIVER_SETUP PaymentInfo_PaymentInfoTxnStatus = 2 + PaymentInfo_INIT PaymentInfo_PaymentInfoTxnStatus = 3 + PaymentInfo_SUCCESS PaymentInfo_PaymentInfoTxnStatus = 4 + PaymentInfo_COMPLETED PaymentInfo_PaymentInfoTxnStatus = 5 + PaymentInfo_FAILED PaymentInfo_PaymentInfoTxnStatus = 6 + PaymentInfo_FAILED_RISK PaymentInfo_PaymentInfoTxnStatus = 7 + PaymentInfo_FAILED_PROCESSING PaymentInfo_PaymentInfoTxnStatus = 8 + PaymentInfo_FAILED_RECEIVER_PROCESSING PaymentInfo_PaymentInfoTxnStatus = 9 + PaymentInfo_FAILED_DA PaymentInfo_PaymentInfoTxnStatus = 10 + PaymentInfo_FAILED_DA_FINAL PaymentInfo_PaymentInfoTxnStatus = 11 + PaymentInfo_REFUNDED_TXN PaymentInfo_PaymentInfoTxnStatus = 12 + PaymentInfo_REFUND_FAILED PaymentInfo_PaymentInfoTxnStatus = 13 + PaymentInfo_REFUND_FAILED_PROCESSING PaymentInfo_PaymentInfoTxnStatus = 14 + PaymentInfo_REFUND_FAILED_DA PaymentInfo_PaymentInfoTxnStatus = 15 + PaymentInfo_EXPIRED_TXN PaymentInfo_PaymentInfoTxnStatus = 16 + PaymentInfo_AUTH_CANCELED PaymentInfo_PaymentInfoTxnStatus = 17 + PaymentInfo_AUTH_CANCEL_FAILED_PROCESSING PaymentInfo_PaymentInfoTxnStatus = 18 + PaymentInfo_AUTH_CANCEL_FAILED PaymentInfo_PaymentInfoTxnStatus = 19 + PaymentInfo_COLLECT_INIT PaymentInfo_PaymentInfoTxnStatus = 20 + PaymentInfo_COLLECT_SUCCESS PaymentInfo_PaymentInfoTxnStatus = 21 + PaymentInfo_COLLECT_FAILED PaymentInfo_PaymentInfoTxnStatus = 22 + PaymentInfo_COLLECT_FAILED_RISK PaymentInfo_PaymentInfoTxnStatus = 23 + PaymentInfo_COLLECT_REJECTED PaymentInfo_PaymentInfoTxnStatus = 24 + PaymentInfo_COLLECT_EXPIRED PaymentInfo_PaymentInfoTxnStatus = 25 + PaymentInfo_COLLECT_CANCELED PaymentInfo_PaymentInfoTxnStatus = 26 + PaymentInfo_COLLECT_CANCELLING PaymentInfo_PaymentInfoTxnStatus = 27 +) + +// Enum value maps for PaymentInfo_PaymentInfoTxnStatus. +var ( + PaymentInfo_PaymentInfoTxnStatus_name = map[int32]string{ + 0: "UNKNOWN", + 1: "PENDING_SETUP", + 2: "PENDING_RECEIVER_SETUP", + 3: "INIT", + 4: "SUCCESS", + 5: "COMPLETED", + 6: "FAILED", + 7: "FAILED_RISK", + 8: "FAILED_PROCESSING", + 9: "FAILED_RECEIVER_PROCESSING", + 10: "FAILED_DA", + 11: "FAILED_DA_FINAL", + 12: "REFUNDED_TXN", + 13: "REFUND_FAILED", + 14: "REFUND_FAILED_PROCESSING", + 15: "REFUND_FAILED_DA", + 16: "EXPIRED_TXN", + 17: "AUTH_CANCELED", + 18: "AUTH_CANCEL_FAILED_PROCESSING", + 19: "AUTH_CANCEL_FAILED", + 20: "COLLECT_INIT", + 21: "COLLECT_SUCCESS", + 22: "COLLECT_FAILED", + 23: "COLLECT_FAILED_RISK", + 24: "COLLECT_REJECTED", + 25: "COLLECT_EXPIRED", + 26: "COLLECT_CANCELED", + 27: "COLLECT_CANCELLING", + } + PaymentInfo_PaymentInfoTxnStatus_value = map[string]int32{ + "UNKNOWN": 0, + "PENDING_SETUP": 1, + "PENDING_RECEIVER_SETUP": 2, + "INIT": 3, + "SUCCESS": 4, + "COMPLETED": 5, + "FAILED": 6, + "FAILED_RISK": 7, + "FAILED_PROCESSING": 8, + "FAILED_RECEIVER_PROCESSING": 9, + "FAILED_DA": 10, + "FAILED_DA_FINAL": 11, + "REFUNDED_TXN": 12, + "REFUND_FAILED": 13, + "REFUND_FAILED_PROCESSING": 14, + "REFUND_FAILED_DA": 15, + "EXPIRED_TXN": 16, + "AUTH_CANCELED": 17, + "AUTH_CANCEL_FAILED_PROCESSING": 18, + "AUTH_CANCEL_FAILED": 19, + "COLLECT_INIT": 20, + "COLLECT_SUCCESS": 21, + "COLLECT_FAILED": 22, + "COLLECT_FAILED_RISK": 23, + "COLLECT_REJECTED": 24, + "COLLECT_EXPIRED": 25, + "COLLECT_CANCELED": 26, + "COLLECT_CANCELLING": 27, + } +) + +func (x PaymentInfo_PaymentInfoTxnStatus) Enum() *PaymentInfo_PaymentInfoTxnStatus { + p := new(PaymentInfo_PaymentInfoTxnStatus) + *p = x + return p +} + +func (x PaymentInfo_PaymentInfoTxnStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (PaymentInfo_PaymentInfoTxnStatus) Descriptor() protoreflect.EnumDescriptor { + return file_def_proto_enumTypes[20].Descriptor() +} + +func (PaymentInfo_PaymentInfoTxnStatus) Type() protoreflect.EnumType { + return &file_def_proto_enumTypes[20] +} + +func (x PaymentInfo_PaymentInfoTxnStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *PaymentInfo_PaymentInfoTxnStatus) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = PaymentInfo_PaymentInfoTxnStatus(num) + return nil +} + +// Deprecated: Use PaymentInfo_PaymentInfoTxnStatus.Descriptor instead. +func (PaymentInfo_PaymentInfoTxnStatus) EnumDescriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{77, 2} +} + +type WebMessageInfo_WebMessageInfoStatus int32 + +const ( + WebMessageInfo_ERROR WebMessageInfo_WebMessageInfoStatus = 0 + WebMessageInfo_PENDING WebMessageInfo_WebMessageInfoStatus = 1 + WebMessageInfo_SERVER_ACK WebMessageInfo_WebMessageInfoStatus = 2 + WebMessageInfo_DELIVERY_ACK WebMessageInfo_WebMessageInfoStatus = 3 + WebMessageInfo_READ WebMessageInfo_WebMessageInfoStatus = 4 + WebMessageInfo_PLAYED WebMessageInfo_WebMessageInfoStatus = 5 +) + +// Enum value maps for WebMessageInfo_WebMessageInfoStatus. +var ( + WebMessageInfo_WebMessageInfoStatus_name = map[int32]string{ + 0: "ERROR", + 1: "PENDING", + 2: "SERVER_ACK", + 3: "DELIVERY_ACK", + 4: "READ", + 5: "PLAYED", + } + WebMessageInfo_WebMessageInfoStatus_value = map[string]int32{ + "ERROR": 0, + "PENDING": 1, + "SERVER_ACK": 2, + "DELIVERY_ACK": 3, + "READ": 4, + "PLAYED": 5, + } +) + +func (x WebMessageInfo_WebMessageInfoStatus) Enum() *WebMessageInfo_WebMessageInfoStatus { + p := new(WebMessageInfo_WebMessageInfoStatus) + *p = x + return p +} + +func (x WebMessageInfo_WebMessageInfoStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (WebMessageInfo_WebMessageInfoStatus) Descriptor() protoreflect.EnumDescriptor { + return file_def_proto_enumTypes[21].Descriptor() +} + +func (WebMessageInfo_WebMessageInfoStatus) Type() protoreflect.EnumType { + return &file_def_proto_enumTypes[21] +} + +func (x WebMessageInfo_WebMessageInfoStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *WebMessageInfo_WebMessageInfoStatus) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = WebMessageInfo_WebMessageInfoStatus(num) + return nil +} + +// Deprecated: Use WebMessageInfo_WebMessageInfoStatus.Descriptor instead. +func (WebMessageInfo_WebMessageInfoStatus) EnumDescriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{78, 0} +} + +type WebMessageInfo_WebMessageInfoStubType int32 + +const ( + WebMessageInfo_UNKNOWN WebMessageInfo_WebMessageInfoStubType = 0 + WebMessageInfo_REVOKE WebMessageInfo_WebMessageInfoStubType = 1 + WebMessageInfo_CIPHERTEXT WebMessageInfo_WebMessageInfoStubType = 2 + WebMessageInfo_FUTUREPROOF WebMessageInfo_WebMessageInfoStubType = 3 + WebMessageInfo_NON_VERIFIED_TRANSITION WebMessageInfo_WebMessageInfoStubType = 4 + WebMessageInfo_UNVERIFIED_TRANSITION WebMessageInfo_WebMessageInfoStubType = 5 + WebMessageInfo_VERIFIED_TRANSITION WebMessageInfo_WebMessageInfoStubType = 6 + WebMessageInfo_VERIFIED_LOW_UNKNOWN WebMessageInfo_WebMessageInfoStubType = 7 + WebMessageInfo_VERIFIED_HIGH WebMessageInfo_WebMessageInfoStubType = 8 + WebMessageInfo_VERIFIED_INITIAL_UNKNOWN WebMessageInfo_WebMessageInfoStubType = 9 + WebMessageInfo_VERIFIED_INITIAL_LOW WebMessageInfo_WebMessageInfoStubType = 10 + WebMessageInfo_VERIFIED_INITIAL_HIGH WebMessageInfo_WebMessageInfoStubType = 11 + WebMessageInfo_VERIFIED_TRANSITION_ANY_TO_NONE WebMessageInfo_WebMessageInfoStubType = 12 + WebMessageInfo_VERIFIED_TRANSITION_ANY_TO_HIGH WebMessageInfo_WebMessageInfoStubType = 13 + WebMessageInfo_VERIFIED_TRANSITION_HIGH_TO_LOW WebMessageInfo_WebMessageInfoStubType = 14 + WebMessageInfo_VERIFIED_TRANSITION_HIGH_TO_UNKNOWN WebMessageInfo_WebMessageInfoStubType = 15 + WebMessageInfo_VERIFIED_TRANSITION_UNKNOWN_TO_LOW WebMessageInfo_WebMessageInfoStubType = 16 + WebMessageInfo_VERIFIED_TRANSITION_LOW_TO_UNKNOWN WebMessageInfo_WebMessageInfoStubType = 17 + WebMessageInfo_VERIFIED_TRANSITION_NONE_TO_LOW WebMessageInfo_WebMessageInfoStubType = 18 + WebMessageInfo_VERIFIED_TRANSITION_NONE_TO_UNKNOWN WebMessageInfo_WebMessageInfoStubType = 19 + WebMessageInfo_GROUP_CREATE WebMessageInfo_WebMessageInfoStubType = 20 + WebMessageInfo_GROUP_CHANGE_SUBJECT WebMessageInfo_WebMessageInfoStubType = 21 + WebMessageInfo_GROUP_CHANGE_ICON WebMessageInfo_WebMessageInfoStubType = 22 + WebMessageInfo_GROUP_CHANGE_INVITE_LINK WebMessageInfo_WebMessageInfoStubType = 23 + WebMessageInfo_GROUP_CHANGE_DESCRIPTION WebMessageInfo_WebMessageInfoStubType = 24 + WebMessageInfo_GROUP_CHANGE_RESTRICT WebMessageInfo_WebMessageInfoStubType = 25 + WebMessageInfo_GROUP_CHANGE_ANNOUNCE WebMessageInfo_WebMessageInfoStubType = 26 + WebMessageInfo_GROUP_PARTICIPANT_ADD WebMessageInfo_WebMessageInfoStubType = 27 + WebMessageInfo_GROUP_PARTICIPANT_REMOVE WebMessageInfo_WebMessageInfoStubType = 28 + WebMessageInfo_GROUP_PARTICIPANT_PROMOTE WebMessageInfo_WebMessageInfoStubType = 29 + WebMessageInfo_GROUP_PARTICIPANT_DEMOTE WebMessageInfo_WebMessageInfoStubType = 30 + WebMessageInfo_GROUP_PARTICIPANT_INVITE WebMessageInfo_WebMessageInfoStubType = 31 + WebMessageInfo_GROUP_PARTICIPANT_LEAVE WebMessageInfo_WebMessageInfoStubType = 32 + WebMessageInfo_GROUP_PARTICIPANT_CHANGE_NUMBER WebMessageInfo_WebMessageInfoStubType = 33 + WebMessageInfo_BROADCAST_CREATE WebMessageInfo_WebMessageInfoStubType = 34 + WebMessageInfo_BROADCAST_ADD WebMessageInfo_WebMessageInfoStubType = 35 + WebMessageInfo_BROADCAST_REMOVE WebMessageInfo_WebMessageInfoStubType = 36 + WebMessageInfo_GENERIC_NOTIFICATION WebMessageInfo_WebMessageInfoStubType = 37 + WebMessageInfo_E2E_IDENTITY_CHANGED WebMessageInfo_WebMessageInfoStubType = 38 + WebMessageInfo_E2E_ENCRYPTED WebMessageInfo_WebMessageInfoStubType = 39 + WebMessageInfo_CALL_MISSED_VOICE WebMessageInfo_WebMessageInfoStubType = 40 + WebMessageInfo_CALL_MISSED_VIDEO WebMessageInfo_WebMessageInfoStubType = 41 + WebMessageInfo_INDIVIDUAL_CHANGE_NUMBER WebMessageInfo_WebMessageInfoStubType = 42 + WebMessageInfo_GROUP_DELETE WebMessageInfo_WebMessageInfoStubType = 43 + WebMessageInfo_GROUP_ANNOUNCE_MODE_MESSAGE_BOUNCE WebMessageInfo_WebMessageInfoStubType = 44 + WebMessageInfo_CALL_MISSED_GROUP_VOICE WebMessageInfo_WebMessageInfoStubType = 45 + WebMessageInfo_CALL_MISSED_GROUP_VIDEO WebMessageInfo_WebMessageInfoStubType = 46 + WebMessageInfo_PAYMENT_CIPHERTEXT WebMessageInfo_WebMessageInfoStubType = 47 + WebMessageInfo_PAYMENT_FUTUREPROOF WebMessageInfo_WebMessageInfoStubType = 48 + WebMessageInfo_PAYMENT_TRANSACTION_STATUS_UPDATE_FAILED WebMessageInfo_WebMessageInfoStubType = 49 + WebMessageInfo_PAYMENT_TRANSACTION_STATUS_UPDATE_REFUNDED WebMessageInfo_WebMessageInfoStubType = 50 + WebMessageInfo_PAYMENT_TRANSACTION_STATUS_UPDATE_REFUND_FAILED WebMessageInfo_WebMessageInfoStubType = 51 + WebMessageInfo_PAYMENT_TRANSACTION_STATUS_RECEIVER_PENDING_SETUP WebMessageInfo_WebMessageInfoStubType = 52 + WebMessageInfo_PAYMENT_TRANSACTION_STATUS_RECEIVER_SUCCESS_AFTER_HICCUP WebMessageInfo_WebMessageInfoStubType = 53 + WebMessageInfo_PAYMENT_ACTION_ACCOUNT_SETUP_REMINDER WebMessageInfo_WebMessageInfoStubType = 54 + WebMessageInfo_PAYMENT_ACTION_SEND_PAYMENT_REMINDER WebMessageInfo_WebMessageInfoStubType = 55 + WebMessageInfo_PAYMENT_ACTION_SEND_PAYMENT_INVITATION WebMessageInfo_WebMessageInfoStubType = 56 + WebMessageInfo_PAYMENT_ACTION_REQUEST_DECLINED WebMessageInfo_WebMessageInfoStubType = 57 + WebMessageInfo_PAYMENT_ACTION_REQUEST_EXPIRED WebMessageInfo_WebMessageInfoStubType = 58 + WebMessageInfo_PAYMENT_ACTION_REQUEST_CANCELLED WebMessageInfo_WebMessageInfoStubType = 59 + WebMessageInfo_BIZ_VERIFIED_TRANSITION_TOP_TO_BOTTOM WebMessageInfo_WebMessageInfoStubType = 60 + WebMessageInfo_BIZ_VERIFIED_TRANSITION_BOTTOM_TO_TOP WebMessageInfo_WebMessageInfoStubType = 61 + WebMessageInfo_BIZ_INTRO_TOP WebMessageInfo_WebMessageInfoStubType = 62 + WebMessageInfo_BIZ_INTRO_BOTTOM WebMessageInfo_WebMessageInfoStubType = 63 + WebMessageInfo_BIZ_NAME_CHANGE WebMessageInfo_WebMessageInfoStubType = 64 + WebMessageInfo_BIZ_MOVE_TO_CONSUMER_APP WebMessageInfo_WebMessageInfoStubType = 65 + WebMessageInfo_BIZ_TWO_TIER_MIGRATION_TOP WebMessageInfo_WebMessageInfoStubType = 66 + WebMessageInfo_BIZ_TWO_TIER_MIGRATION_BOTTOM WebMessageInfo_WebMessageInfoStubType = 67 + WebMessageInfo_OVERSIZED WebMessageInfo_WebMessageInfoStubType = 68 + WebMessageInfo_GROUP_CHANGE_NO_FREQUENTLY_FORWARDED WebMessageInfo_WebMessageInfoStubType = 69 + WebMessageInfo_GROUP_V4_ADD_INVITE_SENT WebMessageInfo_WebMessageInfoStubType = 70 + WebMessageInfo_GROUP_PARTICIPANT_ADD_REQUEST_JOIN WebMessageInfo_WebMessageInfoStubType = 71 + WebMessageInfo_CHANGE_EPHEMERAL_SETTING WebMessageInfo_WebMessageInfoStubType = 72 + WebMessageInfo_E2E_DEVICE_CHANGED WebMessageInfo_WebMessageInfoStubType = 73 + WebMessageInfo_VIEWED_ONCE WebMessageInfo_WebMessageInfoStubType = 74 + WebMessageInfo_E2E_ENCRYPTED_NOW WebMessageInfo_WebMessageInfoStubType = 75 + WebMessageInfo_BLUE_MSG_BSP_FB_TO_BSP_PREMISE WebMessageInfo_WebMessageInfoStubType = 76 + WebMessageInfo_BLUE_MSG_BSP_FB_TO_SELF_FB WebMessageInfo_WebMessageInfoStubType = 77 + WebMessageInfo_BLUE_MSG_BSP_FB_TO_SELF_PREMISE WebMessageInfo_WebMessageInfoStubType = 78 + WebMessageInfo_BLUE_MSG_BSP_FB_UNVERIFIED WebMessageInfo_WebMessageInfoStubType = 79 + WebMessageInfo_BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED WebMessageInfo_WebMessageInfoStubType = 80 + WebMessageInfo_BLUE_MSG_BSP_FB_VERIFIED WebMessageInfo_WebMessageInfoStubType = 81 + WebMessageInfo_BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED WebMessageInfo_WebMessageInfoStubType = 82 + WebMessageInfo_BLUE_MSG_BSP_PREMISE_TO_SELF_PREMISE WebMessageInfo_WebMessageInfoStubType = 83 + WebMessageInfo_BLUE_MSG_BSP_PREMISE_UNVERIFIED WebMessageInfo_WebMessageInfoStubType = 84 + WebMessageInfo_BLUE_MSG_BSP_PREMISE_UNVERIFIED_TO_SELF_PREMISE_VERIFIED WebMessageInfo_WebMessageInfoStubType = 85 + WebMessageInfo_BLUE_MSG_BSP_PREMISE_VERIFIED WebMessageInfo_WebMessageInfoStubType = 86 + WebMessageInfo_BLUE_MSG_BSP_PREMISE_VERIFIED_TO_SELF_PREMISE_UNVERIFIED WebMessageInfo_WebMessageInfoStubType = 87 + WebMessageInfo_BLUE_MSG_CONSUMER_TO_BSP_FB_UNVERIFIED WebMessageInfo_WebMessageInfoStubType = 88 + WebMessageInfo_BLUE_MSG_CONSUMER_TO_BSP_PREMISE_UNVERIFIED WebMessageInfo_WebMessageInfoStubType = 89 + WebMessageInfo_BLUE_MSG_CONSUMER_TO_SELF_FB_UNVERIFIED WebMessageInfo_WebMessageInfoStubType = 90 + WebMessageInfo_BLUE_MSG_CONSUMER_TO_SELF_PREMISE_UNVERIFIED WebMessageInfo_WebMessageInfoStubType = 91 + WebMessageInfo_BLUE_MSG_SELF_FB_TO_BSP_PREMISE WebMessageInfo_WebMessageInfoStubType = 92 + WebMessageInfo_BLUE_MSG_SELF_FB_TO_SELF_PREMISE WebMessageInfo_WebMessageInfoStubType = 93 + WebMessageInfo_BLUE_MSG_SELF_FB_UNVERIFIED WebMessageInfo_WebMessageInfoStubType = 94 + WebMessageInfo_BLUE_MSG_SELF_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED WebMessageInfo_WebMessageInfoStubType = 95 + WebMessageInfo_BLUE_MSG_SELF_FB_VERIFIED WebMessageInfo_WebMessageInfoStubType = 96 + WebMessageInfo_BLUE_MSG_SELF_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED WebMessageInfo_WebMessageInfoStubType = 97 + WebMessageInfo_BLUE_MSG_SELF_PREMISE_TO_BSP_PREMISE WebMessageInfo_WebMessageInfoStubType = 98 + WebMessageInfo_BLUE_MSG_SELF_PREMISE_UNVERIFIED WebMessageInfo_WebMessageInfoStubType = 99 + WebMessageInfo_BLUE_MSG_SELF_PREMISE_VERIFIED WebMessageInfo_WebMessageInfoStubType = 100 + WebMessageInfo_BLUE_MSG_TO_BSP_FB WebMessageInfo_WebMessageInfoStubType = 101 + WebMessageInfo_BLUE_MSG_TO_CONSUMER WebMessageInfo_WebMessageInfoStubType = 102 + WebMessageInfo_BLUE_MSG_TO_SELF_FB WebMessageInfo_WebMessageInfoStubType = 103 + WebMessageInfo_BLUE_MSG_UNVERIFIED_TO_BSP_FB_VERIFIED WebMessageInfo_WebMessageInfoStubType = 104 + WebMessageInfo_BLUE_MSG_UNVERIFIED_TO_BSP_PREMISE_VERIFIED WebMessageInfo_WebMessageInfoStubType = 105 + WebMessageInfo_BLUE_MSG_UNVERIFIED_TO_SELF_FB_VERIFIED WebMessageInfo_WebMessageInfoStubType = 106 + WebMessageInfo_BLUE_MSG_UNVERIFIED_TO_VERIFIED WebMessageInfo_WebMessageInfoStubType = 107 + WebMessageInfo_BLUE_MSG_VERIFIED_TO_BSP_FB_UNVERIFIED WebMessageInfo_WebMessageInfoStubType = 108 + WebMessageInfo_BLUE_MSG_VERIFIED_TO_BSP_PREMISE_UNVERIFIED WebMessageInfo_WebMessageInfoStubType = 109 + WebMessageInfo_BLUE_MSG_VERIFIED_TO_SELF_FB_UNVERIFIED WebMessageInfo_WebMessageInfoStubType = 110 + WebMessageInfo_BLUE_MSG_VERIFIED_TO_UNVERIFIED WebMessageInfo_WebMessageInfoStubType = 111 + WebMessageInfo_BLUE_MSG_BSP_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED WebMessageInfo_WebMessageInfoStubType = 112 + WebMessageInfo_BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_FB_VERIFIED WebMessageInfo_WebMessageInfoStubType = 113 + WebMessageInfo_BLUE_MSG_BSP_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED WebMessageInfo_WebMessageInfoStubType = 114 + WebMessageInfo_BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_FB_UNVERIFIED WebMessageInfo_WebMessageInfoStubType = 115 + WebMessageInfo_BLUE_MSG_SELF_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED WebMessageInfo_WebMessageInfoStubType = 116 + WebMessageInfo_BLUE_MSG_SELF_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED WebMessageInfo_WebMessageInfoStubType = 117 + WebMessageInfo_E2E_IDENTITY_UNAVAILABLE WebMessageInfo_WebMessageInfoStubType = 118 +) + +// Enum value maps for WebMessageInfo_WebMessageInfoStubType. +var ( + WebMessageInfo_WebMessageInfoStubType_name = map[int32]string{ + 0: "UNKNOWN", + 1: "REVOKE", + 2: "CIPHERTEXT", + 3: "FUTUREPROOF", + 4: "NON_VERIFIED_TRANSITION", + 5: "UNVERIFIED_TRANSITION", + 6: "VERIFIED_TRANSITION", + 7: "VERIFIED_LOW_UNKNOWN", + 8: "VERIFIED_HIGH", + 9: "VERIFIED_INITIAL_UNKNOWN", + 10: "VERIFIED_INITIAL_LOW", + 11: "VERIFIED_INITIAL_HIGH", + 12: "VERIFIED_TRANSITION_ANY_TO_NONE", + 13: "VERIFIED_TRANSITION_ANY_TO_HIGH", + 14: "VERIFIED_TRANSITION_HIGH_TO_LOW", + 15: "VERIFIED_TRANSITION_HIGH_TO_UNKNOWN", + 16: "VERIFIED_TRANSITION_UNKNOWN_TO_LOW", + 17: "VERIFIED_TRANSITION_LOW_TO_UNKNOWN", + 18: "VERIFIED_TRANSITION_NONE_TO_LOW", + 19: "VERIFIED_TRANSITION_NONE_TO_UNKNOWN", + 20: "GROUP_CREATE", + 21: "GROUP_CHANGE_SUBJECT", + 22: "GROUP_CHANGE_ICON", + 23: "GROUP_CHANGE_INVITE_LINK", + 24: "GROUP_CHANGE_DESCRIPTION", + 25: "GROUP_CHANGE_RESTRICT", + 26: "GROUP_CHANGE_ANNOUNCE", + 27: "GROUP_PARTICIPANT_ADD", + 28: "GROUP_PARTICIPANT_REMOVE", + 29: "GROUP_PARTICIPANT_PROMOTE", + 30: "GROUP_PARTICIPANT_DEMOTE", + 31: "GROUP_PARTICIPANT_INVITE", + 32: "GROUP_PARTICIPANT_LEAVE", + 33: "GROUP_PARTICIPANT_CHANGE_NUMBER", + 34: "BROADCAST_CREATE", + 35: "BROADCAST_ADD", + 36: "BROADCAST_REMOVE", + 37: "GENERIC_NOTIFICATION", + 38: "E2E_IDENTITY_CHANGED", + 39: "E2E_ENCRYPTED", + 40: "CALL_MISSED_VOICE", + 41: "CALL_MISSED_VIDEO", + 42: "INDIVIDUAL_CHANGE_NUMBER", + 43: "GROUP_DELETE", + 44: "GROUP_ANNOUNCE_MODE_MESSAGE_BOUNCE", + 45: "CALL_MISSED_GROUP_VOICE", + 46: "CALL_MISSED_GROUP_VIDEO", + 47: "PAYMENT_CIPHERTEXT", + 48: "PAYMENT_FUTUREPROOF", + 49: "PAYMENT_TRANSACTION_STATUS_UPDATE_FAILED", + 50: "PAYMENT_TRANSACTION_STATUS_UPDATE_REFUNDED", + 51: "PAYMENT_TRANSACTION_STATUS_UPDATE_REFUND_FAILED", + 52: "PAYMENT_TRANSACTION_STATUS_RECEIVER_PENDING_SETUP", + 53: "PAYMENT_TRANSACTION_STATUS_RECEIVER_SUCCESS_AFTER_HICCUP", + 54: "PAYMENT_ACTION_ACCOUNT_SETUP_REMINDER", + 55: "PAYMENT_ACTION_SEND_PAYMENT_REMINDER", + 56: "PAYMENT_ACTION_SEND_PAYMENT_INVITATION", + 57: "PAYMENT_ACTION_REQUEST_DECLINED", + 58: "PAYMENT_ACTION_REQUEST_EXPIRED", + 59: "PAYMENT_ACTION_REQUEST_CANCELLED", + 60: "BIZ_VERIFIED_TRANSITION_TOP_TO_BOTTOM", + 61: "BIZ_VERIFIED_TRANSITION_BOTTOM_TO_TOP", + 62: "BIZ_INTRO_TOP", + 63: "BIZ_INTRO_BOTTOM", + 64: "BIZ_NAME_CHANGE", + 65: "BIZ_MOVE_TO_CONSUMER_APP", + 66: "BIZ_TWO_TIER_MIGRATION_TOP", + 67: "BIZ_TWO_TIER_MIGRATION_BOTTOM", + 68: "OVERSIZED", + 69: "GROUP_CHANGE_NO_FREQUENTLY_FORWARDED", + 70: "GROUP_V4_ADD_INVITE_SENT", + 71: "GROUP_PARTICIPANT_ADD_REQUEST_JOIN", + 72: "CHANGE_EPHEMERAL_SETTING", + 73: "E2E_DEVICE_CHANGED", + 74: "VIEWED_ONCE", + 75: "E2E_ENCRYPTED_NOW", + 76: "BLUE_MSG_BSP_FB_TO_BSP_PREMISE", + 77: "BLUE_MSG_BSP_FB_TO_SELF_FB", + 78: "BLUE_MSG_BSP_FB_TO_SELF_PREMISE", + 79: "BLUE_MSG_BSP_FB_UNVERIFIED", + 80: "BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED", + 81: "BLUE_MSG_BSP_FB_VERIFIED", + 82: "BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED", + 83: "BLUE_MSG_BSP_PREMISE_TO_SELF_PREMISE", + 84: "BLUE_MSG_BSP_PREMISE_UNVERIFIED", + 85: "BLUE_MSG_BSP_PREMISE_UNVERIFIED_TO_SELF_PREMISE_VERIFIED", + 86: "BLUE_MSG_BSP_PREMISE_VERIFIED", + 87: "BLUE_MSG_BSP_PREMISE_VERIFIED_TO_SELF_PREMISE_UNVERIFIED", + 88: "BLUE_MSG_CONSUMER_TO_BSP_FB_UNVERIFIED", + 89: "BLUE_MSG_CONSUMER_TO_BSP_PREMISE_UNVERIFIED", + 90: "BLUE_MSG_CONSUMER_TO_SELF_FB_UNVERIFIED", + 91: "BLUE_MSG_CONSUMER_TO_SELF_PREMISE_UNVERIFIED", + 92: "BLUE_MSG_SELF_FB_TO_BSP_PREMISE", + 93: "BLUE_MSG_SELF_FB_TO_SELF_PREMISE", + 94: "BLUE_MSG_SELF_FB_UNVERIFIED", + 95: "BLUE_MSG_SELF_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED", + 96: "BLUE_MSG_SELF_FB_VERIFIED", + 97: "BLUE_MSG_SELF_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED", + 98: "BLUE_MSG_SELF_PREMISE_TO_BSP_PREMISE", + 99: "BLUE_MSG_SELF_PREMISE_UNVERIFIED", + 100: "BLUE_MSG_SELF_PREMISE_VERIFIED", + 101: "BLUE_MSG_TO_BSP_FB", + 102: "BLUE_MSG_TO_CONSUMER", + 103: "BLUE_MSG_TO_SELF_FB", + 104: "BLUE_MSG_UNVERIFIED_TO_BSP_FB_VERIFIED", + 105: "BLUE_MSG_UNVERIFIED_TO_BSP_PREMISE_VERIFIED", + 106: "BLUE_MSG_UNVERIFIED_TO_SELF_FB_VERIFIED", + 107: "BLUE_MSG_UNVERIFIED_TO_VERIFIED", + 108: "BLUE_MSG_VERIFIED_TO_BSP_FB_UNVERIFIED", + 109: "BLUE_MSG_VERIFIED_TO_BSP_PREMISE_UNVERIFIED", + 110: "BLUE_MSG_VERIFIED_TO_SELF_FB_UNVERIFIED", + 111: "BLUE_MSG_VERIFIED_TO_UNVERIFIED", + 112: "BLUE_MSG_BSP_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED", + 113: "BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_FB_VERIFIED", + 114: "BLUE_MSG_BSP_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED", + 115: "BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_FB_UNVERIFIED", + 116: "BLUE_MSG_SELF_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED", + 117: "BLUE_MSG_SELF_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED", + 118: "E2E_IDENTITY_UNAVAILABLE", + } + WebMessageInfo_WebMessageInfoStubType_value = map[string]int32{ + "UNKNOWN": 0, + "REVOKE": 1, + "CIPHERTEXT": 2, + "FUTUREPROOF": 3, + "NON_VERIFIED_TRANSITION": 4, + "UNVERIFIED_TRANSITION": 5, + "VERIFIED_TRANSITION": 6, + "VERIFIED_LOW_UNKNOWN": 7, + "VERIFIED_HIGH": 8, + "VERIFIED_INITIAL_UNKNOWN": 9, + "VERIFIED_INITIAL_LOW": 10, + "VERIFIED_INITIAL_HIGH": 11, + "VERIFIED_TRANSITION_ANY_TO_NONE": 12, + "VERIFIED_TRANSITION_ANY_TO_HIGH": 13, + "VERIFIED_TRANSITION_HIGH_TO_LOW": 14, + "VERIFIED_TRANSITION_HIGH_TO_UNKNOWN": 15, + "VERIFIED_TRANSITION_UNKNOWN_TO_LOW": 16, + "VERIFIED_TRANSITION_LOW_TO_UNKNOWN": 17, + "VERIFIED_TRANSITION_NONE_TO_LOW": 18, + "VERIFIED_TRANSITION_NONE_TO_UNKNOWN": 19, + "GROUP_CREATE": 20, + "GROUP_CHANGE_SUBJECT": 21, + "GROUP_CHANGE_ICON": 22, + "GROUP_CHANGE_INVITE_LINK": 23, + "GROUP_CHANGE_DESCRIPTION": 24, + "GROUP_CHANGE_RESTRICT": 25, + "GROUP_CHANGE_ANNOUNCE": 26, + "GROUP_PARTICIPANT_ADD": 27, + "GROUP_PARTICIPANT_REMOVE": 28, + "GROUP_PARTICIPANT_PROMOTE": 29, + "GROUP_PARTICIPANT_DEMOTE": 30, + "GROUP_PARTICIPANT_INVITE": 31, + "GROUP_PARTICIPANT_LEAVE": 32, + "GROUP_PARTICIPANT_CHANGE_NUMBER": 33, + "BROADCAST_CREATE": 34, + "BROADCAST_ADD": 35, + "BROADCAST_REMOVE": 36, + "GENERIC_NOTIFICATION": 37, + "E2E_IDENTITY_CHANGED": 38, + "E2E_ENCRYPTED": 39, + "CALL_MISSED_VOICE": 40, + "CALL_MISSED_VIDEO": 41, + "INDIVIDUAL_CHANGE_NUMBER": 42, + "GROUP_DELETE": 43, + "GROUP_ANNOUNCE_MODE_MESSAGE_BOUNCE": 44, + "CALL_MISSED_GROUP_VOICE": 45, + "CALL_MISSED_GROUP_VIDEO": 46, + "PAYMENT_CIPHERTEXT": 47, + "PAYMENT_FUTUREPROOF": 48, + "PAYMENT_TRANSACTION_STATUS_UPDATE_FAILED": 49, + "PAYMENT_TRANSACTION_STATUS_UPDATE_REFUNDED": 50, + "PAYMENT_TRANSACTION_STATUS_UPDATE_REFUND_FAILED": 51, + "PAYMENT_TRANSACTION_STATUS_RECEIVER_PENDING_SETUP": 52, + "PAYMENT_TRANSACTION_STATUS_RECEIVER_SUCCESS_AFTER_HICCUP": 53, + "PAYMENT_ACTION_ACCOUNT_SETUP_REMINDER": 54, + "PAYMENT_ACTION_SEND_PAYMENT_REMINDER": 55, + "PAYMENT_ACTION_SEND_PAYMENT_INVITATION": 56, + "PAYMENT_ACTION_REQUEST_DECLINED": 57, + "PAYMENT_ACTION_REQUEST_EXPIRED": 58, + "PAYMENT_ACTION_REQUEST_CANCELLED": 59, + "BIZ_VERIFIED_TRANSITION_TOP_TO_BOTTOM": 60, + "BIZ_VERIFIED_TRANSITION_BOTTOM_TO_TOP": 61, + "BIZ_INTRO_TOP": 62, + "BIZ_INTRO_BOTTOM": 63, + "BIZ_NAME_CHANGE": 64, + "BIZ_MOVE_TO_CONSUMER_APP": 65, + "BIZ_TWO_TIER_MIGRATION_TOP": 66, + "BIZ_TWO_TIER_MIGRATION_BOTTOM": 67, + "OVERSIZED": 68, + "GROUP_CHANGE_NO_FREQUENTLY_FORWARDED": 69, + "GROUP_V4_ADD_INVITE_SENT": 70, + "GROUP_PARTICIPANT_ADD_REQUEST_JOIN": 71, + "CHANGE_EPHEMERAL_SETTING": 72, + "E2E_DEVICE_CHANGED": 73, + "VIEWED_ONCE": 74, + "E2E_ENCRYPTED_NOW": 75, + "BLUE_MSG_BSP_FB_TO_BSP_PREMISE": 76, + "BLUE_MSG_BSP_FB_TO_SELF_FB": 77, + "BLUE_MSG_BSP_FB_TO_SELF_PREMISE": 78, + "BLUE_MSG_BSP_FB_UNVERIFIED": 79, + "BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED": 80, + "BLUE_MSG_BSP_FB_VERIFIED": 81, + "BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED": 82, + "BLUE_MSG_BSP_PREMISE_TO_SELF_PREMISE": 83, + "BLUE_MSG_BSP_PREMISE_UNVERIFIED": 84, + "BLUE_MSG_BSP_PREMISE_UNVERIFIED_TO_SELF_PREMISE_VERIFIED": 85, + "BLUE_MSG_BSP_PREMISE_VERIFIED": 86, + "BLUE_MSG_BSP_PREMISE_VERIFIED_TO_SELF_PREMISE_UNVERIFIED": 87, + "BLUE_MSG_CONSUMER_TO_BSP_FB_UNVERIFIED": 88, + "BLUE_MSG_CONSUMER_TO_BSP_PREMISE_UNVERIFIED": 89, + "BLUE_MSG_CONSUMER_TO_SELF_FB_UNVERIFIED": 90, + "BLUE_MSG_CONSUMER_TO_SELF_PREMISE_UNVERIFIED": 91, + "BLUE_MSG_SELF_FB_TO_BSP_PREMISE": 92, + "BLUE_MSG_SELF_FB_TO_SELF_PREMISE": 93, + "BLUE_MSG_SELF_FB_UNVERIFIED": 94, + "BLUE_MSG_SELF_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED": 95, + "BLUE_MSG_SELF_FB_VERIFIED": 96, + "BLUE_MSG_SELF_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED": 97, + "BLUE_MSG_SELF_PREMISE_TO_BSP_PREMISE": 98, + "BLUE_MSG_SELF_PREMISE_UNVERIFIED": 99, + "BLUE_MSG_SELF_PREMISE_VERIFIED": 100, + "BLUE_MSG_TO_BSP_FB": 101, + "BLUE_MSG_TO_CONSUMER": 102, + "BLUE_MSG_TO_SELF_FB": 103, + "BLUE_MSG_UNVERIFIED_TO_BSP_FB_VERIFIED": 104, + "BLUE_MSG_UNVERIFIED_TO_BSP_PREMISE_VERIFIED": 105, + "BLUE_MSG_UNVERIFIED_TO_SELF_FB_VERIFIED": 106, + "BLUE_MSG_UNVERIFIED_TO_VERIFIED": 107, + "BLUE_MSG_VERIFIED_TO_BSP_FB_UNVERIFIED": 108, + "BLUE_MSG_VERIFIED_TO_BSP_PREMISE_UNVERIFIED": 109, + "BLUE_MSG_VERIFIED_TO_SELF_FB_UNVERIFIED": 110, + "BLUE_MSG_VERIFIED_TO_UNVERIFIED": 111, + "BLUE_MSG_BSP_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED": 112, + "BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_FB_VERIFIED": 113, + "BLUE_MSG_BSP_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED": 114, + "BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_FB_UNVERIFIED": 115, + "BLUE_MSG_SELF_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED": 116, + "BLUE_MSG_SELF_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED": 117, + "E2E_IDENTITY_UNAVAILABLE": 118, + } +) + +func (x WebMessageInfo_WebMessageInfoStubType) Enum() *WebMessageInfo_WebMessageInfoStubType { + p := new(WebMessageInfo_WebMessageInfoStubType) + *p = x + return p +} + +func (x WebMessageInfo_WebMessageInfoStubType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (WebMessageInfo_WebMessageInfoStubType) Descriptor() protoreflect.EnumDescriptor { + return file_def_proto_enumTypes[22].Descriptor() +} + +func (WebMessageInfo_WebMessageInfoStubType) Type() protoreflect.EnumType { + return &file_def_proto_enumTypes[22] +} + +func (x WebMessageInfo_WebMessageInfoStubType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *WebMessageInfo_WebMessageInfoStubType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = WebMessageInfo_WebMessageInfoStubType(num) + return nil +} + +// Deprecated: Use WebMessageInfo_WebMessageInfoStubType.Descriptor instead. +func (WebMessageInfo_WebMessageInfoStubType) EnumDescriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{78, 1} +} + +type WebMessageInfo_WebMessageInfoBizPrivacyStatus int32 + +const ( + WebMessageInfo_E2EE WebMessageInfo_WebMessageInfoBizPrivacyStatus = 0 + WebMessageInfo_FB WebMessageInfo_WebMessageInfoBizPrivacyStatus = 2 + WebMessageInfo_BSP WebMessageInfo_WebMessageInfoBizPrivacyStatus = 1 + WebMessageInfo_BSP_AND_FB WebMessageInfo_WebMessageInfoBizPrivacyStatus = 3 +) + +// Enum value maps for WebMessageInfo_WebMessageInfoBizPrivacyStatus. +var ( + WebMessageInfo_WebMessageInfoBizPrivacyStatus_name = map[int32]string{ + 0: "E2EE", + 2: "FB", + 1: "BSP", + 3: "BSP_AND_FB", + } + WebMessageInfo_WebMessageInfoBizPrivacyStatus_value = map[string]int32{ + "E2EE": 0, + "FB": 2, + "BSP": 1, + "BSP_AND_FB": 3, + } +) + +func (x WebMessageInfo_WebMessageInfoBizPrivacyStatus) Enum() *WebMessageInfo_WebMessageInfoBizPrivacyStatus { + p := new(WebMessageInfo_WebMessageInfoBizPrivacyStatus) + *p = x + return p +} + +func (x WebMessageInfo_WebMessageInfoBizPrivacyStatus) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (WebMessageInfo_WebMessageInfoBizPrivacyStatus) Descriptor() protoreflect.EnumDescriptor { + return file_def_proto_enumTypes[23].Descriptor() +} + +func (WebMessageInfo_WebMessageInfoBizPrivacyStatus) Type() protoreflect.EnumType { + return &file_def_proto_enumTypes[23] +} + +func (x WebMessageInfo_WebMessageInfoBizPrivacyStatus) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *WebMessageInfo_WebMessageInfoBizPrivacyStatus) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = WebMessageInfo_WebMessageInfoBizPrivacyStatus(num) + return nil +} + +// Deprecated: Use WebMessageInfo_WebMessageInfoBizPrivacyStatus.Descriptor instead. +func (WebMessageInfo_WebMessageInfoBizPrivacyStatus) EnumDescriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{78, 2} +} + +type PaymentMoney struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Value *int64 `protobuf:"varint,1,opt,name=value" json:"value,omitempty"` + Offset *uint32 `protobuf:"varint,2,opt,name=offset" json:"offset,omitempty"` + CurrencyCode *string `protobuf:"bytes,3,opt,name=currencyCode" json:"currencyCode,omitempty"` +} + +func (x *PaymentMoney) Reset() { + *x = PaymentMoney{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PaymentMoney) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PaymentMoney) ProtoMessage() {} + +func (x *PaymentMoney) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PaymentMoney.ProtoReflect.Descriptor instead. +func (*PaymentMoney) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{0} +} + +func (x *PaymentMoney) GetValue() int64 { + if x != nil && x.Value != nil { + return *x.Value + } + return 0 +} + +func (x *PaymentMoney) GetOffset() uint32 { + if x != nil && x.Offset != nil { + return *x.Offset + } + return 0 +} + +func (x *PaymentMoney) GetCurrencyCode() string { + if x != nil && x.CurrencyCode != nil { + return *x.CurrencyCode + } + return "" +} + +type HydratedQuickReplyButton struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DisplayText *string `protobuf:"bytes,1,opt,name=displayText" json:"displayText,omitempty"` + Id *string `protobuf:"bytes,2,opt,name=id" json:"id,omitempty"` +} + +func (x *HydratedQuickReplyButton) Reset() { + *x = HydratedQuickReplyButton{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HydratedQuickReplyButton) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HydratedQuickReplyButton) ProtoMessage() {} + +func (x *HydratedQuickReplyButton) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HydratedQuickReplyButton.ProtoReflect.Descriptor instead. +func (*HydratedQuickReplyButton) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{1} +} + +func (x *HydratedQuickReplyButton) GetDisplayText() string { + if x != nil && x.DisplayText != nil { + return *x.DisplayText + } + return "" +} + +func (x *HydratedQuickReplyButton) GetId() string { + if x != nil && x.Id != nil { + return *x.Id + } + return "" +} + +type HydratedURLButton struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DisplayText *string `protobuf:"bytes,1,opt,name=displayText" json:"displayText,omitempty"` + Url *string `protobuf:"bytes,2,opt,name=url" json:"url,omitempty"` +} + +func (x *HydratedURLButton) Reset() { + *x = HydratedURLButton{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HydratedURLButton) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HydratedURLButton) ProtoMessage() {} + +func (x *HydratedURLButton) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HydratedURLButton.ProtoReflect.Descriptor instead. +func (*HydratedURLButton) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{2} +} + +func (x *HydratedURLButton) GetDisplayText() string { + if x != nil && x.DisplayText != nil { + return *x.DisplayText + } + return "" +} + +func (x *HydratedURLButton) GetUrl() string { + if x != nil && x.Url != nil { + return *x.Url + } + return "" +} + +type HydratedCallButton struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DisplayText *string `protobuf:"bytes,1,opt,name=displayText" json:"displayText,omitempty"` + PhoneNumber *string `protobuf:"bytes,2,opt,name=phoneNumber" json:"phoneNumber,omitempty"` +} + +func (x *HydratedCallButton) Reset() { + *x = HydratedCallButton{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HydratedCallButton) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HydratedCallButton) ProtoMessage() {} + +func (x *HydratedCallButton) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HydratedCallButton.ProtoReflect.Descriptor instead. +func (*HydratedCallButton) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{3} +} + +func (x *HydratedCallButton) GetDisplayText() string { + if x != nil && x.DisplayText != nil { + return *x.DisplayText + } + return "" +} + +func (x *HydratedCallButton) GetPhoneNumber() string { + if x != nil && x.PhoneNumber != nil { + return *x.PhoneNumber + } + return "" +} + +type HydratedTemplateButton struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Index *uint32 `protobuf:"varint,4,opt,name=index" json:"index,omitempty"` + // Types that are assignable to HydratedButton: + // *HydratedTemplateButton_QuickReplyButton + // *HydratedTemplateButton_UrlButton + // *HydratedTemplateButton_CallButton + HydratedButton isHydratedTemplateButton_HydratedButton `protobuf_oneof:"hydratedButton"` +} + +func (x *HydratedTemplateButton) Reset() { + *x = HydratedTemplateButton{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HydratedTemplateButton) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HydratedTemplateButton) ProtoMessage() {} + +func (x *HydratedTemplateButton) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HydratedTemplateButton.ProtoReflect.Descriptor instead. +func (*HydratedTemplateButton) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{4} +} + +func (x *HydratedTemplateButton) GetIndex() uint32 { + if x != nil && x.Index != nil { + return *x.Index + } + return 0 +} + +func (m *HydratedTemplateButton) GetHydratedButton() isHydratedTemplateButton_HydratedButton { + if m != nil { + return m.HydratedButton + } + return nil +} + +func (x *HydratedTemplateButton) GetQuickReplyButton() *HydratedQuickReplyButton { + if x, ok := x.GetHydratedButton().(*HydratedTemplateButton_QuickReplyButton); ok { + return x.QuickReplyButton + } + return nil +} + +func (x *HydratedTemplateButton) GetUrlButton() *HydratedURLButton { + if x, ok := x.GetHydratedButton().(*HydratedTemplateButton_UrlButton); ok { + return x.UrlButton + } + return nil +} + +func (x *HydratedTemplateButton) GetCallButton() *HydratedCallButton { + if x, ok := x.GetHydratedButton().(*HydratedTemplateButton_CallButton); ok { + return x.CallButton + } + return nil +} + +type isHydratedTemplateButton_HydratedButton interface { + isHydratedTemplateButton_HydratedButton() +} + +type HydratedTemplateButton_QuickReplyButton struct { + QuickReplyButton *HydratedQuickReplyButton `protobuf:"bytes,1,opt,name=quickReplyButton,oneof"` +} + +type HydratedTemplateButton_UrlButton struct { + UrlButton *HydratedURLButton `protobuf:"bytes,2,opt,name=urlButton,oneof"` +} + +type HydratedTemplateButton_CallButton struct { + CallButton *HydratedCallButton `protobuf:"bytes,3,opt,name=callButton,oneof"` +} + +func (*HydratedTemplateButton_QuickReplyButton) isHydratedTemplateButton_HydratedButton() {} + +func (*HydratedTemplateButton_UrlButton) isHydratedTemplateButton_HydratedButton() {} + +func (*HydratedTemplateButton_CallButton) isHydratedTemplateButton_HydratedButton() {} + +type QuickReplyButton struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DisplayText *HighlyStructuredMessage `protobuf:"bytes,1,opt,name=displayText" json:"displayText,omitempty"` + Id *string `protobuf:"bytes,2,opt,name=id" json:"id,omitempty"` +} + +func (x *QuickReplyButton) Reset() { + *x = QuickReplyButton{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *QuickReplyButton) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*QuickReplyButton) ProtoMessage() {} + +func (x *QuickReplyButton) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use QuickReplyButton.ProtoReflect.Descriptor instead. +func (*QuickReplyButton) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{5} +} + +func (x *QuickReplyButton) GetDisplayText() *HighlyStructuredMessage { + if x != nil { + return x.DisplayText + } + return nil +} + +func (x *QuickReplyButton) GetId() string { + if x != nil && x.Id != nil { + return *x.Id + } + return "" +} + +type URLButton struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DisplayText *HighlyStructuredMessage `protobuf:"bytes,1,opt,name=displayText" json:"displayText,omitempty"` + Url *HighlyStructuredMessage `protobuf:"bytes,2,opt,name=url" json:"url,omitempty"` +} + +func (x *URLButton) Reset() { + *x = URLButton{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *URLButton) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*URLButton) ProtoMessage() {} + +func (x *URLButton) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use URLButton.ProtoReflect.Descriptor instead. +func (*URLButton) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{6} +} + +func (x *URLButton) GetDisplayText() *HighlyStructuredMessage { + if x != nil { + return x.DisplayText + } + return nil +} + +func (x *URLButton) GetUrl() *HighlyStructuredMessage { + if x != nil { + return x.Url + } + return nil +} + +type CallButton struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DisplayText *HighlyStructuredMessage `protobuf:"bytes,1,opt,name=displayText" json:"displayText,omitempty"` + PhoneNumber *HighlyStructuredMessage `protobuf:"bytes,2,opt,name=phoneNumber" json:"phoneNumber,omitempty"` +} + +func (x *CallButton) Reset() { + *x = CallButton{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CallButton) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CallButton) ProtoMessage() {} + +func (x *CallButton) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CallButton.ProtoReflect.Descriptor instead. +func (*CallButton) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{7} +} + +func (x *CallButton) GetDisplayText() *HighlyStructuredMessage { + if x != nil { + return x.DisplayText + } + return nil +} + +func (x *CallButton) GetPhoneNumber() *HighlyStructuredMessage { + if x != nil { + return x.PhoneNumber + } + return nil +} + +type TemplateButton struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Index *uint32 `protobuf:"varint,4,opt,name=index" json:"index,omitempty"` + // Types that are assignable to Button: + // *TemplateButton_QuickReplyButton + // *TemplateButton_UrlButton + // *TemplateButton_CallButton + Button isTemplateButton_Button `protobuf_oneof:"button"` +} + +func (x *TemplateButton) Reset() { + *x = TemplateButton{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TemplateButton) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TemplateButton) ProtoMessage() {} + +func (x *TemplateButton) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TemplateButton.ProtoReflect.Descriptor instead. +func (*TemplateButton) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{8} +} + +func (x *TemplateButton) GetIndex() uint32 { + if x != nil && x.Index != nil { + return *x.Index + } + return 0 +} + +func (m *TemplateButton) GetButton() isTemplateButton_Button { + if m != nil { + return m.Button + } + return nil +} + +func (x *TemplateButton) GetQuickReplyButton() *QuickReplyButton { + if x, ok := x.GetButton().(*TemplateButton_QuickReplyButton); ok { + return x.QuickReplyButton + } + return nil +} + +func (x *TemplateButton) GetUrlButton() *URLButton { + if x, ok := x.GetButton().(*TemplateButton_UrlButton); ok { + return x.UrlButton + } + return nil +} + +func (x *TemplateButton) GetCallButton() *CallButton { + if x, ok := x.GetButton().(*TemplateButton_CallButton); ok { + return x.CallButton + } + return nil +} + +type isTemplateButton_Button interface { + isTemplateButton_Button() +} + +type TemplateButton_QuickReplyButton struct { + QuickReplyButton *QuickReplyButton `protobuf:"bytes,1,opt,name=quickReplyButton,oneof"` +} + +type TemplateButton_UrlButton struct { + UrlButton *URLButton `protobuf:"bytes,2,opt,name=urlButton,oneof"` +} + +type TemplateButton_CallButton struct { + CallButton *CallButton `protobuf:"bytes,3,opt,name=callButton,oneof"` +} + +func (*TemplateButton_QuickReplyButton) isTemplateButton_Button() {} + +func (*TemplateButton_UrlButton) isTemplateButton_Button() {} + +func (*TemplateButton_CallButton) isTemplateButton_Button() {} + +type Location struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DegreesLatitude *float64 `protobuf:"fixed64,1,opt,name=degreesLatitude" json:"degreesLatitude,omitempty"` + DegreesLongitude *float64 `protobuf:"fixed64,2,opt,name=degreesLongitude" json:"degreesLongitude,omitempty"` + Name *string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"` +} + +func (x *Location) Reset() { + *x = Location{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Location) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Location) ProtoMessage() {} + +func (x *Location) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Location.ProtoReflect.Descriptor instead. +func (*Location) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{9} +} + +func (x *Location) GetDegreesLatitude() float64 { + if x != nil && x.DegreesLatitude != nil { + return *x.DegreesLatitude + } + return 0 +} + +func (x *Location) GetDegreesLongitude() float64 { + if x != nil && x.DegreesLongitude != nil { + return *x.DegreesLongitude + } + return 0 +} + +func (x *Location) GetName() string { + if x != nil && x.Name != nil { + return *x.Name + } + return "" +} + +type Point struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + XDeprecated *int32 `protobuf:"varint,1,opt,name=xDeprecated" json:"xDeprecated,omitempty"` + YDeprecated *int32 `protobuf:"varint,2,opt,name=yDeprecated" json:"yDeprecated,omitempty"` + X *float64 `protobuf:"fixed64,3,opt,name=x" json:"x,omitempty"` + Y *float64 `protobuf:"fixed64,4,opt,name=y" json:"y,omitempty"` +} + +func (x *Point) Reset() { + *x = Point{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Point) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Point) ProtoMessage() {} + +func (x *Point) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Point.ProtoReflect.Descriptor instead. +func (*Point) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{10} +} + +func (x *Point) GetXDeprecated() int32 { + if x != nil && x.XDeprecated != nil { + return *x.XDeprecated + } + return 0 +} + +func (x *Point) GetYDeprecated() int32 { + if x != nil && x.YDeprecated != nil { + return *x.YDeprecated + } + return 0 +} + +func (x *Point) GetX() float64 { + if x != nil && x.X != nil { + return *x.X + } + return 0 +} + +func (x *Point) GetY() float64 { + if x != nil && x.Y != nil { + return *x.Y + } + return 0 +} + +type InteractiveAnnotation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PolygonVertices []*Point `protobuf:"bytes,1,rep,name=polygonVertices" json:"polygonVertices,omitempty"` + // Types that are assignable to Action: + // *InteractiveAnnotation_Location + Action isInteractiveAnnotation_Action `protobuf_oneof:"action"` +} + +func (x *InteractiveAnnotation) Reset() { + *x = InteractiveAnnotation{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InteractiveAnnotation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InteractiveAnnotation) ProtoMessage() {} + +func (x *InteractiveAnnotation) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InteractiveAnnotation.ProtoReflect.Descriptor instead. +func (*InteractiveAnnotation) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{11} +} + +func (x *InteractiveAnnotation) GetPolygonVertices() []*Point { + if x != nil { + return x.PolygonVertices + } + return nil +} + +func (m *InteractiveAnnotation) GetAction() isInteractiveAnnotation_Action { + if m != nil { + return m.Action + } + return nil +} + +func (x *InteractiveAnnotation) GetLocation() *Location { + if x, ok := x.GetAction().(*InteractiveAnnotation_Location); ok { + return x.Location + } + return nil +} + +type isInteractiveAnnotation_Action interface { + isInteractiveAnnotation_Action() +} + +type InteractiveAnnotation_Location struct { + Location *Location `protobuf:"bytes,2,opt,name=location,oneof"` +} + +func (*InteractiveAnnotation_Location) isInteractiveAnnotation_Action() {} + +type DeviceListMetadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SenderKeyHash []byte `protobuf:"bytes,1,opt,name=senderKeyHash" json:"senderKeyHash,omitempty"` + SenderTimestamp *uint64 `protobuf:"varint,2,opt,name=senderTimestamp" json:"senderTimestamp,omitempty"` + RecipientKeyHash []byte `protobuf:"bytes,8,opt,name=recipientKeyHash" json:"recipientKeyHash,omitempty"` + RecipientTimestamp *uint64 `protobuf:"varint,9,opt,name=recipientTimestamp" json:"recipientTimestamp,omitempty"` +} + +func (x *DeviceListMetadata) Reset() { + *x = DeviceListMetadata{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeviceListMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeviceListMetadata) ProtoMessage() {} + +func (x *DeviceListMetadata) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeviceListMetadata.ProtoReflect.Descriptor instead. +func (*DeviceListMetadata) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{12} +} + +func (x *DeviceListMetadata) GetSenderKeyHash() []byte { + if x != nil { + return x.SenderKeyHash + } + return nil +} + +func (x *DeviceListMetadata) GetSenderTimestamp() uint64 { + if x != nil && x.SenderTimestamp != nil { + return *x.SenderTimestamp + } + return 0 +} + +func (x *DeviceListMetadata) GetRecipientKeyHash() []byte { + if x != nil { + return x.RecipientKeyHash + } + return nil +} + +func (x *DeviceListMetadata) GetRecipientTimestamp() uint64 { + if x != nil && x.RecipientTimestamp != nil { + return *x.RecipientTimestamp + } + return 0 +} + +type MessageContextInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DeviceListMetadata *DeviceListMetadata `protobuf:"bytes,1,opt,name=deviceListMetadata" json:"deviceListMetadata,omitempty"` +} + +func (x *MessageContextInfo) Reset() { + *x = MessageContextInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MessageContextInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MessageContextInfo) ProtoMessage() {} + +func (x *MessageContextInfo) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MessageContextInfo.ProtoReflect.Descriptor instead. +func (*MessageContextInfo) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{13} +} + +func (x *MessageContextInfo) GetDeviceListMetadata() *DeviceListMetadata { + if x != nil { + return x.DeviceListMetadata + } + return nil +} + +type AdReplyInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AdvertiserName *string `protobuf:"bytes,1,opt,name=advertiserName" json:"advertiserName,omitempty"` + MediaType *AdReplyInfo_AdReplyInfoMediaType `protobuf:"varint,2,opt,name=mediaType,enum=proto.AdReplyInfo_AdReplyInfoMediaType" json:"mediaType,omitempty"` + JpegThumbnail []byte `protobuf:"bytes,16,opt,name=jpegThumbnail" json:"jpegThumbnail,omitempty"` + Caption *string `protobuf:"bytes,17,opt,name=caption" json:"caption,omitempty"` +} + +func (x *AdReplyInfo) Reset() { + *x = AdReplyInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AdReplyInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AdReplyInfo) ProtoMessage() {} + +func (x *AdReplyInfo) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AdReplyInfo.ProtoReflect.Descriptor instead. +func (*AdReplyInfo) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{14} +} + +func (x *AdReplyInfo) GetAdvertiserName() string { + if x != nil && x.AdvertiserName != nil { + return *x.AdvertiserName + } + return "" +} + +func (x *AdReplyInfo) GetMediaType() AdReplyInfo_AdReplyInfoMediaType { + if x != nil && x.MediaType != nil { + return *x.MediaType + } + return AdReplyInfo_NONE +} + +func (x *AdReplyInfo) GetJpegThumbnail() []byte { + if x != nil { + return x.JpegThumbnail + } + return nil +} + +func (x *AdReplyInfo) GetCaption() string { + if x != nil && x.Caption != nil { + return *x.Caption + } + return "" +} + +type ExternalAdReplyInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Title *string `protobuf:"bytes,1,opt,name=title" json:"title,omitempty"` + Body *string `protobuf:"bytes,2,opt,name=body" json:"body,omitempty"` + MediaType *ExternalAdReplyInfo_ExternalAdReplyInfoMediaType `protobuf:"varint,3,opt,name=mediaType,enum=proto.ExternalAdReplyInfo_ExternalAdReplyInfoMediaType" json:"mediaType,omitempty"` + ThumbnailUrl *string `protobuf:"bytes,4,opt,name=thumbnailUrl" json:"thumbnailUrl,omitempty"` + MediaUrl *string `protobuf:"bytes,5,opt,name=mediaUrl" json:"mediaUrl,omitempty"` + Thumbnail []byte `protobuf:"bytes,6,opt,name=thumbnail" json:"thumbnail,omitempty"` + SourceType *string `protobuf:"bytes,7,opt,name=sourceType" json:"sourceType,omitempty"` + SourceId *string `protobuf:"bytes,8,opt,name=sourceId" json:"sourceId,omitempty"` + SourceUrl *string `protobuf:"bytes,9,opt,name=sourceUrl" json:"sourceUrl,omitempty"` +} + +func (x *ExternalAdReplyInfo) Reset() { + *x = ExternalAdReplyInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExternalAdReplyInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExternalAdReplyInfo) ProtoMessage() {} + +func (x *ExternalAdReplyInfo) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExternalAdReplyInfo.ProtoReflect.Descriptor instead. +func (*ExternalAdReplyInfo) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{15} +} + +func (x *ExternalAdReplyInfo) GetTitle() string { + if x != nil && x.Title != nil { + return *x.Title + } + return "" +} + +func (x *ExternalAdReplyInfo) GetBody() string { + if x != nil && x.Body != nil { + return *x.Body + } + return "" +} + +func (x *ExternalAdReplyInfo) GetMediaType() ExternalAdReplyInfo_ExternalAdReplyInfoMediaType { + if x != nil && x.MediaType != nil { + return *x.MediaType + } + return ExternalAdReplyInfo_NONE +} + +func (x *ExternalAdReplyInfo) GetThumbnailUrl() string { + if x != nil && x.ThumbnailUrl != nil { + return *x.ThumbnailUrl + } + return "" +} + +func (x *ExternalAdReplyInfo) GetMediaUrl() string { + if x != nil && x.MediaUrl != nil { + return *x.MediaUrl + } + return "" +} + +func (x *ExternalAdReplyInfo) GetThumbnail() []byte { + if x != nil { + return x.Thumbnail + } + return nil +} + +func (x *ExternalAdReplyInfo) GetSourceType() string { + if x != nil && x.SourceType != nil { + return *x.SourceType + } + return "" +} + +func (x *ExternalAdReplyInfo) GetSourceId() string { + if x != nil && x.SourceId != nil { + return *x.SourceId + } + return "" +} + +func (x *ExternalAdReplyInfo) GetSourceUrl() string { + if x != nil && x.SourceUrl != nil { + return *x.SourceUrl + } + return "" +} + +type ContextInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + StanzaId *string `protobuf:"bytes,1,opt,name=stanzaId" json:"stanzaId,omitempty"` + Participant *string `protobuf:"bytes,2,opt,name=participant" json:"participant,omitempty"` + QuotedMessage *Message `protobuf:"bytes,3,opt,name=quotedMessage" json:"quotedMessage,omitempty"` + RemoteJid *string `protobuf:"bytes,4,opt,name=remoteJid" json:"remoteJid,omitempty"` + MentionedJid []string `protobuf:"bytes,15,rep,name=mentionedJid" json:"mentionedJid,omitempty"` + ConversionSource *string `protobuf:"bytes,18,opt,name=conversionSource" json:"conversionSource,omitempty"` + ConversionData []byte `protobuf:"bytes,19,opt,name=conversionData" json:"conversionData,omitempty"` + ConversionDelaySeconds *uint32 `protobuf:"varint,20,opt,name=conversionDelaySeconds" json:"conversionDelaySeconds,omitempty"` + ForwardingScore *uint32 `protobuf:"varint,21,opt,name=forwardingScore" json:"forwardingScore,omitempty"` + IsForwarded *bool `protobuf:"varint,22,opt,name=isForwarded" json:"isForwarded,omitempty"` + QuotedAd *AdReplyInfo `protobuf:"bytes,23,opt,name=quotedAd" json:"quotedAd,omitempty"` + PlaceholderKey *MessageKey `protobuf:"bytes,24,opt,name=placeholderKey" json:"placeholderKey,omitempty"` + Expiration *uint32 `protobuf:"varint,25,opt,name=expiration" json:"expiration,omitempty"` + EphemeralSettingTimestamp *int64 `protobuf:"varint,26,opt,name=ephemeralSettingTimestamp" json:"ephemeralSettingTimestamp,omitempty"` + EphemeralSharedSecret []byte `protobuf:"bytes,27,opt,name=ephemeralSharedSecret" json:"ephemeralSharedSecret,omitempty"` + ExternalAdReply *ExternalAdReplyInfo `protobuf:"bytes,28,opt,name=externalAdReply" json:"externalAdReply,omitempty"` +} + +func (x *ContextInfo) Reset() { + *x = ContextInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ContextInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContextInfo) ProtoMessage() {} + +func (x *ContextInfo) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContextInfo.ProtoReflect.Descriptor instead. +func (*ContextInfo) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{16} +} + +func (x *ContextInfo) GetStanzaId() string { + if x != nil && x.StanzaId != nil { + return *x.StanzaId + } + return "" +} + +func (x *ContextInfo) GetParticipant() string { + if x != nil && x.Participant != nil { + return *x.Participant + } + return "" +} + +func (x *ContextInfo) GetQuotedMessage() *Message { + if x != nil { + return x.QuotedMessage + } + return nil +} + +func (x *ContextInfo) GetRemoteJid() string { + if x != nil && x.RemoteJid != nil { + return *x.RemoteJid + } + return "" +} + +func (x *ContextInfo) GetMentionedJid() []string { + if x != nil { + return x.MentionedJid + } + return nil +} + +func (x *ContextInfo) GetConversionSource() string { + if x != nil && x.ConversionSource != nil { + return *x.ConversionSource + } + return "" +} + +func (x *ContextInfo) GetConversionData() []byte { + if x != nil { + return x.ConversionData + } + return nil +} + +func (x *ContextInfo) GetConversionDelaySeconds() uint32 { + if x != nil && x.ConversionDelaySeconds != nil { + return *x.ConversionDelaySeconds + } + return 0 +} + +func (x *ContextInfo) GetForwardingScore() uint32 { + if x != nil && x.ForwardingScore != nil { + return *x.ForwardingScore + } + return 0 +} + +func (x *ContextInfo) GetIsForwarded() bool { + if x != nil && x.IsForwarded != nil { + return *x.IsForwarded + } + return false +} + +func (x *ContextInfo) GetQuotedAd() *AdReplyInfo { + if x != nil { + return x.QuotedAd + } + return nil +} + +func (x *ContextInfo) GetPlaceholderKey() *MessageKey { + if x != nil { + return x.PlaceholderKey + } + return nil +} + +func (x *ContextInfo) GetExpiration() uint32 { + if x != nil && x.Expiration != nil { + return *x.Expiration + } + return 0 +} + +func (x *ContextInfo) GetEphemeralSettingTimestamp() int64 { + if x != nil && x.EphemeralSettingTimestamp != nil { + return *x.EphemeralSettingTimestamp + } + return 0 +} + +func (x *ContextInfo) GetEphemeralSharedSecret() []byte { + if x != nil { + return x.EphemeralSharedSecret + } + return nil +} + +func (x *ContextInfo) GetExternalAdReply() *ExternalAdReplyInfo { + if x != nil { + return x.ExternalAdReply + } + return nil +} + +type SenderKeyDistributionMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + GroupId *string `protobuf:"bytes,1,opt,name=groupId" json:"groupId,omitempty"` + AxolotlSenderKeyDistributionMessage []byte `protobuf:"bytes,2,opt,name=axolotlSenderKeyDistributionMessage" json:"axolotlSenderKeyDistributionMessage,omitempty"` +} + +func (x *SenderKeyDistributionMessage) Reset() { + *x = SenderKeyDistributionMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SenderKeyDistributionMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SenderKeyDistributionMessage) ProtoMessage() {} + +func (x *SenderKeyDistributionMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SenderKeyDistributionMessage.ProtoReflect.Descriptor instead. +func (*SenderKeyDistributionMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{17} +} + +func (x *SenderKeyDistributionMessage) GetGroupId() string { + if x != nil && x.GroupId != nil { + return *x.GroupId + } + return "" +} + +func (x *SenderKeyDistributionMessage) GetAxolotlSenderKeyDistributionMessage() []byte { + if x != nil { + return x.AxolotlSenderKeyDistributionMessage + } + return nil +} + +type ImageMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Url *string `protobuf:"bytes,1,opt,name=url" json:"url,omitempty"` + Mimetype *string `protobuf:"bytes,2,opt,name=mimetype" json:"mimetype,omitempty"` + Caption *string `protobuf:"bytes,3,opt,name=caption" json:"caption,omitempty"` + FileSha256 []byte `protobuf:"bytes,4,opt,name=fileSha256" json:"fileSha256,omitempty"` + FileLength *uint64 `protobuf:"varint,5,opt,name=fileLength" json:"fileLength,omitempty"` + Height *uint32 `protobuf:"varint,6,opt,name=height" json:"height,omitempty"` + Width *uint32 `protobuf:"varint,7,opt,name=width" json:"width,omitempty"` + MediaKey []byte `protobuf:"bytes,8,opt,name=mediaKey" json:"mediaKey,omitempty"` + FileEncSha256 []byte `protobuf:"bytes,9,opt,name=fileEncSha256" json:"fileEncSha256,omitempty"` + InteractiveAnnotations []*InteractiveAnnotation `protobuf:"bytes,10,rep,name=interactiveAnnotations" json:"interactiveAnnotations,omitempty"` + DirectPath *string `protobuf:"bytes,11,opt,name=directPath" json:"directPath,omitempty"` + MediaKeyTimestamp *int64 `protobuf:"varint,12,opt,name=mediaKeyTimestamp" json:"mediaKeyTimestamp,omitempty"` + JpegThumbnail []byte `protobuf:"bytes,16,opt,name=jpegThumbnail" json:"jpegThumbnail,omitempty"` + ContextInfo *ContextInfo `protobuf:"bytes,17,opt,name=contextInfo" json:"contextInfo,omitempty"` + FirstScanSidecar []byte `protobuf:"bytes,18,opt,name=firstScanSidecar" json:"firstScanSidecar,omitempty"` + FirstScanLength *uint32 `protobuf:"varint,19,opt,name=firstScanLength" json:"firstScanLength,omitempty"` + ExperimentGroupId *uint32 `protobuf:"varint,20,opt,name=experimentGroupId" json:"experimentGroupId,omitempty"` + ScansSidecar []byte `protobuf:"bytes,21,opt,name=scansSidecar" json:"scansSidecar,omitempty"` + ScanLengths []uint32 `protobuf:"varint,22,rep,name=scanLengths" json:"scanLengths,omitempty"` + MidQualityFileSha256 []byte `protobuf:"bytes,23,opt,name=midQualityFileSha256" json:"midQualityFileSha256,omitempty"` + MidQualityFileEncSha256 []byte `protobuf:"bytes,24,opt,name=midQualityFileEncSha256" json:"midQualityFileEncSha256,omitempty"` + ViewOnce *bool `protobuf:"varint,25,opt,name=viewOnce" json:"viewOnce,omitempty"` + ThumbnailDirectPath *string `protobuf:"bytes,26,opt,name=thumbnailDirectPath" json:"thumbnailDirectPath,omitempty"` + ThumbnailSha256 []byte `protobuf:"bytes,27,opt,name=thumbnailSha256" json:"thumbnailSha256,omitempty"` + ThumbnailEncSha256 []byte `protobuf:"bytes,28,opt,name=thumbnailEncSha256" json:"thumbnailEncSha256,omitempty"` +} + +func (x *ImageMessage) Reset() { + *x = ImageMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ImageMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ImageMessage) ProtoMessage() {} + +func (x *ImageMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ImageMessage.ProtoReflect.Descriptor instead. +func (*ImageMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{18} +} + +func (x *ImageMessage) GetUrl() string { + if x != nil && x.Url != nil { + return *x.Url + } + return "" +} + +func (x *ImageMessage) GetMimetype() string { + if x != nil && x.Mimetype != nil { + return *x.Mimetype + } + return "" +} + +func (x *ImageMessage) GetCaption() string { + if x != nil && x.Caption != nil { + return *x.Caption + } + return "" +} + +func (x *ImageMessage) GetFileSha256() []byte { + if x != nil { + return x.FileSha256 + } + return nil +} + +func (x *ImageMessage) GetFileLength() uint64 { + if x != nil && x.FileLength != nil { + return *x.FileLength + } + return 0 +} + +func (x *ImageMessage) GetHeight() uint32 { + if x != nil && x.Height != nil { + return *x.Height + } + return 0 +} + +func (x *ImageMessage) GetWidth() uint32 { + if x != nil && x.Width != nil { + return *x.Width + } + return 0 +} + +func (x *ImageMessage) GetMediaKey() []byte { + if x != nil { + return x.MediaKey + } + return nil +} + +func (x *ImageMessage) GetFileEncSha256() []byte { + if x != nil { + return x.FileEncSha256 + } + return nil +} + +func (x *ImageMessage) GetInteractiveAnnotations() []*InteractiveAnnotation { + if x != nil { + return x.InteractiveAnnotations + } + return nil +} + +func (x *ImageMessage) GetDirectPath() string { + if x != nil && x.DirectPath != nil { + return *x.DirectPath + } + return "" +} + +func (x *ImageMessage) GetMediaKeyTimestamp() int64 { + if x != nil && x.MediaKeyTimestamp != nil { + return *x.MediaKeyTimestamp + } + return 0 +} + +func (x *ImageMessage) GetJpegThumbnail() []byte { + if x != nil { + return x.JpegThumbnail + } + return nil +} + +func (x *ImageMessage) GetContextInfo() *ContextInfo { + if x != nil { + return x.ContextInfo + } + return nil +} + +func (x *ImageMessage) GetFirstScanSidecar() []byte { + if x != nil { + return x.FirstScanSidecar + } + return nil +} + +func (x *ImageMessage) GetFirstScanLength() uint32 { + if x != nil && x.FirstScanLength != nil { + return *x.FirstScanLength + } + return 0 +} + +func (x *ImageMessage) GetExperimentGroupId() uint32 { + if x != nil && x.ExperimentGroupId != nil { + return *x.ExperimentGroupId + } + return 0 +} + +func (x *ImageMessage) GetScansSidecar() []byte { + if x != nil { + return x.ScansSidecar + } + return nil +} + +func (x *ImageMessage) GetScanLengths() []uint32 { + if x != nil { + return x.ScanLengths + } + return nil +} + +func (x *ImageMessage) GetMidQualityFileSha256() []byte { + if x != nil { + return x.MidQualityFileSha256 + } + return nil +} + +func (x *ImageMessage) GetMidQualityFileEncSha256() []byte { + if x != nil { + return x.MidQualityFileEncSha256 + } + return nil +} + +func (x *ImageMessage) GetViewOnce() bool { + if x != nil && x.ViewOnce != nil { + return *x.ViewOnce + } + return false +} + +func (x *ImageMessage) GetThumbnailDirectPath() string { + if x != nil && x.ThumbnailDirectPath != nil { + return *x.ThumbnailDirectPath + } + return "" +} + +func (x *ImageMessage) GetThumbnailSha256() []byte { + if x != nil { + return x.ThumbnailSha256 + } + return nil +} + +func (x *ImageMessage) GetThumbnailEncSha256() []byte { + if x != nil { + return x.ThumbnailEncSha256 + } + return nil +} + +type InvoiceMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Note *string `protobuf:"bytes,1,opt,name=note" json:"note,omitempty"` + Token *string `protobuf:"bytes,2,opt,name=token" json:"token,omitempty"` + AttachmentType *InvoiceMessage_InvoiceMessageAttachmentType `protobuf:"varint,3,opt,name=attachmentType,enum=proto.InvoiceMessage_InvoiceMessageAttachmentType" json:"attachmentType,omitempty"` + AttachmentMimetype *string `protobuf:"bytes,4,opt,name=attachmentMimetype" json:"attachmentMimetype,omitempty"` + AttachmentMediaKey []byte `protobuf:"bytes,5,opt,name=attachmentMediaKey" json:"attachmentMediaKey,omitempty"` + AttachmentMediaKeyTimestamp *int64 `protobuf:"varint,6,opt,name=attachmentMediaKeyTimestamp" json:"attachmentMediaKeyTimestamp,omitempty"` + AttachmentFileSha256 []byte `protobuf:"bytes,7,opt,name=attachmentFileSha256" json:"attachmentFileSha256,omitempty"` + AttachmentFileEncSha256 []byte `protobuf:"bytes,8,opt,name=attachmentFileEncSha256" json:"attachmentFileEncSha256,omitempty"` + AttachmentDirectPath *string `protobuf:"bytes,9,opt,name=attachmentDirectPath" json:"attachmentDirectPath,omitempty"` + AttachmentJpegThumbnail []byte `protobuf:"bytes,10,opt,name=attachmentJpegThumbnail" json:"attachmentJpegThumbnail,omitempty"` +} + +func (x *InvoiceMessage) Reset() { + *x = InvoiceMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InvoiceMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InvoiceMessage) ProtoMessage() {} + +func (x *InvoiceMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InvoiceMessage.ProtoReflect.Descriptor instead. +func (*InvoiceMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{19} +} + +func (x *InvoiceMessage) GetNote() string { + if x != nil && x.Note != nil { + return *x.Note + } + return "" +} + +func (x *InvoiceMessage) GetToken() string { + if x != nil && x.Token != nil { + return *x.Token + } + return "" +} + +func (x *InvoiceMessage) GetAttachmentType() InvoiceMessage_InvoiceMessageAttachmentType { + if x != nil && x.AttachmentType != nil { + return *x.AttachmentType + } + return InvoiceMessage_IMAGE +} + +func (x *InvoiceMessage) GetAttachmentMimetype() string { + if x != nil && x.AttachmentMimetype != nil { + return *x.AttachmentMimetype + } + return "" +} + +func (x *InvoiceMessage) GetAttachmentMediaKey() []byte { + if x != nil { + return x.AttachmentMediaKey + } + return nil +} + +func (x *InvoiceMessage) GetAttachmentMediaKeyTimestamp() int64 { + if x != nil && x.AttachmentMediaKeyTimestamp != nil { + return *x.AttachmentMediaKeyTimestamp + } + return 0 +} + +func (x *InvoiceMessage) GetAttachmentFileSha256() []byte { + if x != nil { + return x.AttachmentFileSha256 + } + return nil +} + +func (x *InvoiceMessage) GetAttachmentFileEncSha256() []byte { + if x != nil { + return x.AttachmentFileEncSha256 + } + return nil +} + +func (x *InvoiceMessage) GetAttachmentDirectPath() string { + if x != nil && x.AttachmentDirectPath != nil { + return *x.AttachmentDirectPath + } + return "" +} + +func (x *InvoiceMessage) GetAttachmentJpegThumbnail() []byte { + if x != nil { + return x.AttachmentJpegThumbnail + } + return nil +} + +type ContactMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DisplayName *string `protobuf:"bytes,1,opt,name=displayName" json:"displayName,omitempty"` + Vcard *string `protobuf:"bytes,16,opt,name=vcard" json:"vcard,omitempty"` + ContextInfo *ContextInfo `protobuf:"bytes,17,opt,name=contextInfo" json:"contextInfo,omitempty"` +} + +func (x *ContactMessage) Reset() { + *x = ContactMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ContactMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContactMessage) ProtoMessage() {} + +func (x *ContactMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContactMessage.ProtoReflect.Descriptor instead. +func (*ContactMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{20} +} + +func (x *ContactMessage) GetDisplayName() string { + if x != nil && x.DisplayName != nil { + return *x.DisplayName + } + return "" +} + +func (x *ContactMessage) GetVcard() string { + if x != nil && x.Vcard != nil { + return *x.Vcard + } + return "" +} + +func (x *ContactMessage) GetContextInfo() *ContextInfo { + if x != nil { + return x.ContextInfo + } + return nil +} + +type LocationMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DegreesLatitude *float64 `protobuf:"fixed64,1,opt,name=degreesLatitude" json:"degreesLatitude,omitempty"` + DegreesLongitude *float64 `protobuf:"fixed64,2,opt,name=degreesLongitude" json:"degreesLongitude,omitempty"` + Name *string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"` + Address *string `protobuf:"bytes,4,opt,name=address" json:"address,omitempty"` + Url *string `protobuf:"bytes,5,opt,name=url" json:"url,omitempty"` + IsLive *bool `protobuf:"varint,6,opt,name=isLive" json:"isLive,omitempty"` + AccuracyInMeters *uint32 `protobuf:"varint,7,opt,name=accuracyInMeters" json:"accuracyInMeters,omitempty"` + SpeedInMps *float32 `protobuf:"fixed32,8,opt,name=speedInMps" json:"speedInMps,omitempty"` + DegreesClockwiseFromMagneticNorth *uint32 `protobuf:"varint,9,opt,name=degreesClockwiseFromMagneticNorth" json:"degreesClockwiseFromMagneticNorth,omitempty"` + Comment *string `protobuf:"bytes,11,opt,name=comment" json:"comment,omitempty"` + JpegThumbnail []byte `protobuf:"bytes,16,opt,name=jpegThumbnail" json:"jpegThumbnail,omitempty"` + ContextInfo *ContextInfo `protobuf:"bytes,17,opt,name=contextInfo" json:"contextInfo,omitempty"` +} + +func (x *LocationMessage) Reset() { + *x = LocationMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LocationMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LocationMessage) ProtoMessage() {} + +func (x *LocationMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LocationMessage.ProtoReflect.Descriptor instead. +func (*LocationMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{21} +} + +func (x *LocationMessage) GetDegreesLatitude() float64 { + if x != nil && x.DegreesLatitude != nil { + return *x.DegreesLatitude + } + return 0 +} + +func (x *LocationMessage) GetDegreesLongitude() float64 { + if x != nil && x.DegreesLongitude != nil { + return *x.DegreesLongitude + } + return 0 +} + +func (x *LocationMessage) GetName() string { + if x != nil && x.Name != nil { + return *x.Name + } + return "" +} + +func (x *LocationMessage) GetAddress() string { + if x != nil && x.Address != nil { + return *x.Address + } + return "" +} + +func (x *LocationMessage) GetUrl() string { + if x != nil && x.Url != nil { + return *x.Url + } + return "" +} + +func (x *LocationMessage) GetIsLive() bool { + if x != nil && x.IsLive != nil { + return *x.IsLive + } + return false +} + +func (x *LocationMessage) GetAccuracyInMeters() uint32 { + if x != nil && x.AccuracyInMeters != nil { + return *x.AccuracyInMeters + } + return 0 +} + +func (x *LocationMessage) GetSpeedInMps() float32 { + if x != nil && x.SpeedInMps != nil { + return *x.SpeedInMps + } + return 0 +} + +func (x *LocationMessage) GetDegreesClockwiseFromMagneticNorth() uint32 { + if x != nil && x.DegreesClockwiseFromMagneticNorth != nil { + return *x.DegreesClockwiseFromMagneticNorth + } + return 0 +} + +func (x *LocationMessage) GetComment() string { + if x != nil && x.Comment != nil { + return *x.Comment + } + return "" +} + +func (x *LocationMessage) GetJpegThumbnail() []byte { + if x != nil { + return x.JpegThumbnail + } + return nil +} + +func (x *LocationMessage) GetContextInfo() *ContextInfo { + if x != nil { + return x.ContextInfo + } + return nil +} + +type ExtendedTextMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Text *string `protobuf:"bytes,1,opt,name=text" json:"text,omitempty"` + MatchedText *string `protobuf:"bytes,2,opt,name=matchedText" json:"matchedText,omitempty"` + CanonicalUrl *string `protobuf:"bytes,4,opt,name=canonicalUrl" json:"canonicalUrl,omitempty"` + Description *string `protobuf:"bytes,5,opt,name=description" json:"description,omitempty"` + Title *string `protobuf:"bytes,6,opt,name=title" json:"title,omitempty"` + TextArgb *uint32 `protobuf:"fixed32,7,opt,name=textArgb" json:"textArgb,omitempty"` + BackgroundArgb *uint32 `protobuf:"fixed32,8,opt,name=backgroundArgb" json:"backgroundArgb,omitempty"` + Font *ExtendedTextMessage_ExtendedTextMessageFontType `protobuf:"varint,9,opt,name=font,enum=proto.ExtendedTextMessage_ExtendedTextMessageFontType" json:"font,omitempty"` + PreviewType *ExtendedTextMessage_ExtendedTextMessagePreviewType `protobuf:"varint,10,opt,name=previewType,enum=proto.ExtendedTextMessage_ExtendedTextMessagePreviewType" json:"previewType,omitempty"` + JpegThumbnail []byte `protobuf:"bytes,16,opt,name=jpegThumbnail" json:"jpegThumbnail,omitempty"` + ContextInfo *ContextInfo `protobuf:"bytes,17,opt,name=contextInfo" json:"contextInfo,omitempty"` + DoNotPlayInline *bool `protobuf:"varint,18,opt,name=doNotPlayInline" json:"doNotPlayInline,omitempty"` +} + +func (x *ExtendedTextMessage) Reset() { + *x = ExtendedTextMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExtendedTextMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExtendedTextMessage) ProtoMessage() {} + +func (x *ExtendedTextMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExtendedTextMessage.ProtoReflect.Descriptor instead. +func (*ExtendedTextMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{22} +} + +func (x *ExtendedTextMessage) GetText() string { + if x != nil && x.Text != nil { + return *x.Text + } + return "" +} + +func (x *ExtendedTextMessage) GetMatchedText() string { + if x != nil && x.MatchedText != nil { + return *x.MatchedText + } + return "" +} + +func (x *ExtendedTextMessage) GetCanonicalUrl() string { + if x != nil && x.CanonicalUrl != nil { + return *x.CanonicalUrl + } + return "" +} + +func (x *ExtendedTextMessage) GetDescription() string { + if x != nil && x.Description != nil { + return *x.Description + } + return "" +} + +func (x *ExtendedTextMessage) GetTitle() string { + if x != nil && x.Title != nil { + return *x.Title + } + return "" +} + +func (x *ExtendedTextMessage) GetTextArgb() uint32 { + if x != nil && x.TextArgb != nil { + return *x.TextArgb + } + return 0 +} + +func (x *ExtendedTextMessage) GetBackgroundArgb() uint32 { + if x != nil && x.BackgroundArgb != nil { + return *x.BackgroundArgb + } + return 0 +} + +func (x *ExtendedTextMessage) GetFont() ExtendedTextMessage_ExtendedTextMessageFontType { + if x != nil && x.Font != nil { + return *x.Font + } + return ExtendedTextMessage_SANS_SERIF +} + +func (x *ExtendedTextMessage) GetPreviewType() ExtendedTextMessage_ExtendedTextMessagePreviewType { + if x != nil && x.PreviewType != nil { + return *x.PreviewType + } + return ExtendedTextMessage_NONE +} + +func (x *ExtendedTextMessage) GetJpegThumbnail() []byte { + if x != nil { + return x.JpegThumbnail + } + return nil +} + +func (x *ExtendedTextMessage) GetContextInfo() *ContextInfo { + if x != nil { + return x.ContextInfo + } + return nil +} + +func (x *ExtendedTextMessage) GetDoNotPlayInline() bool { + if x != nil && x.DoNotPlayInline != nil { + return *x.DoNotPlayInline + } + return false +} + +type DocumentMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Url *string `protobuf:"bytes,1,opt,name=url" json:"url,omitempty"` + Mimetype *string `protobuf:"bytes,2,opt,name=mimetype" json:"mimetype,omitempty"` + Title *string `protobuf:"bytes,3,opt,name=title" json:"title,omitempty"` + FileSha256 []byte `protobuf:"bytes,4,opt,name=fileSha256" json:"fileSha256,omitempty"` + FileLength *uint64 `protobuf:"varint,5,opt,name=fileLength" json:"fileLength,omitempty"` + PageCount *uint32 `protobuf:"varint,6,opt,name=pageCount" json:"pageCount,omitempty"` + MediaKey []byte `protobuf:"bytes,7,opt,name=mediaKey" json:"mediaKey,omitempty"` + FileName *string `protobuf:"bytes,8,opt,name=fileName" json:"fileName,omitempty"` + FileEncSha256 []byte `protobuf:"bytes,9,opt,name=fileEncSha256" json:"fileEncSha256,omitempty"` + DirectPath *string `protobuf:"bytes,10,opt,name=directPath" json:"directPath,omitempty"` + MediaKeyTimestamp *int64 `protobuf:"varint,11,opt,name=mediaKeyTimestamp" json:"mediaKeyTimestamp,omitempty"` + ContactVcard *bool `protobuf:"varint,12,opt,name=contactVcard" json:"contactVcard,omitempty"` + ThumbnailDirectPath *string `protobuf:"bytes,13,opt,name=thumbnailDirectPath" json:"thumbnailDirectPath,omitempty"` + ThumbnailSha256 []byte `protobuf:"bytes,14,opt,name=thumbnailSha256" json:"thumbnailSha256,omitempty"` + ThumbnailEncSha256 []byte `protobuf:"bytes,15,opt,name=thumbnailEncSha256" json:"thumbnailEncSha256,omitempty"` + JpegThumbnail []byte `protobuf:"bytes,16,opt,name=jpegThumbnail" json:"jpegThumbnail,omitempty"` + ContextInfo *ContextInfo `protobuf:"bytes,17,opt,name=contextInfo" json:"contextInfo,omitempty"` + ThumbnailHeight *uint32 `protobuf:"varint,18,opt,name=thumbnailHeight" json:"thumbnailHeight,omitempty"` + ThumbnailWidth *uint32 `protobuf:"varint,19,opt,name=thumbnailWidth" json:"thumbnailWidth,omitempty"` +} + +func (x *DocumentMessage) Reset() { + *x = DocumentMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DocumentMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DocumentMessage) ProtoMessage() {} + +func (x *DocumentMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DocumentMessage.ProtoReflect.Descriptor instead. +func (*DocumentMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{23} +} + +func (x *DocumentMessage) GetUrl() string { + if x != nil && x.Url != nil { + return *x.Url + } + return "" +} + +func (x *DocumentMessage) GetMimetype() string { + if x != nil && x.Mimetype != nil { + return *x.Mimetype + } + return "" +} + +func (x *DocumentMessage) GetTitle() string { + if x != nil && x.Title != nil { + return *x.Title + } + return "" +} + +func (x *DocumentMessage) GetFileSha256() []byte { + if x != nil { + return x.FileSha256 + } + return nil +} + +func (x *DocumentMessage) GetFileLength() uint64 { + if x != nil && x.FileLength != nil { + return *x.FileLength + } + return 0 +} + +func (x *DocumentMessage) GetPageCount() uint32 { + if x != nil && x.PageCount != nil { + return *x.PageCount + } + return 0 +} + +func (x *DocumentMessage) GetMediaKey() []byte { + if x != nil { + return x.MediaKey + } + return nil +} + +func (x *DocumentMessage) GetFileName() string { + if x != nil && x.FileName != nil { + return *x.FileName + } + return "" +} + +func (x *DocumentMessage) GetFileEncSha256() []byte { + if x != nil { + return x.FileEncSha256 + } + return nil +} + +func (x *DocumentMessage) GetDirectPath() string { + if x != nil && x.DirectPath != nil { + return *x.DirectPath + } + return "" +} + +func (x *DocumentMessage) GetMediaKeyTimestamp() int64 { + if x != nil && x.MediaKeyTimestamp != nil { + return *x.MediaKeyTimestamp + } + return 0 +} + +func (x *DocumentMessage) GetContactVcard() bool { + if x != nil && x.ContactVcard != nil { + return *x.ContactVcard + } + return false +} + +func (x *DocumentMessage) GetThumbnailDirectPath() string { + if x != nil && x.ThumbnailDirectPath != nil { + return *x.ThumbnailDirectPath + } + return "" +} + +func (x *DocumentMessage) GetThumbnailSha256() []byte { + if x != nil { + return x.ThumbnailSha256 + } + return nil +} + +func (x *DocumentMessage) GetThumbnailEncSha256() []byte { + if x != nil { + return x.ThumbnailEncSha256 + } + return nil +} + +func (x *DocumentMessage) GetJpegThumbnail() []byte { + if x != nil { + return x.JpegThumbnail + } + return nil +} + +func (x *DocumentMessage) GetContextInfo() *ContextInfo { + if x != nil { + return x.ContextInfo + } + return nil +} + +func (x *DocumentMessage) GetThumbnailHeight() uint32 { + if x != nil && x.ThumbnailHeight != nil { + return *x.ThumbnailHeight + } + return 0 +} + +func (x *DocumentMessage) GetThumbnailWidth() uint32 { + if x != nil && x.ThumbnailWidth != nil { + return *x.ThumbnailWidth + } + return 0 +} + +type AudioMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Url *string `protobuf:"bytes,1,opt,name=url" json:"url,omitempty"` + Mimetype *string `protobuf:"bytes,2,opt,name=mimetype" json:"mimetype,omitempty"` + FileSha256 []byte `protobuf:"bytes,3,opt,name=fileSha256" json:"fileSha256,omitempty"` + FileLength *uint64 `protobuf:"varint,4,opt,name=fileLength" json:"fileLength,omitempty"` + Seconds *uint32 `protobuf:"varint,5,opt,name=seconds" json:"seconds,omitempty"` + Ptt *bool `protobuf:"varint,6,opt,name=ptt" json:"ptt,omitempty"` + MediaKey []byte `protobuf:"bytes,7,opt,name=mediaKey" json:"mediaKey,omitempty"` + FileEncSha256 []byte `protobuf:"bytes,8,opt,name=fileEncSha256" json:"fileEncSha256,omitempty"` + DirectPath *string `protobuf:"bytes,9,opt,name=directPath" json:"directPath,omitempty"` + MediaKeyTimestamp *int64 `protobuf:"varint,10,opt,name=mediaKeyTimestamp" json:"mediaKeyTimestamp,omitempty"` + ContextInfo *ContextInfo `protobuf:"bytes,17,opt,name=contextInfo" json:"contextInfo,omitempty"` + StreamingSidecar []byte `protobuf:"bytes,18,opt,name=streamingSidecar" json:"streamingSidecar,omitempty"` +} + +func (x *AudioMessage) Reset() { + *x = AudioMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AudioMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AudioMessage) ProtoMessage() {} + +func (x *AudioMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AudioMessage.ProtoReflect.Descriptor instead. +func (*AudioMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{24} +} + +func (x *AudioMessage) GetUrl() string { + if x != nil && x.Url != nil { + return *x.Url + } + return "" +} + +func (x *AudioMessage) GetMimetype() string { + if x != nil && x.Mimetype != nil { + return *x.Mimetype + } + return "" +} + +func (x *AudioMessage) GetFileSha256() []byte { + if x != nil { + return x.FileSha256 + } + return nil +} + +func (x *AudioMessage) GetFileLength() uint64 { + if x != nil && x.FileLength != nil { + return *x.FileLength + } + return 0 +} + +func (x *AudioMessage) GetSeconds() uint32 { + if x != nil && x.Seconds != nil { + return *x.Seconds + } + return 0 +} + +func (x *AudioMessage) GetPtt() bool { + if x != nil && x.Ptt != nil { + return *x.Ptt + } + return false +} + +func (x *AudioMessage) GetMediaKey() []byte { + if x != nil { + return x.MediaKey + } + return nil +} + +func (x *AudioMessage) GetFileEncSha256() []byte { + if x != nil { + return x.FileEncSha256 + } + return nil +} + +func (x *AudioMessage) GetDirectPath() string { + if x != nil && x.DirectPath != nil { + return *x.DirectPath + } + return "" +} + +func (x *AudioMessage) GetMediaKeyTimestamp() int64 { + if x != nil && x.MediaKeyTimestamp != nil { + return *x.MediaKeyTimestamp + } + return 0 +} + +func (x *AudioMessage) GetContextInfo() *ContextInfo { + if x != nil { + return x.ContextInfo + } + return nil +} + +func (x *AudioMessage) GetStreamingSidecar() []byte { + if x != nil { + return x.StreamingSidecar + } + return nil +} + +type VideoMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Url *string `protobuf:"bytes,1,opt,name=url" json:"url,omitempty"` + Mimetype *string `protobuf:"bytes,2,opt,name=mimetype" json:"mimetype,omitempty"` + FileSha256 []byte `protobuf:"bytes,3,opt,name=fileSha256" json:"fileSha256,omitempty"` + FileLength *uint64 `protobuf:"varint,4,opt,name=fileLength" json:"fileLength,omitempty"` + Seconds *uint32 `protobuf:"varint,5,opt,name=seconds" json:"seconds,omitempty"` + MediaKey []byte `protobuf:"bytes,6,opt,name=mediaKey" json:"mediaKey,omitempty"` + Caption *string `protobuf:"bytes,7,opt,name=caption" json:"caption,omitempty"` + GifPlayback *bool `protobuf:"varint,8,opt,name=gifPlayback" json:"gifPlayback,omitempty"` + Height *uint32 `protobuf:"varint,9,opt,name=height" json:"height,omitempty"` + Width *uint32 `protobuf:"varint,10,opt,name=width" json:"width,omitempty"` + FileEncSha256 []byte `protobuf:"bytes,11,opt,name=fileEncSha256" json:"fileEncSha256,omitempty"` + InteractiveAnnotations []*InteractiveAnnotation `protobuf:"bytes,12,rep,name=interactiveAnnotations" json:"interactiveAnnotations,omitempty"` + DirectPath *string `protobuf:"bytes,13,opt,name=directPath" json:"directPath,omitempty"` + MediaKeyTimestamp *int64 `protobuf:"varint,14,opt,name=mediaKeyTimestamp" json:"mediaKeyTimestamp,omitempty"` + JpegThumbnail []byte `protobuf:"bytes,16,opt,name=jpegThumbnail" json:"jpegThumbnail,omitempty"` + ContextInfo *ContextInfo `protobuf:"bytes,17,opt,name=contextInfo" json:"contextInfo,omitempty"` + StreamingSidecar []byte `protobuf:"bytes,18,opt,name=streamingSidecar" json:"streamingSidecar,omitempty"` + GifAttribution *VideoMessage_VideoMessageAttribution `protobuf:"varint,19,opt,name=gifAttribution,enum=proto.VideoMessage_VideoMessageAttribution" json:"gifAttribution,omitempty"` + ViewOnce *bool `protobuf:"varint,20,opt,name=viewOnce" json:"viewOnce,omitempty"` + ThumbnailDirectPath *string `protobuf:"bytes,21,opt,name=thumbnailDirectPath" json:"thumbnailDirectPath,omitempty"` + ThumbnailSha256 []byte `protobuf:"bytes,22,opt,name=thumbnailSha256" json:"thumbnailSha256,omitempty"` + ThumbnailEncSha256 []byte `protobuf:"bytes,23,opt,name=thumbnailEncSha256" json:"thumbnailEncSha256,omitempty"` +} + +func (x *VideoMessage) Reset() { + *x = VideoMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *VideoMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*VideoMessage) ProtoMessage() {} + +func (x *VideoMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use VideoMessage.ProtoReflect.Descriptor instead. +func (*VideoMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{25} +} + +func (x *VideoMessage) GetUrl() string { + if x != nil && x.Url != nil { + return *x.Url + } + return "" +} + +func (x *VideoMessage) GetMimetype() string { + if x != nil && x.Mimetype != nil { + return *x.Mimetype + } + return "" +} + +func (x *VideoMessage) GetFileSha256() []byte { + if x != nil { + return x.FileSha256 + } + return nil +} + +func (x *VideoMessage) GetFileLength() uint64 { + if x != nil && x.FileLength != nil { + return *x.FileLength + } + return 0 +} + +func (x *VideoMessage) GetSeconds() uint32 { + if x != nil && x.Seconds != nil { + return *x.Seconds + } + return 0 +} + +func (x *VideoMessage) GetMediaKey() []byte { + if x != nil { + return x.MediaKey + } + return nil +} + +func (x *VideoMessage) GetCaption() string { + if x != nil && x.Caption != nil { + return *x.Caption + } + return "" +} + +func (x *VideoMessage) GetGifPlayback() bool { + if x != nil && x.GifPlayback != nil { + return *x.GifPlayback + } + return false +} + +func (x *VideoMessage) GetHeight() uint32 { + if x != nil && x.Height != nil { + return *x.Height + } + return 0 +} + +func (x *VideoMessage) GetWidth() uint32 { + if x != nil && x.Width != nil { + return *x.Width + } + return 0 +} + +func (x *VideoMessage) GetFileEncSha256() []byte { + if x != nil { + return x.FileEncSha256 + } + return nil +} + +func (x *VideoMessage) GetInteractiveAnnotations() []*InteractiveAnnotation { + if x != nil { + return x.InteractiveAnnotations + } + return nil +} + +func (x *VideoMessage) GetDirectPath() string { + if x != nil && x.DirectPath != nil { + return *x.DirectPath + } + return "" +} + +func (x *VideoMessage) GetMediaKeyTimestamp() int64 { + if x != nil && x.MediaKeyTimestamp != nil { + return *x.MediaKeyTimestamp + } + return 0 +} + +func (x *VideoMessage) GetJpegThumbnail() []byte { + if x != nil { + return x.JpegThumbnail + } + return nil +} + +func (x *VideoMessage) GetContextInfo() *ContextInfo { + if x != nil { + return x.ContextInfo + } + return nil +} + +func (x *VideoMessage) GetStreamingSidecar() []byte { + if x != nil { + return x.StreamingSidecar + } + return nil +} + +func (x *VideoMessage) GetGifAttribution() VideoMessage_VideoMessageAttribution { + if x != nil && x.GifAttribution != nil { + return *x.GifAttribution + } + return VideoMessage_NONE +} + +func (x *VideoMessage) GetViewOnce() bool { + if x != nil && x.ViewOnce != nil { + return *x.ViewOnce + } + return false +} + +func (x *VideoMessage) GetThumbnailDirectPath() string { + if x != nil && x.ThumbnailDirectPath != nil { + return *x.ThumbnailDirectPath + } + return "" +} + +func (x *VideoMessage) GetThumbnailSha256() []byte { + if x != nil { + return x.ThumbnailSha256 + } + return nil +} + +func (x *VideoMessage) GetThumbnailEncSha256() []byte { + if x != nil { + return x.ThumbnailEncSha256 + } + return nil +} + +type Call struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + CallKey []byte `protobuf:"bytes,1,opt,name=callKey" json:"callKey,omitempty"` +} + +func (x *Call) Reset() { + *x = Call{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Call) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Call) ProtoMessage() {} + +func (x *Call) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Call.ProtoReflect.Descriptor instead. +func (*Call) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{26} +} + +func (x *Call) GetCallKey() []byte { + if x != nil { + return x.CallKey + } + return nil +} + +type Chat struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DisplayName *string `protobuf:"bytes,1,opt,name=displayName" json:"displayName,omitempty"` + Id *string `protobuf:"bytes,2,opt,name=id" json:"id,omitempty"` +} + +func (x *Chat) Reset() { + *x = Chat{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Chat) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Chat) ProtoMessage() {} + +func (x *Chat) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[27] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Chat.ProtoReflect.Descriptor instead. +func (*Chat) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{27} +} + +func (x *Chat) GetDisplayName() string { + if x != nil && x.DisplayName != nil { + return *x.DisplayName + } + return "" +} + +func (x *Chat) GetId() string { + if x != nil && x.Id != nil { + return *x.Id + } + return "" +} + +type ProtocolMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key *MessageKey `protobuf:"bytes,1,opt,name=key" json:"key,omitempty"` + Type *ProtocolMessage_ProtocolMessageType `protobuf:"varint,2,opt,name=type,enum=proto.ProtocolMessage_ProtocolMessageType" json:"type,omitempty"` + EphemeralExpiration *uint32 `protobuf:"varint,4,opt,name=ephemeralExpiration" json:"ephemeralExpiration,omitempty"` + EphemeralSettingTimestamp *int64 `protobuf:"varint,5,opt,name=ephemeralSettingTimestamp" json:"ephemeralSettingTimestamp,omitempty"` + HistorySyncNotification *HistorySyncNotification `protobuf:"bytes,6,opt,name=historySyncNotification" json:"historySyncNotification,omitempty"` + AppStateSyncKeyShare *AppStateSyncKeyShare `protobuf:"bytes,7,opt,name=appStateSyncKeyShare" json:"appStateSyncKeyShare,omitempty"` + AppStateSyncKeyRequest *AppStateSyncKeyRequest `protobuf:"bytes,8,opt,name=appStateSyncKeyRequest" json:"appStateSyncKeyRequest,omitempty"` + InitialSecurityNotificationSettingSync *InitialSecurityNotificationSettingSync `protobuf:"bytes,9,opt,name=initialSecurityNotificationSettingSync" json:"initialSecurityNotificationSettingSync,omitempty"` + AppStateFatalExceptionNotification *AppStateFatalExceptionNotification `protobuf:"bytes,10,opt,name=appStateFatalExceptionNotification" json:"appStateFatalExceptionNotification,omitempty"` +} + +func (x *ProtocolMessage) Reset() { + *x = ProtocolMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProtocolMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProtocolMessage) ProtoMessage() {} + +func (x *ProtocolMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[28] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProtocolMessage.ProtoReflect.Descriptor instead. +func (*ProtocolMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{28} +} + +func (x *ProtocolMessage) GetKey() *MessageKey { + if x != nil { + return x.Key + } + return nil +} + +func (x *ProtocolMessage) GetType() ProtocolMessage_ProtocolMessageType { + if x != nil && x.Type != nil { + return *x.Type + } + return ProtocolMessage_REVOKE +} + +func (x *ProtocolMessage) GetEphemeralExpiration() uint32 { + if x != nil && x.EphemeralExpiration != nil { + return *x.EphemeralExpiration + } + return 0 +} + +func (x *ProtocolMessage) GetEphemeralSettingTimestamp() int64 { + if x != nil && x.EphemeralSettingTimestamp != nil { + return *x.EphemeralSettingTimestamp + } + return 0 +} + +func (x *ProtocolMessage) GetHistorySyncNotification() *HistorySyncNotification { + if x != nil { + return x.HistorySyncNotification + } + return nil +} + +func (x *ProtocolMessage) GetAppStateSyncKeyShare() *AppStateSyncKeyShare { + if x != nil { + return x.AppStateSyncKeyShare + } + return nil +} + +func (x *ProtocolMessage) GetAppStateSyncKeyRequest() *AppStateSyncKeyRequest { + if x != nil { + return x.AppStateSyncKeyRequest + } + return nil +} + +func (x *ProtocolMessage) GetInitialSecurityNotificationSettingSync() *InitialSecurityNotificationSettingSync { + if x != nil { + return x.InitialSecurityNotificationSettingSync + } + return nil +} + +func (x *ProtocolMessage) GetAppStateFatalExceptionNotification() *AppStateFatalExceptionNotification { + if x != nil { + return x.AppStateFatalExceptionNotification + } + return nil +} + +type HistorySyncNotification struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + FileSha256 []byte `protobuf:"bytes,1,opt,name=fileSha256" json:"fileSha256,omitempty"` + FileLength *uint64 `protobuf:"varint,2,opt,name=fileLength" json:"fileLength,omitempty"` + MediaKey []byte `protobuf:"bytes,3,opt,name=mediaKey" json:"mediaKey,omitempty"` + FileEncSha256 []byte `protobuf:"bytes,4,opt,name=fileEncSha256" json:"fileEncSha256,omitempty"` + DirectPath *string `protobuf:"bytes,5,opt,name=directPath" json:"directPath,omitempty"` + SyncType *HistorySyncNotification_HistorySyncNotificationHistorySyncType `protobuf:"varint,6,opt,name=syncType,enum=proto.HistorySyncNotification_HistorySyncNotificationHistorySyncType" json:"syncType,omitempty"` + ChunkOrder *uint32 `protobuf:"varint,7,opt,name=chunkOrder" json:"chunkOrder,omitempty"` + OriginalMessageId *string `protobuf:"bytes,8,opt,name=originalMessageId" json:"originalMessageId,omitempty"` +} + +func (x *HistorySyncNotification) Reset() { + *x = HistorySyncNotification{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HistorySyncNotification) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HistorySyncNotification) ProtoMessage() {} + +func (x *HistorySyncNotification) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[29] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HistorySyncNotification.ProtoReflect.Descriptor instead. +func (*HistorySyncNotification) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{29} +} + +func (x *HistorySyncNotification) GetFileSha256() []byte { + if x != nil { + return x.FileSha256 + } + return nil +} + +func (x *HistorySyncNotification) GetFileLength() uint64 { + if x != nil && x.FileLength != nil { + return *x.FileLength + } + return 0 +} + +func (x *HistorySyncNotification) GetMediaKey() []byte { + if x != nil { + return x.MediaKey + } + return nil +} + +func (x *HistorySyncNotification) GetFileEncSha256() []byte { + if x != nil { + return x.FileEncSha256 + } + return nil +} + +func (x *HistorySyncNotification) GetDirectPath() string { + if x != nil && x.DirectPath != nil { + return *x.DirectPath + } + return "" +} + +func (x *HistorySyncNotification) GetSyncType() HistorySyncNotification_HistorySyncNotificationHistorySyncType { + if x != nil && x.SyncType != nil { + return *x.SyncType + } + return HistorySyncNotification_INITIAL_BOOTSTRAP +} + +func (x *HistorySyncNotification) GetChunkOrder() uint32 { + if x != nil && x.ChunkOrder != nil { + return *x.ChunkOrder + } + return 0 +} + +func (x *HistorySyncNotification) GetOriginalMessageId() string { + if x != nil && x.OriginalMessageId != nil { + return *x.OriginalMessageId + } + return "" +} + +type AppStateSyncKey struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + KeyId *AppStateSyncKeyId `protobuf:"bytes,1,opt,name=keyId" json:"keyId,omitempty"` + KeyData *AppStateSyncKeyData `protobuf:"bytes,2,opt,name=keyData" json:"keyData,omitempty"` +} + +func (x *AppStateSyncKey) Reset() { + *x = AppStateSyncKey{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AppStateSyncKey) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AppStateSyncKey) ProtoMessage() {} + +func (x *AppStateSyncKey) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[30] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AppStateSyncKey.ProtoReflect.Descriptor instead. +func (*AppStateSyncKey) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{30} +} + +func (x *AppStateSyncKey) GetKeyId() *AppStateSyncKeyId { + if x != nil { + return x.KeyId + } + return nil +} + +func (x *AppStateSyncKey) GetKeyData() *AppStateSyncKeyData { + if x != nil { + return x.KeyData + } + return nil +} + +type AppStateSyncKeyId struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + KeyId []byte `protobuf:"bytes,1,opt,name=keyId" json:"keyId,omitempty"` +} + +func (x *AppStateSyncKeyId) Reset() { + *x = AppStateSyncKeyId{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AppStateSyncKeyId) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AppStateSyncKeyId) ProtoMessage() {} + +func (x *AppStateSyncKeyId) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[31] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AppStateSyncKeyId.ProtoReflect.Descriptor instead. +func (*AppStateSyncKeyId) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{31} +} + +func (x *AppStateSyncKeyId) GetKeyId() []byte { + if x != nil { + return x.KeyId + } + return nil +} + +type AppStateSyncKeyFingerprint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RawId *uint32 `protobuf:"varint,1,opt,name=rawId" json:"rawId,omitempty"` + CurrentIndex *uint32 `protobuf:"varint,2,opt,name=currentIndex" json:"currentIndex,omitempty"` + DeviceIndexes []uint32 `protobuf:"varint,3,rep,packed,name=deviceIndexes" json:"deviceIndexes,omitempty"` +} + +func (x *AppStateSyncKeyFingerprint) Reset() { + *x = AppStateSyncKeyFingerprint{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AppStateSyncKeyFingerprint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AppStateSyncKeyFingerprint) ProtoMessage() {} + +func (x *AppStateSyncKeyFingerprint) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[32] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AppStateSyncKeyFingerprint.ProtoReflect.Descriptor instead. +func (*AppStateSyncKeyFingerprint) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{32} +} + +func (x *AppStateSyncKeyFingerprint) GetRawId() uint32 { + if x != nil && x.RawId != nil { + return *x.RawId + } + return 0 +} + +func (x *AppStateSyncKeyFingerprint) GetCurrentIndex() uint32 { + if x != nil && x.CurrentIndex != nil { + return *x.CurrentIndex + } + return 0 +} + +func (x *AppStateSyncKeyFingerprint) GetDeviceIndexes() []uint32 { + if x != nil { + return x.DeviceIndexes + } + return nil +} + +type AppStateSyncKeyData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + KeyData []byte `protobuf:"bytes,1,opt,name=keyData" json:"keyData,omitempty"` + Fingerprint *AppStateSyncKeyFingerprint `protobuf:"bytes,2,opt,name=fingerprint" json:"fingerprint,omitempty"` + Timestamp *int64 `protobuf:"varint,3,opt,name=timestamp" json:"timestamp,omitempty"` +} + +func (x *AppStateSyncKeyData) Reset() { + *x = AppStateSyncKeyData{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AppStateSyncKeyData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AppStateSyncKeyData) ProtoMessage() {} + +func (x *AppStateSyncKeyData) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[33] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AppStateSyncKeyData.ProtoReflect.Descriptor instead. +func (*AppStateSyncKeyData) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{33} +} + +func (x *AppStateSyncKeyData) GetKeyData() []byte { + if x != nil { + return x.KeyData + } + return nil +} + +func (x *AppStateSyncKeyData) GetFingerprint() *AppStateSyncKeyFingerprint { + if x != nil { + return x.Fingerprint + } + return nil +} + +func (x *AppStateSyncKeyData) GetTimestamp() int64 { + if x != nil && x.Timestamp != nil { + return *x.Timestamp + } + return 0 +} + +type AppStateSyncKeyShare struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Keys []*AppStateSyncKey `protobuf:"bytes,1,rep,name=keys" json:"keys,omitempty"` +} + +func (x *AppStateSyncKeyShare) Reset() { + *x = AppStateSyncKeyShare{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AppStateSyncKeyShare) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AppStateSyncKeyShare) ProtoMessage() {} + +func (x *AppStateSyncKeyShare) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[34] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AppStateSyncKeyShare.ProtoReflect.Descriptor instead. +func (*AppStateSyncKeyShare) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{34} +} + +func (x *AppStateSyncKeyShare) GetKeys() []*AppStateSyncKey { + if x != nil { + return x.Keys + } + return nil +} + +type AppStateSyncKeyRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + KeyIds []*AppStateSyncKeyId `protobuf:"bytes,1,rep,name=keyIds" json:"keyIds,omitempty"` +} + +func (x *AppStateSyncKeyRequest) Reset() { + *x = AppStateSyncKeyRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AppStateSyncKeyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AppStateSyncKeyRequest) ProtoMessage() {} + +func (x *AppStateSyncKeyRequest) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[35] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AppStateSyncKeyRequest.ProtoReflect.Descriptor instead. +func (*AppStateSyncKeyRequest) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{35} +} + +func (x *AppStateSyncKeyRequest) GetKeyIds() []*AppStateSyncKeyId { + if x != nil { + return x.KeyIds + } + return nil +} + +type AppStateFatalExceptionNotification struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + CollectionNames []string `protobuf:"bytes,1,rep,name=collectionNames" json:"collectionNames,omitempty"` + Timestamp *int64 `protobuf:"varint,2,opt,name=timestamp" json:"timestamp,omitempty"` +} + +func (x *AppStateFatalExceptionNotification) Reset() { + *x = AppStateFatalExceptionNotification{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AppStateFatalExceptionNotification) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AppStateFatalExceptionNotification) ProtoMessage() {} + +func (x *AppStateFatalExceptionNotification) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[36] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AppStateFatalExceptionNotification.ProtoReflect.Descriptor instead. +func (*AppStateFatalExceptionNotification) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{36} +} + +func (x *AppStateFatalExceptionNotification) GetCollectionNames() []string { + if x != nil { + return x.CollectionNames + } + return nil +} + +func (x *AppStateFatalExceptionNotification) GetTimestamp() int64 { + if x != nil && x.Timestamp != nil { + return *x.Timestamp + } + return 0 +} + +type InitialSecurityNotificationSettingSync struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SecurityNotificationEnabled *bool `protobuf:"varint,1,opt,name=securityNotificationEnabled" json:"securityNotificationEnabled,omitempty"` +} + +func (x *InitialSecurityNotificationSettingSync) Reset() { + *x = InitialSecurityNotificationSettingSync{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *InitialSecurityNotificationSettingSync) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*InitialSecurityNotificationSettingSync) ProtoMessage() {} + +func (x *InitialSecurityNotificationSettingSync) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[37] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use InitialSecurityNotificationSettingSync.ProtoReflect.Descriptor instead. +func (*InitialSecurityNotificationSettingSync) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{37} +} + +func (x *InitialSecurityNotificationSettingSync) GetSecurityNotificationEnabled() bool { + if x != nil && x.SecurityNotificationEnabled != nil { + return *x.SecurityNotificationEnabled + } + return false +} + +type ContactsArrayMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DisplayName *string `protobuf:"bytes,1,opt,name=displayName" json:"displayName,omitempty"` + Contacts []*ContactMessage `protobuf:"bytes,2,rep,name=contacts" json:"contacts,omitempty"` + ContextInfo *ContextInfo `protobuf:"bytes,17,opt,name=contextInfo" json:"contextInfo,omitempty"` +} + +func (x *ContactsArrayMessage) Reset() { + *x = ContactsArrayMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ContactsArrayMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContactsArrayMessage) ProtoMessage() {} + +func (x *ContactsArrayMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[38] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContactsArrayMessage.ProtoReflect.Descriptor instead. +func (*ContactsArrayMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{38} +} + +func (x *ContactsArrayMessage) GetDisplayName() string { + if x != nil && x.DisplayName != nil { + return *x.DisplayName + } + return "" +} + +func (x *ContactsArrayMessage) GetContacts() []*ContactMessage { + if x != nil { + return x.Contacts + } + return nil +} + +func (x *ContactsArrayMessage) GetContextInfo() *ContextInfo { + if x != nil { + return x.ContextInfo + } + return nil +} + +type HSMCurrency struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + CurrencyCode *string `protobuf:"bytes,1,opt,name=currencyCode" json:"currencyCode,omitempty"` + Amount1000 *int64 `protobuf:"varint,2,opt,name=amount1000" json:"amount1000,omitempty"` +} + +func (x *HSMCurrency) Reset() { + *x = HSMCurrency{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HSMCurrency) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HSMCurrency) ProtoMessage() {} + +func (x *HSMCurrency) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[39] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HSMCurrency.ProtoReflect.Descriptor instead. +func (*HSMCurrency) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{39} +} + +func (x *HSMCurrency) GetCurrencyCode() string { + if x != nil && x.CurrencyCode != nil { + return *x.CurrencyCode + } + return "" +} + +func (x *HSMCurrency) GetAmount1000() int64 { + if x != nil && x.Amount1000 != nil { + return *x.Amount1000 + } + return 0 +} + +type HSMDateTimeComponent struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DayOfWeek *HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType `protobuf:"varint,1,opt,name=dayOfWeek,enum=proto.HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType" json:"dayOfWeek,omitempty"` + Year *uint32 `protobuf:"varint,2,opt,name=year" json:"year,omitempty"` + Month *uint32 `protobuf:"varint,3,opt,name=month" json:"month,omitempty"` + DayOfMonth *uint32 `protobuf:"varint,4,opt,name=dayOfMonth" json:"dayOfMonth,omitempty"` + Hour *uint32 `protobuf:"varint,5,opt,name=hour" json:"hour,omitempty"` + Minute *uint32 `protobuf:"varint,6,opt,name=minute" json:"minute,omitempty"` + Calendar *HSMDateTimeComponent_HSMDateTimeComponentCalendarType `protobuf:"varint,7,opt,name=calendar,enum=proto.HSMDateTimeComponent_HSMDateTimeComponentCalendarType" json:"calendar,omitempty"` +} + +func (x *HSMDateTimeComponent) Reset() { + *x = HSMDateTimeComponent{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HSMDateTimeComponent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HSMDateTimeComponent) ProtoMessage() {} + +func (x *HSMDateTimeComponent) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[40] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HSMDateTimeComponent.ProtoReflect.Descriptor instead. +func (*HSMDateTimeComponent) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{40} +} + +func (x *HSMDateTimeComponent) GetDayOfWeek() HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType { + if x != nil && x.DayOfWeek != nil { + return *x.DayOfWeek + } + return HSMDateTimeComponent_MONDAY +} + +func (x *HSMDateTimeComponent) GetYear() uint32 { + if x != nil && x.Year != nil { + return *x.Year + } + return 0 +} + +func (x *HSMDateTimeComponent) GetMonth() uint32 { + if x != nil && x.Month != nil { + return *x.Month + } + return 0 +} + +func (x *HSMDateTimeComponent) GetDayOfMonth() uint32 { + if x != nil && x.DayOfMonth != nil { + return *x.DayOfMonth + } + return 0 +} + +func (x *HSMDateTimeComponent) GetHour() uint32 { + if x != nil && x.Hour != nil { + return *x.Hour + } + return 0 +} + +func (x *HSMDateTimeComponent) GetMinute() uint32 { + if x != nil && x.Minute != nil { + return *x.Minute + } + return 0 +} + +func (x *HSMDateTimeComponent) GetCalendar() HSMDateTimeComponent_HSMDateTimeComponentCalendarType { + if x != nil && x.Calendar != nil { + return *x.Calendar + } + return HSMDateTimeComponent_GREGORIAN +} + +type HSMDateTimeUnixEpoch struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Timestamp *int64 `protobuf:"varint,1,opt,name=timestamp" json:"timestamp,omitempty"` +} + +func (x *HSMDateTimeUnixEpoch) Reset() { + *x = HSMDateTimeUnixEpoch{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HSMDateTimeUnixEpoch) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HSMDateTimeUnixEpoch) ProtoMessage() {} + +func (x *HSMDateTimeUnixEpoch) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[41] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HSMDateTimeUnixEpoch.ProtoReflect.Descriptor instead. +func (*HSMDateTimeUnixEpoch) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{41} +} + +func (x *HSMDateTimeUnixEpoch) GetTimestamp() int64 { + if x != nil && x.Timestamp != nil { + return *x.Timestamp + } + return 0 +} + +type HSMDateTime struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to DatetimeOneof: + // *HSMDateTime_Component + // *HSMDateTime_UnixEpoch + DatetimeOneof isHSMDateTime_DatetimeOneof `protobuf_oneof:"datetimeOneof"` +} + +func (x *HSMDateTime) Reset() { + *x = HSMDateTime{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HSMDateTime) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HSMDateTime) ProtoMessage() {} + +func (x *HSMDateTime) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[42] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HSMDateTime.ProtoReflect.Descriptor instead. +func (*HSMDateTime) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{42} +} + +func (m *HSMDateTime) GetDatetimeOneof() isHSMDateTime_DatetimeOneof { + if m != nil { + return m.DatetimeOneof + } + return nil +} + +func (x *HSMDateTime) GetComponent() *HSMDateTimeComponent { + if x, ok := x.GetDatetimeOneof().(*HSMDateTime_Component); ok { + return x.Component + } + return nil +} + +func (x *HSMDateTime) GetUnixEpoch() *HSMDateTimeUnixEpoch { + if x, ok := x.GetDatetimeOneof().(*HSMDateTime_UnixEpoch); ok { + return x.UnixEpoch + } + return nil +} + +type isHSMDateTime_DatetimeOneof interface { + isHSMDateTime_DatetimeOneof() +} + +type HSMDateTime_Component struct { + Component *HSMDateTimeComponent `protobuf:"bytes,1,opt,name=component,oneof"` +} + +type HSMDateTime_UnixEpoch struct { + UnixEpoch *HSMDateTimeUnixEpoch `protobuf:"bytes,2,opt,name=unixEpoch,oneof"` +} + +func (*HSMDateTime_Component) isHSMDateTime_DatetimeOneof() {} + +func (*HSMDateTime_UnixEpoch) isHSMDateTime_DatetimeOneof() {} + +type HSMLocalizableParameter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Default *string `protobuf:"bytes,1,opt,name=default" json:"default,omitempty"` + // Types that are assignable to ParamOneof: + // *HSMLocalizableParameter_Currency + // *HSMLocalizableParameter_DateTime + ParamOneof isHSMLocalizableParameter_ParamOneof `protobuf_oneof:"paramOneof"` +} + +func (x *HSMLocalizableParameter) Reset() { + *x = HSMLocalizableParameter{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[43] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HSMLocalizableParameter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HSMLocalizableParameter) ProtoMessage() {} + +func (x *HSMLocalizableParameter) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[43] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HSMLocalizableParameter.ProtoReflect.Descriptor instead. +func (*HSMLocalizableParameter) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{43} +} + +func (x *HSMLocalizableParameter) GetDefault() string { + if x != nil && x.Default != nil { + return *x.Default + } + return "" +} + +func (m *HSMLocalizableParameter) GetParamOneof() isHSMLocalizableParameter_ParamOneof { + if m != nil { + return m.ParamOneof + } + return nil +} + +func (x *HSMLocalizableParameter) GetCurrency() *HSMCurrency { + if x, ok := x.GetParamOneof().(*HSMLocalizableParameter_Currency); ok { + return x.Currency + } + return nil +} + +func (x *HSMLocalizableParameter) GetDateTime() *HSMDateTime { + if x, ok := x.GetParamOneof().(*HSMLocalizableParameter_DateTime); ok { + return x.DateTime + } + return nil +} + +type isHSMLocalizableParameter_ParamOneof interface { + isHSMLocalizableParameter_ParamOneof() +} + +type HSMLocalizableParameter_Currency struct { + Currency *HSMCurrency `protobuf:"bytes,2,opt,name=currency,oneof"` +} + +type HSMLocalizableParameter_DateTime struct { + DateTime *HSMDateTime `protobuf:"bytes,3,opt,name=dateTime,oneof"` +} + +func (*HSMLocalizableParameter_Currency) isHSMLocalizableParameter_ParamOneof() {} + +func (*HSMLocalizableParameter_DateTime) isHSMLocalizableParameter_ParamOneof() {} + +type HighlyStructuredMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Namespace *string `protobuf:"bytes,1,opt,name=namespace" json:"namespace,omitempty"` + ElementName *string `protobuf:"bytes,2,opt,name=elementName" json:"elementName,omitempty"` + Params []string `protobuf:"bytes,3,rep,name=params" json:"params,omitempty"` + FallbackLg *string `protobuf:"bytes,4,opt,name=fallbackLg" json:"fallbackLg,omitempty"` + FallbackLc *string `protobuf:"bytes,5,opt,name=fallbackLc" json:"fallbackLc,omitempty"` + LocalizableParams []*HSMLocalizableParameter `protobuf:"bytes,6,rep,name=localizableParams" json:"localizableParams,omitempty"` + DeterministicLg *string `protobuf:"bytes,7,opt,name=deterministicLg" json:"deterministicLg,omitempty"` + DeterministicLc *string `protobuf:"bytes,8,opt,name=deterministicLc" json:"deterministicLc,omitempty"` + HydratedHsm *TemplateMessage `protobuf:"bytes,9,opt,name=hydratedHsm" json:"hydratedHsm,omitempty"` +} + +func (x *HighlyStructuredMessage) Reset() { + *x = HighlyStructuredMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[44] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HighlyStructuredMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HighlyStructuredMessage) ProtoMessage() {} + +func (x *HighlyStructuredMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[44] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HighlyStructuredMessage.ProtoReflect.Descriptor instead. +func (*HighlyStructuredMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{44} +} + +func (x *HighlyStructuredMessage) GetNamespace() string { + if x != nil && x.Namespace != nil { + return *x.Namespace + } + return "" +} + +func (x *HighlyStructuredMessage) GetElementName() string { + if x != nil && x.ElementName != nil { + return *x.ElementName + } + return "" +} + +func (x *HighlyStructuredMessage) GetParams() []string { + if x != nil { + return x.Params + } + return nil +} + +func (x *HighlyStructuredMessage) GetFallbackLg() string { + if x != nil && x.FallbackLg != nil { + return *x.FallbackLg + } + return "" +} + +func (x *HighlyStructuredMessage) GetFallbackLc() string { + if x != nil && x.FallbackLc != nil { + return *x.FallbackLc + } + return "" +} + +func (x *HighlyStructuredMessage) GetLocalizableParams() []*HSMLocalizableParameter { + if x != nil { + return x.LocalizableParams + } + return nil +} + +func (x *HighlyStructuredMessage) GetDeterministicLg() string { + if x != nil && x.DeterministicLg != nil { + return *x.DeterministicLg + } + return "" +} + +func (x *HighlyStructuredMessage) GetDeterministicLc() string { + if x != nil && x.DeterministicLc != nil { + return *x.DeterministicLc + } + return "" +} + +func (x *HighlyStructuredMessage) GetHydratedHsm() *TemplateMessage { + if x != nil { + return x.HydratedHsm + } + return nil +} + +type SendPaymentMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NoteMessage *Message `protobuf:"bytes,2,opt,name=noteMessage" json:"noteMessage,omitempty"` + RequestMessageKey *MessageKey `protobuf:"bytes,3,opt,name=requestMessageKey" json:"requestMessageKey,omitempty"` +} + +func (x *SendPaymentMessage) Reset() { + *x = SendPaymentMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SendPaymentMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SendPaymentMessage) ProtoMessage() {} + +func (x *SendPaymentMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[45] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SendPaymentMessage.ProtoReflect.Descriptor instead. +func (*SendPaymentMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{45} +} + +func (x *SendPaymentMessage) GetNoteMessage() *Message { + if x != nil { + return x.NoteMessage + } + return nil +} + +func (x *SendPaymentMessage) GetRequestMessageKey() *MessageKey { + if x != nil { + return x.RequestMessageKey + } + return nil +} + +type RequestPaymentMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NoteMessage *Message `protobuf:"bytes,4,opt,name=noteMessage" json:"noteMessage,omitempty"` + CurrencyCodeIso4217 *string `protobuf:"bytes,1,opt,name=currencyCodeIso4217" json:"currencyCodeIso4217,omitempty"` + Amount1000 *uint64 `protobuf:"varint,2,opt,name=amount1000" json:"amount1000,omitempty"` + RequestFrom *string `protobuf:"bytes,3,opt,name=requestFrom" json:"requestFrom,omitempty"` + ExpiryTimestamp *int64 `protobuf:"varint,5,opt,name=expiryTimestamp" json:"expiryTimestamp,omitempty"` + Amount *PaymentMoney `protobuf:"bytes,6,opt,name=amount" json:"amount,omitempty"` +} + +func (x *RequestPaymentMessage) Reset() { + *x = RequestPaymentMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[46] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RequestPaymentMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RequestPaymentMessage) ProtoMessage() {} + +func (x *RequestPaymentMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[46] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RequestPaymentMessage.ProtoReflect.Descriptor instead. +func (*RequestPaymentMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{46} +} + +func (x *RequestPaymentMessage) GetNoteMessage() *Message { + if x != nil { + return x.NoteMessage + } + return nil +} + +func (x *RequestPaymentMessage) GetCurrencyCodeIso4217() string { + if x != nil && x.CurrencyCodeIso4217 != nil { + return *x.CurrencyCodeIso4217 + } + return "" +} + +func (x *RequestPaymentMessage) GetAmount1000() uint64 { + if x != nil && x.Amount1000 != nil { + return *x.Amount1000 + } + return 0 +} + +func (x *RequestPaymentMessage) GetRequestFrom() string { + if x != nil && x.RequestFrom != nil { + return *x.RequestFrom + } + return "" +} + +func (x *RequestPaymentMessage) GetExpiryTimestamp() int64 { + if x != nil && x.ExpiryTimestamp != nil { + return *x.ExpiryTimestamp + } + return 0 +} + +func (x *RequestPaymentMessage) GetAmount() *PaymentMoney { + if x != nil { + return x.Amount + } + return nil +} + +type DeclinePaymentRequestMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key *MessageKey `protobuf:"bytes,1,opt,name=key" json:"key,omitempty"` +} + +func (x *DeclinePaymentRequestMessage) Reset() { + *x = DeclinePaymentRequestMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[47] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeclinePaymentRequestMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeclinePaymentRequestMessage) ProtoMessage() {} + +func (x *DeclinePaymentRequestMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[47] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeclinePaymentRequestMessage.ProtoReflect.Descriptor instead. +func (*DeclinePaymentRequestMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{47} +} + +func (x *DeclinePaymentRequestMessage) GetKey() *MessageKey { + if x != nil { + return x.Key + } + return nil +} + +type CancelPaymentRequestMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key *MessageKey `protobuf:"bytes,1,opt,name=key" json:"key,omitempty"` +} + +func (x *CancelPaymentRequestMessage) Reset() { + *x = CancelPaymentRequestMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[48] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CancelPaymentRequestMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CancelPaymentRequestMessage) ProtoMessage() {} + +func (x *CancelPaymentRequestMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[48] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CancelPaymentRequestMessage.ProtoReflect.Descriptor instead. +func (*CancelPaymentRequestMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{48} +} + +func (x *CancelPaymentRequestMessage) GetKey() *MessageKey { + if x != nil { + return x.Key + } + return nil +} + +type LiveLocationMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DegreesLatitude *float64 `protobuf:"fixed64,1,opt,name=degreesLatitude" json:"degreesLatitude,omitempty"` + DegreesLongitude *float64 `protobuf:"fixed64,2,opt,name=degreesLongitude" json:"degreesLongitude,omitempty"` + AccuracyInMeters *uint32 `protobuf:"varint,3,opt,name=accuracyInMeters" json:"accuracyInMeters,omitempty"` + SpeedInMps *float32 `protobuf:"fixed32,4,opt,name=speedInMps" json:"speedInMps,omitempty"` + DegreesClockwiseFromMagneticNorth *uint32 `protobuf:"varint,5,opt,name=degreesClockwiseFromMagneticNorth" json:"degreesClockwiseFromMagneticNorth,omitempty"` + Caption *string `protobuf:"bytes,6,opt,name=caption" json:"caption,omitempty"` + SequenceNumber *int64 `protobuf:"varint,7,opt,name=sequenceNumber" json:"sequenceNumber,omitempty"` + TimeOffset *uint32 `protobuf:"varint,8,opt,name=timeOffset" json:"timeOffset,omitempty"` + JpegThumbnail []byte `protobuf:"bytes,16,opt,name=jpegThumbnail" json:"jpegThumbnail,omitempty"` + ContextInfo *ContextInfo `protobuf:"bytes,17,opt,name=contextInfo" json:"contextInfo,omitempty"` +} + +func (x *LiveLocationMessage) Reset() { + *x = LiveLocationMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[49] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LiveLocationMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LiveLocationMessage) ProtoMessage() {} + +func (x *LiveLocationMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[49] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LiveLocationMessage.ProtoReflect.Descriptor instead. +func (*LiveLocationMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{49} +} + +func (x *LiveLocationMessage) GetDegreesLatitude() float64 { + if x != nil && x.DegreesLatitude != nil { + return *x.DegreesLatitude + } + return 0 +} + +func (x *LiveLocationMessage) GetDegreesLongitude() float64 { + if x != nil && x.DegreesLongitude != nil { + return *x.DegreesLongitude + } + return 0 +} + +func (x *LiveLocationMessage) GetAccuracyInMeters() uint32 { + if x != nil && x.AccuracyInMeters != nil { + return *x.AccuracyInMeters + } + return 0 +} + +func (x *LiveLocationMessage) GetSpeedInMps() float32 { + if x != nil && x.SpeedInMps != nil { + return *x.SpeedInMps + } + return 0 +} + +func (x *LiveLocationMessage) GetDegreesClockwiseFromMagneticNorth() uint32 { + if x != nil && x.DegreesClockwiseFromMagneticNorth != nil { + return *x.DegreesClockwiseFromMagneticNorth + } + return 0 +} + +func (x *LiveLocationMessage) GetCaption() string { + if x != nil && x.Caption != nil { + return *x.Caption + } + return "" +} + +func (x *LiveLocationMessage) GetSequenceNumber() int64 { + if x != nil && x.SequenceNumber != nil { + return *x.SequenceNumber + } + return 0 +} + +func (x *LiveLocationMessage) GetTimeOffset() uint32 { + if x != nil && x.TimeOffset != nil { + return *x.TimeOffset + } + return 0 +} + +func (x *LiveLocationMessage) GetJpegThumbnail() []byte { + if x != nil { + return x.JpegThumbnail + } + return nil +} + +func (x *LiveLocationMessage) GetContextInfo() *ContextInfo { + if x != nil { + return x.ContextInfo + } + return nil +} + +type StickerMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Url *string `protobuf:"bytes,1,opt,name=url" json:"url,omitempty"` + FileSha256 []byte `protobuf:"bytes,2,opt,name=fileSha256" json:"fileSha256,omitempty"` + FileEncSha256 []byte `protobuf:"bytes,3,opt,name=fileEncSha256" json:"fileEncSha256,omitempty"` + MediaKey []byte `protobuf:"bytes,4,opt,name=mediaKey" json:"mediaKey,omitempty"` + Mimetype *string `protobuf:"bytes,5,opt,name=mimetype" json:"mimetype,omitempty"` + Height *uint32 `protobuf:"varint,6,opt,name=height" json:"height,omitempty"` + Width *uint32 `protobuf:"varint,7,opt,name=width" json:"width,omitempty"` + DirectPath *string `protobuf:"bytes,8,opt,name=directPath" json:"directPath,omitempty"` + FileLength *uint64 `protobuf:"varint,9,opt,name=fileLength" json:"fileLength,omitempty"` + MediaKeyTimestamp *int64 `protobuf:"varint,10,opt,name=mediaKeyTimestamp" json:"mediaKeyTimestamp,omitempty"` + FirstFrameLength *uint32 `protobuf:"varint,11,opt,name=firstFrameLength" json:"firstFrameLength,omitempty"` + FirstFrameSidecar []byte `protobuf:"bytes,12,opt,name=firstFrameSidecar" json:"firstFrameSidecar,omitempty"` + IsAnimated *bool `protobuf:"varint,13,opt,name=isAnimated" json:"isAnimated,omitempty"` + PngThumbnail []byte `protobuf:"bytes,16,opt,name=pngThumbnail" json:"pngThumbnail,omitempty"` + ContextInfo *ContextInfo `protobuf:"bytes,17,opt,name=contextInfo" json:"contextInfo,omitempty"` +} + +func (x *StickerMessage) Reset() { + *x = StickerMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[50] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StickerMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StickerMessage) ProtoMessage() {} + +func (x *StickerMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[50] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StickerMessage.ProtoReflect.Descriptor instead. +func (*StickerMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{50} +} + +func (x *StickerMessage) GetUrl() string { + if x != nil && x.Url != nil { + return *x.Url + } + return "" +} + +func (x *StickerMessage) GetFileSha256() []byte { + if x != nil { + return x.FileSha256 + } + return nil +} + +func (x *StickerMessage) GetFileEncSha256() []byte { + if x != nil { + return x.FileEncSha256 + } + return nil +} + +func (x *StickerMessage) GetMediaKey() []byte { + if x != nil { + return x.MediaKey + } + return nil +} + +func (x *StickerMessage) GetMimetype() string { + if x != nil && x.Mimetype != nil { + return *x.Mimetype + } + return "" +} + +func (x *StickerMessage) GetHeight() uint32 { + if x != nil && x.Height != nil { + return *x.Height + } + return 0 +} + +func (x *StickerMessage) GetWidth() uint32 { + if x != nil && x.Width != nil { + return *x.Width + } + return 0 +} + +func (x *StickerMessage) GetDirectPath() string { + if x != nil && x.DirectPath != nil { + return *x.DirectPath + } + return "" +} + +func (x *StickerMessage) GetFileLength() uint64 { + if x != nil && x.FileLength != nil { + return *x.FileLength + } + return 0 +} + +func (x *StickerMessage) GetMediaKeyTimestamp() int64 { + if x != nil && x.MediaKeyTimestamp != nil { + return *x.MediaKeyTimestamp + } + return 0 +} + +func (x *StickerMessage) GetFirstFrameLength() uint32 { + if x != nil && x.FirstFrameLength != nil { + return *x.FirstFrameLength + } + return 0 +} + +func (x *StickerMessage) GetFirstFrameSidecar() []byte { + if x != nil { + return x.FirstFrameSidecar + } + return nil +} + +func (x *StickerMessage) GetIsAnimated() bool { + if x != nil && x.IsAnimated != nil { + return *x.IsAnimated + } + return false +} + +func (x *StickerMessage) GetPngThumbnail() []byte { + if x != nil { + return x.PngThumbnail + } + return nil +} + +func (x *StickerMessage) GetContextInfo() *ContextInfo { + if x != nil { + return x.ContextInfo + } + return nil +} + +type FourRowTemplate struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Content *HighlyStructuredMessage `protobuf:"bytes,6,opt,name=content" json:"content,omitempty"` + Footer *HighlyStructuredMessage `protobuf:"bytes,7,opt,name=footer" json:"footer,omitempty"` + Buttons []*TemplateButton `protobuf:"bytes,8,rep,name=buttons" json:"buttons,omitempty"` + // Types that are assignable to Title: + // *FourRowTemplate_DocumentMessage + // *FourRowTemplate_HighlyStructuredMessage + // *FourRowTemplate_ImageMessage + // *FourRowTemplate_VideoMessage + // *FourRowTemplate_LocationMessage + Title isFourRowTemplate_Title `protobuf_oneof:"title"` +} + +func (x *FourRowTemplate) Reset() { + *x = FourRowTemplate{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[51] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FourRowTemplate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FourRowTemplate) ProtoMessage() {} + +func (x *FourRowTemplate) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[51] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FourRowTemplate.ProtoReflect.Descriptor instead. +func (*FourRowTemplate) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{51} +} + +func (x *FourRowTemplate) GetContent() *HighlyStructuredMessage { + if x != nil { + return x.Content + } + return nil +} + +func (x *FourRowTemplate) GetFooter() *HighlyStructuredMessage { + if x != nil { + return x.Footer + } + return nil +} + +func (x *FourRowTemplate) GetButtons() []*TemplateButton { + if x != nil { + return x.Buttons + } + return nil +} + +func (m *FourRowTemplate) GetTitle() isFourRowTemplate_Title { + if m != nil { + return m.Title + } + return nil +} + +func (x *FourRowTemplate) GetDocumentMessage() *DocumentMessage { + if x, ok := x.GetTitle().(*FourRowTemplate_DocumentMessage); ok { + return x.DocumentMessage + } + return nil +} + +func (x *FourRowTemplate) GetHighlyStructuredMessage() *HighlyStructuredMessage { + if x, ok := x.GetTitle().(*FourRowTemplate_HighlyStructuredMessage); ok { + return x.HighlyStructuredMessage + } + return nil +} + +func (x *FourRowTemplate) GetImageMessage() *ImageMessage { + if x, ok := x.GetTitle().(*FourRowTemplate_ImageMessage); ok { + return x.ImageMessage + } + return nil +} + +func (x *FourRowTemplate) GetVideoMessage() *VideoMessage { + if x, ok := x.GetTitle().(*FourRowTemplate_VideoMessage); ok { + return x.VideoMessage + } + return nil +} + +func (x *FourRowTemplate) GetLocationMessage() *LocationMessage { + if x, ok := x.GetTitle().(*FourRowTemplate_LocationMessage); ok { + return x.LocationMessage + } + return nil +} + +type isFourRowTemplate_Title interface { + isFourRowTemplate_Title() +} + +type FourRowTemplate_DocumentMessage struct { + DocumentMessage *DocumentMessage `protobuf:"bytes,1,opt,name=documentMessage,oneof"` +} + +type FourRowTemplate_HighlyStructuredMessage struct { + HighlyStructuredMessage *HighlyStructuredMessage `protobuf:"bytes,2,opt,name=highlyStructuredMessage,oneof"` +} + +type FourRowTemplate_ImageMessage struct { + ImageMessage *ImageMessage `protobuf:"bytes,3,opt,name=imageMessage,oneof"` +} + +type FourRowTemplate_VideoMessage struct { + VideoMessage *VideoMessage `protobuf:"bytes,4,opt,name=videoMessage,oneof"` +} + +type FourRowTemplate_LocationMessage struct { + LocationMessage *LocationMessage `protobuf:"bytes,5,opt,name=locationMessage,oneof"` +} + +func (*FourRowTemplate_DocumentMessage) isFourRowTemplate_Title() {} + +func (*FourRowTemplate_HighlyStructuredMessage) isFourRowTemplate_Title() {} + +func (*FourRowTemplate_ImageMessage) isFourRowTemplate_Title() {} + +func (*FourRowTemplate_VideoMessage) isFourRowTemplate_Title() {} + +func (*FourRowTemplate_LocationMessage) isFourRowTemplate_Title() {} + +type HydratedFourRowTemplate struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + HydratedContentText *string `protobuf:"bytes,6,opt,name=hydratedContentText" json:"hydratedContentText,omitempty"` + HydratedFooterText *string `protobuf:"bytes,7,opt,name=hydratedFooterText" json:"hydratedFooterText,omitempty"` + HydratedButtons []*HydratedTemplateButton `protobuf:"bytes,8,rep,name=hydratedButtons" json:"hydratedButtons,omitempty"` + TemplateId *string `protobuf:"bytes,9,opt,name=templateId" json:"templateId,omitempty"` + // Types that are assignable to Title: + // *HydratedFourRowTemplate_DocumentMessage + // *HydratedFourRowTemplate_HydratedTitleText + // *HydratedFourRowTemplate_ImageMessage + // *HydratedFourRowTemplate_VideoMessage + // *HydratedFourRowTemplate_LocationMessage + Title isHydratedFourRowTemplate_Title `protobuf_oneof:"title"` +} + +func (x *HydratedFourRowTemplate) Reset() { + *x = HydratedFourRowTemplate{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[52] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HydratedFourRowTemplate) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HydratedFourRowTemplate) ProtoMessage() {} + +func (x *HydratedFourRowTemplate) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[52] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HydratedFourRowTemplate.ProtoReflect.Descriptor instead. +func (*HydratedFourRowTemplate) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{52} +} + +func (x *HydratedFourRowTemplate) GetHydratedContentText() string { + if x != nil && x.HydratedContentText != nil { + return *x.HydratedContentText + } + return "" +} + +func (x *HydratedFourRowTemplate) GetHydratedFooterText() string { + if x != nil && x.HydratedFooterText != nil { + return *x.HydratedFooterText + } + return "" +} + +func (x *HydratedFourRowTemplate) GetHydratedButtons() []*HydratedTemplateButton { + if x != nil { + return x.HydratedButtons + } + return nil +} + +func (x *HydratedFourRowTemplate) GetTemplateId() string { + if x != nil && x.TemplateId != nil { + return *x.TemplateId + } + return "" +} + +func (m *HydratedFourRowTemplate) GetTitle() isHydratedFourRowTemplate_Title { + if m != nil { + return m.Title + } + return nil +} + +func (x *HydratedFourRowTemplate) GetDocumentMessage() *DocumentMessage { + if x, ok := x.GetTitle().(*HydratedFourRowTemplate_DocumentMessage); ok { + return x.DocumentMessage + } + return nil +} + +func (x *HydratedFourRowTemplate) GetHydratedTitleText() string { + if x, ok := x.GetTitle().(*HydratedFourRowTemplate_HydratedTitleText); ok { + return x.HydratedTitleText + } + return "" +} + +func (x *HydratedFourRowTemplate) GetImageMessage() *ImageMessage { + if x, ok := x.GetTitle().(*HydratedFourRowTemplate_ImageMessage); ok { + return x.ImageMessage + } + return nil +} + +func (x *HydratedFourRowTemplate) GetVideoMessage() *VideoMessage { + if x, ok := x.GetTitle().(*HydratedFourRowTemplate_VideoMessage); ok { + return x.VideoMessage + } + return nil +} + +func (x *HydratedFourRowTemplate) GetLocationMessage() *LocationMessage { + if x, ok := x.GetTitle().(*HydratedFourRowTemplate_LocationMessage); ok { + return x.LocationMessage + } + return nil +} + +type isHydratedFourRowTemplate_Title interface { + isHydratedFourRowTemplate_Title() +} + +type HydratedFourRowTemplate_DocumentMessage struct { + DocumentMessage *DocumentMessage `protobuf:"bytes,1,opt,name=documentMessage,oneof"` +} + +type HydratedFourRowTemplate_HydratedTitleText struct { + HydratedTitleText string `protobuf:"bytes,2,opt,name=hydratedTitleText,oneof"` +} + +type HydratedFourRowTemplate_ImageMessage struct { + ImageMessage *ImageMessage `protobuf:"bytes,3,opt,name=imageMessage,oneof"` +} + +type HydratedFourRowTemplate_VideoMessage struct { + VideoMessage *VideoMessage `protobuf:"bytes,4,opt,name=videoMessage,oneof"` +} + +type HydratedFourRowTemplate_LocationMessage struct { + LocationMessage *LocationMessage `protobuf:"bytes,5,opt,name=locationMessage,oneof"` +} + +func (*HydratedFourRowTemplate_DocumentMessage) isHydratedFourRowTemplate_Title() {} + +func (*HydratedFourRowTemplate_HydratedTitleText) isHydratedFourRowTemplate_Title() {} + +func (*HydratedFourRowTemplate_ImageMessage) isHydratedFourRowTemplate_Title() {} + +func (*HydratedFourRowTemplate_VideoMessage) isHydratedFourRowTemplate_Title() {} + +func (*HydratedFourRowTemplate_LocationMessage) isHydratedFourRowTemplate_Title() {} + +type TemplateMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ContextInfo *ContextInfo `protobuf:"bytes,3,opt,name=contextInfo" json:"contextInfo,omitempty"` + HydratedTemplate *HydratedFourRowTemplate `protobuf:"bytes,4,opt,name=hydratedTemplate" json:"hydratedTemplate,omitempty"` + // Types that are assignable to Format: + // *TemplateMessage_FourRowTemplate + // *TemplateMessage_HydratedFourRowTemplate + Format isTemplateMessage_Format `protobuf_oneof:"format"` +} + +func (x *TemplateMessage) Reset() { + *x = TemplateMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[53] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TemplateMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TemplateMessage) ProtoMessage() {} + +func (x *TemplateMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[53] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TemplateMessage.ProtoReflect.Descriptor instead. +func (*TemplateMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{53} +} + +func (x *TemplateMessage) GetContextInfo() *ContextInfo { + if x != nil { + return x.ContextInfo + } + return nil +} + +func (x *TemplateMessage) GetHydratedTemplate() *HydratedFourRowTemplate { + if x != nil { + return x.HydratedTemplate + } + return nil +} + +func (m *TemplateMessage) GetFormat() isTemplateMessage_Format { + if m != nil { + return m.Format + } + return nil +} + +func (x *TemplateMessage) GetFourRowTemplate() *FourRowTemplate { + if x, ok := x.GetFormat().(*TemplateMessage_FourRowTemplate); ok { + return x.FourRowTemplate + } + return nil +} + +func (x *TemplateMessage) GetHydratedFourRowTemplate() *HydratedFourRowTemplate { + if x, ok := x.GetFormat().(*TemplateMessage_HydratedFourRowTemplate); ok { + return x.HydratedFourRowTemplate + } + return nil +} + +type isTemplateMessage_Format interface { + isTemplateMessage_Format() +} + +type TemplateMessage_FourRowTemplate struct { + FourRowTemplate *FourRowTemplate `protobuf:"bytes,1,opt,name=fourRowTemplate,oneof"` +} + +type TemplateMessage_HydratedFourRowTemplate struct { + HydratedFourRowTemplate *HydratedFourRowTemplate `protobuf:"bytes,2,opt,name=hydratedFourRowTemplate,oneof"` +} + +func (*TemplateMessage_FourRowTemplate) isTemplateMessage_Format() {} + +func (*TemplateMessage_HydratedFourRowTemplate) isTemplateMessage_Format() {} + +type TemplateButtonReplyMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SelectedId *string `protobuf:"bytes,1,opt,name=selectedId" json:"selectedId,omitempty"` + SelectedDisplayText *string `protobuf:"bytes,2,opt,name=selectedDisplayText" json:"selectedDisplayText,omitempty"` + ContextInfo *ContextInfo `protobuf:"bytes,3,opt,name=contextInfo" json:"contextInfo,omitempty"` + SelectedIndex *uint32 `protobuf:"varint,4,opt,name=selectedIndex" json:"selectedIndex,omitempty"` +} + +func (x *TemplateButtonReplyMessage) Reset() { + *x = TemplateButtonReplyMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[54] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TemplateButtonReplyMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TemplateButtonReplyMessage) ProtoMessage() {} + +func (x *TemplateButtonReplyMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[54] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TemplateButtonReplyMessage.ProtoReflect.Descriptor instead. +func (*TemplateButtonReplyMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{54} +} + +func (x *TemplateButtonReplyMessage) GetSelectedId() string { + if x != nil && x.SelectedId != nil { + return *x.SelectedId + } + return "" +} + +func (x *TemplateButtonReplyMessage) GetSelectedDisplayText() string { + if x != nil && x.SelectedDisplayText != nil { + return *x.SelectedDisplayText + } + return "" +} + +func (x *TemplateButtonReplyMessage) GetContextInfo() *ContextInfo { + if x != nil { + return x.ContextInfo + } + return nil +} + +func (x *TemplateButtonReplyMessage) GetSelectedIndex() uint32 { + if x != nil && x.SelectedIndex != nil { + return *x.SelectedIndex + } + return 0 +} + +type CatalogSnapshot struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + CatalogImage *ImageMessage `protobuf:"bytes,1,opt,name=catalogImage" json:"catalogImage,omitempty"` + Title *string `protobuf:"bytes,2,opt,name=title" json:"title,omitempty"` + Description *string `protobuf:"bytes,3,opt,name=description" json:"description,omitempty"` +} + +func (x *CatalogSnapshot) Reset() { + *x = CatalogSnapshot{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[55] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CatalogSnapshot) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CatalogSnapshot) ProtoMessage() {} + +func (x *CatalogSnapshot) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[55] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CatalogSnapshot.ProtoReflect.Descriptor instead. +func (*CatalogSnapshot) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{55} +} + +func (x *CatalogSnapshot) GetCatalogImage() *ImageMessage { + if x != nil { + return x.CatalogImage + } + return nil +} + +func (x *CatalogSnapshot) GetTitle() string { + if x != nil && x.Title != nil { + return *x.Title + } + return "" +} + +func (x *CatalogSnapshot) GetDescription() string { + if x != nil && x.Description != nil { + return *x.Description + } + return "" +} + +type ProductSnapshot struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ProductImage *ImageMessage `protobuf:"bytes,1,opt,name=productImage" json:"productImage,omitempty"` + ProductId *string `protobuf:"bytes,2,opt,name=productId" json:"productId,omitempty"` + Title *string `protobuf:"bytes,3,opt,name=title" json:"title,omitempty"` + Description *string `protobuf:"bytes,4,opt,name=description" json:"description,omitempty"` + CurrencyCode *string `protobuf:"bytes,5,opt,name=currencyCode" json:"currencyCode,omitempty"` + PriceAmount1000 *int64 `protobuf:"varint,6,opt,name=priceAmount1000" json:"priceAmount1000,omitempty"` + RetailerId *string `protobuf:"bytes,7,opt,name=retailerId" json:"retailerId,omitempty"` + Url *string `protobuf:"bytes,8,opt,name=url" json:"url,omitempty"` + ProductImageCount *uint32 `protobuf:"varint,9,opt,name=productImageCount" json:"productImageCount,omitempty"` + FirstImageId *string `protobuf:"bytes,11,opt,name=firstImageId" json:"firstImageId,omitempty"` +} + +func (x *ProductSnapshot) Reset() { + *x = ProductSnapshot{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[56] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProductSnapshot) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProductSnapshot) ProtoMessage() {} + +func (x *ProductSnapshot) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[56] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProductSnapshot.ProtoReflect.Descriptor instead. +func (*ProductSnapshot) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{56} +} + +func (x *ProductSnapshot) GetProductImage() *ImageMessage { + if x != nil { + return x.ProductImage + } + return nil +} + +func (x *ProductSnapshot) GetProductId() string { + if x != nil && x.ProductId != nil { + return *x.ProductId + } + return "" +} + +func (x *ProductSnapshot) GetTitle() string { + if x != nil && x.Title != nil { + return *x.Title + } + return "" +} + +func (x *ProductSnapshot) GetDescription() string { + if x != nil && x.Description != nil { + return *x.Description + } + return "" +} + +func (x *ProductSnapshot) GetCurrencyCode() string { + if x != nil && x.CurrencyCode != nil { + return *x.CurrencyCode + } + return "" +} + +func (x *ProductSnapshot) GetPriceAmount1000() int64 { + if x != nil && x.PriceAmount1000 != nil { + return *x.PriceAmount1000 + } + return 0 +} + +func (x *ProductSnapshot) GetRetailerId() string { + if x != nil && x.RetailerId != nil { + return *x.RetailerId + } + return "" +} + +func (x *ProductSnapshot) GetUrl() string { + if x != nil && x.Url != nil { + return *x.Url + } + return "" +} + +func (x *ProductSnapshot) GetProductImageCount() uint32 { + if x != nil && x.ProductImageCount != nil { + return *x.ProductImageCount + } + return 0 +} + +func (x *ProductSnapshot) GetFirstImageId() string { + if x != nil && x.FirstImageId != nil { + return *x.FirstImageId + } + return "" +} + +type ProductMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Product *ProductSnapshot `protobuf:"bytes,1,opt,name=product" json:"product,omitempty"` + BusinessOwnerJid *string `protobuf:"bytes,2,opt,name=businessOwnerJid" json:"businessOwnerJid,omitempty"` + Catalog *CatalogSnapshot `protobuf:"bytes,4,opt,name=catalog" json:"catalog,omitempty"` + ContextInfo *ContextInfo `protobuf:"bytes,17,opt,name=contextInfo" json:"contextInfo,omitempty"` +} + +func (x *ProductMessage) Reset() { + *x = ProductMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[57] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProductMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProductMessage) ProtoMessage() {} + +func (x *ProductMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[57] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProductMessage.ProtoReflect.Descriptor instead. +func (*ProductMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{57} +} + +func (x *ProductMessage) GetProduct() *ProductSnapshot { + if x != nil { + return x.Product + } + return nil +} + +func (x *ProductMessage) GetBusinessOwnerJid() string { + if x != nil && x.BusinessOwnerJid != nil { + return *x.BusinessOwnerJid + } + return "" +} + +func (x *ProductMessage) GetCatalog() *CatalogSnapshot { + if x != nil { + return x.Catalog + } + return nil +} + +func (x *ProductMessage) GetContextInfo() *ContextInfo { + if x != nil { + return x.ContextInfo + } + return nil +} + +type OrderMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + OrderId *string `protobuf:"bytes,1,opt,name=orderId" json:"orderId,omitempty"` + Thumbnail []byte `protobuf:"bytes,2,opt,name=thumbnail" json:"thumbnail,omitempty"` + ItemCount *int32 `protobuf:"varint,3,opt,name=itemCount" json:"itemCount,omitempty"` + Status *OrderMessage_OrderMessageOrderStatus `protobuf:"varint,4,opt,name=status,enum=proto.OrderMessage_OrderMessageOrderStatus" json:"status,omitempty"` + Surface *OrderMessage_OrderMessageOrderSurface `protobuf:"varint,5,opt,name=surface,enum=proto.OrderMessage_OrderMessageOrderSurface" json:"surface,omitempty"` + Message *string `protobuf:"bytes,6,opt,name=message" json:"message,omitempty"` + OrderTitle *string `protobuf:"bytes,7,opt,name=orderTitle" json:"orderTitle,omitempty"` + SellerJid *string `protobuf:"bytes,8,opt,name=sellerJid" json:"sellerJid,omitempty"` + Token *string `protobuf:"bytes,9,opt,name=token" json:"token,omitempty"` + TotalAmount1000 *int64 `protobuf:"varint,10,opt,name=totalAmount1000" json:"totalAmount1000,omitempty"` + TotalCurrencyCode *string `protobuf:"bytes,11,opt,name=totalCurrencyCode" json:"totalCurrencyCode,omitempty"` + ContextInfo *ContextInfo `protobuf:"bytes,17,opt,name=contextInfo" json:"contextInfo,omitempty"` +} + +func (x *OrderMessage) Reset() { + *x = OrderMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[58] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *OrderMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*OrderMessage) ProtoMessage() {} + +func (x *OrderMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[58] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use OrderMessage.ProtoReflect.Descriptor instead. +func (*OrderMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{58} +} + +func (x *OrderMessage) GetOrderId() string { + if x != nil && x.OrderId != nil { + return *x.OrderId + } + return "" +} + +func (x *OrderMessage) GetThumbnail() []byte { + if x != nil { + return x.Thumbnail + } + return nil +} + +func (x *OrderMessage) GetItemCount() int32 { + if x != nil && x.ItemCount != nil { + return *x.ItemCount + } + return 0 +} + +func (x *OrderMessage) GetStatus() OrderMessage_OrderMessageOrderStatus { + if x != nil && x.Status != nil { + return *x.Status + } + return OrderMessage_INQUIRY +} + +func (x *OrderMessage) GetSurface() OrderMessage_OrderMessageOrderSurface { + if x != nil && x.Surface != nil { + return *x.Surface + } + return OrderMessage_CATALOG +} + +func (x *OrderMessage) GetMessage() string { + if x != nil && x.Message != nil { + return *x.Message + } + return "" +} + +func (x *OrderMessage) GetOrderTitle() string { + if x != nil && x.OrderTitle != nil { + return *x.OrderTitle + } + return "" +} + +func (x *OrderMessage) GetSellerJid() string { + if x != nil && x.SellerJid != nil { + return *x.SellerJid + } + return "" +} + +func (x *OrderMessage) GetToken() string { + if x != nil && x.Token != nil { + return *x.Token + } + return "" +} + +func (x *OrderMessage) GetTotalAmount1000() int64 { + if x != nil && x.TotalAmount1000 != nil { + return *x.TotalAmount1000 + } + return 0 +} + +func (x *OrderMessage) GetTotalCurrencyCode() string { + if x != nil && x.TotalCurrencyCode != nil { + return *x.TotalCurrencyCode + } + return "" +} + +func (x *OrderMessage) GetContextInfo() *ContextInfo { + if x != nil { + return x.ContextInfo + } + return nil +} + +type Row struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Title *string `protobuf:"bytes,1,opt,name=title" json:"title,omitempty"` + Description *string `protobuf:"bytes,2,opt,name=description" json:"description,omitempty"` + RowId *string `protobuf:"bytes,3,opt,name=rowId" json:"rowId,omitempty"` +} + +func (x *Row) Reset() { + *x = Row{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[59] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Row) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Row) ProtoMessage() {} + +func (x *Row) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[59] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Row.ProtoReflect.Descriptor instead. +func (*Row) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{59} +} + +func (x *Row) GetTitle() string { + if x != nil && x.Title != nil { + return *x.Title + } + return "" +} + +func (x *Row) GetDescription() string { + if x != nil && x.Description != nil { + return *x.Description + } + return "" +} + +func (x *Row) GetRowId() string { + if x != nil && x.RowId != nil { + return *x.RowId + } + return "" +} + +type Section struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Title *string `protobuf:"bytes,1,opt,name=title" json:"title,omitempty"` + Rows []*Row `protobuf:"bytes,2,rep,name=rows" json:"rows,omitempty"` +} + +func (x *Section) Reset() { + *x = Section{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[60] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Section) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Section) ProtoMessage() {} + +func (x *Section) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[60] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Section.ProtoReflect.Descriptor instead. +func (*Section) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{60} +} + +func (x *Section) GetTitle() string { + if x != nil && x.Title != nil { + return *x.Title + } + return "" +} + +func (x *Section) GetRows() []*Row { + if x != nil { + return x.Rows + } + return nil +} + +type ListMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Title *string `protobuf:"bytes,1,opt,name=title" json:"title,omitempty"` + Description *string `protobuf:"bytes,2,opt,name=description" json:"description,omitempty"` + ButtonText *string `protobuf:"bytes,3,opt,name=buttonText" json:"buttonText,omitempty"` + ListType *ListMessage_ListMessageListType `protobuf:"varint,4,opt,name=listType,enum=proto.ListMessage_ListMessageListType" json:"listType,omitempty"` + Sections []*Section `protobuf:"bytes,5,rep,name=sections" json:"sections,omitempty"` +} + +func (x *ListMessage) Reset() { + *x = ListMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[61] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListMessage) ProtoMessage() {} + +func (x *ListMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[61] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListMessage.ProtoReflect.Descriptor instead. +func (*ListMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{61} +} + +func (x *ListMessage) GetTitle() string { + if x != nil && x.Title != nil { + return *x.Title + } + return "" +} + +func (x *ListMessage) GetDescription() string { + if x != nil && x.Description != nil { + return *x.Description + } + return "" +} + +func (x *ListMessage) GetButtonText() string { + if x != nil && x.ButtonText != nil { + return *x.ButtonText + } + return "" +} + +func (x *ListMessage) GetListType() ListMessage_ListMessageListType { + if x != nil && x.ListType != nil { + return *x.ListType + } + return ListMessage_UNKNOWN +} + +func (x *ListMessage) GetSections() []*Section { + if x != nil { + return x.Sections + } + return nil +} + +type SingleSelectReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SelectedRowId *string `protobuf:"bytes,1,opt,name=selectedRowId" json:"selectedRowId,omitempty"` +} + +func (x *SingleSelectReply) Reset() { + *x = SingleSelectReply{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[62] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SingleSelectReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SingleSelectReply) ProtoMessage() {} + +func (x *SingleSelectReply) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[62] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SingleSelectReply.ProtoReflect.Descriptor instead. +func (*SingleSelectReply) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{62} +} + +func (x *SingleSelectReply) GetSelectedRowId() string { + if x != nil && x.SelectedRowId != nil { + return *x.SelectedRowId + } + return "" +} + +type ListResponseMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Title *string `protobuf:"bytes,1,opt,name=title" json:"title,omitempty"` + ListType *ListResponseMessage_ListResponseMessageListType `protobuf:"varint,2,opt,name=listType,enum=proto.ListResponseMessage_ListResponseMessageListType" json:"listType,omitempty"` + SingleSelectReply *SingleSelectReply `protobuf:"bytes,3,opt,name=singleSelectReply" json:"singleSelectReply,omitempty"` + ContextInfo *ContextInfo `protobuf:"bytes,4,opt,name=contextInfo" json:"contextInfo,omitempty"` + Description *string `protobuf:"bytes,5,opt,name=description" json:"description,omitempty"` +} + +func (x *ListResponseMessage) Reset() { + *x = ListResponseMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[63] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListResponseMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListResponseMessage) ProtoMessage() {} + +func (x *ListResponseMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[63] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListResponseMessage.ProtoReflect.Descriptor instead. +func (*ListResponseMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{63} +} + +func (x *ListResponseMessage) GetTitle() string { + if x != nil && x.Title != nil { + return *x.Title + } + return "" +} + +func (x *ListResponseMessage) GetListType() ListResponseMessage_ListResponseMessageListType { + if x != nil && x.ListType != nil { + return *x.ListType + } + return ListResponseMessage_UNKNOWN +} + +func (x *ListResponseMessage) GetSingleSelectReply() *SingleSelectReply { + if x != nil { + return x.SingleSelectReply + } + return nil +} + +func (x *ListResponseMessage) GetContextInfo() *ContextInfo { + if x != nil { + return x.ContextInfo + } + return nil +} + +func (x *ListResponseMessage) GetDescription() string { + if x != nil && x.Description != nil { + return *x.Description + } + return "" +} + +type GroupInviteMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + GroupJid *string `protobuf:"bytes,1,opt,name=groupJid" json:"groupJid,omitempty"` + InviteCode *string `protobuf:"bytes,2,opt,name=inviteCode" json:"inviteCode,omitempty"` + InviteExpiration *int64 `protobuf:"varint,3,opt,name=inviteExpiration" json:"inviteExpiration,omitempty"` + GroupName *string `protobuf:"bytes,4,opt,name=groupName" json:"groupName,omitempty"` + JpegThumbnail []byte `protobuf:"bytes,5,opt,name=jpegThumbnail" json:"jpegThumbnail,omitempty"` + Caption *string `protobuf:"bytes,6,opt,name=caption" json:"caption,omitempty"` + ContextInfo *ContextInfo `protobuf:"bytes,7,opt,name=contextInfo" json:"contextInfo,omitempty"` +} + +func (x *GroupInviteMessage) Reset() { + *x = GroupInviteMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[64] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GroupInviteMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GroupInviteMessage) ProtoMessage() {} + +func (x *GroupInviteMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[64] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GroupInviteMessage.ProtoReflect.Descriptor instead. +func (*GroupInviteMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{64} +} + +func (x *GroupInviteMessage) GetGroupJid() string { + if x != nil && x.GroupJid != nil { + return *x.GroupJid + } + return "" +} + +func (x *GroupInviteMessage) GetInviteCode() string { + if x != nil && x.InviteCode != nil { + return *x.InviteCode + } + return "" +} + +func (x *GroupInviteMessage) GetInviteExpiration() int64 { + if x != nil && x.InviteExpiration != nil { + return *x.InviteExpiration + } + return 0 +} + +func (x *GroupInviteMessage) GetGroupName() string { + if x != nil && x.GroupName != nil { + return *x.GroupName + } + return "" +} + +func (x *GroupInviteMessage) GetJpegThumbnail() []byte { + if x != nil { + return x.JpegThumbnail + } + return nil +} + +func (x *GroupInviteMessage) GetCaption() string { + if x != nil && x.Caption != nil { + return *x.Caption + } + return "" +} + +func (x *GroupInviteMessage) GetContextInfo() *ContextInfo { + if x != nil { + return x.ContextInfo + } + return nil +} + +type EphemeralSetting struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ChatJid *string `protobuf:"bytes,1,opt,name=chatJid" json:"chatJid,omitempty"` + EphemeralExpiration *uint32 `protobuf:"varint,2,opt,name=ephemeralExpiration" json:"ephemeralExpiration,omitempty"` + EphemeralSettingTimestamp *int64 `protobuf:"varint,3,opt,name=ephemeralSettingTimestamp" json:"ephemeralSettingTimestamp,omitempty"` +} + +func (x *EphemeralSetting) Reset() { + *x = EphemeralSetting{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[65] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EphemeralSetting) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EphemeralSetting) ProtoMessage() {} + +func (x *EphemeralSetting) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[65] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EphemeralSetting.ProtoReflect.Descriptor instead. +func (*EphemeralSetting) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{65} +} + +func (x *EphemeralSetting) GetChatJid() string { + if x != nil && x.ChatJid != nil { + return *x.ChatJid + } + return "" +} + +func (x *EphemeralSetting) GetEphemeralExpiration() uint32 { + if x != nil && x.EphemeralExpiration != nil { + return *x.EphemeralExpiration + } + return 0 +} + +func (x *EphemeralSetting) GetEphemeralSettingTimestamp() int64 { + if x != nil && x.EphemeralSettingTimestamp != nil { + return *x.EphemeralSettingTimestamp + } + return 0 +} + +type DeviceSentMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DestinationJid *string `protobuf:"bytes,1,opt,name=destinationJid" json:"destinationJid,omitempty"` + Message *Message `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"` + Phash *string `protobuf:"bytes,3,opt,name=phash" json:"phash,omitempty"` + BroadcastEphemeralSettings []*EphemeralSetting `protobuf:"bytes,4,rep,name=broadcastEphemeralSettings" json:"broadcastEphemeralSettings,omitempty"` +} + +func (x *DeviceSentMessage) Reset() { + *x = DeviceSentMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[66] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeviceSentMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeviceSentMessage) ProtoMessage() {} + +func (x *DeviceSentMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[66] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeviceSentMessage.ProtoReflect.Descriptor instead. +func (*DeviceSentMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{66} +} + +func (x *DeviceSentMessage) GetDestinationJid() string { + if x != nil && x.DestinationJid != nil { + return *x.DestinationJid + } + return "" +} + +func (x *DeviceSentMessage) GetMessage() *Message { + if x != nil { + return x.Message + } + return nil +} + +func (x *DeviceSentMessage) GetPhash() string { + if x != nil && x.Phash != nil { + return *x.Phash + } + return "" +} + +func (x *DeviceSentMessage) GetBroadcastEphemeralSettings() []*EphemeralSetting { + if x != nil { + return x.BroadcastEphemeralSettings + } + return nil +} + +type FutureProofMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message *Message `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` +} + +func (x *FutureProofMessage) Reset() { + *x = FutureProofMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[67] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FutureProofMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FutureProofMessage) ProtoMessage() {} + +func (x *FutureProofMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[67] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FutureProofMessage.ProtoReflect.Descriptor instead. +func (*FutureProofMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{67} +} + +func (x *FutureProofMessage) GetMessage() *Message { + if x != nil { + return x.Message + } + return nil +} + +type ButtonText struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + DisplayText *string `protobuf:"bytes,1,opt,name=displayText" json:"displayText,omitempty"` +} + +func (x *ButtonText) Reset() { + *x = ButtonText{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[68] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ButtonText) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ButtonText) ProtoMessage() {} + +func (x *ButtonText) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[68] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ButtonText.ProtoReflect.Descriptor instead. +func (*ButtonText) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{68} +} + +func (x *ButtonText) GetDisplayText() string { + if x != nil && x.DisplayText != nil { + return *x.DisplayText + } + return "" +} + +type Button struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ButtonId *string `protobuf:"bytes,1,opt,name=buttonId" json:"buttonId,omitempty"` + ButtonText *ButtonText `protobuf:"bytes,2,opt,name=buttonText" json:"buttonText,omitempty"` + Type *Button_ButtonType `protobuf:"varint,3,opt,name=type,enum=proto.Button_ButtonType" json:"type,omitempty"` +} + +func (x *Button) Reset() { + *x = Button{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[69] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Button) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Button) ProtoMessage() {} + +func (x *Button) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[69] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Button.ProtoReflect.Descriptor instead. +func (*Button) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{69} +} + +func (x *Button) GetButtonId() string { + if x != nil && x.ButtonId != nil { + return *x.ButtonId + } + return "" +} + +func (x *Button) GetButtonText() *ButtonText { + if x != nil { + return x.ButtonText + } + return nil +} + +func (x *Button) GetType() Button_ButtonType { + if x != nil && x.Type != nil { + return *x.Type + } + return Button_UNKNOWN +} + +type ButtonsMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ContentText *string `protobuf:"bytes,6,opt,name=contentText" json:"contentText,omitempty"` + FooterText *string `protobuf:"bytes,7,opt,name=footerText" json:"footerText,omitempty"` + ContextInfo *ContextInfo `protobuf:"bytes,8,opt,name=contextInfo" json:"contextInfo,omitempty"` + Buttons []*Button `protobuf:"bytes,9,rep,name=buttons" json:"buttons,omitempty"` + HeaderType *ButtonsMessage_ButtonsMessageHeaderType `protobuf:"varint,10,opt,name=headerType,enum=proto.ButtonsMessage_ButtonsMessageHeaderType" json:"headerType,omitempty"` + // Types that are assignable to Header: + // *ButtonsMessage_Text + // *ButtonsMessage_DocumentMessage + // *ButtonsMessage_ImageMessage + // *ButtonsMessage_VideoMessage + // *ButtonsMessage_LocationMessage + Header isButtonsMessage_Header `protobuf_oneof:"header"` +} + +func (x *ButtonsMessage) Reset() { + *x = ButtonsMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[70] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ButtonsMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ButtonsMessage) ProtoMessage() {} + +func (x *ButtonsMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[70] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ButtonsMessage.ProtoReflect.Descriptor instead. +func (*ButtonsMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{70} +} + +func (x *ButtonsMessage) GetContentText() string { + if x != nil && x.ContentText != nil { + return *x.ContentText + } + return "" +} + +func (x *ButtonsMessage) GetFooterText() string { + if x != nil && x.FooterText != nil { + return *x.FooterText + } + return "" +} + +func (x *ButtonsMessage) GetContextInfo() *ContextInfo { + if x != nil { + return x.ContextInfo + } + return nil +} + +func (x *ButtonsMessage) GetButtons() []*Button { + if x != nil { + return x.Buttons + } + return nil +} + +func (x *ButtonsMessage) GetHeaderType() ButtonsMessage_ButtonsMessageHeaderType { + if x != nil && x.HeaderType != nil { + return *x.HeaderType + } + return ButtonsMessage_UNKNOWN +} + +func (m *ButtonsMessage) GetHeader() isButtonsMessage_Header { + if m != nil { + return m.Header + } + return nil +} + +func (x *ButtonsMessage) GetText() string { + if x, ok := x.GetHeader().(*ButtonsMessage_Text); ok { + return x.Text + } + return "" +} + +func (x *ButtonsMessage) GetDocumentMessage() *DocumentMessage { + if x, ok := x.GetHeader().(*ButtonsMessage_DocumentMessage); ok { + return x.DocumentMessage + } + return nil +} + +func (x *ButtonsMessage) GetImageMessage() *ImageMessage { + if x, ok := x.GetHeader().(*ButtonsMessage_ImageMessage); ok { + return x.ImageMessage + } + return nil +} + +func (x *ButtonsMessage) GetVideoMessage() *VideoMessage { + if x, ok := x.GetHeader().(*ButtonsMessage_VideoMessage); ok { + return x.VideoMessage + } + return nil +} + +func (x *ButtonsMessage) GetLocationMessage() *LocationMessage { + if x, ok := x.GetHeader().(*ButtonsMessage_LocationMessage); ok { + return x.LocationMessage + } + return nil +} + +type isButtonsMessage_Header interface { + isButtonsMessage_Header() +} + +type ButtonsMessage_Text struct { + Text string `protobuf:"bytes,1,opt,name=text,oneof"` +} + +type ButtonsMessage_DocumentMessage struct { + DocumentMessage *DocumentMessage `protobuf:"bytes,2,opt,name=documentMessage,oneof"` +} + +type ButtonsMessage_ImageMessage struct { + ImageMessage *ImageMessage `protobuf:"bytes,3,opt,name=imageMessage,oneof"` +} + +type ButtonsMessage_VideoMessage struct { + VideoMessage *VideoMessage `protobuf:"bytes,4,opt,name=videoMessage,oneof"` +} + +type ButtonsMessage_LocationMessage struct { + LocationMessage *LocationMessage `protobuf:"bytes,5,opt,name=locationMessage,oneof"` +} + +func (*ButtonsMessage_Text) isButtonsMessage_Header() {} + +func (*ButtonsMessage_DocumentMessage) isButtonsMessage_Header() {} + +func (*ButtonsMessage_ImageMessage) isButtonsMessage_Header() {} + +func (*ButtonsMessage_VideoMessage) isButtonsMessage_Header() {} + +func (*ButtonsMessage_LocationMessage) isButtonsMessage_Header() {} + +type ButtonsResponseMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SelectedButtonId *string `protobuf:"bytes,1,opt,name=selectedButtonId" json:"selectedButtonId,omitempty"` + ContextInfo *ContextInfo `protobuf:"bytes,3,opt,name=contextInfo" json:"contextInfo,omitempty"` + Type *ButtonsResponseMessage_ButtonsResponseMessageType `protobuf:"varint,4,opt,name=type,enum=proto.ButtonsResponseMessage_ButtonsResponseMessageType" json:"type,omitempty"` + // Types that are assignable to Response: + // *ButtonsResponseMessage_SelectedDisplayText + Response isButtonsResponseMessage_Response `protobuf_oneof:"response"` +} + +func (x *ButtonsResponseMessage) Reset() { + *x = ButtonsResponseMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[71] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ButtonsResponseMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ButtonsResponseMessage) ProtoMessage() {} + +func (x *ButtonsResponseMessage) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[71] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ButtonsResponseMessage.ProtoReflect.Descriptor instead. +func (*ButtonsResponseMessage) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{71} +} + +func (x *ButtonsResponseMessage) GetSelectedButtonId() string { + if x != nil && x.SelectedButtonId != nil { + return *x.SelectedButtonId + } + return "" +} + +func (x *ButtonsResponseMessage) GetContextInfo() *ContextInfo { + if x != nil { + return x.ContextInfo + } + return nil +} + +func (x *ButtonsResponseMessage) GetType() ButtonsResponseMessage_ButtonsResponseMessageType { + if x != nil && x.Type != nil { + return *x.Type + } + return ButtonsResponseMessage_UNKNOWN +} + +func (m *ButtonsResponseMessage) GetResponse() isButtonsResponseMessage_Response { + if m != nil { + return m.Response + } + return nil +} + +func (x *ButtonsResponseMessage) GetSelectedDisplayText() string { + if x, ok := x.GetResponse().(*ButtonsResponseMessage_SelectedDisplayText); ok { + return x.SelectedDisplayText + } + return "" +} + +type isButtonsResponseMessage_Response interface { + isButtonsResponseMessage_Response() +} + +type ButtonsResponseMessage_SelectedDisplayText struct { + SelectedDisplayText string `protobuf:"bytes,2,opt,name=selectedDisplayText,oneof"` +} + +func (*ButtonsResponseMessage_SelectedDisplayText) isButtonsResponseMessage_Response() {} + +type Message struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Conversation *string `protobuf:"bytes,1,opt,name=conversation" json:"conversation,omitempty"` + SenderKeyDistributionMessage *SenderKeyDistributionMessage `protobuf:"bytes,2,opt,name=senderKeyDistributionMessage" json:"senderKeyDistributionMessage,omitempty"` + ImageMessage *ImageMessage `protobuf:"bytes,3,opt,name=imageMessage" json:"imageMessage,omitempty"` + ContactMessage *ContactMessage `protobuf:"bytes,4,opt,name=contactMessage" json:"contactMessage,omitempty"` + LocationMessage *LocationMessage `protobuf:"bytes,5,opt,name=locationMessage" json:"locationMessage,omitempty"` + ExtendedTextMessage *ExtendedTextMessage `protobuf:"bytes,6,opt,name=extendedTextMessage" json:"extendedTextMessage,omitempty"` + DocumentMessage *DocumentMessage `protobuf:"bytes,7,opt,name=documentMessage" json:"documentMessage,omitempty"` + AudioMessage *AudioMessage `protobuf:"bytes,8,opt,name=audioMessage" json:"audioMessage,omitempty"` + VideoMessage *VideoMessage `protobuf:"bytes,9,opt,name=videoMessage" json:"videoMessage,omitempty"` + Call *Call `protobuf:"bytes,10,opt,name=call" json:"call,omitempty"` + Chat *Chat `protobuf:"bytes,11,opt,name=chat" json:"chat,omitempty"` + ProtocolMessage *ProtocolMessage `protobuf:"bytes,12,opt,name=protocolMessage" json:"protocolMessage,omitempty"` + ContactsArrayMessage *ContactsArrayMessage `protobuf:"bytes,13,opt,name=contactsArrayMessage" json:"contactsArrayMessage,omitempty"` + HighlyStructuredMessage *HighlyStructuredMessage `protobuf:"bytes,14,opt,name=highlyStructuredMessage" json:"highlyStructuredMessage,omitempty"` + FastRatchetKeySenderKeyDistributionMessage *SenderKeyDistributionMessage `protobuf:"bytes,15,opt,name=fastRatchetKeySenderKeyDistributionMessage" json:"fastRatchetKeySenderKeyDistributionMessage,omitempty"` + SendPaymentMessage *SendPaymentMessage `protobuf:"bytes,16,opt,name=sendPaymentMessage" json:"sendPaymentMessage,omitempty"` + LiveLocationMessage *LiveLocationMessage `protobuf:"bytes,18,opt,name=liveLocationMessage" json:"liveLocationMessage,omitempty"` + RequestPaymentMessage *RequestPaymentMessage `protobuf:"bytes,22,opt,name=requestPaymentMessage" json:"requestPaymentMessage,omitempty"` + DeclinePaymentRequestMessage *DeclinePaymentRequestMessage `protobuf:"bytes,23,opt,name=declinePaymentRequestMessage" json:"declinePaymentRequestMessage,omitempty"` + CancelPaymentRequestMessage *CancelPaymentRequestMessage `protobuf:"bytes,24,opt,name=cancelPaymentRequestMessage" json:"cancelPaymentRequestMessage,omitempty"` + TemplateMessage *TemplateMessage `protobuf:"bytes,25,opt,name=templateMessage" json:"templateMessage,omitempty"` + StickerMessage *StickerMessage `protobuf:"bytes,26,opt,name=stickerMessage" json:"stickerMessage,omitempty"` + GroupInviteMessage *GroupInviteMessage `protobuf:"bytes,28,opt,name=groupInviteMessage" json:"groupInviteMessage,omitempty"` + TemplateButtonReplyMessage *TemplateButtonReplyMessage `protobuf:"bytes,29,opt,name=templateButtonReplyMessage" json:"templateButtonReplyMessage,omitempty"` + ProductMessage *ProductMessage `protobuf:"bytes,30,opt,name=productMessage" json:"productMessage,omitempty"` + DeviceSentMessage *DeviceSentMessage `protobuf:"bytes,31,opt,name=deviceSentMessage" json:"deviceSentMessage,omitempty"` + MessageContextInfo *MessageContextInfo `protobuf:"bytes,35,opt,name=messageContextInfo" json:"messageContextInfo,omitempty"` + ListMessage *ListMessage `protobuf:"bytes,36,opt,name=listMessage" json:"listMessage,omitempty"` + ViewOnceMessage *FutureProofMessage `protobuf:"bytes,37,opt,name=viewOnceMessage" json:"viewOnceMessage,omitempty"` + OrderMessage *OrderMessage `protobuf:"bytes,38,opt,name=orderMessage" json:"orderMessage,omitempty"` + ListResponseMessage *ListResponseMessage `protobuf:"bytes,39,opt,name=listResponseMessage" json:"listResponseMessage,omitempty"` + EphemeralMessage *FutureProofMessage `protobuf:"bytes,40,opt,name=ephemeralMessage" json:"ephemeralMessage,omitempty"` + InvoiceMessage *InvoiceMessage `protobuf:"bytes,41,opt,name=invoiceMessage" json:"invoiceMessage,omitempty"` + ButtonsMessage *ButtonsMessage `protobuf:"bytes,42,opt,name=buttonsMessage" json:"buttonsMessage,omitempty"` + ButtonsResponseMessage *ButtonsResponseMessage `protobuf:"bytes,43,opt,name=buttonsResponseMessage" json:"buttonsResponseMessage,omitempty"` +} + +func (x *Message) Reset() { + *x = Message{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[72] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Message) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Message) ProtoMessage() {} + +func (x *Message) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[72] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Message.ProtoReflect.Descriptor instead. +func (*Message) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{72} +} + +func (x *Message) GetConversation() string { + if x != nil && x.Conversation != nil { + return *x.Conversation + } + return "" +} + +func (x *Message) GetSenderKeyDistributionMessage() *SenderKeyDistributionMessage { + if x != nil { + return x.SenderKeyDistributionMessage + } + return nil +} + +func (x *Message) GetImageMessage() *ImageMessage { + if x != nil { + return x.ImageMessage + } + return nil +} + +func (x *Message) GetContactMessage() *ContactMessage { + if x != nil { + return x.ContactMessage + } + return nil +} + +func (x *Message) GetLocationMessage() *LocationMessage { + if x != nil { + return x.LocationMessage + } + return nil +} + +func (x *Message) GetExtendedTextMessage() *ExtendedTextMessage { + if x != nil { + return x.ExtendedTextMessage + } + return nil +} + +func (x *Message) GetDocumentMessage() *DocumentMessage { + if x != nil { + return x.DocumentMessage + } + return nil +} + +func (x *Message) GetAudioMessage() *AudioMessage { + if x != nil { + return x.AudioMessage + } + return nil +} + +func (x *Message) GetVideoMessage() *VideoMessage { + if x != nil { + return x.VideoMessage + } + return nil +} + +func (x *Message) GetCall() *Call { + if x != nil { + return x.Call + } + return nil +} + +func (x *Message) GetChat() *Chat { + if x != nil { + return x.Chat + } + return nil +} + +func (x *Message) GetProtocolMessage() *ProtocolMessage { + if x != nil { + return x.ProtocolMessage + } + return nil +} + +func (x *Message) GetContactsArrayMessage() *ContactsArrayMessage { + if x != nil { + return x.ContactsArrayMessage + } + return nil +} + +func (x *Message) GetHighlyStructuredMessage() *HighlyStructuredMessage { + if x != nil { + return x.HighlyStructuredMessage + } + return nil +} + +func (x *Message) GetFastRatchetKeySenderKeyDistributionMessage() *SenderKeyDistributionMessage { + if x != nil { + return x.FastRatchetKeySenderKeyDistributionMessage + } + return nil +} + +func (x *Message) GetSendPaymentMessage() *SendPaymentMessage { + if x != nil { + return x.SendPaymentMessage + } + return nil +} + +func (x *Message) GetLiveLocationMessage() *LiveLocationMessage { + if x != nil { + return x.LiveLocationMessage + } + return nil +} + +func (x *Message) GetRequestPaymentMessage() *RequestPaymentMessage { + if x != nil { + return x.RequestPaymentMessage + } + return nil +} + +func (x *Message) GetDeclinePaymentRequestMessage() *DeclinePaymentRequestMessage { + if x != nil { + return x.DeclinePaymentRequestMessage + } + return nil +} + +func (x *Message) GetCancelPaymentRequestMessage() *CancelPaymentRequestMessage { + if x != nil { + return x.CancelPaymentRequestMessage + } + return nil +} + +func (x *Message) GetTemplateMessage() *TemplateMessage { + if x != nil { + return x.TemplateMessage + } + return nil +} + +func (x *Message) GetStickerMessage() *StickerMessage { + if x != nil { + return x.StickerMessage + } + return nil +} + +func (x *Message) GetGroupInviteMessage() *GroupInviteMessage { + if x != nil { + return x.GroupInviteMessage + } + return nil +} + +func (x *Message) GetTemplateButtonReplyMessage() *TemplateButtonReplyMessage { + if x != nil { + return x.TemplateButtonReplyMessage + } + return nil +} + +func (x *Message) GetProductMessage() *ProductMessage { + if x != nil { + return x.ProductMessage + } + return nil +} + +func (x *Message) GetDeviceSentMessage() *DeviceSentMessage { + if x != nil { + return x.DeviceSentMessage + } + return nil +} + +func (x *Message) GetMessageContextInfo() *MessageContextInfo { + if x != nil { + return x.MessageContextInfo + } + return nil +} + +func (x *Message) GetListMessage() *ListMessage { + if x != nil { + return x.ListMessage + } + return nil +} + +func (x *Message) GetViewOnceMessage() *FutureProofMessage { + if x != nil { + return x.ViewOnceMessage + } + return nil +} + +func (x *Message) GetOrderMessage() *OrderMessage { + if x != nil { + return x.OrderMessage + } + return nil +} + +func (x *Message) GetListResponseMessage() *ListResponseMessage { + if x != nil { + return x.ListResponseMessage + } + return nil +} + +func (x *Message) GetEphemeralMessage() *FutureProofMessage { + if x != nil { + return x.EphemeralMessage + } + return nil +} + +func (x *Message) GetInvoiceMessage() *InvoiceMessage { + if x != nil { + return x.InvoiceMessage + } + return nil +} + +func (x *Message) GetButtonsMessage() *ButtonsMessage { + if x != nil { + return x.ButtonsMessage + } + return nil +} + +func (x *Message) GetButtonsResponseMessage() *ButtonsResponseMessage { + if x != nil { + return x.ButtonsResponseMessage + } + return nil +} + +type MessageKey struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + RemoteJid *string `protobuf:"bytes,1,opt,name=remoteJid" json:"remoteJid,omitempty"` + FromMe *bool `protobuf:"varint,2,opt,name=fromMe" json:"fromMe,omitempty"` + Id *string `protobuf:"bytes,3,opt,name=id" json:"id,omitempty"` + Participant *string `protobuf:"bytes,4,opt,name=participant" json:"participant,omitempty"` +} + +func (x *MessageKey) Reset() { + *x = MessageKey{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[73] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MessageKey) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MessageKey) ProtoMessage() {} + +func (x *MessageKey) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[73] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MessageKey.ProtoReflect.Descriptor instead. +func (*MessageKey) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{73} +} + +func (x *MessageKey) GetRemoteJid() string { + if x != nil && x.RemoteJid != nil { + return *x.RemoteJid + } + return "" +} + +func (x *MessageKey) GetFromMe() bool { + if x != nil && x.FromMe != nil { + return *x.FromMe + } + return false +} + +func (x *MessageKey) GetId() string { + if x != nil && x.Id != nil { + return *x.Id + } + return "" +} + +func (x *MessageKey) GetParticipant() string { + if x != nil && x.Participant != nil { + return *x.Participant + } + return "" +} + +type WebFeatures struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + LabelsDisplay *WebFeatures_WebFeaturesFlag `protobuf:"varint,1,opt,name=labelsDisplay,enum=proto.WebFeatures_WebFeaturesFlag" json:"labelsDisplay,omitempty"` + VoipIndividualOutgoing *WebFeatures_WebFeaturesFlag `protobuf:"varint,2,opt,name=voipIndividualOutgoing,enum=proto.WebFeatures_WebFeaturesFlag" json:"voipIndividualOutgoing,omitempty"` + GroupsV3 *WebFeatures_WebFeaturesFlag `protobuf:"varint,3,opt,name=groupsV3,enum=proto.WebFeatures_WebFeaturesFlag" json:"groupsV3,omitempty"` + GroupsV3Create *WebFeatures_WebFeaturesFlag `protobuf:"varint,4,opt,name=groupsV3Create,enum=proto.WebFeatures_WebFeaturesFlag" json:"groupsV3Create,omitempty"` + ChangeNumberV2 *WebFeatures_WebFeaturesFlag `protobuf:"varint,5,opt,name=changeNumberV2,enum=proto.WebFeatures_WebFeaturesFlag" json:"changeNumberV2,omitempty"` + QueryStatusV3Thumbnail *WebFeatures_WebFeaturesFlag `protobuf:"varint,6,opt,name=queryStatusV3Thumbnail,enum=proto.WebFeatures_WebFeaturesFlag" json:"queryStatusV3Thumbnail,omitempty"` + LiveLocations *WebFeatures_WebFeaturesFlag `protobuf:"varint,7,opt,name=liveLocations,enum=proto.WebFeatures_WebFeaturesFlag" json:"liveLocations,omitempty"` + QueryVname *WebFeatures_WebFeaturesFlag `protobuf:"varint,8,opt,name=queryVname,enum=proto.WebFeatures_WebFeaturesFlag" json:"queryVname,omitempty"` + VoipIndividualIncoming *WebFeatures_WebFeaturesFlag `protobuf:"varint,9,opt,name=voipIndividualIncoming,enum=proto.WebFeatures_WebFeaturesFlag" json:"voipIndividualIncoming,omitempty"` + QuickRepliesQuery *WebFeatures_WebFeaturesFlag `protobuf:"varint,10,opt,name=quickRepliesQuery,enum=proto.WebFeatures_WebFeaturesFlag" json:"quickRepliesQuery,omitempty"` + Payments *WebFeatures_WebFeaturesFlag `protobuf:"varint,11,opt,name=payments,enum=proto.WebFeatures_WebFeaturesFlag" json:"payments,omitempty"` + StickerPackQuery *WebFeatures_WebFeaturesFlag `protobuf:"varint,12,opt,name=stickerPackQuery,enum=proto.WebFeatures_WebFeaturesFlag" json:"stickerPackQuery,omitempty"` + LiveLocationsFinal *WebFeatures_WebFeaturesFlag `protobuf:"varint,13,opt,name=liveLocationsFinal,enum=proto.WebFeatures_WebFeaturesFlag" json:"liveLocationsFinal,omitempty"` + LabelsEdit *WebFeatures_WebFeaturesFlag `protobuf:"varint,14,opt,name=labelsEdit,enum=proto.WebFeatures_WebFeaturesFlag" json:"labelsEdit,omitempty"` + MediaUpload *WebFeatures_WebFeaturesFlag `protobuf:"varint,15,opt,name=mediaUpload,enum=proto.WebFeatures_WebFeaturesFlag" json:"mediaUpload,omitempty"` + MediaUploadRichQuickReplies *WebFeatures_WebFeaturesFlag `protobuf:"varint,18,opt,name=mediaUploadRichQuickReplies,enum=proto.WebFeatures_WebFeaturesFlag" json:"mediaUploadRichQuickReplies,omitempty"` + VnameV2 *WebFeatures_WebFeaturesFlag `protobuf:"varint,19,opt,name=vnameV2,enum=proto.WebFeatures_WebFeaturesFlag" json:"vnameV2,omitempty"` + VideoPlaybackUrl *WebFeatures_WebFeaturesFlag `protobuf:"varint,20,opt,name=videoPlaybackUrl,enum=proto.WebFeatures_WebFeaturesFlag" json:"videoPlaybackUrl,omitempty"` + StatusRanking *WebFeatures_WebFeaturesFlag `protobuf:"varint,21,opt,name=statusRanking,enum=proto.WebFeatures_WebFeaturesFlag" json:"statusRanking,omitempty"` + VoipIndividualVideo *WebFeatures_WebFeaturesFlag `protobuf:"varint,22,opt,name=voipIndividualVideo,enum=proto.WebFeatures_WebFeaturesFlag" json:"voipIndividualVideo,omitempty"` + ThirdPartyStickers *WebFeatures_WebFeaturesFlag `protobuf:"varint,23,opt,name=thirdPartyStickers,enum=proto.WebFeatures_WebFeaturesFlag" json:"thirdPartyStickers,omitempty"` + FrequentlyForwardedSetting *WebFeatures_WebFeaturesFlag `protobuf:"varint,24,opt,name=frequentlyForwardedSetting,enum=proto.WebFeatures_WebFeaturesFlag" json:"frequentlyForwardedSetting,omitempty"` + GroupsV4JoinPermission *WebFeatures_WebFeaturesFlag `protobuf:"varint,25,opt,name=groupsV4JoinPermission,enum=proto.WebFeatures_WebFeaturesFlag" json:"groupsV4JoinPermission,omitempty"` + RecentStickers *WebFeatures_WebFeaturesFlag `protobuf:"varint,26,opt,name=recentStickers,enum=proto.WebFeatures_WebFeaturesFlag" json:"recentStickers,omitempty"` + Catalog *WebFeatures_WebFeaturesFlag `protobuf:"varint,27,opt,name=catalog,enum=proto.WebFeatures_WebFeaturesFlag" json:"catalog,omitempty"` + StarredStickers *WebFeatures_WebFeaturesFlag `protobuf:"varint,28,opt,name=starredStickers,enum=proto.WebFeatures_WebFeaturesFlag" json:"starredStickers,omitempty"` + VoipGroupCall *WebFeatures_WebFeaturesFlag `protobuf:"varint,29,opt,name=voipGroupCall,enum=proto.WebFeatures_WebFeaturesFlag" json:"voipGroupCall,omitempty"` + TemplateMessage *WebFeatures_WebFeaturesFlag `protobuf:"varint,30,opt,name=templateMessage,enum=proto.WebFeatures_WebFeaturesFlag" json:"templateMessage,omitempty"` + TemplateMessageInteractivity *WebFeatures_WebFeaturesFlag `protobuf:"varint,31,opt,name=templateMessageInteractivity,enum=proto.WebFeatures_WebFeaturesFlag" json:"templateMessageInteractivity,omitempty"` + EphemeralMessages *WebFeatures_WebFeaturesFlag `protobuf:"varint,32,opt,name=ephemeralMessages,enum=proto.WebFeatures_WebFeaturesFlag" json:"ephemeralMessages,omitempty"` + E2ENotificationSync *WebFeatures_WebFeaturesFlag `protobuf:"varint,33,opt,name=e2ENotificationSync,enum=proto.WebFeatures_WebFeaturesFlag" json:"e2ENotificationSync,omitempty"` + RecentStickersV2 *WebFeatures_WebFeaturesFlag `protobuf:"varint,34,opt,name=recentStickersV2,enum=proto.WebFeatures_WebFeaturesFlag" json:"recentStickersV2,omitempty"` + SyncdRelease1 *WebFeatures_WebFeaturesFlag `protobuf:"varint,35,opt,name=syncdRelease1,enum=proto.WebFeatures_WebFeaturesFlag" json:"syncdRelease1,omitempty"` + RecentStickersV3 *WebFeatures_WebFeaturesFlag `protobuf:"varint,36,opt,name=recentStickersV3,enum=proto.WebFeatures_WebFeaturesFlag" json:"recentStickersV3,omitempty"` + UserNotice *WebFeatures_WebFeaturesFlag `protobuf:"varint,37,opt,name=userNotice,enum=proto.WebFeatures_WebFeaturesFlag" json:"userNotice,omitempty"` + SyncdRelease11 *WebFeatures_WebFeaturesFlag `protobuf:"varint,38,opt,name=syncdRelease11,enum=proto.WebFeatures_WebFeaturesFlag" json:"syncdRelease11,omitempty"` + Support *WebFeatures_WebFeaturesFlag `protobuf:"varint,39,opt,name=support,enum=proto.WebFeatures_WebFeaturesFlag" json:"support,omitempty"` + GroupUiiCleanup *WebFeatures_WebFeaturesFlag `protobuf:"varint,40,opt,name=groupUiiCleanup,enum=proto.WebFeatures_WebFeaturesFlag" json:"groupUiiCleanup,omitempty"` + GroupDogfoodingInternalOnly *WebFeatures_WebFeaturesFlag `protobuf:"varint,41,opt,name=groupDogfoodingInternalOnly,enum=proto.WebFeatures_WebFeaturesFlag" json:"groupDogfoodingInternalOnly,omitempty"` + SettingsSync *WebFeatures_WebFeaturesFlag `protobuf:"varint,42,opt,name=settingsSync,enum=proto.WebFeatures_WebFeaturesFlag" json:"settingsSync,omitempty"` +} + +func (x *WebFeatures) Reset() { + *x = WebFeatures{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[74] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WebFeatures) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WebFeatures) ProtoMessage() {} + +func (x *WebFeatures) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[74] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WebFeatures.ProtoReflect.Descriptor instead. +func (*WebFeatures) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{74} +} + +func (x *WebFeatures) GetLabelsDisplay() WebFeatures_WebFeaturesFlag { + if x != nil && x.LabelsDisplay != nil { + return *x.LabelsDisplay + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetVoipIndividualOutgoing() WebFeatures_WebFeaturesFlag { + if x != nil && x.VoipIndividualOutgoing != nil { + return *x.VoipIndividualOutgoing + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetGroupsV3() WebFeatures_WebFeaturesFlag { + if x != nil && x.GroupsV3 != nil { + return *x.GroupsV3 + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetGroupsV3Create() WebFeatures_WebFeaturesFlag { + if x != nil && x.GroupsV3Create != nil { + return *x.GroupsV3Create + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetChangeNumberV2() WebFeatures_WebFeaturesFlag { + if x != nil && x.ChangeNumberV2 != nil { + return *x.ChangeNumberV2 + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetQueryStatusV3Thumbnail() WebFeatures_WebFeaturesFlag { + if x != nil && x.QueryStatusV3Thumbnail != nil { + return *x.QueryStatusV3Thumbnail + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetLiveLocations() WebFeatures_WebFeaturesFlag { + if x != nil && x.LiveLocations != nil { + return *x.LiveLocations + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetQueryVname() WebFeatures_WebFeaturesFlag { + if x != nil && x.QueryVname != nil { + return *x.QueryVname + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetVoipIndividualIncoming() WebFeatures_WebFeaturesFlag { + if x != nil && x.VoipIndividualIncoming != nil { + return *x.VoipIndividualIncoming + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetQuickRepliesQuery() WebFeatures_WebFeaturesFlag { + if x != nil && x.QuickRepliesQuery != nil { + return *x.QuickRepliesQuery + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetPayments() WebFeatures_WebFeaturesFlag { + if x != nil && x.Payments != nil { + return *x.Payments + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetStickerPackQuery() WebFeatures_WebFeaturesFlag { + if x != nil && x.StickerPackQuery != nil { + return *x.StickerPackQuery + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetLiveLocationsFinal() WebFeatures_WebFeaturesFlag { + if x != nil && x.LiveLocationsFinal != nil { + return *x.LiveLocationsFinal + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetLabelsEdit() WebFeatures_WebFeaturesFlag { + if x != nil && x.LabelsEdit != nil { + return *x.LabelsEdit + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetMediaUpload() WebFeatures_WebFeaturesFlag { + if x != nil && x.MediaUpload != nil { + return *x.MediaUpload + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetMediaUploadRichQuickReplies() WebFeatures_WebFeaturesFlag { + if x != nil && x.MediaUploadRichQuickReplies != nil { + return *x.MediaUploadRichQuickReplies + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetVnameV2() WebFeatures_WebFeaturesFlag { + if x != nil && x.VnameV2 != nil { + return *x.VnameV2 + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetVideoPlaybackUrl() WebFeatures_WebFeaturesFlag { + if x != nil && x.VideoPlaybackUrl != nil { + return *x.VideoPlaybackUrl + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetStatusRanking() WebFeatures_WebFeaturesFlag { + if x != nil && x.StatusRanking != nil { + return *x.StatusRanking + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetVoipIndividualVideo() WebFeatures_WebFeaturesFlag { + if x != nil && x.VoipIndividualVideo != nil { + return *x.VoipIndividualVideo + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetThirdPartyStickers() WebFeatures_WebFeaturesFlag { + if x != nil && x.ThirdPartyStickers != nil { + return *x.ThirdPartyStickers + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetFrequentlyForwardedSetting() WebFeatures_WebFeaturesFlag { + if x != nil && x.FrequentlyForwardedSetting != nil { + return *x.FrequentlyForwardedSetting + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetGroupsV4JoinPermission() WebFeatures_WebFeaturesFlag { + if x != nil && x.GroupsV4JoinPermission != nil { + return *x.GroupsV4JoinPermission + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetRecentStickers() WebFeatures_WebFeaturesFlag { + if x != nil && x.RecentStickers != nil { + return *x.RecentStickers + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetCatalog() WebFeatures_WebFeaturesFlag { + if x != nil && x.Catalog != nil { + return *x.Catalog + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetStarredStickers() WebFeatures_WebFeaturesFlag { + if x != nil && x.StarredStickers != nil { + return *x.StarredStickers + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetVoipGroupCall() WebFeatures_WebFeaturesFlag { + if x != nil && x.VoipGroupCall != nil { + return *x.VoipGroupCall + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetTemplateMessage() WebFeatures_WebFeaturesFlag { + if x != nil && x.TemplateMessage != nil { + return *x.TemplateMessage + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetTemplateMessageInteractivity() WebFeatures_WebFeaturesFlag { + if x != nil && x.TemplateMessageInteractivity != nil { + return *x.TemplateMessageInteractivity + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetEphemeralMessages() WebFeatures_WebFeaturesFlag { + if x != nil && x.EphemeralMessages != nil { + return *x.EphemeralMessages + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetE2ENotificationSync() WebFeatures_WebFeaturesFlag { + if x != nil && x.E2ENotificationSync != nil { + return *x.E2ENotificationSync + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetRecentStickersV2() WebFeatures_WebFeaturesFlag { + if x != nil && x.RecentStickersV2 != nil { + return *x.RecentStickersV2 + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetSyncdRelease1() WebFeatures_WebFeaturesFlag { + if x != nil && x.SyncdRelease1 != nil { + return *x.SyncdRelease1 + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetRecentStickersV3() WebFeatures_WebFeaturesFlag { + if x != nil && x.RecentStickersV3 != nil { + return *x.RecentStickersV3 + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetUserNotice() WebFeatures_WebFeaturesFlag { + if x != nil && x.UserNotice != nil { + return *x.UserNotice + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetSyncdRelease11() WebFeatures_WebFeaturesFlag { + if x != nil && x.SyncdRelease11 != nil { + return *x.SyncdRelease11 + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetSupport() WebFeatures_WebFeaturesFlag { + if x != nil && x.Support != nil { + return *x.Support + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetGroupUiiCleanup() WebFeatures_WebFeaturesFlag { + if x != nil && x.GroupUiiCleanup != nil { + return *x.GroupUiiCleanup + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetGroupDogfoodingInternalOnly() WebFeatures_WebFeaturesFlag { + if x != nil && x.GroupDogfoodingInternalOnly != nil { + return *x.GroupDogfoodingInternalOnly + } + return WebFeatures_NOT_STARTED +} + +func (x *WebFeatures) GetSettingsSync() WebFeatures_WebFeaturesFlag { + if x != nil && x.SettingsSync != nil { + return *x.SettingsSync + } + return WebFeatures_NOT_STARTED +} + +type NotificationMessageInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key *MessageKey `protobuf:"bytes,1,opt,name=key" json:"key,omitempty"` + Message *Message `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"` + MessageTimestamp *uint64 `protobuf:"varint,3,opt,name=messageTimestamp" json:"messageTimestamp,omitempty"` + Participant *string `protobuf:"bytes,4,opt,name=participant" json:"participant,omitempty"` +} + +func (x *NotificationMessageInfo) Reset() { + *x = NotificationMessageInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[75] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NotificationMessageInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NotificationMessageInfo) ProtoMessage() {} + +func (x *NotificationMessageInfo) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[75] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NotificationMessageInfo.ProtoReflect.Descriptor instead. +func (*NotificationMessageInfo) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{75} +} + +func (x *NotificationMessageInfo) GetKey() *MessageKey { + if x != nil { + return x.Key + } + return nil +} + +func (x *NotificationMessageInfo) GetMessage() *Message { + if x != nil { + return x.Message + } + return nil +} + +func (x *NotificationMessageInfo) GetMessageTimestamp() uint64 { + if x != nil && x.MessageTimestamp != nil { + return *x.MessageTimestamp + } + return 0 +} + +func (x *NotificationMessageInfo) GetParticipant() string { + if x != nil && x.Participant != nil { + return *x.Participant + } + return "" +} + +type WebNotificationsInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Timestamp *uint64 `protobuf:"varint,2,opt,name=timestamp" json:"timestamp,omitempty"` + UnreadChats *uint32 `protobuf:"varint,3,opt,name=unreadChats" json:"unreadChats,omitempty"` + NotifyMessageCount *uint32 `protobuf:"varint,4,opt,name=notifyMessageCount" json:"notifyMessageCount,omitempty"` + NotifyMessages []*WebMessageInfo `protobuf:"bytes,5,rep,name=notifyMessages" json:"notifyMessages,omitempty"` +} + +func (x *WebNotificationsInfo) Reset() { + *x = WebNotificationsInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[76] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WebNotificationsInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WebNotificationsInfo) ProtoMessage() {} + +func (x *WebNotificationsInfo) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[76] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WebNotificationsInfo.ProtoReflect.Descriptor instead. +func (*WebNotificationsInfo) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{76} +} + +func (x *WebNotificationsInfo) GetTimestamp() uint64 { + if x != nil && x.Timestamp != nil { + return *x.Timestamp + } + return 0 +} + +func (x *WebNotificationsInfo) GetUnreadChats() uint32 { + if x != nil && x.UnreadChats != nil { + return *x.UnreadChats + } + return 0 +} + +func (x *WebNotificationsInfo) GetNotifyMessageCount() uint32 { + if x != nil && x.NotifyMessageCount != nil { + return *x.NotifyMessageCount + } + return 0 +} + +func (x *WebNotificationsInfo) GetNotifyMessages() []*WebMessageInfo { + if x != nil { + return x.NotifyMessages + } + return nil +} + +type PaymentInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + CurrencyDeprecated *PaymentInfo_PaymentInfoCurrency `protobuf:"varint,1,opt,name=currencyDeprecated,enum=proto.PaymentInfo_PaymentInfoCurrency" json:"currencyDeprecated,omitempty"` + Amount1000 *uint64 `protobuf:"varint,2,opt,name=amount1000" json:"amount1000,omitempty"` + ReceiverJid *string `protobuf:"bytes,3,opt,name=receiverJid" json:"receiverJid,omitempty"` + Status *PaymentInfo_PaymentInfoStatus `protobuf:"varint,4,opt,name=status,enum=proto.PaymentInfo_PaymentInfoStatus" json:"status,omitempty"` + TransactionTimestamp *uint64 `protobuf:"varint,5,opt,name=transactionTimestamp" json:"transactionTimestamp,omitempty"` + RequestMessageKey *MessageKey `protobuf:"bytes,6,opt,name=requestMessageKey" json:"requestMessageKey,omitempty"` + ExpiryTimestamp *uint64 `protobuf:"varint,7,opt,name=expiryTimestamp" json:"expiryTimestamp,omitempty"` + Futureproofed *bool `protobuf:"varint,8,opt,name=futureproofed" json:"futureproofed,omitempty"` + Currency *string `protobuf:"bytes,9,opt,name=currency" json:"currency,omitempty"` + TxnStatus *PaymentInfo_PaymentInfoTxnStatus `protobuf:"varint,10,opt,name=txnStatus,enum=proto.PaymentInfo_PaymentInfoTxnStatus" json:"txnStatus,omitempty"` + UseNoviFiatFormat *bool `protobuf:"varint,11,opt,name=useNoviFiatFormat" json:"useNoviFiatFormat,omitempty"` + PrimaryAmount *PaymentMoney `protobuf:"bytes,12,opt,name=primaryAmount" json:"primaryAmount,omitempty"` + ExchangeAmount *PaymentMoney `protobuf:"bytes,13,opt,name=exchangeAmount" json:"exchangeAmount,omitempty"` +} + +func (x *PaymentInfo) Reset() { + *x = PaymentInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[77] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PaymentInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PaymentInfo) ProtoMessage() {} + +func (x *PaymentInfo) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[77] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PaymentInfo.ProtoReflect.Descriptor instead. +func (*PaymentInfo) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{77} +} + +func (x *PaymentInfo) GetCurrencyDeprecated() PaymentInfo_PaymentInfoCurrency { + if x != nil && x.CurrencyDeprecated != nil { + return *x.CurrencyDeprecated + } + return PaymentInfo_UNKNOWN_CURRENCY +} + +func (x *PaymentInfo) GetAmount1000() uint64 { + if x != nil && x.Amount1000 != nil { + return *x.Amount1000 + } + return 0 +} + +func (x *PaymentInfo) GetReceiverJid() string { + if x != nil && x.ReceiverJid != nil { + return *x.ReceiverJid + } + return "" +} + +func (x *PaymentInfo) GetStatus() PaymentInfo_PaymentInfoStatus { + if x != nil && x.Status != nil { + return *x.Status + } + return PaymentInfo_UNKNOWN_STATUS +} + +func (x *PaymentInfo) GetTransactionTimestamp() uint64 { + if x != nil && x.TransactionTimestamp != nil { + return *x.TransactionTimestamp + } + return 0 +} + +func (x *PaymentInfo) GetRequestMessageKey() *MessageKey { + if x != nil { + return x.RequestMessageKey + } + return nil +} + +func (x *PaymentInfo) GetExpiryTimestamp() uint64 { + if x != nil && x.ExpiryTimestamp != nil { + return *x.ExpiryTimestamp + } + return 0 +} + +func (x *PaymentInfo) GetFutureproofed() bool { + if x != nil && x.Futureproofed != nil { + return *x.Futureproofed + } + return false +} + +func (x *PaymentInfo) GetCurrency() string { + if x != nil && x.Currency != nil { + return *x.Currency + } + return "" +} + +func (x *PaymentInfo) GetTxnStatus() PaymentInfo_PaymentInfoTxnStatus { + if x != nil && x.TxnStatus != nil { + return *x.TxnStatus + } + return PaymentInfo_UNKNOWN +} + +func (x *PaymentInfo) GetUseNoviFiatFormat() bool { + if x != nil && x.UseNoviFiatFormat != nil { + return *x.UseNoviFiatFormat + } + return false +} + +func (x *PaymentInfo) GetPrimaryAmount() *PaymentMoney { + if x != nil { + return x.PrimaryAmount + } + return nil +} + +func (x *PaymentInfo) GetExchangeAmount() *PaymentMoney { + if x != nil { + return x.ExchangeAmount + } + return nil +} + +type WebMessageInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key *MessageKey `protobuf:"bytes,1,req,name=key" json:"key,omitempty"` + Message *Message `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"` + MessageTimestamp *uint64 `protobuf:"varint,3,opt,name=messageTimestamp" json:"messageTimestamp,omitempty"` + Status *WebMessageInfo_WebMessageInfoStatus `protobuf:"varint,4,opt,name=status,enum=proto.WebMessageInfo_WebMessageInfoStatus" json:"status,omitempty"` + Participant *string `protobuf:"bytes,5,opt,name=participant" json:"participant,omitempty"` + Ignore *bool `protobuf:"varint,16,opt,name=ignore" json:"ignore,omitempty"` + Starred *bool `protobuf:"varint,17,opt,name=starred" json:"starred,omitempty"` + Broadcast *bool `protobuf:"varint,18,opt,name=broadcast" json:"broadcast,omitempty"` + PushName *string `protobuf:"bytes,19,opt,name=pushName" json:"pushName,omitempty"` + MediaCiphertextSha256 []byte `protobuf:"bytes,20,opt,name=mediaCiphertextSha256" json:"mediaCiphertextSha256,omitempty"` + Multicast *bool `protobuf:"varint,21,opt,name=multicast" json:"multicast,omitempty"` + UrlText *bool `protobuf:"varint,22,opt,name=urlText" json:"urlText,omitempty"` + UrlNumber *bool `protobuf:"varint,23,opt,name=urlNumber" json:"urlNumber,omitempty"` + MessageStubType *WebMessageInfo_WebMessageInfoStubType `protobuf:"varint,24,opt,name=messageStubType,enum=proto.WebMessageInfo_WebMessageInfoStubType" json:"messageStubType,omitempty"` + ClearMedia *bool `protobuf:"varint,25,opt,name=clearMedia" json:"clearMedia,omitempty"` + MessageStubParameters []string `protobuf:"bytes,26,rep,name=messageStubParameters" json:"messageStubParameters,omitempty"` + Duration *uint32 `protobuf:"varint,27,opt,name=duration" json:"duration,omitempty"` + Labels []string `protobuf:"bytes,28,rep,name=labels" json:"labels,omitempty"` + PaymentInfo *PaymentInfo `protobuf:"bytes,29,opt,name=paymentInfo" json:"paymentInfo,omitempty"` + FinalLiveLocation *LiveLocationMessage `protobuf:"bytes,30,opt,name=finalLiveLocation" json:"finalLiveLocation,omitempty"` + QuotedPaymentInfo *PaymentInfo `protobuf:"bytes,31,opt,name=quotedPaymentInfo" json:"quotedPaymentInfo,omitempty"` + EphemeralStartTimestamp *uint64 `protobuf:"varint,32,opt,name=ephemeralStartTimestamp" json:"ephemeralStartTimestamp,omitempty"` + EphemeralDuration *uint32 `protobuf:"varint,33,opt,name=ephemeralDuration" json:"ephemeralDuration,omitempty"` + EphemeralOffToOn *bool `protobuf:"varint,34,opt,name=ephemeralOffToOn" json:"ephemeralOffToOn,omitempty"` + EphemeralOutOfSync *bool `protobuf:"varint,35,opt,name=ephemeralOutOfSync" json:"ephemeralOutOfSync,omitempty"` + BizPrivacyStatus *WebMessageInfo_WebMessageInfoBizPrivacyStatus `protobuf:"varint,36,opt,name=bizPrivacyStatus,enum=proto.WebMessageInfo_WebMessageInfoBizPrivacyStatus" json:"bizPrivacyStatus,omitempty"` + VerifiedBizName *string `protobuf:"bytes,37,opt,name=verifiedBizName" json:"verifiedBizName,omitempty"` +} + +func (x *WebMessageInfo) Reset() { + *x = WebMessageInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_def_proto_msgTypes[78] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *WebMessageInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*WebMessageInfo) ProtoMessage() {} + +func (x *WebMessageInfo) ProtoReflect() protoreflect.Message { + mi := &file_def_proto_msgTypes[78] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use WebMessageInfo.ProtoReflect.Descriptor instead. +func (*WebMessageInfo) Descriptor() ([]byte, []int) { + return file_def_proto_rawDescGZIP(), []int{78} +} + +func (x *WebMessageInfo) GetKey() *MessageKey { + if x != nil { + return x.Key + } + return nil +} + +func (x *WebMessageInfo) GetMessage() *Message { + if x != nil { + return x.Message + } + return nil +} + +func (x *WebMessageInfo) GetMessageTimestamp() uint64 { + if x != nil && x.MessageTimestamp != nil { + return *x.MessageTimestamp + } + return 0 +} + +func (x *WebMessageInfo) GetStatus() WebMessageInfo_WebMessageInfoStatus { + if x != nil && x.Status != nil { + return *x.Status + } + return WebMessageInfo_ERROR +} + +func (x *WebMessageInfo) GetParticipant() string { + if x != nil && x.Participant != nil { + return *x.Participant + } + return "" +} + +func (x *WebMessageInfo) GetIgnore() bool { + if x != nil && x.Ignore != nil { + return *x.Ignore + } + return false +} + +func (x *WebMessageInfo) GetStarred() bool { + if x != nil && x.Starred != nil { + return *x.Starred + } + return false +} + +func (x *WebMessageInfo) GetBroadcast() bool { + if x != nil && x.Broadcast != nil { + return *x.Broadcast + } + return false +} + +func (x *WebMessageInfo) GetPushName() string { + if x != nil && x.PushName != nil { + return *x.PushName + } + return "" +} + +func (x *WebMessageInfo) GetMediaCiphertextSha256() []byte { + if x != nil { + return x.MediaCiphertextSha256 + } + return nil +} + +func (x *WebMessageInfo) GetMulticast() bool { + if x != nil && x.Multicast != nil { + return *x.Multicast + } + return false +} + +func (x *WebMessageInfo) GetUrlText() bool { + if x != nil && x.UrlText != nil { + return *x.UrlText + } + return false +} + +func (x *WebMessageInfo) GetUrlNumber() bool { + if x != nil && x.UrlNumber != nil { + return *x.UrlNumber + } + return false +} + +func (x *WebMessageInfo) GetMessageStubType() WebMessageInfo_WebMessageInfoStubType { + if x != nil && x.MessageStubType != nil { + return *x.MessageStubType + } + return WebMessageInfo_UNKNOWN +} + +func (x *WebMessageInfo) GetClearMedia() bool { + if x != nil && x.ClearMedia != nil { + return *x.ClearMedia + } + return false +} + +func (x *WebMessageInfo) GetMessageStubParameters() []string { + if x != nil { + return x.MessageStubParameters + } + return nil +} + +func (x *WebMessageInfo) GetDuration() uint32 { + if x != nil && x.Duration != nil { + return *x.Duration + } + return 0 +} + +func (x *WebMessageInfo) GetLabels() []string { + if x != nil { + return x.Labels + } + return nil +} + +func (x *WebMessageInfo) GetPaymentInfo() *PaymentInfo { + if x != nil { + return x.PaymentInfo + } + return nil +} + +func (x *WebMessageInfo) GetFinalLiveLocation() *LiveLocationMessage { + if x != nil { + return x.FinalLiveLocation + } + return nil +} + +func (x *WebMessageInfo) GetQuotedPaymentInfo() *PaymentInfo { + if x != nil { + return x.QuotedPaymentInfo + } + return nil +} + +func (x *WebMessageInfo) GetEphemeralStartTimestamp() uint64 { + if x != nil && x.EphemeralStartTimestamp != nil { + return *x.EphemeralStartTimestamp + } + return 0 +} + +func (x *WebMessageInfo) GetEphemeralDuration() uint32 { + if x != nil && x.EphemeralDuration != nil { + return *x.EphemeralDuration + } + return 0 +} + +func (x *WebMessageInfo) GetEphemeralOffToOn() bool { + if x != nil && x.EphemeralOffToOn != nil { + return *x.EphemeralOffToOn + } + return false +} + +func (x *WebMessageInfo) GetEphemeralOutOfSync() bool { + if x != nil && x.EphemeralOutOfSync != nil { + return *x.EphemeralOutOfSync + } + return false +} + +func (x *WebMessageInfo) GetBizPrivacyStatus() WebMessageInfo_WebMessageInfoBizPrivacyStatus { + if x != nil && x.BizPrivacyStatus != nil { + return *x.BizPrivacyStatus + } + return WebMessageInfo_E2EE +} + +func (x *WebMessageInfo) GetVerifiedBizName() string { + if x != nil && x.VerifiedBizName != nil { + return *x.VerifiedBizName + } + return "" +} + +var File_def_proto protoreflect.FileDescriptor + +var file_def_proto_rawDesc = []byte{ + 0x0a, 0x09, 0x64, 0x65, 0x66, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x22, 0x60, 0x0a, 0x0c, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x6e, + 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, + 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, + 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x64, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, + 0x43, 0x6f, 0x64, 0x65, 0x22, 0x4c, 0x0a, 0x18, 0x48, 0x79, 0x64, 0x72, 0x61, 0x74, 0x65, 0x64, + 0x51, 0x75, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, + 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x54, 0x65, 0x78, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x54, 0x65, + 0x78, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x69, 0x64, 0x22, 0x47, 0x0a, 0x11, 0x48, 0x79, 0x64, 0x72, 0x61, 0x74, 0x65, 0x64, 0x55, 0x52, + 0x4c, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, + 0x61, 0x79, 0x54, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x54, 0x65, 0x78, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x58, 0x0a, 0x12, 0x48, + 0x79, 0x64, 0x72, 0x61, 0x74, 0x65, 0x64, 0x43, 0x61, 0x6c, 0x6c, 0x42, 0x75, 0x74, 0x74, 0x6f, + 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x54, 0x65, 0x78, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x54, + 0x65, 0x78, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x4e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x86, 0x02, 0x0a, 0x16, 0x48, 0x79, 0x64, 0x72, 0x61, 0x74, + 0x65, 0x64, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, + 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x4d, 0x0a, 0x10, 0x71, 0x75, 0x69, 0x63, 0x6b, 0x52, + 0x65, 0x70, 0x6c, 0x79, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x79, 0x64, 0x72, 0x61, 0x74, 0x65, + 0x64, 0x51, 0x75, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x42, 0x75, 0x74, 0x74, 0x6f, + 0x6e, 0x48, 0x00, 0x52, 0x10, 0x71, 0x75, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x42, + 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x09, 0x75, 0x72, 0x6c, 0x42, 0x75, 0x74, 0x74, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x48, 0x79, 0x64, 0x72, 0x61, 0x74, 0x65, 0x64, 0x55, 0x52, 0x4c, 0x42, 0x75, 0x74, 0x74, + 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x09, 0x75, 0x72, 0x6c, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x12, + 0x3b, 0x0a, 0x0a, 0x63, 0x61, 0x6c, 0x6c, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x79, 0x64, 0x72, + 0x61, 0x74, 0x65, 0x64, 0x43, 0x61, 0x6c, 0x6c, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x48, 0x00, + 0x52, 0x0a, 0x63, 0x61, 0x6c, 0x6c, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x42, 0x10, 0x0a, 0x0e, + 0x68, 0x79, 0x64, 0x72, 0x61, 0x74, 0x65, 0x64, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x22, 0x64, + 0x0a, 0x10, 0x51, 0x75, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x42, 0x75, 0x74, 0x74, + 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x54, 0x65, 0x78, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x48, 0x69, 0x67, 0x68, 0x6c, 0x79, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x64, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, + 0x54, 0x65, 0x78, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x22, 0x7f, 0x0a, 0x09, 0x55, 0x52, 0x4c, 0x42, 0x75, 0x74, 0x74, 0x6f, + 0x6e, 0x12, 0x40, 0x0a, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x54, 0x65, 0x78, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, + 0x69, 0x67, 0x68, 0x6c, 0x79, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x64, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x54, + 0x65, 0x78, 0x74, 0x12, 0x30, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x69, 0x67, 0x68, 0x6c, 0x79, 0x53, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x90, 0x01, 0x0a, 0x0a, 0x43, 0x61, 0x6c, 0x6c, 0x42, 0x75, + 0x74, 0x74, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x54, + 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x48, 0x69, 0x67, 0x68, 0x6c, 0x79, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, + 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, + 0x61, 0x79, 0x54, 0x65, 0x78, 0x74, 0x12, 0x40, 0x0a, 0x0b, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x4e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x69, 0x67, 0x68, 0x6c, 0x79, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x75, 0x72, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0b, 0x70, 0x68, 0x6f, + 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0xde, 0x01, 0x0a, 0x0e, 0x54, 0x65, 0x6d, + 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x12, 0x45, 0x0a, 0x10, 0x71, 0x75, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x42, + 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x51, 0x75, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x42, 0x75, + 0x74, 0x74, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x10, 0x71, 0x75, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x70, + 0x6c, 0x79, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x09, 0x75, 0x72, 0x6c, 0x42, + 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x55, 0x52, 0x4c, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x48, 0x00, 0x52, + 0x09, 0x75, 0x72, 0x6c, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x12, 0x33, 0x0a, 0x0a, 0x63, 0x61, + 0x6c, 0x6c, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x42, 0x75, 0x74, 0x74, 0x6f, + 0x6e, 0x48, 0x00, 0x52, 0x0a, 0x63, 0x61, 0x6c, 0x6c, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x42, + 0x08, 0x0a, 0x06, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x22, 0x74, 0x0a, 0x08, 0x4c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x0f, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x73, + 0x4c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0f, + 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x73, 0x4c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, + 0x2a, 0x0a, 0x10, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x73, 0x4c, 0x6f, 0x6e, 0x67, 0x69, 0x74, + 0x75, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x10, 0x64, 0x65, 0x67, 0x72, 0x65, + 0x65, 0x73, 0x4c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, + 0x67, 0x0a, 0x05, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x78, 0x44, 0x65, 0x70, + 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x78, + 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x79, 0x44, + 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x0b, 0x79, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x12, 0x0c, 0x0a, 0x01, + 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x01, 0x78, 0x12, 0x0c, 0x0a, 0x01, 0x79, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x01, 0x79, 0x22, 0x88, 0x01, 0x0a, 0x15, 0x49, 0x6e, 0x74, + 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x0f, 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x56, 0x65, 0x72, + 0x74, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x0f, 0x70, 0x6f, 0x6c, 0x79, 0x67, + 0x6f, 0x6e, 0x56, 0x65, 0x72, 0x74, 0x69, 0x63, 0x65, 0x73, 0x12, 0x2d, 0x0a, 0x08, 0x6c, 0x6f, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, + 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x08, 0x0a, 0x06, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x22, 0xc0, 0x01, 0x0a, 0x12, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, + 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x65, + 0x6e, 0x64, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x48, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0d, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x48, 0x61, 0x73, 0x68, + 0x12, 0x28, 0x0a, 0x0f, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x73, 0x65, 0x6e, 0x64, 0x65, + 0x72, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2a, 0x0a, 0x10, 0x72, 0x65, + 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x48, 0x61, 0x73, 0x68, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x4b, + 0x65, 0x79, 0x48, 0x61, 0x73, 0x68, 0x12, 0x2e, 0x0a, 0x12, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, + 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x12, 0x72, 0x65, 0x63, 0x69, 0x70, 0x69, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x5f, 0x0a, 0x12, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x49, 0x0a, 0x12, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x52, 0x12, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0xf4, 0x01, 0x0a, 0x0b, 0x41, 0x64, 0x52, 0x65, + 0x70, 0x6c, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x26, 0x0a, 0x0e, 0x61, 0x64, 0x76, 0x65, 0x72, + 0x74, 0x69, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0e, 0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x45, 0x0a, 0x09, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x64, 0x52, 0x65, 0x70, + 0x6c, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x41, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x49, 0x6e, + 0x66, 0x6f, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x6d, 0x65, 0x64, + 0x69, 0x61, 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x6a, 0x70, 0x65, 0x67, 0x54, 0x68, + 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x6a, + 0x70, 0x65, 0x67, 0x54, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x12, 0x18, 0x0a, 0x07, + 0x63, 0x61, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, + 0x61, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x36, 0x0a, 0x14, 0x41, 0x64, 0x52, 0x65, 0x70, 0x6c, + 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, + 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x49, 0x4d, 0x41, 0x47, + 0x45, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x49, 0x44, 0x45, 0x4f, 0x10, 0x02, 0x22, 0x8e, + 0x03, 0x0a, 0x13, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x64, 0x52, 0x65, 0x70, + 0x6c, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x62, 0x6f, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, + 0x12, 0x55, 0x0a, 0x09, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x37, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x78, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x2e, + 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x49, + 0x6e, 0x66, 0x6f, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x6d, 0x65, + 0x64, 0x69, 0x61, 0x54, 0x79, 0x70, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x74, 0x68, 0x75, 0x6d, 0x62, + 0x6e, 0x61, 0x69, 0x6c, 0x55, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x74, + 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x55, 0x72, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x6d, + 0x65, 0x64, 0x69, 0x61, 0x55, 0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, + 0x65, 0x64, 0x69, 0x61, 0x55, 0x72, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, 0x75, 0x6d, 0x62, + 0x6e, 0x61, 0x69, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x74, 0x68, 0x75, 0x6d, + 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, + 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, + 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x72, 0x6c, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, 0x72, 0x6c, 0x22, + 0x3e, 0x0a, 0x1c, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x64, 0x52, 0x65, 0x70, + 0x6c, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x49, 0x4d, 0x41, + 0x47, 0x45, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x49, 0x44, 0x45, 0x4f, 0x10, 0x02, 0x22, + 0xe0, 0x05, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x1a, 0x0a, 0x08, 0x73, 0x74, 0x61, 0x6e, 0x7a, 0x61, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x73, 0x74, 0x61, 0x6e, 0x7a, 0x61, 0x49, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x70, + 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x12, 0x34, 0x0a, + 0x0d, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x52, 0x0d, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4a, 0x69, 0x64, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4a, 0x69, + 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x4a, 0x69, + 0x64, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x6d, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, + 0x65, 0x64, 0x4a, 0x69, 0x64, 0x12, 0x2a, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x10, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x44, + 0x61, 0x74, 0x61, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x36, 0x0a, 0x16, 0x63, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x53, 0x65, 0x63, 0x6f, + 0x6e, 0x64, 0x73, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x16, 0x63, 0x6f, 0x6e, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x6c, 0x61, 0x79, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, + 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x66, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x53, + 0x63, 0x6f, 0x72, 0x65, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x66, 0x6f, 0x72, 0x77, + 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x69, + 0x73, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x64, 0x18, 0x16, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0b, 0x69, 0x73, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x64, 0x12, 0x2e, 0x0a, + 0x08, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x64, 0x41, 0x64, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x64, 0x41, 0x64, 0x12, 0x39, 0x0a, + 0x0e, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x18, + 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x0e, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, + 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x65, 0x78, 0x70, 0x69, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x65, 0x78, + 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3c, 0x0a, 0x19, 0x65, 0x70, 0x68, 0x65, + 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x19, 0x65, 0x70, 0x68, + 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x34, 0x0a, 0x15, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, + 0x72, 0x61, 0x6c, 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, + 0x1b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x15, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, + 0x53, 0x68, 0x61, 0x72, 0x65, 0x64, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x44, 0x0a, 0x0f, + 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x18, + 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x78, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x0f, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x64, 0x52, 0x65, 0x70, + 0x6c, 0x79, 0x22, 0x8a, 0x01, 0x0a, 0x1c, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4b, 0x65, 0x79, + 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, 0x50, 0x0a, + 0x23, 0x61, 0x78, 0x6f, 0x6c, 0x6f, 0x74, 0x6c, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4b, 0x65, + 0x79, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x23, 0x61, 0x78, 0x6f, 0x6c, + 0x6f, 0x74, 0x6c, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x44, 0x69, 0x73, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, + 0xe6, 0x07, 0x0a, 0x0c, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, + 0x72, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x69, 0x6d, 0x65, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x69, 0x6d, 0x65, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, + 0x0a, 0x07, 0x63, 0x61, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x63, 0x61, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x69, 0x6c, 0x65, + 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x66, 0x69, + 0x6c, 0x65, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x69, 0x6c, 0x65, + 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x66, 0x69, + 0x6c, 0x65, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x12, 0x14, 0x0a, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x4b, + 0x65, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x4b, + 0x65, 0x79, 0x12, 0x24, 0x0a, 0x0d, 0x66, 0x69, 0x6c, 0x65, 0x45, 0x6e, 0x63, 0x53, 0x68, 0x61, + 0x32, 0x35, 0x36, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x66, 0x69, 0x6c, 0x65, 0x45, + 0x6e, 0x63, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x12, 0x54, 0x0a, 0x16, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x41, 0x6e, 0x6e, 0x6f, + 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x16, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x65, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e, + 0x0a, 0x0a, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x50, 0x61, 0x74, 0x68, 0x18, 0x0b, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, 0x2c, + 0x0a, 0x11, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x4b, 0x65, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x6d, 0x65, 0x64, 0x69, 0x61, + 0x4b, 0x65, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x24, 0x0a, 0x0d, + 0x6a, 0x70, 0x65, 0x67, 0x54, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x18, 0x10, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x6a, 0x70, 0x65, 0x67, 0x54, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, + 0x69, 0x6c, 0x12, 0x34, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, + 0x6f, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2a, 0x0a, 0x10, 0x66, 0x69, 0x72, 0x73, + 0x74, 0x53, 0x63, 0x61, 0x6e, 0x53, 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x18, 0x12, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x10, 0x66, 0x69, 0x72, 0x73, 0x74, 0x53, 0x63, 0x61, 0x6e, 0x53, 0x69, 0x64, + 0x65, 0x63, 0x61, 0x72, 0x12, 0x28, 0x0a, 0x0f, 0x66, 0x69, 0x72, 0x73, 0x74, 0x53, 0x63, 0x61, + 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x66, + 0x69, 0x72, 0x73, 0x74, 0x53, 0x63, 0x61, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x2c, + 0x0a, 0x11, 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x49, 0x64, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x65, 0x78, 0x70, 0x65, 0x72, + 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0c, + 0x73, 0x63, 0x61, 0x6e, 0x73, 0x53, 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x18, 0x15, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x0c, 0x73, 0x63, 0x61, 0x6e, 0x73, 0x53, 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, + 0x12, 0x20, 0x0a, 0x0b, 0x73, 0x63, 0x61, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x73, 0x18, + 0x16, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x0b, 0x73, 0x63, 0x61, 0x6e, 0x4c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x73, 0x12, 0x32, 0x0a, 0x14, 0x6d, 0x69, 0x64, 0x51, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, + 0x46, 0x69, 0x6c, 0x65, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x14, 0x6d, 0x69, 0x64, 0x51, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x46, 0x69, 0x6c, 0x65, + 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x12, 0x38, 0x0a, 0x17, 0x6d, 0x69, 0x64, 0x51, 0x75, 0x61, + 0x6c, 0x69, 0x74, 0x79, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x6e, 0x63, 0x53, 0x68, 0x61, 0x32, 0x35, + 0x36, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x17, 0x6d, 0x69, 0x64, 0x51, 0x75, 0x61, 0x6c, + 0x69, 0x74, 0x79, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x6e, 0x63, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, + 0x12, 0x1a, 0x0a, 0x08, 0x76, 0x69, 0x65, 0x77, 0x4f, 0x6e, 0x63, 0x65, 0x18, 0x19, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x08, 0x76, 0x69, 0x65, 0x77, 0x4f, 0x6e, 0x63, 0x65, 0x12, 0x30, 0x0a, 0x13, + 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x50, + 0x61, 0x74, 0x68, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x74, 0x68, 0x75, 0x6d, 0x62, + 0x6e, 0x61, 0x69, 0x6c, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, 0x28, + 0x0a, 0x0f, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x53, 0x68, 0x61, 0x32, 0x35, + 0x36, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, + 0x69, 0x6c, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x12, 0x2e, 0x0a, 0x12, 0x74, 0x68, 0x75, 0x6d, + 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x45, 0x6e, 0x63, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x18, 0x1c, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x12, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x45, + 0x6e, 0x63, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x22, 0xc8, 0x04, 0x0a, 0x0e, 0x49, 0x6e, 0x76, + 0x6f, 0x69, 0x63, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x6f, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x6f, 0x74, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x5a, 0x0a, 0x0e, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, + 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x32, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x0e, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x4d, + 0x69, 0x6d, 0x65, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x61, + 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x69, 0x6d, 0x65, 0x74, 0x79, 0x70, + 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x4d, + 0x65, 0x64, 0x69, 0x61, 0x4b, 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x12, 0x61, + 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x4b, 0x65, + 0x79, 0x12, 0x40, 0x0a, 0x1b, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x4d, + 0x65, 0x64, 0x69, 0x61, 0x4b, 0x65, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1b, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, + 0x6e, 0x74, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x4b, 0x65, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x12, 0x32, 0x0a, 0x14, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, + 0x74, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x14, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x46, 0x69, 0x6c, + 0x65, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x12, 0x38, 0x0a, 0x17, 0x61, 0x74, 0x74, 0x61, 0x63, + 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x6e, 0x63, 0x53, 0x68, 0x61, 0x32, + 0x35, 0x36, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x17, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, + 0x6d, 0x65, 0x6e, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x45, 0x6e, 0x63, 0x53, 0x68, 0x61, 0x32, 0x35, + 0x36, 0x12, 0x32, 0x0a, 0x14, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x44, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x50, 0x61, 0x74, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x14, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x44, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, 0x38, 0x0a, 0x17, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, + 0x65, 0x6e, 0x74, 0x4a, 0x70, 0x65, 0x67, 0x54, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x17, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, + 0x6e, 0x74, 0x4a, 0x70, 0x65, 0x67, 0x54, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x22, + 0x32, 0x0a, 0x1c, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x41, 0x74, 0x74, 0x61, 0x63, 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x09, 0x0a, 0x05, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x50, 0x44, + 0x46, 0x10, 0x01, 0x22, 0x7e, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, + 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x63, 0x61, 0x72, 0x64, + 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x63, 0x61, 0x72, 0x64, 0x12, 0x34, 0x0a, + 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x11, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, + 0x6e, 0x66, 0x6f, 0x22, 0xcf, 0x03, 0x0a, 0x0f, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x64, 0x65, 0x67, 0x72, 0x65, + 0x65, 0x73, 0x4c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, + 0x52, 0x0f, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x73, 0x4c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, + 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x73, 0x4c, 0x6f, 0x6e, 0x67, + 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x10, 0x64, 0x65, 0x67, + 0x72, 0x65, 0x65, 0x73, 0x4c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x75, + 0x72, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x16, 0x0a, + 0x06, 0x69, 0x73, 0x4c, 0x69, 0x76, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, + 0x73, 0x4c, 0x69, 0x76, 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x61, 0x63, 0x63, 0x75, 0x72, 0x61, 0x63, + 0x79, 0x49, 0x6e, 0x4d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x10, 0x61, 0x63, 0x63, 0x75, 0x72, 0x61, 0x63, 0x79, 0x49, 0x6e, 0x4d, 0x65, 0x74, 0x65, 0x72, + 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x70, 0x65, 0x65, 0x64, 0x49, 0x6e, 0x4d, 0x70, 0x73, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0a, 0x73, 0x70, 0x65, 0x65, 0x64, 0x49, 0x6e, 0x4d, 0x70, + 0x73, 0x12, 0x4c, 0x0a, 0x21, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x73, 0x43, 0x6c, 0x6f, 0x63, + 0x6b, 0x77, 0x69, 0x73, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x4d, 0x61, 0x67, 0x6e, 0x65, 0x74, 0x69, + 0x63, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x21, 0x64, 0x65, + 0x67, 0x72, 0x65, 0x65, 0x73, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x77, 0x69, 0x73, 0x65, 0x46, 0x72, + 0x6f, 0x6d, 0x4d, 0x61, 0x67, 0x6e, 0x65, 0x74, 0x69, 0x63, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x12, + 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x6a, 0x70, 0x65, + 0x67, 0x54, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0d, 0x6a, 0x70, 0x65, 0x67, 0x54, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x12, + 0x34, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x11, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0xdd, 0x05, 0x0a, 0x13, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, + 0x65, 0x64, 0x54, 0x65, 0x78, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, 0x78, + 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x54, 0x65, 0x78, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x64, 0x54, + 0x65, 0x78, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x61, 0x6e, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x6c, + 0x55, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x61, 0x6e, 0x6f, 0x6e, + 0x69, 0x63, 0x61, 0x6c, 0x55, 0x72, 0x6c, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, + 0x1a, 0x0a, 0x08, 0x74, 0x65, 0x78, 0x74, 0x41, 0x72, 0x67, 0x62, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x07, 0x52, 0x08, 0x74, 0x65, 0x78, 0x74, 0x41, 0x72, 0x67, 0x62, 0x12, 0x26, 0x0a, 0x0e, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x41, 0x72, 0x67, 0x62, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x07, 0x52, 0x0e, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x41, + 0x72, 0x67, 0x62, 0x12, 0x4a, 0x0a, 0x04, 0x66, 0x6f, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x36, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, + 0x65, 0x64, 0x54, 0x65, 0x78, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x45, 0x78, + 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x54, 0x65, 0x78, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x46, 0x6f, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x66, 0x6f, 0x6e, 0x74, 0x12, + 0x5b, 0x0a, 0x0b, 0x70, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x54, 0x79, 0x70, 0x65, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x78, 0x74, + 0x65, 0x6e, 0x64, 0x65, 0x64, 0x54, 0x65, 0x78, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x54, 0x65, 0x78, 0x74, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x0b, 0x70, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x0d, + 0x6a, 0x70, 0x65, 0x67, 0x54, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x18, 0x10, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x6a, 0x70, 0x65, 0x67, 0x54, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, + 0x69, 0x6c, 0x12, 0x34, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, + 0x6f, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x28, 0x0a, 0x0f, 0x64, 0x6f, 0x4e, 0x6f, + 0x74, 0x50, 0x6c, 0x61, 0x79, 0x49, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0f, 0x64, 0x6f, 0x4e, 0x6f, 0x74, 0x50, 0x6c, 0x61, 0x79, 0x49, 0x6e, 0x6c, 0x69, + 0x6e, 0x65, 0x22, 0x89, 0x01, 0x0a, 0x1b, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x54, + 0x65, 0x78, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x46, 0x6f, 0x6e, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x0e, 0x0a, 0x0a, 0x53, 0x41, 0x4e, 0x53, 0x5f, 0x53, 0x45, 0x52, 0x49, 0x46, + 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x45, 0x52, 0x49, 0x46, 0x10, 0x01, 0x12, 0x13, 0x0a, + 0x0f, 0x4e, 0x4f, 0x52, 0x49, 0x43, 0x41, 0x4e, 0x5f, 0x52, 0x45, 0x47, 0x55, 0x4c, 0x41, 0x52, + 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x42, 0x52, 0x59, 0x4e, 0x44, 0x41, 0x4e, 0x5f, 0x57, 0x52, + 0x49, 0x54, 0x45, 0x10, 0x03, 0x12, 0x15, 0x0a, 0x11, 0x42, 0x45, 0x42, 0x41, 0x53, 0x4e, 0x45, + 0x55, 0x45, 0x5f, 0x52, 0x45, 0x47, 0x55, 0x4c, 0x41, 0x52, 0x10, 0x04, 0x12, 0x10, 0x0a, 0x0c, + 0x4f, 0x53, 0x57, 0x41, 0x4c, 0x44, 0x5f, 0x48, 0x45, 0x41, 0x56, 0x59, 0x10, 0x05, 0x22, 0x35, + 0x0a, 0x1e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x54, 0x65, 0x78, 0x74, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x49, + 0x44, 0x45, 0x4f, 0x10, 0x01, 0x22, 0xbd, 0x05, 0x0a, 0x0f, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x6d, + 0x69, 0x6d, 0x65, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, + 0x69, 0x6d, 0x65, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x1e, 0x0a, + 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x12, 0x1e, 0x0a, + 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x1c, 0x0a, + 0x09, 0x70, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6d, + 0x65, 0x64, 0x69, 0x61, 0x4b, 0x65, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6d, + 0x65, 0x64, 0x69, 0x61, 0x4b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x66, 0x69, 0x6c, 0x65, 0x45, 0x6e, 0x63, 0x53, 0x68, + 0x61, 0x32, 0x35, 0x36, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x66, 0x69, 0x6c, 0x65, + 0x45, 0x6e, 0x63, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x69, 0x72, + 0x65, 0x63, 0x74, 0x50, 0x61, 0x74, 0x68, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, 0x2c, 0x0a, 0x11, 0x6d, 0x65, 0x64, + 0x69, 0x61, 0x4b, 0x65, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x0b, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x4b, 0x65, 0x79, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x63, 0x74, 0x56, 0x63, 0x61, 0x72, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x56, 0x63, 0x61, 0x72, 0x64, 0x12, 0x30, 0x0a, 0x13, 0x74, + 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x50, 0x61, + 0x74, 0x68, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, + 0x61, 0x69, 0x6c, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, 0x28, 0x0a, + 0x0f, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, + 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, + 0x6c, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x12, 0x2e, 0x0a, 0x12, 0x74, 0x68, 0x75, 0x6d, 0x62, + 0x6e, 0x61, 0x69, 0x6c, 0x45, 0x6e, 0x63, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x18, 0x0f, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x12, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x45, 0x6e, + 0x63, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x12, 0x24, 0x0a, 0x0d, 0x6a, 0x70, 0x65, 0x67, 0x54, + 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, + 0x6a, 0x70, 0x65, 0x67, 0x54, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x12, 0x34, 0x0a, + 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x11, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, + 0x6e, 0x66, 0x6f, 0x12, 0x28, 0x0a, 0x0f, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, + 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x74, 0x68, + 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x26, 0x0a, + 0x0e, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x57, 0x69, 0x64, 0x74, 0x68, 0x18, + 0x13, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, + 0x57, 0x69, 0x64, 0x74, 0x68, 0x22, 0x9a, 0x03, 0x0a, 0x0c, 0x41, 0x75, 0x64, 0x69, 0x6f, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x69, 0x6d, 0x65, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x69, 0x6d, 0x65, + 0x74, 0x79, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x68, 0x61, 0x32, + 0x35, 0x36, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x68, + 0x61, 0x32, 0x35, 0x36, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x4c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x4c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x10, + 0x0a, 0x03, 0x70, 0x74, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x70, 0x74, 0x74, + 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x4b, 0x65, 0x79, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x08, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x4b, 0x65, 0x79, 0x12, 0x24, 0x0a, 0x0d, + 0x66, 0x69, 0x6c, 0x65, 0x45, 0x6e, 0x63, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x66, 0x69, 0x6c, 0x65, 0x45, 0x6e, 0x63, 0x53, 0x68, 0x61, 0x32, + 0x35, 0x36, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x50, 0x61, 0x74, 0x68, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x50, 0x61, + 0x74, 0x68, 0x12, 0x2c, 0x0a, 0x11, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x4b, 0x65, 0x79, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x6d, + 0x65, 0x64, 0x69, 0x61, 0x4b, 0x65, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x12, 0x34, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x18, + 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2a, 0x0a, 0x10, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x69, 0x6e, 0x67, 0x53, 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x10, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x69, 0x64, 0x65, 0x63, + 0x61, 0x72, 0x22, 0xa6, 0x07, 0x0a, 0x0c, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x69, 0x6d, 0x65, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x69, 0x6d, 0x65, 0x74, 0x79, 0x70, + 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x68, 0x61, 0x32, 0x35, + 0x36, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x4c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x07, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x6d, + 0x65, 0x64, 0x69, 0x61, 0x4b, 0x65, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6d, + 0x65, 0x64, 0x69, 0x61, 0x4b, 0x65, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x61, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x61, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x67, 0x69, 0x66, 0x50, 0x6c, 0x61, 0x79, 0x62, 0x61, 0x63, 0x6b, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x67, 0x69, 0x66, 0x50, 0x6c, 0x61, 0x79, 0x62, + 0x61, 0x63, 0x6b, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x12, 0x24, 0x0a, 0x0d, 0x66, 0x69, 0x6c, 0x65, 0x45, 0x6e, 0x63, 0x53, 0x68, 0x61, 0x32, + 0x35, 0x36, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x66, 0x69, 0x6c, 0x65, 0x45, 0x6e, + 0x63, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x12, 0x54, 0x0a, 0x16, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x49, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x41, 0x6e, 0x6e, 0x6f, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x16, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x0a, + 0x0a, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x50, 0x61, 0x74, 0x68, 0x18, 0x0d, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, 0x2c, 0x0a, + 0x11, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x4b, 0x65, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x03, 0x52, 0x11, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x4b, + 0x65, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x24, 0x0a, 0x0d, 0x6a, + 0x70, 0x65, 0x67, 0x54, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x18, 0x10, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x0d, 0x6a, 0x70, 0x65, 0x67, 0x54, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, + 0x6c, 0x12, 0x34, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, + 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2a, 0x0a, 0x10, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x18, 0x12, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x10, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x53, 0x69, 0x64, 0x65, + 0x63, 0x61, 0x72, 0x12, 0x53, 0x0a, 0x0e, 0x67, 0x69, 0x66, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x2e, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x67, 0x69, 0x66, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x76, 0x69, 0x65, 0x77, + 0x4f, 0x6e, 0x63, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x76, 0x69, 0x65, 0x77, + 0x4f, 0x6e, 0x63, 0x65, 0x12, 0x30, 0x0a, 0x13, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, + 0x6c, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x50, 0x61, 0x74, 0x68, 0x18, 0x15, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x13, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x44, 0x69, 0x72, 0x65, + 0x63, 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, 0x28, 0x0a, 0x0f, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, + 0x61, 0x69, 0x6c, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0f, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, + 0x12, 0x2e, 0x0a, 0x12, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x45, 0x6e, 0x63, + 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x12, 0x74, 0x68, + 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x45, 0x6e, 0x63, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, + 0x22, 0x39, 0x0a, 0x17, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x08, 0x0a, 0x04, 0x4e, + 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x47, 0x49, 0x50, 0x48, 0x59, 0x10, 0x01, + 0x12, 0x09, 0x0a, 0x05, 0x54, 0x45, 0x4e, 0x4f, 0x52, 0x10, 0x02, 0x22, 0x20, 0x0a, 0x04, 0x43, + 0x61, 0x6c, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x61, 0x6c, 0x6c, 0x4b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x63, 0x61, 0x6c, 0x6c, 0x4b, 0x65, 0x79, 0x22, 0x38, 0x0a, + 0x04, 0x43, 0x68, 0x61, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, + 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x9d, 0x08, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x3e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x12, 0x30, 0x0a, 0x13, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x45, 0x78, 0x70, + 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x65, + 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x3c, 0x0a, 0x19, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x19, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, + 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x12, 0x58, 0x0a, 0x17, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x79, 0x6e, 0x63, 0x4e, + 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, + 0x79, 0x53, 0x79, 0x6e, 0x63, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x17, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x79, 0x6e, 0x63, 0x4e, 0x6f, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4f, 0x0a, 0x14, 0x61, 0x70, + 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x4b, 0x65, 0x79, 0x53, 0x68, 0x61, + 0x72, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x41, 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x4b, 0x65, 0x79, + 0x53, 0x68, 0x61, 0x72, 0x65, 0x52, 0x14, 0x61, 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, + 0x79, 0x6e, 0x63, 0x4b, 0x65, 0x79, 0x53, 0x68, 0x61, 0x72, 0x65, 0x12, 0x55, 0x0a, 0x16, 0x61, + 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, + 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x16, 0x61, 0x70, 0x70, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x85, 0x01, 0x0a, 0x26, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x53, 0x65, + 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x6e, 0x63, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x6e, 0x69, 0x74, + 0x69, 0x61, 0x6c, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x4e, 0x6f, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x79, + 0x6e, 0x63, 0x52, 0x26, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x53, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, + 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x79, 0x0a, 0x22, 0x61, 0x70, + 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x46, 0x61, 0x74, 0x61, 0x6c, 0x45, 0x78, 0x63, 0x65, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, + 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x46, 0x61, 0x74, 0x61, 0x6c, 0x45, 0x78, 0x63, 0x65, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x22, 0x61, 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x46, 0x61, 0x74, 0x61, 0x6c, + 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xaf, 0x02, 0x0a, 0x13, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, + 0x06, 0x52, 0x45, 0x56, 0x4f, 0x4b, 0x45, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x45, 0x50, 0x48, + 0x45, 0x4d, 0x45, 0x52, 0x41, 0x4c, 0x5f, 0x53, 0x45, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x03, + 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x50, 0x48, 0x45, 0x4d, 0x45, 0x52, 0x41, 0x4c, 0x5f, 0x53, 0x59, + 0x4e, 0x43, 0x5f, 0x52, 0x45, 0x53, 0x50, 0x4f, 0x4e, 0x53, 0x45, 0x10, 0x04, 0x12, 0x1d, 0x0a, + 0x19, 0x48, 0x49, 0x53, 0x54, 0x4f, 0x52, 0x59, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x4e, 0x4f, + 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x05, 0x12, 0x1c, 0x0a, 0x18, + 0x41, 0x50, 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x4b, + 0x45, 0x59, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x10, 0x06, 0x12, 0x1e, 0x0a, 0x1a, 0x41, 0x50, + 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x5f, 0x4b, 0x45, 0x59, + 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0x07, 0x12, 0x1f, 0x0a, 0x1b, 0x4d, 0x53, + 0x47, 0x5f, 0x46, 0x41, 0x4e, 0x4f, 0x55, 0x54, 0x5f, 0x42, 0x41, 0x43, 0x4b, 0x46, 0x49, 0x4c, + 0x4c, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0x08, 0x12, 0x2e, 0x0a, 0x2a, 0x49, + 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x5f, 0x53, 0x45, 0x43, 0x55, 0x52, 0x49, 0x54, 0x59, 0x5f, + 0x4e, 0x4f, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x54, + 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x53, 0x59, 0x4e, 0x43, 0x10, 0x09, 0x12, 0x2a, 0x0a, 0x26, 0x41, + 0x50, 0x50, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x46, 0x41, 0x54, 0x41, 0x4c, 0x5f, 0x45, + 0x58, 0x43, 0x45, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, 0x54, 0x49, 0x46, 0x49, 0x43, + 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x0a, 0x22, 0xe9, 0x03, 0x0a, 0x17, 0x48, 0x69, 0x73, 0x74, + 0x6f, 0x72, 0x79, 0x53, 0x79, 0x6e, 0x63, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x68, 0x61, 0x32, 0x35, + 0x36, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x68, 0x61, + 0x32, 0x35, 0x36, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x4c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x4c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x4b, 0x65, 0x79, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x4b, 0x65, 0x79, 0x12, + 0x24, 0x0a, 0x0d, 0x66, 0x69, 0x6c, 0x65, 0x45, 0x6e, 0x63, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x66, 0x69, 0x6c, 0x65, 0x45, 0x6e, 0x63, 0x53, + 0x68, 0x61, 0x32, 0x35, 0x36, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x50, + 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, 0x61, 0x0a, 0x08, 0x73, 0x79, 0x6e, 0x63, 0x54, 0x79, 0x70, + 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x45, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x79, 0x6e, 0x63, 0x4e, 0x6f, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x53, + 0x79, 0x6e, 0x63, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x48, + 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, + 0x73, 0x79, 0x6e, 0x63, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x68, 0x75, 0x6e, + 0x6b, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x63, 0x68, + 0x75, 0x6e, 0x6b, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x2c, 0x0a, 0x11, 0x6f, 0x72, 0x69, 0x67, + 0x69, 0x6e, 0x61, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x11, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x49, 0x64, 0x22, 0x7b, 0x0a, 0x26, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, + 0x79, 0x53, 0x79, 0x6e, 0x63, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x15, 0x0a, 0x11, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x5f, 0x42, 0x4f, 0x4f, 0x54, + 0x53, 0x54, 0x52, 0x41, 0x50, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x49, 0x4e, 0x49, 0x54, 0x49, + 0x41, 0x4c, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x56, 0x33, 0x10, 0x01, 0x12, 0x08, + 0x0a, 0x04, 0x46, 0x55, 0x4c, 0x4c, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x52, 0x45, 0x43, 0x45, + 0x4e, 0x54, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x50, 0x55, 0x53, 0x48, 0x5f, 0x4e, 0x41, 0x4d, + 0x45, 0x10, 0x04, 0x22, 0x77, 0x0a, 0x0f, 0x41, 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, + 0x79, 0x6e, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x70, + 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x52, + 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x34, 0x0a, 0x07, 0x6b, 0x65, 0x79, 0x44, 0x61, 0x74, + 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x41, 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x4b, 0x65, 0x79, 0x44, + 0x61, 0x74, 0x61, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x44, 0x61, 0x74, 0x61, 0x22, 0x29, 0x0a, 0x11, + 0x41, 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x4b, 0x65, 0x79, 0x49, + 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x22, 0x80, 0x01, 0x0a, 0x1a, 0x41, 0x70, 0x70, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x4b, 0x65, 0x79, 0x46, 0x69, 0x6e, 0x67, 0x65, + 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x61, 0x77, 0x49, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x72, 0x61, 0x77, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0c, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, + 0x12, 0x28, 0x0a, 0x0d, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0d, 0x42, 0x02, 0x10, 0x01, 0x52, 0x0d, 0x64, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73, 0x22, 0x92, 0x01, 0x0a, 0x13, 0x41, + 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x4b, 0x65, 0x79, 0x44, 0x61, + 0x74, 0x61, 0x12, 0x18, 0x0a, 0x07, 0x6b, 0x65, 0x79, 0x44, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x44, 0x61, 0x74, 0x61, 0x12, 0x43, 0x0a, 0x0b, + 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x70, 0x70, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x4b, 0x65, 0x79, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, + 0x72, 0x69, 0x6e, 0x74, 0x52, 0x0b, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, + 0x42, 0x0a, 0x14, 0x41, 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x4b, + 0x65, 0x79, 0x53, 0x68, 0x61, 0x72, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x70, + 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, 0x6e, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x04, 0x6b, + 0x65, 0x79, 0x73, 0x22, 0x4a, 0x0a, 0x16, 0x41, 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, + 0x79, 0x6e, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x30, 0x0a, + 0x06, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x79, + 0x6e, 0x63, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x52, 0x06, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x73, 0x22, + 0x6c, 0x0a, 0x22, 0x41, 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x46, 0x61, 0x74, 0x61, 0x6c, + 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x0f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, + 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, + 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x6a, 0x0a, + 0x26, 0x49, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, + 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x74, 0x74, + 0x69, 0x6e, 0x67, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x40, 0x0a, 0x1b, 0x73, 0x65, 0x63, 0x75, 0x72, + 0x69, 0x74, 0x79, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1b, 0x73, 0x65, + 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0xa1, 0x01, 0x0a, 0x14, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x41, 0x72, 0x72, 0x61, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x31, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x12, 0x34, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x51, 0x0a, + 0x0b, 0x48, 0x53, 0x4d, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x22, 0x0a, 0x0c, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x64, 0x65, + 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x31, 0x30, 0x30, 0x30, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x31, 0x30, 0x30, 0x30, + 0x22, 0x88, 0x04, 0x0a, 0x14, 0x48, 0x53, 0x4d, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, + 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x5b, 0x0a, 0x09, 0x64, 0x61, 0x79, + 0x4f, 0x66, 0x57, 0x65, 0x65, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3d, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x53, 0x4d, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, + 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x2e, 0x48, 0x53, 0x4d, 0x44, 0x61, 0x74, + 0x65, 0x54, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x44, 0x61, + 0x79, 0x4f, 0x66, 0x57, 0x65, 0x65, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x52, 0x09, 0x64, 0x61, 0x79, + 0x4f, 0x66, 0x57, 0x65, 0x65, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x79, 0x65, 0x61, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x79, 0x65, 0x61, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, + 0x6e, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x6f, 0x6e, 0x74, 0x68, + 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x61, 0x79, 0x4f, 0x66, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x64, 0x61, 0x79, 0x4f, 0x66, 0x4d, 0x6f, 0x6e, 0x74, 0x68, + 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x75, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, + 0x68, 0x6f, 0x75, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x69, 0x6e, 0x75, 0x74, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6d, 0x69, 0x6e, 0x75, 0x74, 0x65, 0x12, 0x58, 0x0a, 0x08, + 0x63, 0x61, 0x6c, 0x65, 0x6e, 0x64, 0x61, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x3c, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x53, 0x4d, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, + 0x6d, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x2e, 0x48, 0x53, 0x4d, 0x44, + 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, + 0x43, 0x61, 0x6c, 0x65, 0x6e, 0x64, 0x61, 0x72, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x63, 0x61, + 0x6c, 0x65, 0x6e, 0x64, 0x61, 0x72, 0x22, 0x7f, 0x0a, 0x21, 0x48, 0x53, 0x4d, 0x44, 0x61, 0x74, + 0x65, 0x54, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x44, 0x61, + 0x79, 0x4f, 0x66, 0x57, 0x65, 0x65, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x4d, + 0x4f, 0x4e, 0x44, 0x41, 0x59, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x54, 0x55, 0x45, 0x53, 0x44, + 0x41, 0x59, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x57, 0x45, 0x44, 0x4e, 0x45, 0x53, 0x44, 0x41, + 0x59, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x54, 0x48, 0x55, 0x52, 0x53, 0x44, 0x41, 0x59, 0x10, + 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x52, 0x49, 0x44, 0x41, 0x59, 0x10, 0x05, 0x12, 0x0c, 0x0a, + 0x08, 0x53, 0x41, 0x54, 0x55, 0x52, 0x44, 0x41, 0x59, 0x10, 0x06, 0x12, 0x0a, 0x0a, 0x06, 0x53, + 0x55, 0x4e, 0x44, 0x41, 0x59, 0x10, 0x07, 0x22, 0x42, 0x0a, 0x20, 0x48, 0x53, 0x4d, 0x44, 0x61, + 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x43, + 0x61, 0x6c, 0x65, 0x6e, 0x64, 0x61, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0d, 0x0a, 0x09, 0x47, + 0x52, 0x45, 0x47, 0x4f, 0x52, 0x49, 0x41, 0x4e, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x4f, + 0x4c, 0x41, 0x52, 0x5f, 0x48, 0x49, 0x4a, 0x52, 0x49, 0x10, 0x02, 0x22, 0x34, 0x0a, 0x14, 0x48, + 0x53, 0x4d, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x55, 0x6e, 0x69, 0x78, 0x45, 0x70, + 0x6f, 0x63, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x22, 0x98, 0x01, 0x0a, 0x0b, 0x48, 0x53, 0x4d, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, + 0x65, 0x12, 0x3b, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x53, 0x4d, + 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, + 0x74, 0x48, 0x00, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x3b, + 0x0a, 0x09, 0x75, 0x6e, 0x69, 0x78, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x53, 0x4d, 0x44, 0x61, 0x74, + 0x65, 0x54, 0x69, 0x6d, 0x65, 0x55, 0x6e, 0x69, 0x78, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x48, 0x00, + 0x52, 0x09, 0x75, 0x6e, 0x69, 0x78, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x42, 0x0f, 0x0a, 0x0d, 0x64, + 0x61, 0x74, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x4f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0xa5, 0x01, 0x0a, + 0x17, 0x48, 0x53, 0x4d, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x62, 0x6c, 0x65, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x66, 0x61, 0x75, + 0x6c, 0x74, 0x12, 0x30, 0x0a, 0x08, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x53, 0x4d, + 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x48, 0x00, 0x52, 0x08, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x63, 0x79, 0x12, 0x30, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, + 0x53, 0x4d, 0x44, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x48, 0x00, 0x52, 0x08, 0x64, 0x61, + 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x42, 0x0c, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x4f, + 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x8d, 0x03, 0x0a, 0x17, 0x48, 0x69, 0x67, 0x68, 0x6c, 0x79, 0x53, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x20, + 0x0a, 0x0b, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x16, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x61, 0x6c, 0x6c, + 0x62, 0x61, 0x63, 0x6b, 0x4c, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x61, + 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x4c, 0x67, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x61, 0x6c, 0x6c, + 0x62, 0x61, 0x63, 0x6b, 0x4c, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x61, + 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x4c, 0x63, 0x12, 0x4c, 0x0a, 0x11, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x69, 0x7a, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x06, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x53, 0x4d, 0x4c, + 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, + 0x74, 0x65, 0x72, 0x52, 0x11, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x62, 0x6c, 0x65, + 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, + 0x69, 0x6e, 0x69, 0x73, 0x74, 0x69, 0x63, 0x4c, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0f, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x74, 0x69, 0x63, 0x4c, 0x67, + 0x12, 0x28, 0x0a, 0x0f, 0x64, 0x65, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x74, 0x69, + 0x63, 0x4c, 0x63, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x64, 0x65, 0x74, 0x65, 0x72, + 0x6d, 0x69, 0x6e, 0x69, 0x73, 0x74, 0x69, 0x63, 0x4c, 0x63, 0x12, 0x38, 0x0a, 0x0b, 0x68, 0x79, + 0x64, 0x72, 0x61, 0x74, 0x65, 0x64, 0x48, 0x73, 0x6d, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0b, 0x68, 0x79, 0x64, 0x72, 0x61, 0x74, 0x65, + 0x64, 0x48, 0x73, 0x6d, 0x22, 0x87, 0x01, 0x0a, 0x12, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x79, + 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x30, 0x0a, 0x0b, 0x6e, + 0x6f, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x52, 0x0b, 0x6e, 0x6f, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3f, 0x0a, + 0x11, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4b, + 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x11, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4b, 0x65, 0x79, 0x22, 0x94, + 0x02, 0x0a, 0x15, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, + 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x30, 0x0a, 0x0b, 0x6e, 0x6f, 0x74, 0x65, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0b, 0x6e, + 0x6f, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x30, 0x0a, 0x13, 0x63, 0x75, + 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x73, 0x6f, 0x34, 0x32, 0x31, + 0x37, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, + 0x79, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x73, 0x6f, 0x34, 0x32, 0x31, 0x37, 0x12, 0x1e, 0x0a, 0x0a, + 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x31, 0x30, 0x30, 0x30, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x0a, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x31, 0x30, 0x30, 0x30, 0x12, 0x20, 0x0a, 0x0b, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x28, + 0x0a, 0x0f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x54, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2b, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, 0x06, 0x61, + 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x43, 0x0a, 0x1c, 0x44, 0x65, 0x63, 0x6c, 0x69, 0x6e, 0x65, + 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x42, 0x0a, 0x1b, 0x43, 0x61, + 0x6e, 0x63, 0x65, 0x6c, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0xc3, + 0x03, 0x0a, 0x13, 0x4c, 0x69, 0x76, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, + 0x73, 0x4c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, + 0x0f, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x73, 0x4c, 0x61, 0x74, 0x69, 0x74, 0x75, 0x64, 0x65, + 0x12, 0x2a, 0x0a, 0x10, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x73, 0x4c, 0x6f, 0x6e, 0x67, 0x69, + 0x74, 0x75, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x10, 0x64, 0x65, 0x67, 0x72, + 0x65, 0x65, 0x73, 0x4c, 0x6f, 0x6e, 0x67, 0x69, 0x74, 0x75, 0x64, 0x65, 0x12, 0x2a, 0x0a, 0x10, + 0x61, 0x63, 0x63, 0x75, 0x72, 0x61, 0x63, 0x79, 0x49, 0x6e, 0x4d, 0x65, 0x74, 0x65, 0x72, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x61, 0x63, 0x63, 0x75, 0x72, 0x61, 0x63, 0x79, + 0x49, 0x6e, 0x4d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x70, 0x65, 0x65, + 0x64, 0x49, 0x6e, 0x4d, 0x70, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x02, 0x52, 0x0a, 0x73, 0x70, + 0x65, 0x65, 0x64, 0x49, 0x6e, 0x4d, 0x70, 0x73, 0x12, 0x4c, 0x0a, 0x21, 0x64, 0x65, 0x67, 0x72, + 0x65, 0x65, 0x73, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x77, 0x69, 0x73, 0x65, 0x46, 0x72, 0x6f, 0x6d, + 0x4d, 0x61, 0x67, 0x6e, 0x65, 0x74, 0x69, 0x63, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x21, 0x64, 0x65, 0x67, 0x72, 0x65, 0x65, 0x73, 0x43, 0x6c, 0x6f, 0x63, + 0x6b, 0x77, 0x69, 0x73, 0x65, 0x46, 0x72, 0x6f, 0x6d, 0x4d, 0x61, 0x67, 0x6e, 0x65, 0x74, 0x69, + 0x63, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x61, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x61, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x26, 0x0a, 0x0e, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x4e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, + 0x63, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x69, 0x6d, 0x65, + 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x74, 0x69, + 0x6d, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x6a, 0x70, 0x65, 0x67, + 0x54, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0d, 0x6a, 0x70, 0x65, 0x67, 0x54, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x12, 0x34, + 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x11, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x90, 0x04, 0x0a, 0x0e, 0x53, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x69, 0x6c, + 0x65, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x66, + 0x69, 0x6c, 0x65, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x12, 0x24, 0x0a, 0x0d, 0x66, 0x69, 0x6c, + 0x65, 0x45, 0x6e, 0x63, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x0d, 0x66, 0x69, 0x6c, 0x65, 0x45, 0x6e, 0x63, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x12, + 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x4b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x08, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x4b, 0x65, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x6d, + 0x69, 0x6d, 0x65, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, + 0x69, 0x6d, 0x65, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, + 0x14, 0x0a, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x50, + 0x61, 0x74, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x4c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x4c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, 0x2c, 0x0a, 0x11, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x4b, 0x65, + 0x79, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x11, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x4b, 0x65, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x12, 0x2a, 0x0a, 0x10, 0x66, 0x69, 0x72, 0x73, 0x74, 0x46, 0x72, 0x61, 0x6d, + 0x65, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x66, + 0x69, 0x72, 0x73, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x12, + 0x2c, 0x0a, 0x11, 0x66, 0x69, 0x72, 0x73, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x53, 0x69, 0x64, + 0x65, 0x63, 0x61, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x11, 0x66, 0x69, 0x72, 0x73, + 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x53, 0x69, 0x64, 0x65, 0x63, 0x61, 0x72, 0x12, 0x1e, 0x0a, + 0x0a, 0x69, 0x73, 0x41, 0x6e, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0a, 0x69, 0x73, 0x41, 0x6e, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x64, 0x12, 0x22, 0x0a, + 0x0c, 0x70, 0x6e, 0x67, 0x54, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x18, 0x10, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x70, 0x6e, 0x67, 0x54, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, + 0x6c, 0x12, 0x34, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, + 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x97, 0x04, 0x0a, 0x0f, 0x46, 0x6f, 0x75, 0x72, + 0x52, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x38, 0x0a, 0x07, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x69, 0x67, 0x68, 0x6c, 0x79, 0x53, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x75, 0x72, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x36, 0x0a, 0x06, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x69, + 0x67, 0x68, 0x6c, 0x79, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x64, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x06, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x12, 0x2f, 0x0a, + 0x07, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, + 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x07, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x73, 0x12, 0x42, + 0x0a, 0x0f, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, + 0x00, 0x52, 0x0f, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x5a, 0x0a, 0x17, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x79, 0x53, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x75, 0x72, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x69, 0x67, 0x68, + 0x6c, 0x79, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x17, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x79, 0x53, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x39, + 0x0a, 0x0c, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x6d, 0x61, + 0x67, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x69, 0x6d, 0x61, + 0x67, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x39, 0x0a, 0x0c, 0x76, 0x69, 0x64, + 0x65, 0x6f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x12, 0x42, 0x0a, 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, + 0x65, 0x22, 0x9b, 0x04, 0x0a, 0x17, 0x48, 0x79, 0x64, 0x72, 0x61, 0x74, 0x65, 0x64, 0x46, 0x6f, + 0x75, 0x72, 0x52, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x30, 0x0a, + 0x13, 0x68, 0x79, 0x64, 0x72, 0x61, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x54, 0x65, 0x78, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x68, 0x79, 0x64, 0x72, + 0x61, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x65, 0x78, 0x74, 0x12, + 0x2e, 0x0a, 0x12, 0x68, 0x79, 0x64, 0x72, 0x61, 0x74, 0x65, 0x64, 0x46, 0x6f, 0x6f, 0x74, 0x65, + 0x72, 0x54, 0x65, 0x78, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x68, 0x79, 0x64, + 0x72, 0x61, 0x74, 0x65, 0x64, 0x46, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x54, 0x65, 0x78, 0x74, 0x12, + 0x47, 0x0a, 0x0f, 0x68, 0x79, 0x64, 0x72, 0x61, 0x74, 0x65, 0x64, 0x42, 0x75, 0x74, 0x74, 0x6f, + 0x6e, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x48, 0x79, 0x64, 0x72, 0x61, 0x74, 0x65, 0x64, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x0f, 0x68, 0x79, 0x64, 0x72, 0x61, 0x74, 0x65, + 0x64, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x49, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x65, + 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x64, 0x12, 0x42, 0x0a, 0x0f, 0x64, 0x6f, 0x63, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0f, 0x64, 0x6f, 0x63, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2e, 0x0a, 0x11, + 0x68, 0x79, 0x64, 0x72, 0x61, 0x74, 0x65, 0x64, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x54, 0x65, 0x78, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x11, 0x68, 0x79, 0x64, 0x72, 0x61, + 0x74, 0x65, 0x64, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x54, 0x65, 0x78, 0x74, 0x12, 0x39, 0x0a, 0x0c, + 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x69, 0x6d, 0x61, 0x67, 0x65, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x39, 0x0a, 0x0c, 0x76, 0x69, 0x64, 0x65, 0x6f, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x42, 0x0a, 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x22, + 0xbd, 0x02, 0x0a, 0x0f, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x12, 0x34, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, + 0x66, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x4a, 0x0a, 0x10, 0x68, 0x79, 0x64, + 0x72, 0x61, 0x74, 0x65, 0x64, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x79, 0x64, 0x72, + 0x61, 0x74, 0x65, 0x64, 0x46, 0x6f, 0x75, 0x72, 0x52, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x52, 0x10, 0x68, 0x79, 0x64, 0x72, 0x61, 0x74, 0x65, 0x64, 0x54, 0x65, 0x6d, + 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x42, 0x0a, 0x0f, 0x66, 0x6f, 0x75, 0x72, 0x52, 0x6f, 0x77, + 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x6f, 0x75, 0x72, 0x52, 0x6f, 0x77, 0x54, 0x65, + 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x0f, 0x66, 0x6f, 0x75, 0x72, 0x52, 0x6f, + 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x12, 0x5a, 0x0a, 0x17, 0x68, 0x79, 0x64, + 0x72, 0x61, 0x74, 0x65, 0x64, 0x46, 0x6f, 0x75, 0x72, 0x52, 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x48, 0x79, 0x64, 0x72, 0x61, 0x74, 0x65, 0x64, 0x46, 0x6f, 0x75, 0x72, 0x52, + 0x6f, 0x77, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x17, 0x68, 0x79, + 0x64, 0x72, 0x61, 0x74, 0x65, 0x64, 0x46, 0x6f, 0x75, 0x72, 0x52, 0x6f, 0x77, 0x54, 0x65, 0x6d, + 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, + 0xca, 0x01, 0x0a, 0x1a, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x75, 0x74, 0x74, + 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1e, + 0x0a, 0x0a, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x49, 0x64, 0x12, 0x30, + 0x0a, 0x13, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x54, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x65, 0x64, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x54, 0x65, 0x78, 0x74, + 0x12, 0x34, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x65, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x82, 0x01, 0x0a, + 0x0f, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, + 0x12, 0x37, 0x0a, 0x0c, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x49, 0x6d, 0x61, 0x67, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, + 0x6d, 0x61, 0x67, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0c, 0x63, 0x61, 0x74, + 0x61, 0x6c, 0x6f, 0x67, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, + 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x22, 0xf2, 0x02, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x53, 0x6e, 0x61, + 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x37, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, + 0x49, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x1c, + 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, + 0x43, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x70, 0x72, 0x69, 0x63, + 0x65, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x31, 0x30, 0x30, 0x30, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x0f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x31, 0x30, + 0x30, 0x30, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x49, 0x64, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x65, 0x72, + 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x75, 0x72, 0x6c, 0x12, 0x2c, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, + 0x6d, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x11, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x66, 0x69, 0x72, 0x73, 0x74, 0x49, 0x6d, 0x61, 0x67, 0x65, + 0x49, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x66, 0x69, 0x72, 0x73, 0x74, 0x49, + 0x6d, 0x61, 0x67, 0x65, 0x49, 0x64, 0x22, 0xd6, 0x01, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x64, 0x75, + 0x63, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x30, 0x0a, 0x07, 0x70, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, + 0x6f, 0x74, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x2a, 0x0a, 0x10, 0x62, + 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x4a, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x62, 0x75, 0x73, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x4f, + 0x77, 0x6e, 0x65, 0x72, 0x4a, 0x69, 0x64, 0x12, 0x30, 0x0a, 0x07, 0x63, 0x61, 0x74, 0x61, 0x6c, + 0x6f, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, + 0x52, 0x07, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x12, 0x34, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x22, + 0xbe, 0x04, 0x0a, 0x0c, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68, + 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x74, + 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x74, 0x65, 0x6d, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x69, 0x74, 0x65, + 0x6d, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x43, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4f, + 0x72, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4f, 0x72, 0x64, 0x65, + 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x46, 0x0a, 0x07, 0x73, + 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x72, + 0x64, 0x65, 0x72, 0x53, 0x75, 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x07, 0x73, 0x75, 0x72, 0x66, + 0x61, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1e, 0x0a, + 0x0a, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x1c, 0x0a, + 0x09, 0x73, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x4a, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x73, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x4a, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x12, 0x28, 0x0a, 0x0f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x31, 0x30, 0x30, 0x30, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x74, 0x6f, 0x74, 0x61, + 0x6c, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x31, 0x30, 0x30, 0x30, 0x12, 0x2c, 0x0a, 0x11, 0x74, + 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x64, 0x65, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x75, 0x72, + 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x34, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x22, + 0x26, 0x0a, 0x17, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, + 0x72, 0x64, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x49, 0x4e, + 0x51, 0x55, 0x49, 0x52, 0x59, 0x10, 0x01, 0x22, 0x27, 0x0a, 0x18, 0x4f, 0x72, 0x64, 0x65, 0x72, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x53, 0x75, 0x72, 0x66, + 0x61, 0x63, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x41, 0x54, 0x41, 0x4c, 0x4f, 0x47, 0x10, 0x01, + 0x22, 0x53, 0x0a, 0x03, 0x52, 0x6f, 0x77, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, + 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x14, 0x0a, 0x05, 0x72, 0x6f, 0x77, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x72, 0x6f, 0x77, 0x49, 0x64, 0x22, 0x3f, 0x0a, 0x07, 0x53, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x1e, 0x0a, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x6f, 0x77, + 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x22, 0x8c, 0x02, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, + 0x0a, 0x0a, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x54, 0x65, 0x78, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x54, 0x65, 0x78, 0x74, 0x12, 0x42, + 0x0a, 0x08, 0x6c, 0x69, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x4c, 0x69, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x6c, 0x69, 0x73, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x2a, 0x0a, 0x08, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x35, + 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, + 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x49, 0x4e, 0x47, 0x4c, 0x45, 0x5f, 0x53, 0x45, 0x4c, + 0x45, 0x43, 0x54, 0x10, 0x01, 0x22, 0x39, 0x0a, 0x11, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x53, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x6f, 0x77, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0d, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x52, 0x6f, 0x77, 0x49, 0x64, + 0x22, 0xde, 0x02, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x52, + 0x0a, 0x08, 0x6c, 0x69, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x36, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x4c, 0x69, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x6c, 0x69, 0x73, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x46, 0x0a, 0x11, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x53, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x53, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x52, 0x11, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x53, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x34, 0x0a, 0x0b, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, + 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x22, 0x3d, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x11, + 0x0a, 0x0d, 0x53, 0x49, 0x4e, 0x47, 0x4c, 0x45, 0x5f, 0x53, 0x45, 0x4c, 0x45, 0x43, 0x54, 0x10, + 0x01, 0x22, 0x90, 0x02, 0x0a, 0x12, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x6e, 0x76, 0x69, 0x74, + 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x4a, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x4a, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x43, 0x6f, + 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, + 0x43, 0x6f, 0x64, 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x45, 0x78, + 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, + 0x69, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x1c, 0x0a, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, + 0x0a, 0x0d, 0x6a, 0x70, 0x65, 0x67, 0x54, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x6a, 0x70, 0x65, 0x67, 0x54, 0x68, 0x75, 0x6d, 0x62, + 0x6e, 0x61, 0x69, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x61, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x61, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x34, + 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x9c, 0x01, 0x0a, 0x10, 0x45, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, + 0x61, 0x6c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, + 0x74, 0x4a, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x74, + 0x4a, 0x69, 0x64, 0x12, 0x30, 0x0a, 0x13, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, + 0x45, 0x78, 0x70, 0x69, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x13, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x45, 0x78, 0x70, 0x69, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x3c, 0x0a, 0x19, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, + 0x61, 0x6c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x19, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, + 0x72, 0x61, 0x6c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x22, 0xd4, 0x01, 0x0a, 0x11, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x65, + 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x64, 0x65, 0x73, + 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4a, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0e, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4a, 0x69, + 0x64, 0x12, 0x28, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x70, + 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x70, 0x68, 0x61, 0x73, + 0x68, 0x12, 0x57, 0x0a, 0x1a, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x45, 0x70, + 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x18, + 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x70, + 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x1a, + 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x45, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, + 0x61, 0x6c, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x3e, 0x0a, 0x12, 0x46, 0x75, + 0x74, 0x75, 0x72, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x12, 0x28, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x2e, 0x0a, 0x0a, 0x42, 0x75, + 0x74, 0x74, 0x6f, 0x6e, 0x54, 0x65, 0x78, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x54, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, + 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x54, 0x65, 0x78, 0x74, 0x22, 0xae, 0x01, 0x0a, 0x06, 0x42, + 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x49, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x49, + 0x64, 0x12, 0x31, 0x0a, 0x0a, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x54, 0x65, 0x78, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x42, 0x75, + 0x74, 0x74, 0x6f, 0x6e, 0x54, 0x65, 0x78, 0x74, 0x52, 0x0a, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, + 0x54, 0x65, 0x78, 0x74, 0x12, 0x2c, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x42, 0x75, 0x74, 0x74, 0x6f, + 0x6e, 0x2e, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x22, 0x27, 0x0a, 0x0a, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0c, 0x0a, + 0x08, 0x52, 0x45, 0x53, 0x50, 0x4f, 0x4e, 0x53, 0x45, 0x10, 0x01, 0x22, 0x8f, 0x05, 0x0a, 0x0e, + 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x20, + 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x65, 0x78, 0x74, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x65, 0x78, 0x74, + 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x54, 0x65, 0x78, 0x74, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x54, 0x65, 0x78, 0x74, + 0x12, 0x34, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x27, 0x0a, 0x07, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, + 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x07, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x73, 0x12, + 0x4e, 0x0a, 0x0a, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x42, 0x75, 0x74, 0x74, + 0x6f, 0x6e, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x42, 0x75, 0x74, 0x74, 0x6f, + 0x6e, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x0a, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x14, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, + 0x04, 0x74, 0x65, 0x78, 0x74, 0x12, 0x42, 0x0a, 0x0f, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0f, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x39, 0x0a, 0x0c, 0x69, 0x6d, 0x61, + 0x67, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x12, 0x39, 0x0a, 0x0c, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, + 0x00, 0x52, 0x0c, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, + 0x42, 0x0a, 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x48, 0x00, 0x52, 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x22, 0x6e, 0x0a, 0x18, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x73, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, + 0x45, 0x4d, 0x50, 0x54, 0x59, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x54, 0x45, 0x58, 0x54, 0x10, + 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x4f, 0x43, 0x55, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x03, 0x12, + 0x09, 0x0a, 0x05, 0x49, 0x4d, 0x41, 0x47, 0x45, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x49, + 0x44, 0x45, 0x4f, 0x10, 0x05, 0x12, 0x0c, 0x0a, 0x08, 0x4c, 0x4f, 0x43, 0x41, 0x54, 0x49, 0x4f, + 0x4e, 0x10, 0x06, 0x42, 0x08, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0xc5, 0x02, + 0x0a, 0x16, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x73, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x10, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x42, 0x75, 0x74, 0x74, + 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x34, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, + 0x6e, 0x66, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x4c, 0x0a, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x38, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x32, 0x0a, 0x13, 0x73, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x54, 0x65, 0x78, 0x74, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x13, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, + 0x64, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x54, 0x65, 0x78, 0x74, 0x22, 0x3b, 0x0a, 0x1a, + 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, + 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x44, 0x49, 0x53, 0x50, 0x4c, + 0x41, 0x59, 0x5f, 0x54, 0x45, 0x58, 0x54, 0x10, 0x01, 0x42, 0x0a, 0x0a, 0x08, 0x72, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xe2, 0x13, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x67, 0x0a, 0x1c, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4b, + 0x65, 0x79, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x44, 0x69, 0x73, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x52, 0x1c, 0x73, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x44, 0x69, 0x73, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x37, + 0x0a, 0x0c, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x6d, 0x61, + 0x67, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0c, 0x69, 0x6d, 0x61, 0x67, 0x65, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3d, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x63, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x40, 0x0a, 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x4c, 0x0a, 0x13, 0x65, 0x78, 0x74, 0x65, + 0x6e, 0x64, 0x65, 0x64, 0x54, 0x65, 0x78, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x45, 0x78, + 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x54, 0x65, 0x78, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x52, 0x13, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x54, 0x65, 0x78, 0x74, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x40, 0x0a, 0x0f, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0f, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x37, 0x0a, 0x0c, 0x61, 0x75, 0x64, 0x69, + 0x6f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x75, 0x64, 0x69, 0x6f, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x52, 0x0c, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x12, 0x37, 0x0a, 0x0c, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x56, 0x69, 0x64, 0x65, 0x6f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0c, 0x76, 0x69, + 0x64, 0x65, 0x6f, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1f, 0x0a, 0x04, 0x63, 0x61, + 0x6c, 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x04, 0x63, 0x61, 0x6c, 0x6c, 0x12, 0x1f, 0x0a, 0x04, 0x63, + 0x68, 0x61, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x43, 0x68, 0x61, 0x74, 0x52, 0x04, 0x63, 0x68, 0x61, 0x74, 0x12, 0x40, 0x0a, 0x0f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, + 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x4f, + 0x0a, 0x14, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x41, 0x72, 0x72, 0x61, 0x79, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x73, 0x41, 0x72, 0x72, + 0x61, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x14, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x63, 0x74, 0x73, 0x41, 0x72, 0x72, 0x61, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, + 0x58, 0x0a, 0x17, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x79, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, + 0x72, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x69, 0x67, 0x68, 0x6c, 0x79, 0x53, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x52, 0x17, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x79, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x75, 0x72, + 0x65, 0x64, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x83, 0x01, 0x0a, 0x2a, 0x66, 0x61, + 0x73, 0x74, 0x52, 0x61, 0x74, 0x63, 0x68, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x53, 0x65, 0x6e, 0x64, + 0x65, 0x72, 0x4b, 0x65, 0x79, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4b, 0x65, 0x79, + 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x52, 0x2a, 0x66, 0x61, 0x73, 0x74, 0x52, 0x61, 0x74, 0x63, 0x68, 0x65, 0x74, + 0x4b, 0x65, 0x79, 0x53, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x44, 0x69, 0x73, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, + 0x49, 0x0a, 0x12, 0x73, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x12, 0x73, 0x65, 0x6e, 0x64, 0x50, 0x61, 0x79, 0x6d, + 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x4c, 0x0a, 0x13, 0x6c, 0x69, + 0x76, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x4c, 0x69, 0x76, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x52, 0x13, 0x6c, 0x69, 0x76, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x52, 0x0a, 0x15, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x15, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x50, 0x61, + 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x67, 0x0a, 0x1c, + 0x64, 0x65, 0x63, 0x6c, 0x69, 0x6e, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x17, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x65, 0x63, 0x6c, 0x69, + 0x6e, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x1c, 0x64, 0x65, 0x63, 0x6c, 0x69, 0x6e, 0x65, + 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x64, 0x0a, 0x1b, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x50, + 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x1b, + 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x40, 0x0a, 0x0f, 0x74, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x19, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x65, 0x6d, + 0x70, 0x6c, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0f, 0x74, 0x65, + 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3d, 0x0a, + 0x0e, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, + 0x1a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x74, + 0x69, 0x63, 0x6b, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0e, 0x73, 0x74, + 0x69, 0x63, 0x6b, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x49, 0x0a, 0x12, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x52, 0x12, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x6e, 0x76, 0x69, 0x74, 0x65, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x61, 0x0a, 0x1a, 0x74, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x75, 0x74, 0x74, + 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x1a, + 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x52, 0x65, + 0x70, 0x6c, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3d, 0x0a, 0x0e, 0x70, 0x72, + 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x1e, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, + 0x63, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0e, 0x70, 0x72, 0x6f, 0x64, 0x75, + 0x63, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x46, 0x0a, 0x11, 0x64, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x53, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x1f, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x53, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x11, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x53, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x12, 0x49, 0x0a, 0x12, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x23, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x12, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x34, 0x0a, 0x0b, + 0x6c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x24, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0b, 0x6c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x43, 0x0a, 0x0f, 0x76, 0x69, 0x65, 0x77, 0x4f, 0x6e, 0x63, 0x65, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x25, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x46, 0x75, 0x74, 0x75, 0x72, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x0f, 0x76, 0x69, 0x65, 0x77, 0x4f, 0x6e, 0x63, 0x65, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x37, 0x0a, 0x0c, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x26, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x52, 0x0c, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x12, 0x4c, 0x0a, 0x13, 0x6c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x27, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x13, 0x6c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x45, + 0x0a, 0x10, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x28, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x46, 0x75, 0x74, 0x75, 0x72, 0x65, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x52, 0x10, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x3d, 0x0a, 0x0e, 0x69, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x29, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x52, 0x0e, 0x69, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x12, 0x3d, 0x0a, 0x0e, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x73, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x2a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x73, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x52, 0x0e, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x73, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x12, 0x55, 0x0a, 0x16, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x2b, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x42, 0x75, 0x74, 0x74, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x52, 0x16, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x74, 0x0a, 0x0a, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x6d, 0x6f, + 0x74, 0x65, 0x4a, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x6d, + 0x6f, 0x74, 0x65, 0x4a, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x72, 0x6f, 0x6d, 0x4d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x66, 0x72, 0x6f, 0x6d, 0x4d, 0x65, 0x12, 0x0e, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x20, + 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, + 0x22, 0xc5, 0x19, 0x0a, 0x0b, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, + 0x12, 0x48, 0x0a, 0x0d, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, + 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x0d, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x73, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x12, 0x5a, 0x0a, 0x16, 0x76, 0x6f, + 0x69, 0x70, 0x49, 0x6e, 0x64, 0x69, 0x76, 0x69, 0x64, 0x75, 0x61, 0x6c, 0x4f, 0x75, 0x74, 0x67, + 0x6f, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, + 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x16, + 0x76, 0x6f, 0x69, 0x70, 0x49, 0x6e, 0x64, 0x69, 0x76, 0x69, 0x64, 0x75, 0x61, 0x6c, 0x4f, 0x75, + 0x74, 0x67, 0x6f, 0x69, 0x6e, 0x67, 0x12, 0x3e, 0x0a, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, + 0x56, 0x33, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, + 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x08, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x73, 0x56, 0x33, 0x12, 0x4a, 0x0a, 0x0e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, + 0x56, 0x33, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, 0x6c, + 0x61, 0x67, 0x52, 0x0e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x56, 0x33, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x12, 0x4a, 0x0a, 0x0e, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x56, 0x32, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, + 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x0e, + 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x56, 0x32, 0x12, 0x5a, + 0x0a, 0x16, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x56, 0x33, 0x54, + 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, 0x6c, + 0x61, 0x67, 0x52, 0x16, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x56, + 0x33, 0x54, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x12, 0x48, 0x0a, 0x0d, 0x6c, 0x69, + 0x76, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x0d, 0x6c, 0x69, 0x76, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x42, 0x0a, 0x0a, 0x71, 0x75, 0x65, 0x72, 0x79, 0x56, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, + 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x0a, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x56, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x5a, 0x0a, 0x16, 0x76, 0x6f, 0x69, 0x70, + 0x49, 0x6e, 0x64, 0x69, 0x76, 0x69, 0x64, 0x75, 0x61, 0x6c, 0x49, 0x6e, 0x63, 0x6f, 0x6d, 0x69, + 0x6e, 0x67, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, + 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x16, 0x76, 0x6f, + 0x69, 0x70, 0x49, 0x6e, 0x64, 0x69, 0x76, 0x69, 0x64, 0x75, 0x61, 0x6c, 0x49, 0x6e, 0x63, 0x6f, + 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x50, 0x0a, 0x11, 0x71, 0x75, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x70, + 0x6c, 0x69, 0x65, 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, + 0x6c, 0x61, 0x67, 0x52, 0x11, 0x71, 0x75, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x65, + 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x3e, 0x0a, 0x08, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, + 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x08, 0x70, 0x61, + 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x4e, 0x0a, 0x10, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x65, + 0x72, 0x50, 0x61, 0x63, 0x6b, 0x51, 0x75, 0x65, 0x72, 0x79, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, + 0x46, 0x6c, 0x61, 0x67, 0x52, 0x10, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x50, 0x61, 0x63, + 0x6b, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x52, 0x0a, 0x12, 0x6c, 0x69, 0x76, 0x65, 0x4c, 0x6f, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x18, 0x0d, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x12, 0x6c, 0x69, 0x76, 0x65, 0x4c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x46, 0x69, 0x6e, 0x61, 0x6c, 0x12, 0x42, 0x0a, 0x0a, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x73, 0x45, 0x64, 0x69, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, 0x6c, + 0x61, 0x67, 0x52, 0x0a, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x64, 0x69, 0x74, 0x12, 0x44, + 0x0a, 0x0b, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x0f, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, + 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x0b, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x55, 0x70, + 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x64, 0x0a, 0x1b, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x55, 0x70, 0x6c, + 0x6f, 0x61, 0x64, 0x52, 0x69, 0x63, 0x68, 0x51, 0x75, 0x69, 0x63, 0x6b, 0x52, 0x65, 0x70, 0x6c, + 0x69, 0x65, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, + 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x1b, 0x6d, + 0x65, 0x64, 0x69, 0x61, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x69, 0x63, 0x68, 0x51, 0x75, + 0x69, 0x63, 0x6b, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x65, 0x73, 0x12, 0x3c, 0x0a, 0x07, 0x76, 0x6e, + 0x61, 0x6d, 0x65, 0x56, 0x32, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, + 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, + 0x07, 0x76, 0x6e, 0x61, 0x6d, 0x65, 0x56, 0x32, 0x12, 0x4e, 0x0a, 0x10, 0x76, 0x69, 0x64, 0x65, + 0x6f, 0x50, 0x6c, 0x61, 0x79, 0x62, 0x61, 0x63, 0x6b, 0x55, 0x72, 0x6c, 0x18, 0x14, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x10, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x50, 0x6c, 0x61, + 0x79, 0x62, 0x61, 0x63, 0x6b, 0x55, 0x72, 0x6c, 0x12, 0x48, 0x0a, 0x0d, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x61, 0x6e, 0x6b, 0x69, 0x6e, 0x67, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, + 0x6c, 0x61, 0x67, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x61, 0x6e, 0x6b, 0x69, + 0x6e, 0x67, 0x12, 0x54, 0x0a, 0x13, 0x76, 0x6f, 0x69, 0x70, 0x49, 0x6e, 0x64, 0x69, 0x76, 0x69, + 0x64, 0x75, 0x61, 0x6c, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x18, 0x16, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, + 0x6c, 0x61, 0x67, 0x52, 0x13, 0x76, 0x6f, 0x69, 0x70, 0x49, 0x6e, 0x64, 0x69, 0x76, 0x69, 0x64, + 0x75, 0x61, 0x6c, 0x56, 0x69, 0x64, 0x65, 0x6f, 0x12, 0x52, 0x0a, 0x12, 0x74, 0x68, 0x69, 0x72, + 0x64, 0x50, 0x61, 0x72, 0x74, 0x79, 0x53, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x18, 0x17, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, + 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x12, 0x74, 0x68, 0x69, 0x72, 0x64, 0x50, + 0x61, 0x72, 0x74, 0x79, 0x53, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x12, 0x62, 0x0a, 0x1a, + 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, + 0x64, 0x65, 0x64, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, + 0x46, 0x6c, 0x61, 0x67, 0x52, 0x1a, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x74, 0x6c, 0x79, + 0x46, 0x6f, 0x72, 0x77, 0x61, 0x72, 0x64, 0x65, 0x64, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x12, 0x5a, 0x0a, 0x16, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x56, 0x34, 0x4a, 0x6f, 0x69, 0x6e, + 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, + 0x46, 0x6c, 0x61, 0x67, 0x52, 0x16, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x56, 0x34, 0x4a, 0x6f, + 0x69, 0x6e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x4a, 0x0a, 0x0e, + 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x18, 0x1a, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, + 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x0e, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, + 0x53, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x12, 0x3c, 0x0a, 0x07, 0x63, 0x61, 0x74, 0x61, + 0x6c, 0x6f, 0x67, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, + 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x07, 0x63, + 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x12, 0x4c, 0x0a, 0x0f, 0x73, 0x74, 0x61, 0x72, 0x72, 0x65, + 0x64, 0x53, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, + 0x6c, 0x61, 0x67, 0x52, 0x0f, 0x73, 0x74, 0x61, 0x72, 0x72, 0x65, 0x64, 0x53, 0x74, 0x69, 0x63, + 0x6b, 0x65, 0x72, 0x73, 0x12, 0x48, 0x0a, 0x0d, 0x76, 0x6f, 0x69, 0x70, 0x47, 0x72, 0x6f, 0x75, + 0x70, 0x43, 0x61, 0x6c, 0x6c, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, + 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, + 0x0d, 0x76, 0x6f, 0x69, 0x70, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x61, 0x6c, 0x6c, 0x12, 0x4c, + 0x0a, 0x0f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, + 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x0f, 0x74, 0x65, 0x6d, + 0x70, 0x6c, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x66, 0x0a, 0x1c, + 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, + 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x18, 0x1f, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x1c, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x69, 0x74, 0x79, 0x12, 0x50, 0x0a, 0x11, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, + 0x6c, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, + 0x6c, 0x61, 0x67, 0x52, 0x11, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x54, 0x0a, 0x13, 0x65, 0x32, 0x45, 0x4e, 0x6f, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x18, 0x21, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, + 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x13, 0x65, 0x32, 0x45, 0x4e, 0x6f, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x4e, 0x0a, 0x10, + 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x56, 0x32, + 0x18, 0x22, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, + 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x10, 0x72, 0x65, 0x63, 0x65, + 0x6e, 0x74, 0x53, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x56, 0x32, 0x12, 0x48, 0x0a, 0x0d, + 0x73, 0x79, 0x6e, 0x63, 0x64, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x31, 0x18, 0x23, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, + 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x0d, 0x73, 0x79, 0x6e, 0x63, 0x64, 0x52, 0x65, + 0x6c, 0x65, 0x61, 0x73, 0x65, 0x31, 0x12, 0x4e, 0x0a, 0x10, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, + 0x53, 0x74, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x73, 0x56, 0x33, 0x18, 0x24, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, + 0x46, 0x6c, 0x61, 0x67, 0x52, 0x10, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x69, 0x63, + 0x6b, 0x65, 0x72, 0x73, 0x56, 0x33, 0x12, 0x42, 0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x6f, + 0x74, 0x69, 0x63, 0x65, 0x18, 0x25, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, + 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x0a, + 0x75, 0x73, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x69, 0x63, 0x65, 0x12, 0x4a, 0x0a, 0x0e, 0x73, 0x79, + 0x6e, 0x63, 0x64, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x31, 0x31, 0x18, 0x26, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, + 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x0e, 0x73, 0x79, 0x6e, 0x63, 0x64, 0x52, 0x65, 0x6c, + 0x65, 0x61, 0x73, 0x65, 0x31, 0x31, 0x12, 0x3c, 0x0a, 0x07, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, + 0x74, 0x18, 0x27, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, + 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x07, 0x73, 0x75, 0x70, + 0x70, 0x6f, 0x72, 0x74, 0x12, 0x4c, 0x0a, 0x0f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x55, 0x69, 0x69, + 0x43, 0x6c, 0x65, 0x61, 0x6e, 0x75, 0x70, 0x18, 0x28, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, 0x6c, 0x61, + 0x67, 0x52, 0x0f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x55, 0x69, 0x69, 0x43, 0x6c, 0x65, 0x61, 0x6e, + 0x75, 0x70, 0x12, 0x64, 0x0a, 0x1b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x44, 0x6f, 0x67, 0x66, 0x6f, + 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x4f, 0x6e, 0x6c, + 0x79, 0x18, 0x29, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, + 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, 0x6c, 0x61, 0x67, 0x52, 0x1b, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x44, 0x6f, 0x67, 0x66, 0x6f, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x46, 0x0a, 0x0c, 0x73, 0x65, 0x74, 0x74, + 0x69, 0x6e, 0x67, 0x73, 0x53, 0x79, 0x6e, 0x63, 0x18, 0x2a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x22, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x73, 0x2e, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, 0x6c, + 0x61, 0x67, 0x52, 0x0c, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x53, 0x79, 0x6e, 0x63, + 0x22, 0x56, 0x0a, 0x0f, 0x57, 0x65, 0x62, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x46, + 0x6c, 0x61, 0x67, 0x12, 0x0f, 0x0a, 0x0b, 0x4e, 0x4f, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, + 0x45, 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x5f, 0x55, 0x50, + 0x47, 0x52, 0x41, 0x44, 0x45, 0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x44, 0x45, 0x56, 0x45, 0x4c, + 0x4f, 0x50, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x4f, 0x44, + 0x55, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x03, 0x22, 0xb6, 0x01, 0x0a, 0x17, 0x4e, 0x6f, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x23, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x28, 0x0a, 0x07, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x10, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, + 0x20, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, + 0x74, 0x22, 0xc5, 0x01, 0x0a, 0x14, 0x57, 0x65, 0x62, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x20, 0x0a, 0x0b, 0x75, 0x6e, 0x72, 0x65, + 0x61, 0x64, 0x43, 0x68, 0x61, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x75, + 0x6e, 0x72, 0x65, 0x61, 0x64, 0x43, 0x68, 0x61, 0x74, 0x73, 0x12, 0x2e, 0x0a, 0x12, 0x6e, 0x6f, + 0x74, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3d, 0x0a, 0x0e, 0x6e, 0x6f, + 0x74, 0x69, 0x66, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0e, 0x6e, 0x6f, 0x74, 0x69, 0x66, + 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0x9b, 0x0c, 0x0a, 0x0b, 0x50, 0x61, + 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x56, 0x0a, 0x12, 0x63, 0x75, 0x72, + 0x72, 0x65, 0x6e, 0x63, 0x79, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x61, + 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, + 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x12, 0x63, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x44, 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, + 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x31, 0x30, 0x30, 0x30, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x31, 0x30, 0x30, + 0x30, 0x12, 0x20, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x4a, 0x69, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, + 0x4a, 0x69, 0x64, 0x12, 0x3c, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x61, 0x79, 0x6d, + 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x49, + 0x6e, 0x66, 0x6f, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x32, 0x0a, 0x14, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x14, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3f, 0x0a, 0x11, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4b, 0x65, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x4b, 0x65, 0x79, 0x52, 0x11, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x28, 0x0a, 0x0f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x0f, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x12, 0x24, 0x0a, 0x0d, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x65, + 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x70, + 0x72, 0x6f, 0x6f, 0x66, 0x65, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, + 0x63, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, + 0x63, 0x79, 0x12, 0x45, 0x0a, 0x09, 0x74, 0x78, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x27, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x61, + 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, + 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x54, 0x78, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x09, + 0x74, 0x78, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x75, 0x73, 0x65, + 0x4e, 0x6f, 0x76, 0x69, 0x46, 0x69, 0x61, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x0b, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x75, 0x73, 0x65, 0x4e, 0x6f, 0x76, 0x69, 0x46, 0x69, 0x61, + 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x39, 0x0a, 0x0d, 0x70, 0x72, 0x69, 0x6d, 0x61, + 0x72, 0x79, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x6f, + 0x6e, 0x65, 0x79, 0x52, 0x0d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x41, 0x6d, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x3b, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x41, 0x6d, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x52, + 0x0e, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, + 0x34, 0x0a, 0x13, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x43, 0x75, + 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x14, 0x0a, 0x10, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, + 0x4e, 0x5f, 0x43, 0x55, 0x52, 0x52, 0x45, 0x4e, 0x43, 0x59, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, + 0x49, 0x4e, 0x52, 0x10, 0x01, 0x22, 0xd7, 0x01, 0x0a, 0x11, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, + 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x0e, 0x55, + 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x10, 0x00, 0x12, + 0x0e, 0x0a, 0x0a, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, + 0x08, 0x0a, 0x04, 0x53, 0x45, 0x4e, 0x54, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x4e, 0x45, 0x45, + 0x44, 0x5f, 0x54, 0x4f, 0x5f, 0x41, 0x43, 0x43, 0x45, 0x50, 0x54, 0x10, 0x03, 0x12, 0x0c, 0x0a, + 0x08, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x04, 0x12, 0x16, 0x0a, 0x12, 0x43, + 0x4f, 0x55, 0x4c, 0x44, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, + 0x45, 0x10, 0x05, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x45, 0x46, 0x55, 0x4e, 0x44, 0x45, 0x44, 0x10, + 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x07, 0x12, 0x0c, + 0x0a, 0x08, 0x52, 0x45, 0x4a, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x08, 0x12, 0x0d, 0x0a, 0x09, + 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x4c, 0x45, 0x44, 0x10, 0x09, 0x12, 0x15, 0x0a, 0x11, 0x57, + 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x46, 0x4f, 0x52, 0x5f, 0x50, 0x41, 0x59, 0x45, 0x52, + 0x10, 0x0a, 0x12, 0x0b, 0x0a, 0x07, 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x0b, 0x22, + 0xd5, 0x04, 0x0a, 0x14, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x54, + 0x78, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, + 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, + 0x5f, 0x53, 0x45, 0x54, 0x55, 0x50, 0x10, 0x01, 0x12, 0x1a, 0x0a, 0x16, 0x50, 0x45, 0x4e, 0x44, + 0x49, 0x4e, 0x47, 0x5f, 0x52, 0x45, 0x43, 0x45, 0x49, 0x56, 0x45, 0x52, 0x5f, 0x53, 0x45, 0x54, + 0x55, 0x50, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x4e, 0x49, 0x54, 0x10, 0x03, 0x12, 0x0b, + 0x0a, 0x07, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x43, + 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x05, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, + 0x49, 0x4c, 0x45, 0x44, 0x10, 0x06, 0x12, 0x0f, 0x0a, 0x0b, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, + 0x5f, 0x52, 0x49, 0x53, 0x4b, 0x10, 0x07, 0x12, 0x15, 0x0a, 0x11, 0x46, 0x41, 0x49, 0x4c, 0x45, + 0x44, 0x5f, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x10, 0x08, 0x12, 0x1e, + 0x0a, 0x1a, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x52, 0x45, 0x43, 0x45, 0x49, 0x56, 0x45, + 0x52, 0x5f, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x10, 0x09, 0x12, 0x0d, + 0x0a, 0x09, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x44, 0x41, 0x10, 0x0a, 0x12, 0x13, 0x0a, + 0x0f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x44, 0x41, 0x5f, 0x46, 0x49, 0x4e, 0x41, 0x4c, + 0x10, 0x0b, 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x45, 0x46, 0x55, 0x4e, 0x44, 0x45, 0x44, 0x5f, 0x54, + 0x58, 0x4e, 0x10, 0x0c, 0x12, 0x11, 0x0a, 0x0d, 0x52, 0x45, 0x46, 0x55, 0x4e, 0x44, 0x5f, 0x46, + 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x0d, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x45, 0x46, 0x55, 0x4e, + 0x44, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, + 0x49, 0x4e, 0x47, 0x10, 0x0e, 0x12, 0x14, 0x0a, 0x10, 0x52, 0x45, 0x46, 0x55, 0x4e, 0x44, 0x5f, + 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x44, 0x41, 0x10, 0x0f, 0x12, 0x0f, 0x0a, 0x0b, 0x45, + 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x5f, 0x54, 0x58, 0x4e, 0x10, 0x10, 0x12, 0x11, 0x0a, 0x0d, + 0x41, 0x55, 0x54, 0x48, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x45, 0x44, 0x10, 0x11, 0x12, + 0x21, 0x0a, 0x1d, 0x41, 0x55, 0x54, 0x48, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x5f, 0x46, + 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x49, 0x4e, 0x47, + 0x10, 0x12, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x55, 0x54, 0x48, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, + 0x4c, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x13, 0x12, 0x10, 0x0a, 0x0c, 0x43, 0x4f, + 0x4c, 0x4c, 0x45, 0x43, 0x54, 0x5f, 0x49, 0x4e, 0x49, 0x54, 0x10, 0x14, 0x12, 0x13, 0x0a, 0x0f, + 0x43, 0x4f, 0x4c, 0x4c, 0x45, 0x43, 0x54, 0x5f, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, + 0x15, 0x12, 0x12, 0x0a, 0x0e, 0x43, 0x4f, 0x4c, 0x4c, 0x45, 0x43, 0x54, 0x5f, 0x46, 0x41, 0x49, + 0x4c, 0x45, 0x44, 0x10, 0x16, 0x12, 0x17, 0x0a, 0x13, 0x43, 0x4f, 0x4c, 0x4c, 0x45, 0x43, 0x54, + 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x52, 0x49, 0x53, 0x4b, 0x10, 0x17, 0x12, 0x14, + 0x0a, 0x10, 0x43, 0x4f, 0x4c, 0x4c, 0x45, 0x43, 0x54, 0x5f, 0x52, 0x45, 0x4a, 0x45, 0x43, 0x54, + 0x45, 0x44, 0x10, 0x18, 0x12, 0x13, 0x0a, 0x0f, 0x43, 0x4f, 0x4c, 0x4c, 0x45, 0x43, 0x54, 0x5f, + 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x19, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x4f, 0x4c, + 0x4c, 0x45, 0x43, 0x54, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x45, 0x44, 0x10, 0x1a, 0x12, + 0x16, 0x0a, 0x12, 0x43, 0x4f, 0x4c, 0x4c, 0x45, 0x43, 0x54, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, + 0x4c, 0x4c, 0x49, 0x4e, 0x47, 0x10, 0x1b, 0x22, 0x81, 0x2c, 0x0a, 0x0e, 0x57, 0x65, 0x62, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x23, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x02, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x28, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x2a, 0x0a, 0x10, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x10, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x42, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, + 0x62, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x57, 0x65, 0x62, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x53, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x70, 0x61, 0x72, + 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x69, + 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x67, 0x6e, + 0x6f, 0x72, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x74, 0x61, 0x72, 0x72, 0x65, 0x64, 0x18, 0x11, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x73, 0x74, 0x61, 0x72, 0x72, 0x65, 0x64, 0x12, 0x1c, 0x0a, + 0x09, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x18, 0x12, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x09, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, + 0x75, 0x73, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, + 0x75, 0x73, 0x68, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x34, 0x0a, 0x15, 0x6d, 0x65, 0x64, 0x69, 0x61, + 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, + 0x18, 0x14, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x15, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x43, 0x69, 0x70, + 0x68, 0x65, 0x72, 0x74, 0x65, 0x78, 0x74, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x12, 0x1c, 0x0a, + 0x09, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x73, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x09, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x61, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x75, + 0x72, 0x6c, 0x54, 0x65, 0x78, 0x74, 0x18, 0x16, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x75, 0x72, + 0x6c, 0x54, 0x65, 0x78, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x75, 0x72, 0x6c, 0x4e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x18, 0x17, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x75, 0x72, 0x6c, 0x4e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x12, 0x56, 0x0a, 0x0f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, + 0x75, 0x62, 0x54, 0x79, 0x70, 0x65, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, + 0x6e, 0x66, 0x6f, 0x2e, 0x57, 0x65, 0x62, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, + 0x66, 0x6f, 0x53, 0x74, 0x75, 0x62, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0f, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x53, 0x74, 0x75, 0x62, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, + 0x6c, 0x65, 0x61, 0x72, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x18, 0x19, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0a, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x12, 0x34, 0x0a, 0x15, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x53, 0x74, 0x75, 0x62, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, + 0x74, 0x65, 0x72, 0x73, 0x18, 0x1a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x15, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x53, 0x74, 0x75, 0x62, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, + 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x1b, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x08, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, + 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x1c, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x34, 0x0a, 0x0b, 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, + 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, + 0x70, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x48, 0x0a, 0x11, 0x66, + 0x69, 0x6e, 0x61, 0x6c, 0x4c, 0x69, 0x76, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4c, + 0x69, 0x76, 0x65, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x52, 0x11, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x4c, 0x69, 0x76, 0x65, 0x4c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x40, 0x0a, 0x11, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x64, 0x50, + 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x11, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x64, 0x50, 0x61, 0x79, 0x6d, + 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x38, 0x0a, 0x17, 0x65, 0x70, 0x68, 0x65, 0x6d, + 0x65, 0x72, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x18, 0x20, 0x20, 0x01, 0x28, 0x04, 0x52, 0x17, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, + 0x72, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x12, 0x2c, 0x0a, 0x11, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x44, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x21, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x65, 0x70, + 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x2a, 0x0a, 0x10, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x4f, 0x66, 0x66, 0x54, + 0x6f, 0x4f, 0x6e, 0x18, 0x22, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x65, 0x70, 0x68, 0x65, 0x6d, + 0x65, 0x72, 0x61, 0x6c, 0x4f, 0x66, 0x66, 0x54, 0x6f, 0x4f, 0x6e, 0x12, 0x2e, 0x0a, 0x12, 0x65, + 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x4f, 0x75, 0x74, 0x4f, 0x66, 0x53, 0x79, 0x6e, + 0x63, 0x18, 0x23, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, + 0x61, 0x6c, 0x4f, 0x75, 0x74, 0x4f, 0x66, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x60, 0x0a, 0x10, 0x62, + 0x69, 0x7a, 0x50, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x24, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x57, 0x65, + 0x62, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x57, 0x65, 0x62, + 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x69, 0x7a, 0x50, 0x72, + 0x69, 0x76, 0x61, 0x63, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x10, 0x62, 0x69, 0x7a, + 0x50, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x28, 0x0a, + 0x0f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x42, 0x69, 0x7a, 0x4e, 0x61, 0x6d, 0x65, + 0x18, 0x25, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, + 0x42, 0x69, 0x7a, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x66, 0x0a, 0x14, 0x57, 0x65, 0x62, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x45, + 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x53, 0x45, 0x52, 0x56, 0x45, + 0x52, 0x5f, 0x41, 0x43, 0x4b, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x44, 0x45, 0x4c, 0x49, 0x56, + 0x45, 0x52, 0x59, 0x5f, 0x41, 0x43, 0x4b, 0x10, 0x03, 0x12, 0x08, 0x0a, 0x04, 0x52, 0x45, 0x41, + 0x44, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x4c, 0x41, 0x59, 0x45, 0x44, 0x10, 0x05, 0x22, + 0xec, 0x20, 0x0a, 0x16, 0x57, 0x65, 0x62, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, + 0x66, 0x6f, 0x53, 0x74, 0x75, 0x62, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, + 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x52, 0x45, 0x56, 0x4f, 0x4b, + 0x45, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x54, 0x45, 0x58, + 0x54, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x46, 0x55, 0x54, 0x55, 0x52, 0x45, 0x50, 0x52, 0x4f, + 0x4f, 0x46, 0x10, 0x03, 0x12, 0x1b, 0x0a, 0x17, 0x4e, 0x4f, 0x4e, 0x5f, 0x56, 0x45, 0x52, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x10, + 0x04, 0x12, 0x19, 0x0a, 0x15, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, + 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x05, 0x12, 0x17, 0x0a, 0x13, + 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, + 0x49, 0x4f, 0x4e, 0x10, 0x06, 0x12, 0x18, 0x0a, 0x14, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x5f, 0x4c, 0x4f, 0x57, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x07, 0x12, + 0x11, 0x0a, 0x0d, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x48, 0x49, 0x47, 0x48, + 0x10, 0x08, 0x12, 0x1c, 0x0a, 0x18, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x49, + 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x09, + 0x12, 0x18, 0x0a, 0x14, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x49, 0x4e, 0x49, + 0x54, 0x49, 0x41, 0x4c, 0x5f, 0x4c, 0x4f, 0x57, 0x10, 0x0a, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x45, + 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x5f, 0x48, + 0x49, 0x47, 0x48, 0x10, 0x0b, 0x12, 0x23, 0x0a, 0x1f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x4e, 0x59, + 0x5f, 0x54, 0x4f, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x0c, 0x12, 0x23, 0x0a, 0x1f, 0x56, 0x45, + 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x49, 0x4f, + 0x4e, 0x5f, 0x41, 0x4e, 0x59, 0x5f, 0x54, 0x4f, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x10, 0x0d, 0x12, + 0x23, 0x0a, 0x1f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x54, 0x52, 0x41, 0x4e, + 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x48, 0x49, 0x47, 0x48, 0x5f, 0x54, 0x4f, 0x5f, 0x4c, + 0x4f, 0x57, 0x10, 0x0e, 0x12, 0x27, 0x0a, 0x23, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x48, 0x49, 0x47, 0x48, + 0x5f, 0x54, 0x4f, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x0f, 0x12, 0x26, 0x0a, + 0x22, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x54, 0x4f, 0x5f, + 0x4c, 0x4f, 0x57, 0x10, 0x10, 0x12, 0x26, 0x0a, 0x22, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4c, 0x4f, 0x57, + 0x5f, 0x54, 0x4f, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x11, 0x12, 0x23, 0x0a, + 0x1f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x5f, 0x54, 0x4f, 0x5f, 0x4c, 0x4f, 0x57, + 0x10, 0x12, 0x12, 0x27, 0x0a, 0x23, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x54, + 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x4f, 0x4e, 0x45, 0x5f, 0x54, + 0x4f, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x13, 0x12, 0x10, 0x0a, 0x0c, 0x47, + 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x14, 0x12, 0x18, 0x0a, + 0x14, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x53, 0x55, + 0x42, 0x4a, 0x45, 0x43, 0x54, 0x10, 0x15, 0x12, 0x15, 0x0a, 0x11, 0x47, 0x52, 0x4f, 0x55, 0x50, + 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x49, 0x43, 0x4f, 0x4e, 0x10, 0x16, 0x12, 0x1c, + 0x0a, 0x18, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x49, + 0x4e, 0x56, 0x49, 0x54, 0x45, 0x5f, 0x4c, 0x49, 0x4e, 0x4b, 0x10, 0x17, 0x12, 0x1c, 0x0a, 0x18, + 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x44, 0x45, 0x53, + 0x43, 0x52, 0x49, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x18, 0x12, 0x19, 0x0a, 0x15, 0x47, 0x52, + 0x4f, 0x55, 0x50, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x52, 0x45, 0x53, 0x54, 0x52, + 0x49, 0x43, 0x54, 0x10, 0x19, 0x12, 0x19, 0x0a, 0x15, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x43, + 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x41, 0x4e, 0x4e, 0x4f, 0x55, 0x4e, 0x43, 0x45, 0x10, 0x1a, + 0x12, 0x19, 0x0a, 0x15, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x49, 0x43, + 0x49, 0x50, 0x41, 0x4e, 0x54, 0x5f, 0x41, 0x44, 0x44, 0x10, 0x1b, 0x12, 0x1c, 0x0a, 0x18, 0x47, + 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x49, 0x43, 0x49, 0x50, 0x41, 0x4e, 0x54, + 0x5f, 0x52, 0x45, 0x4d, 0x4f, 0x56, 0x45, 0x10, 0x1c, 0x12, 0x1d, 0x0a, 0x19, 0x47, 0x52, 0x4f, + 0x55, 0x50, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x49, 0x43, 0x49, 0x50, 0x41, 0x4e, 0x54, 0x5f, 0x50, + 0x52, 0x4f, 0x4d, 0x4f, 0x54, 0x45, 0x10, 0x1d, 0x12, 0x1c, 0x0a, 0x18, 0x47, 0x52, 0x4f, 0x55, + 0x50, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x49, 0x43, 0x49, 0x50, 0x41, 0x4e, 0x54, 0x5f, 0x44, 0x45, + 0x4d, 0x4f, 0x54, 0x45, 0x10, 0x1e, 0x12, 0x1c, 0x0a, 0x18, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, + 0x50, 0x41, 0x52, 0x54, 0x49, 0x43, 0x49, 0x50, 0x41, 0x4e, 0x54, 0x5f, 0x49, 0x4e, 0x56, 0x49, + 0x54, 0x45, 0x10, 0x1f, 0x12, 0x1b, 0x0a, 0x17, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x50, 0x41, + 0x52, 0x54, 0x49, 0x43, 0x49, 0x50, 0x41, 0x4e, 0x54, 0x5f, 0x4c, 0x45, 0x41, 0x56, 0x45, 0x10, + 0x20, 0x12, 0x23, 0x0a, 0x1f, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x49, + 0x43, 0x49, 0x50, 0x41, 0x4e, 0x54, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x4e, 0x55, + 0x4d, 0x42, 0x45, 0x52, 0x10, 0x21, 0x12, 0x14, 0x0a, 0x10, 0x42, 0x52, 0x4f, 0x41, 0x44, 0x43, + 0x41, 0x53, 0x54, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, 0x22, 0x12, 0x11, 0x0a, 0x0d, + 0x42, 0x52, 0x4f, 0x41, 0x44, 0x43, 0x41, 0x53, 0x54, 0x5f, 0x41, 0x44, 0x44, 0x10, 0x23, 0x12, + 0x14, 0x0a, 0x10, 0x42, 0x52, 0x4f, 0x41, 0x44, 0x43, 0x41, 0x53, 0x54, 0x5f, 0x52, 0x45, 0x4d, + 0x4f, 0x56, 0x45, 0x10, 0x24, 0x12, 0x18, 0x0a, 0x14, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x49, 0x43, + 0x5f, 0x4e, 0x4f, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x25, 0x12, + 0x18, 0x0a, 0x14, 0x45, 0x32, 0x45, 0x5f, 0x49, 0x44, 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, 0x5f, + 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x44, 0x10, 0x26, 0x12, 0x11, 0x0a, 0x0d, 0x45, 0x32, 0x45, + 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50, 0x54, 0x45, 0x44, 0x10, 0x27, 0x12, 0x15, 0x0a, 0x11, + 0x43, 0x41, 0x4c, 0x4c, 0x5f, 0x4d, 0x49, 0x53, 0x53, 0x45, 0x44, 0x5f, 0x56, 0x4f, 0x49, 0x43, + 0x45, 0x10, 0x28, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x41, 0x4c, 0x4c, 0x5f, 0x4d, 0x49, 0x53, 0x53, + 0x45, 0x44, 0x5f, 0x56, 0x49, 0x44, 0x45, 0x4f, 0x10, 0x29, 0x12, 0x1c, 0x0a, 0x18, 0x49, 0x4e, + 0x44, 0x49, 0x56, 0x49, 0x44, 0x55, 0x41, 0x4c, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, + 0x4e, 0x55, 0x4d, 0x42, 0x45, 0x52, 0x10, 0x2a, 0x12, 0x10, 0x0a, 0x0c, 0x47, 0x52, 0x4f, 0x55, + 0x50, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x2b, 0x12, 0x26, 0x0a, 0x22, 0x47, 0x52, + 0x4f, 0x55, 0x50, 0x5f, 0x41, 0x4e, 0x4e, 0x4f, 0x55, 0x4e, 0x43, 0x45, 0x5f, 0x4d, 0x4f, 0x44, + 0x45, 0x5f, 0x4d, 0x45, 0x53, 0x53, 0x41, 0x47, 0x45, 0x5f, 0x42, 0x4f, 0x55, 0x4e, 0x43, 0x45, + 0x10, 0x2c, 0x12, 0x1b, 0x0a, 0x17, 0x43, 0x41, 0x4c, 0x4c, 0x5f, 0x4d, 0x49, 0x53, 0x53, 0x45, + 0x44, 0x5f, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x56, 0x4f, 0x49, 0x43, 0x45, 0x10, 0x2d, 0x12, + 0x1b, 0x0a, 0x17, 0x43, 0x41, 0x4c, 0x4c, 0x5f, 0x4d, 0x49, 0x53, 0x53, 0x45, 0x44, 0x5f, 0x47, + 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x56, 0x49, 0x44, 0x45, 0x4f, 0x10, 0x2e, 0x12, 0x16, 0x0a, 0x12, + 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x43, 0x49, 0x50, 0x48, 0x45, 0x52, 0x54, 0x45, + 0x58, 0x54, 0x10, 0x2f, 0x12, 0x17, 0x0a, 0x13, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, + 0x46, 0x55, 0x54, 0x55, 0x52, 0x45, 0x50, 0x52, 0x4f, 0x4f, 0x46, 0x10, 0x30, 0x12, 0x2c, 0x0a, + 0x28, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x41, 0x43, + 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x50, 0x44, 0x41, + 0x54, 0x45, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x31, 0x12, 0x2e, 0x0a, 0x2a, 0x50, + 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x41, 0x43, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, + 0x5f, 0x52, 0x45, 0x46, 0x55, 0x4e, 0x44, 0x45, 0x44, 0x10, 0x32, 0x12, 0x33, 0x0a, 0x2f, 0x50, + 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x41, 0x43, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, + 0x5f, 0x52, 0x45, 0x46, 0x55, 0x4e, 0x44, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x33, + 0x12, 0x35, 0x0a, 0x31, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x52, 0x41, 0x4e, + 0x53, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, + 0x45, 0x43, 0x45, 0x49, 0x56, 0x45, 0x52, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x5f, + 0x53, 0x45, 0x54, 0x55, 0x50, 0x10, 0x34, 0x12, 0x3c, 0x0a, 0x38, 0x50, 0x41, 0x59, 0x4d, 0x45, + 0x4e, 0x54, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, + 0x54, 0x41, 0x54, 0x55, 0x53, 0x5f, 0x52, 0x45, 0x43, 0x45, 0x49, 0x56, 0x45, 0x52, 0x5f, 0x53, + 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x5f, 0x41, 0x46, 0x54, 0x45, 0x52, 0x5f, 0x48, 0x49, 0x43, + 0x43, 0x55, 0x50, 0x10, 0x35, 0x12, 0x29, 0x0a, 0x25, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, + 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x5f, + 0x53, 0x45, 0x54, 0x55, 0x50, 0x5f, 0x52, 0x45, 0x4d, 0x49, 0x4e, 0x44, 0x45, 0x52, 0x10, 0x36, + 0x12, 0x28, 0x0a, 0x24, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x43, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, + 0x52, 0x45, 0x4d, 0x49, 0x4e, 0x44, 0x45, 0x52, 0x10, 0x37, 0x12, 0x2a, 0x0a, 0x26, 0x50, 0x41, + 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x53, 0x45, 0x4e, + 0x44, 0x5f, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x49, 0x4e, 0x56, 0x49, 0x54, 0x41, + 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x38, 0x12, 0x23, 0x0a, 0x1f, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, + 0x54, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, + 0x5f, 0x44, 0x45, 0x43, 0x4c, 0x49, 0x4e, 0x45, 0x44, 0x10, 0x39, 0x12, 0x22, 0x0a, 0x1e, 0x50, + 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, + 0x51, 0x55, 0x45, 0x53, 0x54, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x3a, 0x12, + 0x24, 0x0a, 0x20, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x4f, + 0x4e, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, + 0x4c, 0x45, 0x44, 0x10, 0x3b, 0x12, 0x29, 0x0a, 0x25, 0x42, 0x49, 0x5a, 0x5f, 0x56, 0x45, 0x52, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x54, 0x4f, 0x50, 0x5f, 0x54, 0x4f, 0x5f, 0x42, 0x4f, 0x54, 0x54, 0x4f, 0x4d, 0x10, 0x3c, + 0x12, 0x29, 0x0a, 0x25, 0x42, 0x49, 0x5a, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x42, 0x4f, 0x54, 0x54, + 0x4f, 0x4d, 0x5f, 0x54, 0x4f, 0x5f, 0x54, 0x4f, 0x50, 0x10, 0x3d, 0x12, 0x11, 0x0a, 0x0d, 0x42, + 0x49, 0x5a, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x4f, 0x5f, 0x54, 0x4f, 0x50, 0x10, 0x3e, 0x12, 0x14, + 0x0a, 0x10, 0x42, 0x49, 0x5a, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x4f, 0x5f, 0x42, 0x4f, 0x54, 0x54, + 0x4f, 0x4d, 0x10, 0x3f, 0x12, 0x13, 0x0a, 0x0f, 0x42, 0x49, 0x5a, 0x5f, 0x4e, 0x41, 0x4d, 0x45, + 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x40, 0x12, 0x1c, 0x0a, 0x18, 0x42, 0x49, 0x5a, + 0x5f, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x54, 0x4f, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x55, 0x4d, 0x45, + 0x52, 0x5f, 0x41, 0x50, 0x50, 0x10, 0x41, 0x12, 0x1e, 0x0a, 0x1a, 0x42, 0x49, 0x5a, 0x5f, 0x54, + 0x57, 0x4f, 0x5f, 0x54, 0x49, 0x45, 0x52, 0x5f, 0x4d, 0x49, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, + 0x4e, 0x5f, 0x54, 0x4f, 0x50, 0x10, 0x42, 0x12, 0x21, 0x0a, 0x1d, 0x42, 0x49, 0x5a, 0x5f, 0x54, + 0x57, 0x4f, 0x5f, 0x54, 0x49, 0x45, 0x52, 0x5f, 0x4d, 0x49, 0x47, 0x52, 0x41, 0x54, 0x49, 0x4f, + 0x4e, 0x5f, 0x42, 0x4f, 0x54, 0x54, 0x4f, 0x4d, 0x10, 0x43, 0x12, 0x0d, 0x0a, 0x09, 0x4f, 0x56, + 0x45, 0x52, 0x53, 0x49, 0x5a, 0x45, 0x44, 0x10, 0x44, 0x12, 0x28, 0x0a, 0x24, 0x47, 0x52, 0x4f, + 0x55, 0x50, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x4e, 0x4f, 0x5f, 0x46, 0x52, 0x45, + 0x51, 0x55, 0x45, 0x4e, 0x54, 0x4c, 0x59, 0x5f, 0x46, 0x4f, 0x52, 0x57, 0x41, 0x52, 0x44, 0x45, + 0x44, 0x10, 0x45, 0x12, 0x1c, 0x0a, 0x18, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x56, 0x34, 0x5f, + 0x41, 0x44, 0x44, 0x5f, 0x49, 0x4e, 0x56, 0x49, 0x54, 0x45, 0x5f, 0x53, 0x45, 0x4e, 0x54, 0x10, + 0x46, 0x12, 0x26, 0x0a, 0x22, 0x47, 0x52, 0x4f, 0x55, 0x50, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x49, + 0x43, 0x49, 0x50, 0x41, 0x4e, 0x54, 0x5f, 0x41, 0x44, 0x44, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, + 0x53, 0x54, 0x5f, 0x4a, 0x4f, 0x49, 0x4e, 0x10, 0x47, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x48, 0x41, + 0x4e, 0x47, 0x45, 0x5f, 0x45, 0x50, 0x48, 0x45, 0x4d, 0x45, 0x52, 0x41, 0x4c, 0x5f, 0x53, 0x45, + 0x54, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x48, 0x12, 0x16, 0x0a, 0x12, 0x45, 0x32, 0x45, 0x5f, 0x44, + 0x45, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x44, 0x10, 0x49, 0x12, + 0x0f, 0x0a, 0x0b, 0x56, 0x49, 0x45, 0x57, 0x45, 0x44, 0x5f, 0x4f, 0x4e, 0x43, 0x45, 0x10, 0x4a, + 0x12, 0x15, 0x0a, 0x11, 0x45, 0x32, 0x45, 0x5f, 0x45, 0x4e, 0x43, 0x52, 0x59, 0x50, 0x54, 0x45, + 0x44, 0x5f, 0x4e, 0x4f, 0x57, 0x10, 0x4b, 0x12, 0x22, 0x0a, 0x1e, 0x42, 0x4c, 0x55, 0x45, 0x5f, + 0x4d, 0x53, 0x47, 0x5f, 0x42, 0x53, 0x50, 0x5f, 0x46, 0x42, 0x5f, 0x54, 0x4f, 0x5f, 0x42, 0x53, + 0x50, 0x5f, 0x50, 0x52, 0x45, 0x4d, 0x49, 0x53, 0x45, 0x10, 0x4c, 0x12, 0x1e, 0x0a, 0x1a, 0x42, + 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x42, 0x53, 0x50, 0x5f, 0x46, 0x42, 0x5f, 0x54, + 0x4f, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x46, 0x42, 0x10, 0x4d, 0x12, 0x23, 0x0a, 0x1f, 0x42, + 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x42, 0x53, 0x50, 0x5f, 0x46, 0x42, 0x5f, 0x54, + 0x4f, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x50, 0x52, 0x45, 0x4d, 0x49, 0x53, 0x45, 0x10, 0x4e, + 0x12, 0x1e, 0x0a, 0x1a, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x42, 0x53, 0x50, + 0x5f, 0x46, 0x42, 0x5f, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x4f, + 0x12, 0x37, 0x0a, 0x33, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x42, 0x53, 0x50, + 0x5f, 0x46, 0x42, 0x5f, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x54, + 0x4f, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x50, 0x52, 0x45, 0x4d, 0x49, 0x53, 0x45, 0x5f, 0x56, + 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x50, 0x12, 0x1c, 0x0a, 0x18, 0x42, 0x4c, 0x55, + 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x42, 0x53, 0x50, 0x5f, 0x46, 0x42, 0x5f, 0x56, 0x45, 0x52, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x51, 0x12, 0x37, 0x0a, 0x33, 0x42, 0x4c, 0x55, 0x45, 0x5f, + 0x4d, 0x53, 0x47, 0x5f, 0x42, 0x53, 0x50, 0x5f, 0x46, 0x42, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, + 0x49, 0x45, 0x44, 0x5f, 0x54, 0x4f, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x50, 0x52, 0x45, 0x4d, + 0x49, 0x53, 0x45, 0x5f, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x52, + 0x12, 0x28, 0x0a, 0x24, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x42, 0x53, 0x50, + 0x5f, 0x50, 0x52, 0x45, 0x4d, 0x49, 0x53, 0x45, 0x5f, 0x54, 0x4f, 0x5f, 0x53, 0x45, 0x4c, 0x46, + 0x5f, 0x50, 0x52, 0x45, 0x4d, 0x49, 0x53, 0x45, 0x10, 0x53, 0x12, 0x23, 0x0a, 0x1f, 0x42, 0x4c, + 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x42, 0x53, 0x50, 0x5f, 0x50, 0x52, 0x45, 0x4d, 0x49, + 0x53, 0x45, 0x5f, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x54, 0x12, + 0x3c, 0x0a, 0x38, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x42, 0x53, 0x50, 0x5f, + 0x50, 0x52, 0x45, 0x4d, 0x49, 0x53, 0x45, 0x5f, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, + 0x45, 0x44, 0x5f, 0x54, 0x4f, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x50, 0x52, 0x45, 0x4d, 0x49, + 0x53, 0x45, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x55, 0x12, 0x21, 0x0a, + 0x1d, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x42, 0x53, 0x50, 0x5f, 0x50, 0x52, + 0x45, 0x4d, 0x49, 0x53, 0x45, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x56, + 0x12, 0x3c, 0x0a, 0x38, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x42, 0x53, 0x50, + 0x5f, 0x50, 0x52, 0x45, 0x4d, 0x49, 0x53, 0x45, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x5f, 0x54, 0x4f, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x50, 0x52, 0x45, 0x4d, 0x49, 0x53, + 0x45, 0x5f, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x57, 0x12, 0x2a, + 0x0a, 0x26, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x55, + 0x4d, 0x45, 0x52, 0x5f, 0x54, 0x4f, 0x5f, 0x42, 0x53, 0x50, 0x5f, 0x46, 0x42, 0x5f, 0x55, 0x4e, + 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x58, 0x12, 0x2f, 0x0a, 0x2b, 0x42, 0x4c, + 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x55, 0x4d, 0x45, 0x52, 0x5f, + 0x54, 0x4f, 0x5f, 0x42, 0x53, 0x50, 0x5f, 0x50, 0x52, 0x45, 0x4d, 0x49, 0x53, 0x45, 0x5f, 0x55, + 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x59, 0x12, 0x2b, 0x0a, 0x27, 0x42, + 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x55, 0x4d, 0x45, 0x52, + 0x5f, 0x54, 0x4f, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x46, 0x42, 0x5f, 0x55, 0x4e, 0x56, 0x45, + 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x5a, 0x12, 0x30, 0x0a, 0x2c, 0x42, 0x4c, 0x55, 0x45, + 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x55, 0x4d, 0x45, 0x52, 0x5f, 0x54, 0x4f, + 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x50, 0x52, 0x45, 0x4d, 0x49, 0x53, 0x45, 0x5f, 0x55, 0x4e, + 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x5b, 0x12, 0x23, 0x0a, 0x1f, 0x42, 0x4c, + 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x46, 0x42, 0x5f, 0x54, + 0x4f, 0x5f, 0x42, 0x53, 0x50, 0x5f, 0x50, 0x52, 0x45, 0x4d, 0x49, 0x53, 0x45, 0x10, 0x5c, 0x12, + 0x24, 0x0a, 0x20, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x53, 0x45, 0x4c, 0x46, + 0x5f, 0x46, 0x42, 0x5f, 0x54, 0x4f, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x50, 0x52, 0x45, 0x4d, + 0x49, 0x53, 0x45, 0x10, 0x5d, 0x12, 0x1f, 0x0a, 0x1b, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, + 0x47, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x46, 0x42, 0x5f, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x5e, 0x12, 0x38, 0x0a, 0x34, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, + 0x53, 0x47, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x46, 0x42, 0x5f, 0x55, 0x4e, 0x56, 0x45, 0x52, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x54, 0x4f, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x50, 0x52, + 0x45, 0x4d, 0x49, 0x53, 0x45, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x5f, + 0x12, 0x1d, 0x0a, 0x19, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x53, 0x45, 0x4c, + 0x46, 0x5f, 0x46, 0x42, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x60, 0x12, + 0x38, 0x0a, 0x34, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x53, 0x45, 0x4c, 0x46, + 0x5f, 0x46, 0x42, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x54, 0x4f, 0x5f, + 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x50, 0x52, 0x45, 0x4d, 0x49, 0x53, 0x45, 0x5f, 0x55, 0x4e, 0x56, + 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x61, 0x12, 0x28, 0x0a, 0x24, 0x42, 0x4c, 0x55, + 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x50, 0x52, 0x45, 0x4d, 0x49, + 0x53, 0x45, 0x5f, 0x54, 0x4f, 0x5f, 0x42, 0x53, 0x50, 0x5f, 0x50, 0x52, 0x45, 0x4d, 0x49, 0x53, + 0x45, 0x10, 0x62, 0x12, 0x24, 0x0a, 0x20, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, + 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x50, 0x52, 0x45, 0x4d, 0x49, 0x53, 0x45, 0x5f, 0x55, 0x4e, 0x56, + 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x63, 0x12, 0x22, 0x0a, 0x1e, 0x42, 0x4c, 0x55, + 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x50, 0x52, 0x45, 0x4d, 0x49, + 0x53, 0x45, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x64, 0x12, 0x16, 0x0a, + 0x12, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x54, 0x4f, 0x5f, 0x42, 0x53, 0x50, + 0x5f, 0x46, 0x42, 0x10, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, + 0x47, 0x5f, 0x54, 0x4f, 0x5f, 0x43, 0x4f, 0x4e, 0x53, 0x55, 0x4d, 0x45, 0x52, 0x10, 0x66, 0x12, + 0x17, 0x0a, 0x13, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x54, 0x4f, 0x5f, 0x53, + 0x45, 0x4c, 0x46, 0x5f, 0x46, 0x42, 0x10, 0x67, 0x12, 0x2a, 0x0a, 0x26, 0x42, 0x4c, 0x55, 0x45, + 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, + 0x54, 0x4f, 0x5f, 0x42, 0x53, 0x50, 0x5f, 0x46, 0x42, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, + 0x45, 0x44, 0x10, 0x68, 0x12, 0x2f, 0x0a, 0x2b, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, + 0x5f, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x54, 0x4f, 0x5f, 0x42, + 0x53, 0x50, 0x5f, 0x50, 0x52, 0x45, 0x4d, 0x49, 0x53, 0x45, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, + 0x49, 0x45, 0x44, 0x10, 0x69, 0x12, 0x2b, 0x0a, 0x27, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, + 0x47, 0x5f, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x54, 0x4f, 0x5f, + 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x46, 0x42, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x6a, 0x12, 0x23, 0x0a, 0x1f, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x55, + 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x54, 0x4f, 0x5f, 0x56, 0x45, 0x52, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x6b, 0x12, 0x2a, 0x0a, 0x26, 0x42, 0x4c, 0x55, 0x45, 0x5f, + 0x4d, 0x53, 0x47, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x54, 0x4f, 0x5f, + 0x42, 0x53, 0x50, 0x5f, 0x46, 0x42, 0x5f, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x10, 0x6c, 0x12, 0x2f, 0x0a, 0x2b, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, + 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x54, 0x4f, 0x5f, 0x42, 0x53, 0x50, 0x5f, + 0x50, 0x52, 0x45, 0x4d, 0x49, 0x53, 0x45, 0x5f, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, + 0x45, 0x44, 0x10, 0x6d, 0x12, 0x2b, 0x0a, 0x27, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, + 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x54, 0x4f, 0x5f, 0x53, 0x45, 0x4c, + 0x46, 0x5f, 0x46, 0x42, 0x5f, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x6e, 0x12, 0x23, 0x0a, 0x1f, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x56, 0x45, + 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x54, 0x4f, 0x5f, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x10, 0x6f, 0x12, 0x36, 0x0a, 0x32, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, + 0x53, 0x47, 0x5f, 0x42, 0x53, 0x50, 0x5f, 0x46, 0x42, 0x5f, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x5f, 0x54, 0x4f, 0x5f, 0x42, 0x53, 0x50, 0x5f, 0x50, 0x52, 0x45, 0x4d, + 0x49, 0x53, 0x45, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x70, 0x12, 0x32, + 0x0a, 0x2e, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x42, 0x53, 0x50, 0x5f, 0x46, + 0x42, 0x5f, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x54, 0x4f, 0x5f, + 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x46, 0x42, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, + 0x10, 0x71, 0x12, 0x36, 0x0a, 0x32, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x42, + 0x53, 0x50, 0x5f, 0x46, 0x42, 0x5f, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x54, + 0x4f, 0x5f, 0x42, 0x53, 0x50, 0x5f, 0x50, 0x52, 0x45, 0x4d, 0x49, 0x53, 0x45, 0x5f, 0x55, 0x4e, + 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x72, 0x12, 0x32, 0x0a, 0x2e, 0x42, 0x4c, + 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x42, 0x53, 0x50, 0x5f, 0x46, 0x42, 0x5f, 0x56, 0x45, + 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x54, 0x4f, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x46, + 0x42, 0x5f, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x73, 0x12, 0x37, + 0x0a, 0x33, 0x42, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x53, 0x47, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, + 0x46, 0x42, 0x5f, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x5f, 0x54, 0x4f, + 0x5f, 0x42, 0x53, 0x50, 0x5f, 0x50, 0x52, 0x45, 0x4d, 0x49, 0x53, 0x45, 0x5f, 0x56, 0x45, 0x52, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x74, 0x12, 0x37, 0x0a, 0x33, 0x42, 0x4c, 0x55, 0x45, 0x5f, + 0x4d, 0x53, 0x47, 0x5f, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x46, 0x42, 0x5f, 0x56, 0x45, 0x52, 0x49, + 0x46, 0x49, 0x45, 0x44, 0x5f, 0x54, 0x4f, 0x5f, 0x42, 0x53, 0x50, 0x5f, 0x50, 0x52, 0x45, 0x4d, + 0x49, 0x53, 0x45, 0x5f, 0x55, 0x4e, 0x56, 0x45, 0x52, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x75, + 0x12, 0x1c, 0x0a, 0x18, 0x45, 0x32, 0x45, 0x5f, 0x49, 0x44, 0x45, 0x4e, 0x54, 0x49, 0x54, 0x59, + 0x5f, 0x55, 0x4e, 0x41, 0x56, 0x41, 0x49, 0x4c, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x76, 0x22, 0x4b, + 0x0a, 0x1e, 0x57, 0x65, 0x62, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, + 0x42, 0x69, 0x7a, 0x50, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x08, 0x0a, 0x04, 0x45, 0x32, 0x45, 0x45, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x46, 0x42, + 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x42, 0x53, 0x50, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x42, + 0x53, 0x50, 0x5f, 0x41, 0x4e, 0x44, 0x5f, 0x46, 0x42, 0x10, 0x03, +} + +var ( + file_def_proto_rawDescOnce sync.Once + file_def_proto_rawDescData = file_def_proto_rawDesc +) + +func file_def_proto_rawDescGZIP() []byte { + file_def_proto_rawDescOnce.Do(func() { + file_def_proto_rawDescData = protoimpl.X.CompressGZIP(file_def_proto_rawDescData) + }) + return file_def_proto_rawDescData +} + +var file_def_proto_enumTypes = make([]protoimpl.EnumInfo, 24) +var file_def_proto_msgTypes = make([]protoimpl.MessageInfo, 79) +var file_def_proto_goTypes = []interface{}{ + (AdReplyInfo_AdReplyInfoMediaType)(0), // 0: proto.AdReplyInfo.AdReplyInfoMediaType + (ExternalAdReplyInfo_ExternalAdReplyInfoMediaType)(0), // 1: proto.ExternalAdReplyInfo.ExternalAdReplyInfoMediaType + (InvoiceMessage_InvoiceMessageAttachmentType)(0), // 2: proto.InvoiceMessage.InvoiceMessageAttachmentType + (ExtendedTextMessage_ExtendedTextMessageFontType)(0), // 3: proto.ExtendedTextMessage.ExtendedTextMessageFontType + (ExtendedTextMessage_ExtendedTextMessagePreviewType)(0), // 4: proto.ExtendedTextMessage.ExtendedTextMessagePreviewType + (VideoMessage_VideoMessageAttribution)(0), // 5: proto.VideoMessage.VideoMessageAttribution + (ProtocolMessage_ProtocolMessageType)(0), // 6: proto.ProtocolMessage.ProtocolMessageType + (HistorySyncNotification_HistorySyncNotificationHistorySyncType)(0), // 7: proto.HistorySyncNotification.HistorySyncNotificationHistorySyncType + (HSMDateTimeComponent_HSMDateTimeComponentDayOfWeekType)(0), // 8: proto.HSMDateTimeComponent.HSMDateTimeComponentDayOfWeekType + (HSMDateTimeComponent_HSMDateTimeComponentCalendarType)(0), // 9: proto.HSMDateTimeComponent.HSMDateTimeComponentCalendarType + (OrderMessage_OrderMessageOrderStatus)(0), // 10: proto.OrderMessage.OrderMessageOrderStatus + (OrderMessage_OrderMessageOrderSurface)(0), // 11: proto.OrderMessage.OrderMessageOrderSurface + (ListMessage_ListMessageListType)(0), // 12: proto.ListMessage.ListMessageListType + (ListResponseMessage_ListResponseMessageListType)(0), // 13: proto.ListResponseMessage.ListResponseMessageListType + (Button_ButtonType)(0), // 14: proto.Button.ButtonType + (ButtonsMessage_ButtonsMessageHeaderType)(0), // 15: proto.ButtonsMessage.ButtonsMessageHeaderType + (ButtonsResponseMessage_ButtonsResponseMessageType)(0), // 16: proto.ButtonsResponseMessage.ButtonsResponseMessageType + (WebFeatures_WebFeaturesFlag)(0), // 17: proto.WebFeatures.WebFeaturesFlag + (PaymentInfo_PaymentInfoCurrency)(0), // 18: proto.PaymentInfo.PaymentInfoCurrency + (PaymentInfo_PaymentInfoStatus)(0), // 19: proto.PaymentInfo.PaymentInfoStatus + (PaymentInfo_PaymentInfoTxnStatus)(0), // 20: proto.PaymentInfo.PaymentInfoTxnStatus + (WebMessageInfo_WebMessageInfoStatus)(0), // 21: proto.WebMessageInfo.WebMessageInfoStatus + (WebMessageInfo_WebMessageInfoStubType)(0), // 22: proto.WebMessageInfo.WebMessageInfoStubType + (WebMessageInfo_WebMessageInfoBizPrivacyStatus)(0), // 23: proto.WebMessageInfo.WebMessageInfoBizPrivacyStatus + (*PaymentMoney)(nil), // 24: proto.PaymentMoney + (*HydratedQuickReplyButton)(nil), // 25: proto.HydratedQuickReplyButton + (*HydratedURLButton)(nil), // 26: proto.HydratedURLButton + (*HydratedCallButton)(nil), // 27: proto.HydratedCallButton + (*HydratedTemplateButton)(nil), // 28: proto.HydratedTemplateButton + (*QuickReplyButton)(nil), // 29: proto.QuickReplyButton + (*URLButton)(nil), // 30: proto.URLButton + (*CallButton)(nil), // 31: proto.CallButton + (*TemplateButton)(nil), // 32: proto.TemplateButton + (*Location)(nil), // 33: proto.Location + (*Point)(nil), // 34: proto.Point + (*InteractiveAnnotation)(nil), // 35: proto.InteractiveAnnotation + (*DeviceListMetadata)(nil), // 36: proto.DeviceListMetadata + (*MessageContextInfo)(nil), // 37: proto.MessageContextInfo + (*AdReplyInfo)(nil), // 38: proto.AdReplyInfo + (*ExternalAdReplyInfo)(nil), // 39: proto.ExternalAdReplyInfo + (*ContextInfo)(nil), // 40: proto.ContextInfo + (*SenderKeyDistributionMessage)(nil), // 41: proto.SenderKeyDistributionMessage + (*ImageMessage)(nil), // 42: proto.ImageMessage + (*InvoiceMessage)(nil), // 43: proto.InvoiceMessage + (*ContactMessage)(nil), // 44: proto.ContactMessage + (*LocationMessage)(nil), // 45: proto.LocationMessage + (*ExtendedTextMessage)(nil), // 46: proto.ExtendedTextMessage + (*DocumentMessage)(nil), // 47: proto.DocumentMessage + (*AudioMessage)(nil), // 48: proto.AudioMessage + (*VideoMessage)(nil), // 49: proto.VideoMessage + (*Call)(nil), // 50: proto.Call + (*Chat)(nil), // 51: proto.Chat + (*ProtocolMessage)(nil), // 52: proto.ProtocolMessage + (*HistorySyncNotification)(nil), // 53: proto.HistorySyncNotification + (*AppStateSyncKey)(nil), // 54: proto.AppStateSyncKey + (*AppStateSyncKeyId)(nil), // 55: proto.AppStateSyncKeyId + (*AppStateSyncKeyFingerprint)(nil), // 56: proto.AppStateSyncKeyFingerprint + (*AppStateSyncKeyData)(nil), // 57: proto.AppStateSyncKeyData + (*AppStateSyncKeyShare)(nil), // 58: proto.AppStateSyncKeyShare + (*AppStateSyncKeyRequest)(nil), // 59: proto.AppStateSyncKeyRequest + (*AppStateFatalExceptionNotification)(nil), // 60: proto.AppStateFatalExceptionNotification + (*InitialSecurityNotificationSettingSync)(nil), // 61: proto.InitialSecurityNotificationSettingSync + (*ContactsArrayMessage)(nil), // 62: proto.ContactsArrayMessage + (*HSMCurrency)(nil), // 63: proto.HSMCurrency + (*HSMDateTimeComponent)(nil), // 64: proto.HSMDateTimeComponent + (*HSMDateTimeUnixEpoch)(nil), // 65: proto.HSMDateTimeUnixEpoch + (*HSMDateTime)(nil), // 66: proto.HSMDateTime + (*HSMLocalizableParameter)(nil), // 67: proto.HSMLocalizableParameter + (*HighlyStructuredMessage)(nil), // 68: proto.HighlyStructuredMessage + (*SendPaymentMessage)(nil), // 69: proto.SendPaymentMessage + (*RequestPaymentMessage)(nil), // 70: proto.RequestPaymentMessage + (*DeclinePaymentRequestMessage)(nil), // 71: proto.DeclinePaymentRequestMessage + (*CancelPaymentRequestMessage)(nil), // 72: proto.CancelPaymentRequestMessage + (*LiveLocationMessage)(nil), // 73: proto.LiveLocationMessage + (*StickerMessage)(nil), // 74: proto.StickerMessage + (*FourRowTemplate)(nil), // 75: proto.FourRowTemplate + (*HydratedFourRowTemplate)(nil), // 76: proto.HydratedFourRowTemplate + (*TemplateMessage)(nil), // 77: proto.TemplateMessage + (*TemplateButtonReplyMessage)(nil), // 78: proto.TemplateButtonReplyMessage + (*CatalogSnapshot)(nil), // 79: proto.CatalogSnapshot + (*ProductSnapshot)(nil), // 80: proto.ProductSnapshot + (*ProductMessage)(nil), // 81: proto.ProductMessage + (*OrderMessage)(nil), // 82: proto.OrderMessage + (*Row)(nil), // 83: proto.Row + (*Section)(nil), // 84: proto.Section + (*ListMessage)(nil), // 85: proto.ListMessage + (*SingleSelectReply)(nil), // 86: proto.SingleSelectReply + (*ListResponseMessage)(nil), // 87: proto.ListResponseMessage + (*GroupInviteMessage)(nil), // 88: proto.GroupInviteMessage + (*EphemeralSetting)(nil), // 89: proto.EphemeralSetting + (*DeviceSentMessage)(nil), // 90: proto.DeviceSentMessage + (*FutureProofMessage)(nil), // 91: proto.FutureProofMessage + (*ButtonText)(nil), // 92: proto.ButtonText + (*Button)(nil), // 93: proto.Button + (*ButtonsMessage)(nil), // 94: proto.ButtonsMessage + (*ButtonsResponseMessage)(nil), // 95: proto.ButtonsResponseMessage + (*Message)(nil), // 96: proto.Message + (*MessageKey)(nil), // 97: proto.MessageKey + (*WebFeatures)(nil), // 98: proto.WebFeatures + (*NotificationMessageInfo)(nil), // 99: proto.NotificationMessageInfo + (*WebNotificationsInfo)(nil), // 100: proto.WebNotificationsInfo + (*PaymentInfo)(nil), // 101: proto.PaymentInfo + (*WebMessageInfo)(nil), // 102: proto.WebMessageInfo +} +var file_def_proto_depIdxs = []int32{ + 25, // 0: proto.HydratedTemplateButton.quickReplyButton:type_name -> proto.HydratedQuickReplyButton + 26, // 1: proto.HydratedTemplateButton.urlButton:type_name -> proto.HydratedURLButton + 27, // 2: proto.HydratedTemplateButton.callButton:type_name -> proto.HydratedCallButton + 68, // 3: proto.QuickReplyButton.displayText:type_name -> proto.HighlyStructuredMessage + 68, // 4: proto.URLButton.displayText:type_name -> proto.HighlyStructuredMessage + 68, // 5: proto.URLButton.url:type_name -> proto.HighlyStructuredMessage + 68, // 6: proto.CallButton.displayText:type_name -> proto.HighlyStructuredMessage + 68, // 7: proto.CallButton.phoneNumber:type_name -> proto.HighlyStructuredMessage + 29, // 8: proto.TemplateButton.quickReplyButton:type_name -> proto.QuickReplyButton + 30, // 9: proto.TemplateButton.urlButton:type_name -> proto.URLButton + 31, // 10: proto.TemplateButton.callButton:type_name -> proto.CallButton + 34, // 11: proto.InteractiveAnnotation.polygonVertices:type_name -> proto.Point + 33, // 12: proto.InteractiveAnnotation.location:type_name -> proto.Location + 36, // 13: proto.MessageContextInfo.deviceListMetadata:type_name -> proto.DeviceListMetadata + 0, // 14: proto.AdReplyInfo.mediaType:type_name -> proto.AdReplyInfo.AdReplyInfoMediaType + 1, // 15: proto.ExternalAdReplyInfo.mediaType:type_name -> proto.ExternalAdReplyInfo.ExternalAdReplyInfoMediaType + 96, // 16: proto.ContextInfo.quotedMessage:type_name -> proto.Message + 38, // 17: proto.ContextInfo.quotedAd:type_name -> proto.AdReplyInfo + 97, // 18: proto.ContextInfo.placeholderKey:type_name -> proto.MessageKey + 39, // 19: proto.ContextInfo.externalAdReply:type_name -> proto.ExternalAdReplyInfo + 35, // 20: proto.ImageMessage.interactiveAnnotations:type_name -> proto.InteractiveAnnotation + 40, // 21: proto.ImageMessage.contextInfo:type_name -> proto.ContextInfo + 2, // 22: proto.InvoiceMessage.attachmentType:type_name -> proto.InvoiceMessage.InvoiceMessageAttachmentType + 40, // 23: proto.ContactMessage.contextInfo:type_name -> proto.ContextInfo + 40, // 24: proto.LocationMessage.contextInfo:type_name -> proto.ContextInfo + 3, // 25: proto.ExtendedTextMessage.font:type_name -> proto.ExtendedTextMessage.ExtendedTextMessageFontType + 4, // 26: proto.ExtendedTextMessage.previewType:type_name -> proto.ExtendedTextMessage.ExtendedTextMessagePreviewType + 40, // 27: proto.ExtendedTextMessage.contextInfo:type_name -> proto.ContextInfo + 40, // 28: proto.DocumentMessage.contextInfo:type_name -> proto.ContextInfo + 40, // 29: proto.AudioMessage.contextInfo:type_name -> proto.ContextInfo + 35, // 30: proto.VideoMessage.interactiveAnnotations:type_name -> proto.InteractiveAnnotation + 40, // 31: proto.VideoMessage.contextInfo:type_name -> proto.ContextInfo + 5, // 32: proto.VideoMessage.gifAttribution:type_name -> proto.VideoMessage.VideoMessageAttribution + 97, // 33: proto.ProtocolMessage.key:type_name -> proto.MessageKey + 6, // 34: proto.ProtocolMessage.type:type_name -> proto.ProtocolMessage.ProtocolMessageType + 53, // 35: proto.ProtocolMessage.historySyncNotification:type_name -> proto.HistorySyncNotification + 58, // 36: proto.ProtocolMessage.appStateSyncKeyShare:type_name -> proto.AppStateSyncKeyShare + 59, // 37: proto.ProtocolMessage.appStateSyncKeyRequest:type_name -> proto.AppStateSyncKeyRequest + 61, // 38: proto.ProtocolMessage.initialSecurityNotificationSettingSync:type_name -> proto.InitialSecurityNotificationSettingSync + 60, // 39: proto.ProtocolMessage.appStateFatalExceptionNotification:type_name -> proto.AppStateFatalExceptionNotification + 7, // 40: proto.HistorySyncNotification.syncType:type_name -> proto.HistorySyncNotification.HistorySyncNotificationHistorySyncType + 55, // 41: proto.AppStateSyncKey.keyId:type_name -> proto.AppStateSyncKeyId + 57, // 42: proto.AppStateSyncKey.keyData:type_name -> proto.AppStateSyncKeyData + 56, // 43: proto.AppStateSyncKeyData.fingerprint:type_name -> proto.AppStateSyncKeyFingerprint + 54, // 44: proto.AppStateSyncKeyShare.keys:type_name -> proto.AppStateSyncKey + 55, // 45: proto.AppStateSyncKeyRequest.keyIds:type_name -> proto.AppStateSyncKeyId + 44, // 46: proto.ContactsArrayMessage.contacts:type_name -> proto.ContactMessage + 40, // 47: proto.ContactsArrayMessage.contextInfo:type_name -> proto.ContextInfo + 8, // 48: proto.HSMDateTimeComponent.dayOfWeek:type_name -> proto.HSMDateTimeComponent.HSMDateTimeComponentDayOfWeekType + 9, // 49: proto.HSMDateTimeComponent.calendar:type_name -> proto.HSMDateTimeComponent.HSMDateTimeComponentCalendarType + 64, // 50: proto.HSMDateTime.component:type_name -> proto.HSMDateTimeComponent + 65, // 51: proto.HSMDateTime.unixEpoch:type_name -> proto.HSMDateTimeUnixEpoch + 63, // 52: proto.HSMLocalizableParameter.currency:type_name -> proto.HSMCurrency + 66, // 53: proto.HSMLocalizableParameter.dateTime:type_name -> proto.HSMDateTime + 67, // 54: proto.HighlyStructuredMessage.localizableParams:type_name -> proto.HSMLocalizableParameter + 77, // 55: proto.HighlyStructuredMessage.hydratedHsm:type_name -> proto.TemplateMessage + 96, // 56: proto.SendPaymentMessage.noteMessage:type_name -> proto.Message + 97, // 57: proto.SendPaymentMessage.requestMessageKey:type_name -> proto.MessageKey + 96, // 58: proto.RequestPaymentMessage.noteMessage:type_name -> proto.Message + 24, // 59: proto.RequestPaymentMessage.amount:type_name -> proto.PaymentMoney + 97, // 60: proto.DeclinePaymentRequestMessage.key:type_name -> proto.MessageKey + 97, // 61: proto.CancelPaymentRequestMessage.key:type_name -> proto.MessageKey + 40, // 62: proto.LiveLocationMessage.contextInfo:type_name -> proto.ContextInfo + 40, // 63: proto.StickerMessage.contextInfo:type_name -> proto.ContextInfo + 68, // 64: proto.FourRowTemplate.content:type_name -> proto.HighlyStructuredMessage + 68, // 65: proto.FourRowTemplate.footer:type_name -> proto.HighlyStructuredMessage + 32, // 66: proto.FourRowTemplate.buttons:type_name -> proto.TemplateButton + 47, // 67: proto.FourRowTemplate.documentMessage:type_name -> proto.DocumentMessage + 68, // 68: proto.FourRowTemplate.highlyStructuredMessage:type_name -> proto.HighlyStructuredMessage + 42, // 69: proto.FourRowTemplate.imageMessage:type_name -> proto.ImageMessage + 49, // 70: proto.FourRowTemplate.videoMessage:type_name -> proto.VideoMessage + 45, // 71: proto.FourRowTemplate.locationMessage:type_name -> proto.LocationMessage + 28, // 72: proto.HydratedFourRowTemplate.hydratedButtons:type_name -> proto.HydratedTemplateButton + 47, // 73: proto.HydratedFourRowTemplate.documentMessage:type_name -> proto.DocumentMessage + 42, // 74: proto.HydratedFourRowTemplate.imageMessage:type_name -> proto.ImageMessage + 49, // 75: proto.HydratedFourRowTemplate.videoMessage:type_name -> proto.VideoMessage + 45, // 76: proto.HydratedFourRowTemplate.locationMessage:type_name -> proto.LocationMessage + 40, // 77: proto.TemplateMessage.contextInfo:type_name -> proto.ContextInfo + 76, // 78: proto.TemplateMessage.hydratedTemplate:type_name -> proto.HydratedFourRowTemplate + 75, // 79: proto.TemplateMessage.fourRowTemplate:type_name -> proto.FourRowTemplate + 76, // 80: proto.TemplateMessage.hydratedFourRowTemplate:type_name -> proto.HydratedFourRowTemplate + 40, // 81: proto.TemplateButtonReplyMessage.contextInfo:type_name -> proto.ContextInfo + 42, // 82: proto.CatalogSnapshot.catalogImage:type_name -> proto.ImageMessage + 42, // 83: proto.ProductSnapshot.productImage:type_name -> proto.ImageMessage + 80, // 84: proto.ProductMessage.product:type_name -> proto.ProductSnapshot + 79, // 85: proto.ProductMessage.catalog:type_name -> proto.CatalogSnapshot + 40, // 86: proto.ProductMessage.contextInfo:type_name -> proto.ContextInfo + 10, // 87: proto.OrderMessage.status:type_name -> proto.OrderMessage.OrderMessageOrderStatus + 11, // 88: proto.OrderMessage.surface:type_name -> proto.OrderMessage.OrderMessageOrderSurface + 40, // 89: proto.OrderMessage.contextInfo:type_name -> proto.ContextInfo + 83, // 90: proto.Section.rows:type_name -> proto.Row + 12, // 91: proto.ListMessage.listType:type_name -> proto.ListMessage.ListMessageListType + 84, // 92: proto.ListMessage.sections:type_name -> proto.Section + 13, // 93: proto.ListResponseMessage.listType:type_name -> proto.ListResponseMessage.ListResponseMessageListType + 86, // 94: proto.ListResponseMessage.singleSelectReply:type_name -> proto.SingleSelectReply + 40, // 95: proto.ListResponseMessage.contextInfo:type_name -> proto.ContextInfo + 40, // 96: proto.GroupInviteMessage.contextInfo:type_name -> proto.ContextInfo + 96, // 97: proto.DeviceSentMessage.message:type_name -> proto.Message + 89, // 98: proto.DeviceSentMessage.broadcastEphemeralSettings:type_name -> proto.EphemeralSetting + 96, // 99: proto.FutureProofMessage.message:type_name -> proto.Message + 92, // 100: proto.Button.buttonText:type_name -> proto.ButtonText + 14, // 101: proto.Button.type:type_name -> proto.Button.ButtonType + 40, // 102: proto.ButtonsMessage.contextInfo:type_name -> proto.ContextInfo + 93, // 103: proto.ButtonsMessage.buttons:type_name -> proto.Button + 15, // 104: proto.ButtonsMessage.headerType:type_name -> proto.ButtonsMessage.ButtonsMessageHeaderType + 47, // 105: proto.ButtonsMessage.documentMessage:type_name -> proto.DocumentMessage + 42, // 106: proto.ButtonsMessage.imageMessage:type_name -> proto.ImageMessage + 49, // 107: proto.ButtonsMessage.videoMessage:type_name -> proto.VideoMessage + 45, // 108: proto.ButtonsMessage.locationMessage:type_name -> proto.LocationMessage + 40, // 109: proto.ButtonsResponseMessage.contextInfo:type_name -> proto.ContextInfo + 16, // 110: proto.ButtonsResponseMessage.type:type_name -> proto.ButtonsResponseMessage.ButtonsResponseMessageType + 41, // 111: proto.Message.senderKeyDistributionMessage:type_name -> proto.SenderKeyDistributionMessage + 42, // 112: proto.Message.imageMessage:type_name -> proto.ImageMessage + 44, // 113: proto.Message.contactMessage:type_name -> proto.ContactMessage + 45, // 114: proto.Message.locationMessage:type_name -> proto.LocationMessage + 46, // 115: proto.Message.extendedTextMessage:type_name -> proto.ExtendedTextMessage + 47, // 116: proto.Message.documentMessage:type_name -> proto.DocumentMessage + 48, // 117: proto.Message.audioMessage:type_name -> proto.AudioMessage + 49, // 118: proto.Message.videoMessage:type_name -> proto.VideoMessage + 50, // 119: proto.Message.call:type_name -> proto.Call + 51, // 120: proto.Message.chat:type_name -> proto.Chat + 52, // 121: proto.Message.protocolMessage:type_name -> proto.ProtocolMessage + 62, // 122: proto.Message.contactsArrayMessage:type_name -> proto.ContactsArrayMessage + 68, // 123: proto.Message.highlyStructuredMessage:type_name -> proto.HighlyStructuredMessage + 41, // 124: proto.Message.fastRatchetKeySenderKeyDistributionMessage:type_name -> proto.SenderKeyDistributionMessage + 69, // 125: proto.Message.sendPaymentMessage:type_name -> proto.SendPaymentMessage + 73, // 126: proto.Message.liveLocationMessage:type_name -> proto.LiveLocationMessage + 70, // 127: proto.Message.requestPaymentMessage:type_name -> proto.RequestPaymentMessage + 71, // 128: proto.Message.declinePaymentRequestMessage:type_name -> proto.DeclinePaymentRequestMessage + 72, // 129: proto.Message.cancelPaymentRequestMessage:type_name -> proto.CancelPaymentRequestMessage + 77, // 130: proto.Message.templateMessage:type_name -> proto.TemplateMessage + 74, // 131: proto.Message.stickerMessage:type_name -> proto.StickerMessage + 88, // 132: proto.Message.groupInviteMessage:type_name -> proto.GroupInviteMessage + 78, // 133: proto.Message.templateButtonReplyMessage:type_name -> proto.TemplateButtonReplyMessage + 81, // 134: proto.Message.productMessage:type_name -> proto.ProductMessage + 90, // 135: proto.Message.deviceSentMessage:type_name -> proto.DeviceSentMessage + 37, // 136: proto.Message.messageContextInfo:type_name -> proto.MessageContextInfo + 85, // 137: proto.Message.listMessage:type_name -> proto.ListMessage + 91, // 138: proto.Message.viewOnceMessage:type_name -> proto.FutureProofMessage + 82, // 139: proto.Message.orderMessage:type_name -> proto.OrderMessage + 87, // 140: proto.Message.listResponseMessage:type_name -> proto.ListResponseMessage + 91, // 141: proto.Message.ephemeralMessage:type_name -> proto.FutureProofMessage + 43, // 142: proto.Message.invoiceMessage:type_name -> proto.InvoiceMessage + 94, // 143: proto.Message.buttonsMessage:type_name -> proto.ButtonsMessage + 95, // 144: proto.Message.buttonsResponseMessage:type_name -> proto.ButtonsResponseMessage + 17, // 145: proto.WebFeatures.labelsDisplay:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 146: proto.WebFeatures.voipIndividualOutgoing:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 147: proto.WebFeatures.groupsV3:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 148: proto.WebFeatures.groupsV3Create:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 149: proto.WebFeatures.changeNumberV2:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 150: proto.WebFeatures.queryStatusV3Thumbnail:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 151: proto.WebFeatures.liveLocations:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 152: proto.WebFeatures.queryVname:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 153: proto.WebFeatures.voipIndividualIncoming:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 154: proto.WebFeatures.quickRepliesQuery:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 155: proto.WebFeatures.payments:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 156: proto.WebFeatures.stickerPackQuery:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 157: proto.WebFeatures.liveLocationsFinal:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 158: proto.WebFeatures.labelsEdit:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 159: proto.WebFeatures.mediaUpload:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 160: proto.WebFeatures.mediaUploadRichQuickReplies:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 161: proto.WebFeatures.vnameV2:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 162: proto.WebFeatures.videoPlaybackUrl:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 163: proto.WebFeatures.statusRanking:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 164: proto.WebFeatures.voipIndividualVideo:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 165: proto.WebFeatures.thirdPartyStickers:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 166: proto.WebFeatures.frequentlyForwardedSetting:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 167: proto.WebFeatures.groupsV4JoinPermission:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 168: proto.WebFeatures.recentStickers:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 169: proto.WebFeatures.catalog:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 170: proto.WebFeatures.starredStickers:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 171: proto.WebFeatures.voipGroupCall:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 172: proto.WebFeatures.templateMessage:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 173: proto.WebFeatures.templateMessageInteractivity:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 174: proto.WebFeatures.ephemeralMessages:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 175: proto.WebFeatures.e2ENotificationSync:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 176: proto.WebFeatures.recentStickersV2:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 177: proto.WebFeatures.syncdRelease1:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 178: proto.WebFeatures.recentStickersV3:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 179: proto.WebFeatures.userNotice:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 180: proto.WebFeatures.syncdRelease11:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 181: proto.WebFeatures.support:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 182: proto.WebFeatures.groupUiiCleanup:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 183: proto.WebFeatures.groupDogfoodingInternalOnly:type_name -> proto.WebFeatures.WebFeaturesFlag + 17, // 184: proto.WebFeatures.settingsSync:type_name -> proto.WebFeatures.WebFeaturesFlag + 97, // 185: proto.NotificationMessageInfo.key:type_name -> proto.MessageKey + 96, // 186: proto.NotificationMessageInfo.message:type_name -> proto.Message + 102, // 187: proto.WebNotificationsInfo.notifyMessages:type_name -> proto.WebMessageInfo + 18, // 188: proto.PaymentInfo.currencyDeprecated:type_name -> proto.PaymentInfo.PaymentInfoCurrency + 19, // 189: proto.PaymentInfo.status:type_name -> proto.PaymentInfo.PaymentInfoStatus + 97, // 190: proto.PaymentInfo.requestMessageKey:type_name -> proto.MessageKey + 20, // 191: proto.PaymentInfo.txnStatus:type_name -> proto.PaymentInfo.PaymentInfoTxnStatus + 24, // 192: proto.PaymentInfo.primaryAmount:type_name -> proto.PaymentMoney + 24, // 193: proto.PaymentInfo.exchangeAmount:type_name -> proto.PaymentMoney + 97, // 194: proto.WebMessageInfo.key:type_name -> proto.MessageKey + 96, // 195: proto.WebMessageInfo.message:type_name -> proto.Message + 21, // 196: proto.WebMessageInfo.status:type_name -> proto.WebMessageInfo.WebMessageInfoStatus + 22, // 197: proto.WebMessageInfo.messageStubType:type_name -> proto.WebMessageInfo.WebMessageInfoStubType + 101, // 198: proto.WebMessageInfo.paymentInfo:type_name -> proto.PaymentInfo + 73, // 199: proto.WebMessageInfo.finalLiveLocation:type_name -> proto.LiveLocationMessage + 101, // 200: proto.WebMessageInfo.quotedPaymentInfo:type_name -> proto.PaymentInfo + 23, // 201: proto.WebMessageInfo.bizPrivacyStatus:type_name -> proto.WebMessageInfo.WebMessageInfoBizPrivacyStatus + 202, // [202:202] is the sub-list for method output_type + 202, // [202:202] is the sub-list for method input_type + 202, // [202:202] is the sub-list for extension type_name + 202, // [202:202] is the sub-list for extension extendee + 0, // [0:202] is the sub-list for field type_name +} + +func init() { file_def_proto_init() } +func file_def_proto_init() { + if File_def_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_def_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PaymentMoney); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HydratedQuickReplyButton); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HydratedURLButton); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HydratedCallButton); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HydratedTemplateButton); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*QuickReplyButton); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*URLButton); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CallButton); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TemplateButton); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Location); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Point); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InteractiveAnnotation); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeviceListMetadata); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MessageContextInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AdReplyInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExternalAdReplyInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ContextInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SenderKeyDistributionMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ImageMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InvoiceMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ContactMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LocationMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExtendedTextMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DocumentMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AudioMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VideoMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Call); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Chat); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProtocolMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HistorySyncNotification); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AppStateSyncKey); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AppStateSyncKeyId); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AppStateSyncKeyFingerprint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AppStateSyncKeyData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AppStateSyncKeyShare); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AppStateSyncKeyRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AppStateFatalExceptionNotification); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*InitialSecurityNotificationSettingSync); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ContactsArrayMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HSMCurrency); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HSMDateTimeComponent); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HSMDateTimeUnixEpoch); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HSMDateTime); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HSMLocalizableParameter); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HighlyStructuredMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SendPaymentMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RequestPaymentMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeclinePaymentRequestMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CancelPaymentRequestMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LiveLocationMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StickerMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FourRowTemplate); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HydratedFourRowTemplate); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TemplateMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TemplateButtonReplyMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CatalogSnapshot); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProductSnapshot); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProductMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*OrderMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Row); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[60].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Section); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[61].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[62].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SingleSelectReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[63].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListResponseMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GroupInviteMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EphemeralSetting); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeviceSentMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FutureProofMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[68].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ButtonText); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[69].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Button); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[70].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ButtonsMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[71].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ButtonsResponseMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[72].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Message); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[73].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MessageKey); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[74].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WebFeatures); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[75].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NotificationMessageInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[76].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WebNotificationsInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[77].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PaymentInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_def_proto_msgTypes[78].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*WebMessageInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_def_proto_msgTypes[4].OneofWrappers = []interface{}{ + (*HydratedTemplateButton_QuickReplyButton)(nil), + (*HydratedTemplateButton_UrlButton)(nil), + (*HydratedTemplateButton_CallButton)(nil), + } + file_def_proto_msgTypes[8].OneofWrappers = []interface{}{ + (*TemplateButton_QuickReplyButton)(nil), + (*TemplateButton_UrlButton)(nil), + (*TemplateButton_CallButton)(nil), + } + file_def_proto_msgTypes[11].OneofWrappers = []interface{}{ + (*InteractiveAnnotation_Location)(nil), + } + file_def_proto_msgTypes[42].OneofWrappers = []interface{}{ + (*HSMDateTime_Component)(nil), + (*HSMDateTime_UnixEpoch)(nil), + } + file_def_proto_msgTypes[43].OneofWrappers = []interface{}{ + (*HSMLocalizableParameter_Currency)(nil), + (*HSMLocalizableParameter_DateTime)(nil), + } + file_def_proto_msgTypes[51].OneofWrappers = []interface{}{ + (*FourRowTemplate_DocumentMessage)(nil), + (*FourRowTemplate_HighlyStructuredMessage)(nil), + (*FourRowTemplate_ImageMessage)(nil), + (*FourRowTemplate_VideoMessage)(nil), + (*FourRowTemplate_LocationMessage)(nil), + } + file_def_proto_msgTypes[52].OneofWrappers = []interface{}{ + (*HydratedFourRowTemplate_DocumentMessage)(nil), + (*HydratedFourRowTemplate_HydratedTitleText)(nil), + (*HydratedFourRowTemplate_ImageMessage)(nil), + (*HydratedFourRowTemplate_VideoMessage)(nil), + (*HydratedFourRowTemplate_LocationMessage)(nil), + } + file_def_proto_msgTypes[53].OneofWrappers = []interface{}{ + (*TemplateMessage_FourRowTemplate)(nil), + (*TemplateMessage_HydratedFourRowTemplate)(nil), + } + file_def_proto_msgTypes[70].OneofWrappers = []interface{}{ + (*ButtonsMessage_Text)(nil), + (*ButtonsMessage_DocumentMessage)(nil), + (*ButtonsMessage_ImageMessage)(nil), + (*ButtonsMessage_VideoMessage)(nil), + (*ButtonsMessage_LocationMessage)(nil), + } + file_def_proto_msgTypes[71].OneofWrappers = []interface{}{ + (*ButtonsResponseMessage_SelectedDisplayText)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_def_proto_rawDesc, + NumEnums: 24, + NumMessages: 79, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_def_proto_goTypes, + DependencyIndexes: file_def_proto_depIdxs, + EnumInfos: file_def_proto_enumTypes, + MessageInfos: file_def_proto_msgTypes, + }.Build() + File_def_proto = out.File + file_def_proto_rawDesc = nil + file_def_proto_goTypes = nil + file_def_proto_depIdxs = nil +} \ No newline at end of file diff --git a/vendor/github.com/Rhymen/go-whatsapp/binary/proto/def.proto b/vendor/github.com/Rhymen/go-whatsapp/binary/proto/def.proto new file mode 100644 index 00000000..58c6f20c --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/binary/proto/def.proto @@ -0,0 +1,1050 @@ +syntax = "proto2"; +package proto; + +message PaymentMoney { + optional int64 value = 1; + optional uint32 offset = 2; + optional string currencyCode = 3; +} + +message HydratedQuickReplyButton { + optional string displayText = 1; + optional string id = 2; +} + +message HydratedURLButton { + optional string displayText = 1; + optional string url = 2; +} + +message HydratedCallButton { + optional string displayText = 1; + optional string phoneNumber = 2; +} + +message HydratedTemplateButton { + optional uint32 index = 4; + oneof hydratedButton { + HydratedQuickReplyButton quickReplyButton = 1; + HydratedURLButton urlButton = 2; + HydratedCallButton callButton = 3; + } +} + +message QuickReplyButton { + optional HighlyStructuredMessage displayText = 1; + optional string id = 2; +} + +message URLButton { + optional HighlyStructuredMessage displayText = 1; + optional HighlyStructuredMessage url = 2; +} + +message CallButton { + optional HighlyStructuredMessage displayText = 1; + optional HighlyStructuredMessage phoneNumber = 2; +} + +message TemplateButton { + optional uint32 index = 4; + oneof button { + QuickReplyButton quickReplyButton = 1; + URLButton urlButton = 2; + CallButton callButton = 3; + } +} + +message Location { + optional double degreesLatitude = 1; + optional double degreesLongitude = 2; + optional string name = 3; +} + +message Point { + optional int32 xDeprecated = 1; + optional int32 yDeprecated = 2; + optional double x = 3; + optional double y = 4; +} + +message InteractiveAnnotation { + repeated Point polygonVertices = 1; + oneof action { + Location location = 2; + } +} + +message DeviceListMetadata { + optional bytes senderKeyHash = 1; + optional uint64 senderTimestamp = 2; + optional bytes recipientKeyHash = 8; + optional uint64 recipientTimestamp = 9; +} + +message MessageContextInfo { + optional DeviceListMetadata deviceListMetadata = 1; +} + +message AdReplyInfo { + optional string advertiserName = 1; + enum AdReplyInfoMediaType { + NONE = 0; + IMAGE = 1; + VIDEO = 2; + } + optional AdReplyInfoMediaType mediaType = 2; + optional bytes jpegThumbnail = 16; + optional string caption = 17; +} + +message ExternalAdReplyInfo { + optional string title = 1; + optional string body = 2; + enum ExternalAdReplyInfoMediaType { + NONE = 0; + IMAGE = 1; + VIDEO = 2; + } + optional ExternalAdReplyInfoMediaType mediaType = 3; + optional string thumbnailUrl = 4; + optional string mediaUrl = 5; + optional bytes thumbnail = 6; + optional string sourceType = 7; + optional string sourceId = 8; + optional string sourceUrl = 9; +} + +message ContextInfo { + optional string stanzaId = 1; + optional string participant = 2; + optional Message quotedMessage = 3; + optional string remoteJid = 4; + repeated string mentionedJid = 15; + optional string conversionSource = 18; + optional bytes conversionData = 19; + optional uint32 conversionDelaySeconds = 20; + optional uint32 forwardingScore = 21; + optional bool isForwarded = 22; + optional AdReplyInfo quotedAd = 23; + optional MessageKey placeholderKey = 24; + optional uint32 expiration = 25; + optional int64 ephemeralSettingTimestamp = 26; + optional bytes ephemeralSharedSecret = 27; + optional ExternalAdReplyInfo externalAdReply = 28; +} + +message SenderKeyDistributionMessage { + optional string groupId = 1; + optional bytes axolotlSenderKeyDistributionMessage = 2; +} + +message ImageMessage { + optional string url = 1; + optional string mimetype = 2; + optional string caption = 3; + optional bytes fileSha256 = 4; + optional uint64 fileLength = 5; + optional uint32 height = 6; + optional uint32 width = 7; + optional bytes mediaKey = 8; + optional bytes fileEncSha256 = 9; + repeated InteractiveAnnotation interactiveAnnotations = 10; + optional string directPath = 11; + optional int64 mediaKeyTimestamp = 12; + optional bytes jpegThumbnail = 16; + optional ContextInfo contextInfo = 17; + optional bytes firstScanSidecar = 18; + optional uint32 firstScanLength = 19; + optional uint32 experimentGroupId = 20; + optional bytes scansSidecar = 21; + repeated uint32 scanLengths = 22; + optional bytes midQualityFileSha256 = 23; + optional bytes midQualityFileEncSha256 = 24; + optional bool viewOnce = 25; + optional string thumbnailDirectPath = 26; + optional bytes thumbnailSha256 = 27; + optional bytes thumbnailEncSha256 = 28; +} + +message InvoiceMessage { + optional string note = 1; + optional string token = 2; + enum InvoiceMessageAttachmentType { + IMAGE = 0; + PDF = 1; + } + optional InvoiceMessageAttachmentType attachmentType = 3; + optional string attachmentMimetype = 4; + optional bytes attachmentMediaKey = 5; + optional int64 attachmentMediaKeyTimestamp = 6; + optional bytes attachmentFileSha256 = 7; + optional bytes attachmentFileEncSha256 = 8; + optional string attachmentDirectPath = 9; + optional bytes attachmentJpegThumbnail = 10; +} + +message ContactMessage { + optional string displayName = 1; + optional string vcard = 16; + optional ContextInfo contextInfo = 17; +} + +message LocationMessage { + optional double degreesLatitude = 1; + optional double degreesLongitude = 2; + optional string name = 3; + optional string address = 4; + optional string url = 5; + optional bool isLive = 6; + optional uint32 accuracyInMeters = 7; + optional float speedInMps = 8; + optional uint32 degreesClockwiseFromMagneticNorth = 9; + optional string comment = 11; + optional bytes jpegThumbnail = 16; + optional ContextInfo contextInfo = 17; +} + +message ExtendedTextMessage { + optional string text = 1; + optional string matchedText = 2; + optional string canonicalUrl = 4; + optional string description = 5; + optional string title = 6; + optional fixed32 textArgb = 7; + optional fixed32 backgroundArgb = 8; + enum ExtendedTextMessageFontType { + SANS_SERIF = 0; + SERIF = 1; + NORICAN_REGULAR = 2; + BRYNDAN_WRITE = 3; + BEBASNEUE_REGULAR = 4; + OSWALD_HEAVY = 5; + } + optional ExtendedTextMessageFontType font = 9; + enum ExtendedTextMessagePreviewType { + NONE = 0; + VIDEO = 1; + } + optional ExtendedTextMessagePreviewType previewType = 10; + optional bytes jpegThumbnail = 16; + optional ContextInfo contextInfo = 17; + optional bool doNotPlayInline = 18; +} + +message DocumentMessage { + optional string url = 1; + optional string mimetype = 2; + optional string title = 3; + optional bytes fileSha256 = 4; + optional uint64 fileLength = 5; + optional uint32 pageCount = 6; + optional bytes mediaKey = 7; + optional string fileName = 8; + optional bytes fileEncSha256 = 9; + optional string directPath = 10; + optional int64 mediaKeyTimestamp = 11; + optional bool contactVcard = 12; + optional string thumbnailDirectPath = 13; + optional bytes thumbnailSha256 = 14; + optional bytes thumbnailEncSha256 = 15; + optional bytes jpegThumbnail = 16; + optional ContextInfo contextInfo = 17; + optional uint32 thumbnailHeight = 18; + optional uint32 thumbnailWidth = 19; +} + +message AudioMessage { + optional string url = 1; + optional string mimetype = 2; + optional bytes fileSha256 = 3; + optional uint64 fileLength = 4; + optional uint32 seconds = 5; + optional bool ptt = 6; + optional bytes mediaKey = 7; + optional bytes fileEncSha256 = 8; + optional string directPath = 9; + optional int64 mediaKeyTimestamp = 10; + optional ContextInfo contextInfo = 17; + optional bytes streamingSidecar = 18; +} + +message VideoMessage { + optional string url = 1; + optional string mimetype = 2; + optional bytes fileSha256 = 3; + optional uint64 fileLength = 4; + optional uint32 seconds = 5; + optional bytes mediaKey = 6; + optional string caption = 7; + optional bool gifPlayback = 8; + optional uint32 height = 9; + optional uint32 width = 10; + optional bytes fileEncSha256 = 11; + repeated InteractiveAnnotation interactiveAnnotations = 12; + optional string directPath = 13; + optional int64 mediaKeyTimestamp = 14; + optional bytes jpegThumbnail = 16; + optional ContextInfo contextInfo = 17; + optional bytes streamingSidecar = 18; + enum VideoMessageAttribution { + NONE = 0; + GIPHY = 1; + TENOR = 2; + } + optional VideoMessageAttribution gifAttribution = 19; + optional bool viewOnce = 20; + optional string thumbnailDirectPath = 21; + optional bytes thumbnailSha256 = 22; + optional bytes thumbnailEncSha256 = 23; +} + +message Call { + optional bytes callKey = 1; +} + +message Chat { + optional string displayName = 1; + optional string id = 2; +} + +message ProtocolMessage { + optional MessageKey key = 1; + enum ProtocolMessageType { + REVOKE = 0; + EPHEMERAL_SETTING = 3; + EPHEMERAL_SYNC_RESPONSE = 4; + HISTORY_SYNC_NOTIFICATION = 5; + APP_STATE_SYNC_KEY_SHARE = 6; + APP_STATE_SYNC_KEY_REQUEST = 7; + MSG_FANOUT_BACKFILL_REQUEST = 8; + INITIAL_SECURITY_NOTIFICATION_SETTING_SYNC = 9; + APP_STATE_FATAL_EXCEPTION_NOTIFICATION = 10; + } + optional ProtocolMessageType type = 2; + optional uint32 ephemeralExpiration = 4; + optional int64 ephemeralSettingTimestamp = 5; + optional HistorySyncNotification historySyncNotification = 6; + optional AppStateSyncKeyShare appStateSyncKeyShare = 7; + optional AppStateSyncKeyRequest appStateSyncKeyRequest = 8; + optional InitialSecurityNotificationSettingSync initialSecurityNotificationSettingSync = 9; + optional AppStateFatalExceptionNotification appStateFatalExceptionNotification = 10; +} + +message HistorySyncNotification { + optional bytes fileSha256 = 1; + optional uint64 fileLength = 2; + optional bytes mediaKey = 3; + optional bytes fileEncSha256 = 4; + optional string directPath = 5; + enum HistorySyncNotificationHistorySyncType { + INITIAL_BOOTSTRAP = 0; + INITIAL_STATUS_V3 = 1; + FULL = 2; + RECENT = 3; + PUSH_NAME = 4; + } + optional HistorySyncNotificationHistorySyncType syncType = 6; + optional uint32 chunkOrder = 7; + optional string originalMessageId = 8; +} + +message AppStateSyncKey { + optional AppStateSyncKeyId keyId = 1; + optional AppStateSyncKeyData keyData = 2; +} + +message AppStateSyncKeyId { + optional bytes keyId = 1; +} + +message AppStateSyncKeyFingerprint { + optional uint32 rawId = 1; + optional uint32 currentIndex = 2; + repeated uint32 deviceIndexes = 3 [packed=true]; +} + +message AppStateSyncKeyData { + optional bytes keyData = 1; + optional AppStateSyncKeyFingerprint fingerprint = 2; + optional int64 timestamp = 3; +} + +message AppStateSyncKeyShare { + repeated AppStateSyncKey keys = 1; +} + +message AppStateSyncKeyRequest { + repeated AppStateSyncKeyId keyIds = 1; +} + +message AppStateFatalExceptionNotification { + repeated string collectionNames = 1; + optional int64 timestamp = 2; +} + +message InitialSecurityNotificationSettingSync { + optional bool securityNotificationEnabled = 1; +} + +message ContactsArrayMessage { + optional string displayName = 1; + repeated ContactMessage contacts = 2; + optional ContextInfo contextInfo = 17; +} + +message HSMCurrency { + optional string currencyCode = 1; + optional int64 amount1000 = 2; +} + +message HSMDateTimeComponent { + enum HSMDateTimeComponentDayOfWeekType { + MONDAY = 1; + TUESDAY = 2; + WEDNESDAY = 3; + THURSDAY = 4; + FRIDAY = 5; + SATURDAY = 6; + SUNDAY = 7; + } + optional HSMDateTimeComponentDayOfWeekType dayOfWeek = 1; + optional uint32 year = 2; + optional uint32 month = 3; + optional uint32 dayOfMonth = 4; + optional uint32 hour = 5; + optional uint32 minute = 6; + enum HSMDateTimeComponentCalendarType { + GREGORIAN = 1; + SOLAR_HIJRI = 2; + } + optional HSMDateTimeComponentCalendarType calendar = 7; +} + +message HSMDateTimeUnixEpoch { + optional int64 timestamp = 1; +} + +message HSMDateTime { + oneof datetimeOneof { + HSMDateTimeComponent component = 1; + HSMDateTimeUnixEpoch unixEpoch = 2; + } +} + +message HSMLocalizableParameter { + optional string default = 1; + oneof paramOneof { + HSMCurrency currency = 2; + HSMDateTime dateTime = 3; + } +} + +message HighlyStructuredMessage { + optional string namespace = 1; + optional string elementName = 2; + repeated string params = 3; + optional string fallbackLg = 4; + optional string fallbackLc = 5; + repeated HSMLocalizableParameter localizableParams = 6; + optional string deterministicLg = 7; + optional string deterministicLc = 8; + optional TemplateMessage hydratedHsm = 9; +} + +message SendPaymentMessage { + optional Message noteMessage = 2; + optional MessageKey requestMessageKey = 3; +} + +message RequestPaymentMessage { + optional Message noteMessage = 4; + optional string currencyCodeIso4217 = 1; + optional uint64 amount1000 = 2; + optional string requestFrom = 3; + optional int64 expiryTimestamp = 5; + optional PaymentMoney amount = 6; +} + +message DeclinePaymentRequestMessage { + optional MessageKey key = 1; +} + +message CancelPaymentRequestMessage { + optional MessageKey key = 1; +} + +message LiveLocationMessage { + optional double degreesLatitude = 1; + optional double degreesLongitude = 2; + optional uint32 accuracyInMeters = 3; + optional float speedInMps = 4; + optional uint32 degreesClockwiseFromMagneticNorth = 5; + optional string caption = 6; + optional int64 sequenceNumber = 7; + optional uint32 timeOffset = 8; + optional bytes jpegThumbnail = 16; + optional ContextInfo contextInfo = 17; +} + +message StickerMessage { + optional string url = 1; + optional bytes fileSha256 = 2; + optional bytes fileEncSha256 = 3; + optional bytes mediaKey = 4; + optional string mimetype = 5; + optional uint32 height = 6; + optional uint32 width = 7; + optional string directPath = 8; + optional uint64 fileLength = 9; + optional int64 mediaKeyTimestamp = 10; + optional uint32 firstFrameLength = 11; + optional bytes firstFrameSidecar = 12; + optional bool isAnimated = 13; + optional bytes pngThumbnail = 16; + optional ContextInfo contextInfo = 17; +} + +message FourRowTemplate { + optional HighlyStructuredMessage content = 6; + optional HighlyStructuredMessage footer = 7; + repeated TemplateButton buttons = 8; + oneof title { + DocumentMessage documentMessage = 1; + HighlyStructuredMessage highlyStructuredMessage = 2; + ImageMessage imageMessage = 3; + VideoMessage videoMessage = 4; + LocationMessage locationMessage = 5; + } +} + +message HydratedFourRowTemplate { + optional string hydratedContentText = 6; + optional string hydratedFooterText = 7; + repeated HydratedTemplateButton hydratedButtons = 8; + optional string templateId = 9; + oneof title { + DocumentMessage documentMessage = 1; + string hydratedTitleText = 2; + ImageMessage imageMessage = 3; + VideoMessage videoMessage = 4; + LocationMessage locationMessage = 5; + } +} + +message TemplateMessage { + optional ContextInfo contextInfo = 3; + optional HydratedFourRowTemplate hydratedTemplate = 4; + oneof format { + FourRowTemplate fourRowTemplate = 1; + HydratedFourRowTemplate hydratedFourRowTemplate = 2; + } +} + +message TemplateButtonReplyMessage { + optional string selectedId = 1; + optional string selectedDisplayText = 2; + optional ContextInfo contextInfo = 3; + optional uint32 selectedIndex = 4; +} + +message CatalogSnapshot { + optional ImageMessage catalogImage = 1; + optional string title = 2; + optional string description = 3; +} + +message ProductSnapshot { + optional ImageMessage productImage = 1; + optional string productId = 2; + optional string title = 3; + optional string description = 4; + optional string currencyCode = 5; + optional int64 priceAmount1000 = 6; + optional string retailerId = 7; + optional string url = 8; + optional uint32 productImageCount = 9; + optional string firstImageId = 11; +} + +message ProductMessage { + optional ProductSnapshot product = 1; + optional string businessOwnerJid = 2; + optional CatalogSnapshot catalog = 4; + optional ContextInfo contextInfo = 17; +} + +message OrderMessage { + optional string orderId = 1; + optional bytes thumbnail = 2; + optional int32 itemCount = 3; + enum OrderMessageOrderStatus { + INQUIRY = 1; + } + optional OrderMessageOrderStatus status = 4; + enum OrderMessageOrderSurface { + CATALOG = 1; + } + optional OrderMessageOrderSurface surface = 5; + optional string message = 6; + optional string orderTitle = 7; + optional string sellerJid = 8; + optional string token = 9; + optional int64 totalAmount1000 = 10; + optional string totalCurrencyCode = 11; + optional ContextInfo contextInfo = 17; +} + +message Row { + optional string title = 1; + optional string description = 2; + optional string rowId = 3; +} + +message Section { + optional string title = 1; + repeated Row rows = 2; +} + +message ListMessage { + optional string title = 1; + optional string description = 2; + optional string buttonText = 3; + enum ListMessageListType { + UNKNOWN = 0; + SINGLE_SELECT = 1; + } + optional ListMessageListType listType = 4; + repeated Section sections = 5; +} + +message SingleSelectReply { + optional string selectedRowId = 1; +} + +message ListResponseMessage { + optional string title = 1; + enum ListResponseMessageListType { + UNKNOWN = 0; + SINGLE_SELECT = 1; + } + optional ListResponseMessageListType listType = 2; + optional SingleSelectReply singleSelectReply = 3; + optional ContextInfo contextInfo = 4; + optional string description = 5; +} + +message GroupInviteMessage { + optional string groupJid = 1; + optional string inviteCode = 2; + optional int64 inviteExpiration = 3; + optional string groupName = 4; + optional bytes jpegThumbnail = 5; + optional string caption = 6; + optional ContextInfo contextInfo = 7; +} + +message EphemeralSetting { + optional string chatJid = 1; + optional uint32 ephemeralExpiration = 2; + optional int64 ephemeralSettingTimestamp = 3; +} + +message DeviceSentMessage { + optional string destinationJid = 1; + optional Message message = 2; + optional string phash = 3; + repeated EphemeralSetting broadcastEphemeralSettings = 4; +} + +message FutureProofMessage { + optional Message message = 1; +} + +message ButtonText { + optional string displayText = 1; +} + +message Button { + optional string buttonId = 1; + optional ButtonText buttonText = 2; + enum ButtonType { + UNKNOWN = 0; + RESPONSE = 1; + } + optional ButtonType type = 3; +} + +message ButtonsMessage { + optional string contentText = 6; + optional string footerText = 7; + optional ContextInfo contextInfo = 8; + repeated Button buttons = 9; + enum ButtonsMessageHeaderType { + UNKNOWN = 0; + EMPTY = 1; + TEXT = 2; + DOCUMENT = 3; + IMAGE = 4; + VIDEO = 5; + LOCATION = 6; + } + optional ButtonsMessageHeaderType headerType = 10; + oneof header { + string text = 1; + DocumentMessage documentMessage = 2; + ImageMessage imageMessage = 3; + VideoMessage videoMessage = 4; + LocationMessage locationMessage = 5; + } +} + +message ButtonsResponseMessage { + optional string selectedButtonId = 1; + optional ContextInfo contextInfo = 3; + enum ButtonsResponseMessageType { + UNKNOWN = 0; + DISPLAY_TEXT = 1; + } + optional ButtonsResponseMessageType type = 4; + oneof response { + string selectedDisplayText = 2; + } +} + +message Message { + optional string conversation = 1; + optional SenderKeyDistributionMessage senderKeyDistributionMessage = 2; + optional ImageMessage imageMessage = 3; + optional ContactMessage contactMessage = 4; + optional LocationMessage locationMessage = 5; + optional ExtendedTextMessage extendedTextMessage = 6; + optional DocumentMessage documentMessage = 7; + optional AudioMessage audioMessage = 8; + optional VideoMessage videoMessage = 9; + optional Call call = 10; + optional Chat chat = 11; + optional ProtocolMessage protocolMessage = 12; + optional ContactsArrayMessage contactsArrayMessage = 13; + optional HighlyStructuredMessage highlyStructuredMessage = 14; + optional SenderKeyDistributionMessage fastRatchetKeySenderKeyDistributionMessage = 15; + optional SendPaymentMessage sendPaymentMessage = 16; + optional LiveLocationMessage liveLocationMessage = 18; + optional RequestPaymentMessage requestPaymentMessage = 22; + optional DeclinePaymentRequestMessage declinePaymentRequestMessage = 23; + optional CancelPaymentRequestMessage cancelPaymentRequestMessage = 24; + optional TemplateMessage templateMessage = 25; + optional StickerMessage stickerMessage = 26; + optional GroupInviteMessage groupInviteMessage = 28; + optional TemplateButtonReplyMessage templateButtonReplyMessage = 29; + optional ProductMessage productMessage = 30; + optional DeviceSentMessage deviceSentMessage = 31; + optional MessageContextInfo messageContextInfo = 35; + optional ListMessage listMessage = 36; + optional FutureProofMessage viewOnceMessage = 37; + optional OrderMessage orderMessage = 38; + optional ListResponseMessage listResponseMessage = 39; + optional FutureProofMessage ephemeralMessage = 40; + optional InvoiceMessage invoiceMessage = 41; + optional ButtonsMessage buttonsMessage = 42; + optional ButtonsResponseMessage buttonsResponseMessage = 43; +} + +message MessageKey { + optional string remoteJid = 1; + optional bool fromMe = 2; + optional string id = 3; + optional string participant = 4; +} + +message WebFeatures { + enum WebFeaturesFlag { + NOT_STARTED = 0; + FORCE_UPGRADE = 1; + DEVELOPMENT = 2; + PRODUCTION = 3; + } + optional WebFeaturesFlag labelsDisplay = 1; + optional WebFeaturesFlag voipIndividualOutgoing = 2; + optional WebFeaturesFlag groupsV3 = 3; + optional WebFeaturesFlag groupsV3Create = 4; + optional WebFeaturesFlag changeNumberV2 = 5; + optional WebFeaturesFlag queryStatusV3Thumbnail = 6; + optional WebFeaturesFlag liveLocations = 7; + optional WebFeaturesFlag queryVname = 8; + optional WebFeaturesFlag voipIndividualIncoming = 9; + optional WebFeaturesFlag quickRepliesQuery = 10; + optional WebFeaturesFlag payments = 11; + optional WebFeaturesFlag stickerPackQuery = 12; + optional WebFeaturesFlag liveLocationsFinal = 13; + optional WebFeaturesFlag labelsEdit = 14; + optional WebFeaturesFlag mediaUpload = 15; + optional WebFeaturesFlag mediaUploadRichQuickReplies = 18; + optional WebFeaturesFlag vnameV2 = 19; + optional WebFeaturesFlag videoPlaybackUrl = 20; + optional WebFeaturesFlag statusRanking = 21; + optional WebFeaturesFlag voipIndividualVideo = 22; + optional WebFeaturesFlag thirdPartyStickers = 23; + optional WebFeaturesFlag frequentlyForwardedSetting = 24; + optional WebFeaturesFlag groupsV4JoinPermission = 25; + optional WebFeaturesFlag recentStickers = 26; + optional WebFeaturesFlag catalog = 27; + optional WebFeaturesFlag starredStickers = 28; + optional WebFeaturesFlag voipGroupCall = 29; + optional WebFeaturesFlag templateMessage = 30; + optional WebFeaturesFlag templateMessageInteractivity = 31; + optional WebFeaturesFlag ephemeralMessages = 32; + optional WebFeaturesFlag e2ENotificationSync = 33; + optional WebFeaturesFlag recentStickersV2 = 34; + optional WebFeaturesFlag syncdRelease1 = 35; + optional WebFeaturesFlag recentStickersV3 = 36; + optional WebFeaturesFlag userNotice = 37; + optional WebFeaturesFlag syncdRelease11 = 38; + optional WebFeaturesFlag support = 39; + optional WebFeaturesFlag groupUiiCleanup = 40; + optional WebFeaturesFlag groupDogfoodingInternalOnly = 41; + optional WebFeaturesFlag settingsSync = 42; +} + +message NotificationMessageInfo { + optional MessageKey key = 1; + optional Message message = 2; + optional uint64 messageTimestamp = 3; + optional string participant = 4; +} + +message WebNotificationsInfo { + optional uint64 timestamp = 2; + optional uint32 unreadChats = 3; + optional uint32 notifyMessageCount = 4; + repeated WebMessageInfo notifyMessages = 5; +} + +message PaymentInfo { + enum PaymentInfoCurrency { + UNKNOWN_CURRENCY = 0; + INR = 1; + } + optional PaymentInfoCurrency currencyDeprecated = 1; + optional uint64 amount1000 = 2; + optional string receiverJid = 3; + enum PaymentInfoStatus { + UNKNOWN_STATUS = 0; + PROCESSING = 1; + SENT = 2; + NEED_TO_ACCEPT = 3; + COMPLETE = 4; + COULD_NOT_COMPLETE = 5; + REFUNDED = 6; + EXPIRED = 7; + REJECTED = 8; + CANCELLED = 9; + WAITING_FOR_PAYER = 10; + WAITING = 11; + } + optional PaymentInfoStatus status = 4; + optional uint64 transactionTimestamp = 5; + optional MessageKey requestMessageKey = 6; + optional uint64 expiryTimestamp = 7; + optional bool futureproofed = 8; + optional string currency = 9; + enum PaymentInfoTxnStatus { + UNKNOWN = 0; + PENDING_SETUP = 1; + PENDING_RECEIVER_SETUP = 2; + INIT = 3; + SUCCESS = 4; + COMPLETED = 5; + FAILED = 6; + FAILED_RISK = 7; + FAILED_PROCESSING = 8; + FAILED_RECEIVER_PROCESSING = 9; + FAILED_DA = 10; + FAILED_DA_FINAL = 11; + REFUNDED_TXN = 12; + REFUND_FAILED = 13; + REFUND_FAILED_PROCESSING = 14; + REFUND_FAILED_DA = 15; + EXPIRED_TXN = 16; + AUTH_CANCELED = 17; + AUTH_CANCEL_FAILED_PROCESSING = 18; + AUTH_CANCEL_FAILED = 19; + COLLECT_INIT = 20; + COLLECT_SUCCESS = 21; + COLLECT_FAILED = 22; + COLLECT_FAILED_RISK = 23; + COLLECT_REJECTED = 24; + COLLECT_EXPIRED = 25; + COLLECT_CANCELED = 26; + COLLECT_CANCELLING = 27; + } + optional PaymentInfoTxnStatus txnStatus = 10; + optional bool useNoviFiatFormat = 11; + optional PaymentMoney primaryAmount = 12; + optional PaymentMoney exchangeAmount = 13; +} + +message WebMessageInfo { + required MessageKey key = 1; + optional Message message = 2; + optional uint64 messageTimestamp = 3; + enum WebMessageInfoStatus { + ERROR = 0; + PENDING = 1; + SERVER_ACK = 2; + DELIVERY_ACK = 3; + READ = 4; + PLAYED = 5; + } + optional WebMessageInfoStatus status = 4; + optional string participant = 5; + optional bool ignore = 16; + optional bool starred = 17; + optional bool broadcast = 18; + optional string pushName = 19; + optional bytes mediaCiphertextSha256 = 20; + optional bool multicast = 21; + optional bool urlText = 22; + optional bool urlNumber = 23; + enum WebMessageInfoStubType { + UNKNOWN = 0; + REVOKE = 1; + CIPHERTEXT = 2; + FUTUREPROOF = 3; + NON_VERIFIED_TRANSITION = 4; + UNVERIFIED_TRANSITION = 5; + VERIFIED_TRANSITION = 6; + VERIFIED_LOW_UNKNOWN = 7; + VERIFIED_HIGH = 8; + VERIFIED_INITIAL_UNKNOWN = 9; + VERIFIED_INITIAL_LOW = 10; + VERIFIED_INITIAL_HIGH = 11; + VERIFIED_TRANSITION_ANY_TO_NONE = 12; + VERIFIED_TRANSITION_ANY_TO_HIGH = 13; + VERIFIED_TRANSITION_HIGH_TO_LOW = 14; + VERIFIED_TRANSITION_HIGH_TO_UNKNOWN = 15; + VERIFIED_TRANSITION_UNKNOWN_TO_LOW = 16; + VERIFIED_TRANSITION_LOW_TO_UNKNOWN = 17; + VERIFIED_TRANSITION_NONE_TO_LOW = 18; + VERIFIED_TRANSITION_NONE_TO_UNKNOWN = 19; + GROUP_CREATE = 20; + GROUP_CHANGE_SUBJECT = 21; + GROUP_CHANGE_ICON = 22; + GROUP_CHANGE_INVITE_LINK = 23; + GROUP_CHANGE_DESCRIPTION = 24; + GROUP_CHANGE_RESTRICT = 25; + GROUP_CHANGE_ANNOUNCE = 26; + GROUP_PARTICIPANT_ADD = 27; + GROUP_PARTICIPANT_REMOVE = 28; + GROUP_PARTICIPANT_PROMOTE = 29; + GROUP_PARTICIPANT_DEMOTE = 30; + GROUP_PARTICIPANT_INVITE = 31; + GROUP_PARTICIPANT_LEAVE = 32; + GROUP_PARTICIPANT_CHANGE_NUMBER = 33; + BROADCAST_CREATE = 34; + BROADCAST_ADD = 35; + BROADCAST_REMOVE = 36; + GENERIC_NOTIFICATION = 37; + E2E_IDENTITY_CHANGED = 38; + E2E_ENCRYPTED = 39; + CALL_MISSED_VOICE = 40; + CALL_MISSED_VIDEO = 41; + INDIVIDUAL_CHANGE_NUMBER = 42; + GROUP_DELETE = 43; + GROUP_ANNOUNCE_MODE_MESSAGE_BOUNCE = 44; + CALL_MISSED_GROUP_VOICE = 45; + CALL_MISSED_GROUP_VIDEO = 46; + PAYMENT_CIPHERTEXT = 47; + PAYMENT_FUTUREPROOF = 48; + PAYMENT_TRANSACTION_STATUS_UPDATE_FAILED = 49; + PAYMENT_TRANSACTION_STATUS_UPDATE_REFUNDED = 50; + PAYMENT_TRANSACTION_STATUS_UPDATE_REFUND_FAILED = 51; + PAYMENT_TRANSACTION_STATUS_RECEIVER_PENDING_SETUP = 52; + PAYMENT_TRANSACTION_STATUS_RECEIVER_SUCCESS_AFTER_HICCUP = 53; + PAYMENT_ACTION_ACCOUNT_SETUP_REMINDER = 54; + PAYMENT_ACTION_SEND_PAYMENT_REMINDER = 55; + PAYMENT_ACTION_SEND_PAYMENT_INVITATION = 56; + PAYMENT_ACTION_REQUEST_DECLINED = 57; + PAYMENT_ACTION_REQUEST_EXPIRED = 58; + PAYMENT_ACTION_REQUEST_CANCELLED = 59; + BIZ_VERIFIED_TRANSITION_TOP_TO_BOTTOM = 60; + BIZ_VERIFIED_TRANSITION_BOTTOM_TO_TOP = 61; + BIZ_INTRO_TOP = 62; + BIZ_INTRO_BOTTOM = 63; + BIZ_NAME_CHANGE = 64; + BIZ_MOVE_TO_CONSUMER_APP = 65; + BIZ_TWO_TIER_MIGRATION_TOP = 66; + BIZ_TWO_TIER_MIGRATION_BOTTOM = 67; + OVERSIZED = 68; + GROUP_CHANGE_NO_FREQUENTLY_FORWARDED = 69; + GROUP_V4_ADD_INVITE_SENT = 70; + GROUP_PARTICIPANT_ADD_REQUEST_JOIN = 71; + CHANGE_EPHEMERAL_SETTING = 72; + E2E_DEVICE_CHANGED = 73; + VIEWED_ONCE = 74; + E2E_ENCRYPTED_NOW = 75; + BLUE_MSG_BSP_FB_TO_BSP_PREMISE = 76; + BLUE_MSG_BSP_FB_TO_SELF_FB = 77; + BLUE_MSG_BSP_FB_TO_SELF_PREMISE = 78; + BLUE_MSG_BSP_FB_UNVERIFIED = 79; + BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED = 80; + BLUE_MSG_BSP_FB_VERIFIED = 81; + BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED = 82; + BLUE_MSG_BSP_PREMISE_TO_SELF_PREMISE = 83; + BLUE_MSG_BSP_PREMISE_UNVERIFIED = 84; + BLUE_MSG_BSP_PREMISE_UNVERIFIED_TO_SELF_PREMISE_VERIFIED = 85; + BLUE_MSG_BSP_PREMISE_VERIFIED = 86; + BLUE_MSG_BSP_PREMISE_VERIFIED_TO_SELF_PREMISE_UNVERIFIED = 87; + BLUE_MSG_CONSUMER_TO_BSP_FB_UNVERIFIED = 88; + BLUE_MSG_CONSUMER_TO_BSP_PREMISE_UNVERIFIED = 89; + BLUE_MSG_CONSUMER_TO_SELF_FB_UNVERIFIED = 90; + BLUE_MSG_CONSUMER_TO_SELF_PREMISE_UNVERIFIED = 91; + BLUE_MSG_SELF_FB_TO_BSP_PREMISE = 92; + BLUE_MSG_SELF_FB_TO_SELF_PREMISE = 93; + BLUE_MSG_SELF_FB_UNVERIFIED = 94; + BLUE_MSG_SELF_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED = 95; + BLUE_MSG_SELF_FB_VERIFIED = 96; + BLUE_MSG_SELF_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED = 97; + BLUE_MSG_SELF_PREMISE_TO_BSP_PREMISE = 98; + BLUE_MSG_SELF_PREMISE_UNVERIFIED = 99; + BLUE_MSG_SELF_PREMISE_VERIFIED = 100; + BLUE_MSG_TO_BSP_FB = 101; + BLUE_MSG_TO_CONSUMER = 102; + BLUE_MSG_TO_SELF_FB = 103; + BLUE_MSG_UNVERIFIED_TO_BSP_FB_VERIFIED = 104; + BLUE_MSG_UNVERIFIED_TO_BSP_PREMISE_VERIFIED = 105; + BLUE_MSG_UNVERIFIED_TO_SELF_FB_VERIFIED = 106; + BLUE_MSG_UNVERIFIED_TO_VERIFIED = 107; + BLUE_MSG_VERIFIED_TO_BSP_FB_UNVERIFIED = 108; + BLUE_MSG_VERIFIED_TO_BSP_PREMISE_UNVERIFIED = 109; + BLUE_MSG_VERIFIED_TO_SELF_FB_UNVERIFIED = 110; + BLUE_MSG_VERIFIED_TO_UNVERIFIED = 111; + BLUE_MSG_BSP_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED = 112; + BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_FB_VERIFIED = 113; + BLUE_MSG_BSP_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED = 114; + BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_FB_UNVERIFIED = 115; + BLUE_MSG_SELF_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED = 116; + BLUE_MSG_SELF_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED = 117; + E2E_IDENTITY_UNAVAILABLE = 118; + } + optional WebMessageInfoStubType messageStubType = 24; + optional bool clearMedia = 25; + repeated string messageStubParameters = 26; + optional uint32 duration = 27; + repeated string labels = 28; + optional PaymentInfo paymentInfo = 29; + optional LiveLocationMessage finalLiveLocation = 30; + optional PaymentInfo quotedPaymentInfo = 31; + optional uint64 ephemeralStartTimestamp = 32; + optional uint32 ephemeralDuration = 33; + optional bool ephemeralOffToOn = 34; + optional bool ephemeralOutOfSync = 35; + enum WebMessageInfoBizPrivacyStatus { + E2EE = 0; + FB = 2; + BSP = 1; + BSP_AND_FB = 3; + } + optional WebMessageInfoBizPrivacyStatus bizPrivacyStatus = 36; + optional string verifiedBizName = 37; +} \ No newline at end of file diff --git a/vendor/github.com/Rhymen/go-whatsapp/binary/token/token.go b/vendor/github.com/Rhymen/go-whatsapp/binary/token/token.go new file mode 100644 index 00000000..8fd28f31 --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/binary/token/token.go @@ -0,0 +1,81 @@ +package token + +import "fmt" + +var SingleByteTokens = [...]string{"", "", "", "200", "400", "404", "500", "501", "502", "action", "add", + "after", "archive", "author", "available", "battery", "before", "body", + "broadcast", "chat", "clear", "code", "composing", "contacts", "count", + "create", "debug", "delete", "demote", "duplicate", "encoding", "error", + "false", "filehash", "from", "g.us", "group", "groups_v2", "height", "id", + "image", "in", "index", "invis", "item", "jid", "kind", "last", "leave", + "live", "log", "media", "message", "mimetype", "missing", "modify", "name", + "notification", "notify", "out", "owner", "participant", "paused", + "picture", "played", "presence", "preview", "promote", "query", "raw", + "read", "receipt", "received", "recipient", "recording", "relay", + "remove", "response", "resume", "retry", "s.whatsapp.net", "seconds", + "set", "size", "status", "subject", "subscribe", "t", "text", "to", "true", + "type", "unarchive", "unavailable", "url", "user", "value", "web", "width", + "mute", "read_only", "admin", "creator", "short", "update", "powersave", + "checksum", "epoch", "block", "previous", "409", "replaced", "reason", + "spam", "modify_tag", "message_info", "delivery", "emoji", "title", + "description", "canonical-url", "matched-text", "star", "unstar", + "media_key", "filename", "identity", "unread", "page", "page_count", + "search", "media_message", "security", "call_log", "profile", "ciphertext", + "invite", "gif", "vcard", "frequent", "privacy", "blacklist", "whitelist", + "verify", "location", "document", "elapsed", "revoke_invite", "expiration", + "unsubscribe", "disable", "vname", "old_jid", "new_jid", "announcement", + "locked", "prop", "label", "color", "call", "offer", "call-id", + "quick_reply", "sticker", "pay_t", "accept", "reject", "sticker_pack", + "invalid", "canceled", "missed", "connected", "result", "audio", + "video", "recent"} + +var doubleByteTokens = [...]string{} + +func GetSingleToken(i int) (string, error) { + if i < 3 || i >= len(SingleByteTokens) { + return "", fmt.Errorf("index out of single byte token bounds %d", i) + } + + return SingleByteTokens[i], nil +} + +func GetDoubleToken(index1 int, index2 int) (string, error) { + n := 256*index1 + index2 + if n < 0 || n >= len(doubleByteTokens) { + return "", fmt.Errorf("index out of double byte token bounds %d", n) + } + + return doubleByteTokens[n], nil +} + +func IndexOfSingleToken(token string) int { + for i, t := range SingleByteTokens { + if t == token { + return i + } + } + + return -1 +} + +const ( + LIST_EMPTY = 0 + STREAM_END = 2 + DICTIONARY_0 = 236 + DICTIONARY_1 = 237 + DICTIONARY_2 = 238 + DICTIONARY_3 = 239 + LIST_8 = 248 + LIST_16 = 249 + JID_PAIR = 250 + HEX_8 = 251 + BINARY_8 = 252 + BINARY_20 = 253 + BINARY_32 = 254 + NIBBLE_8 = 255 +) + +const ( + PACKED_MAX = 254 + SINGLE_BYTE_MAX = 256 +) diff --git a/vendor/github.com/Rhymen/go-whatsapp/chat_history.go b/vendor/github.com/Rhymen/go-whatsapp/chat_history.go new file mode 100644 index 00000000..55c7ae63 --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/chat_history.go @@ -0,0 +1,183 @@ +package whatsapp + +import ( + "github.com/Rhymen/go-whatsapp/binary" + "github.com/Rhymen/go-whatsapp/binary/proto" + "log" + "strconv" + "time" +) + +type MessageOffsetInfo struct { + FirstMessageId string + FirstMessageOwner bool +} + +func decodeMessages(n *binary.Node) []*proto.WebMessageInfo { + + var messages = make([]*proto.WebMessageInfo, 0) + + if n == nil || n.Attributes == nil || n.Content == nil { + return messages + } + + for _, msg := range n.Content.([]interface{}) { + switch msg.(type) { + case *proto.WebMessageInfo: + messages = append(messages, msg.(*proto.WebMessageInfo)) + default: + log.Println("decodeMessages: Non WebMessage encountered") + } + } + + return messages +} + +// LoadChatMessages is useful to "scroll" messages, loading by count at a time +// if handlers == nil the func will use default handlers +// if after == true LoadChatMessages will load messages after the specified messageId, otherwise it will return +// message before the messageId +func (wac *Conn) LoadChatMessages(jid string, count int, messageId string, owner bool, after bool, handlers ...Handler) error { + if count <= 0 { + return nil + } + + if handlers == nil { + handlers = wac.handler + } + + kind := "before" + if after { + kind = "after" + } + + node, err := wac.query("message", jid, messageId, kind, + strconv.FormatBool(owner), "", count, 0) + + if err != nil { + wac.handleWithCustomHandlers(err, handlers) + return err + } + + for _, msg := range decodeMessages(node) { + wac.handleWithCustomHandlers(ParseProtoMessage(msg), handlers) + wac.handleWithCustomHandlers(msg, handlers) + } + return nil + +} + +// LoadFullChatHistory loads full chat history for the given jid +// chunkSize = how many messages to load with one query; if handlers == nil the func will use default handlers; +// pauseBetweenQueries = how much time to sleep between queries +func (wac *Conn) LoadFullChatHistory(jid string, chunkSize int, + pauseBetweenQueries time.Duration, handlers ...Handler) { + if chunkSize <= 0 { + return + } + + if handlers == nil { + handlers = wac.handler + } + + beforeMsg := "" + beforeMsgIsOwner := true + + for { + node, err := wac.query("message", jid, beforeMsg, "before", + strconv.FormatBool(beforeMsgIsOwner), "", chunkSize, 0) + + if err != nil { + wac.handleWithCustomHandlers(err, handlers) + } else { + + msgs := decodeMessages(node) + for _, msg := range msgs { + wac.handleWithCustomHandlers(ParseProtoMessage(msg), handlers) + wac.handleWithCustomHandlers(msg, handlers) + } + + if len(msgs) == 0 { + break + } + + beforeMsg = *msgs[0].Key.Id + beforeMsgIsOwner = msgs[0].Key.FromMe != nil && *msgs[0].Key.FromMe + } + + <-time.After(pauseBetweenQueries) + + } + +} + +// LoadFullChatHistoryAfter loads all messages after the specified messageId +// useful to "catch up" with the message history after some specified message +func (wac *Conn) LoadFullChatHistoryAfter(jid string, messageId string, chunkSize int, + pauseBetweenQueries time.Duration, handlers ...Handler) { + + if chunkSize <= 0 { + return + } + + if handlers == nil { + handlers = wac.handler + } + + msgOwner := true + prevNotFound := false + + for { + node, err := wac.query("message", jid, messageId, "after", + strconv.FormatBool(msgOwner), "", chunkSize, 0) + + if err != nil { + + // Whatsapp will return 404 status when there is wrong owner flag on the requested message id + if err == ErrServerRespondedWith404 { + + // this will detect two consecutive "not found" errors. + // this is done to prevent infinite loop when wrong message id supplied + if prevNotFound { + log.Println("LoadFullChatHistoryAfter: could not retrieve any messages, wrong message id?") + return + } + prevNotFound = true + + // try to reverse the owner flag and retry + if msgOwner { + // reverse initial msgOwner value and retry + msgOwner = false + + <-time.After(time.Second) + continue + } + + } + + // if the error isn't a 404 error, pass it to the error handler + wac.handleWithCustomHandlers(err, handlers) + } else { + + msgs := decodeMessages(node) + for _, msg := range msgs { + wac.handleWithCustomHandlers(ParseProtoMessage(msg), handlers) + wac.handleWithCustomHandlers(msg, handlers) + } + + if len(msgs) != chunkSize { + break + } + + messageId = *msgs[0].Key.Id + msgOwner = msgs[0].Key.FromMe != nil && *msgs[0].Key.FromMe + } + + // message was found + prevNotFound = false + + <-time.After(pauseBetweenQueries) + + } + +} diff --git a/vendor/github.com/Rhymen/go-whatsapp/conn.go b/vendor/github.com/Rhymen/go-whatsapp/conn.go new file mode 100644 index 00000000..4b28cbe1 --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/conn.go @@ -0,0 +1,302 @@ +//Package whatsapp provides a developer API to interact with the WhatsAppWeb-Servers. +package whatsapp + +import ( + "math/rand" + "net/http" + "net/url" + "sync" + "time" + + "github.com/gorilla/websocket" + "github.com/pkg/errors" +) + +type metric byte + +const ( + debugLog metric = iota + 1 + queryResume + queryReceipt + queryMedia + queryChat + queryContacts + queryMessages + presence + presenceSubscribe + group + read + chat + received + pic + status + message + queryActions + block + queryGroup + queryPreview + queryEmoji + queryMessageInfo + spam + querySearch + queryIdentity + queryUrl + profile + contact + queryVcard + queryStatus + queryStatusUpdate + privacyStatus + queryLiveLocations + liveLocation + queryVname + queryLabels + call + queryCall + queryQuickReplies +) + +type flag byte + +const ( + ignore flag = 1 << (7 - iota) + ackRequest + available + notAvailable + expires + skipOffline +) + +/* +Conn is created by NewConn. Interacting with the initialized Conn is the main way of interacting with our package. +It holds all necessary information to make the package work internally. +*/ +type Conn struct { + ws *websocketWrapper + listener *listenerWrapper + + connected bool + loggedIn bool + wg *sync.WaitGroup + + session *Session + sessionLock uint32 + handler []Handler + msgCount int + msgTimeout time.Duration + Info *Info + Store *Store + ServerLastSeen time.Time + + timeTag string // last 3 digits obtained after a successful login takeover + + longClientName string + shortClientName string + clientVersion string + + loginSessionLock sync.RWMutex + Proxy func(*http.Request) (*url.URL, error) + + writerLock sync.RWMutex +} + +type websocketWrapper struct { + sync.Mutex + conn *websocket.Conn + close chan struct{} +} + +type listenerWrapper struct { + sync.RWMutex + m map[string]chan string +} + +/* +Creates a new connection with a given timeout. The websocket connection to the WhatsAppWeb servers getΒ΄s established. +The goroutine for handling incoming messages is started +*/ +func NewConn(timeout time.Duration) (*Conn, error) { + return NewConnWithOptions(&Options{ + Timeout: timeout, + }) +} + +// NewConnWithProxy Create a new connect with a given timeout and a http proxy. +func NewConnWithProxy(timeout time.Duration, proxy func(*http.Request) (*url.URL, error)) (*Conn, error) { + return NewConnWithOptions(&Options{ + Timeout: timeout, + Proxy: proxy, + }) +} + +// NewConnWithOptions Create a new connect with a given options. +type Options struct { + Proxy func(*http.Request) (*url.URL, error) + Timeout time.Duration + Handler []Handler + ShortClientName string + LongClientName string + ClientVersion string + Store *Store +} +func NewConnWithOptions(opt *Options) (*Conn, error) { + if opt == nil { + return nil, ErrOptionsNotProvided + } + wac := &Conn{ + handler: make([]Handler, 0), + msgCount: 0, + msgTimeout: opt.Timeout, + Store: newStore(), + longClientName: "github.com/Rhymen/go-whatsapp", + shortClientName: "go-whatsapp", + clientVersion: "0.1.0", + } + if opt.Handler != nil { + wac.handler = opt.Handler + } + if opt.Store != nil { + wac.Store = opt.Store + } + if opt.Proxy != nil { + wac.Proxy = opt.Proxy + } + if len(opt.ShortClientName) != 0 { + wac.shortClientName = opt.ShortClientName + } + if len(opt.LongClientName) != 0 { + wac.longClientName = opt.LongClientName + } + if len(opt.ClientVersion) != 0 { + wac.clientVersion = opt.ClientVersion + } + return wac, wac.connect() +} + +// connect should be guarded with wsWriteMutex +func (wac *Conn) connect() (err error) { + if wac.connected { + return ErrAlreadyConnected + } + wac.connected = true + defer func() { // set connected to false on error + if err != nil { + wac.connected = false + } + }() + + dialer := &websocket.Dialer{ + ReadBufferSize: 0, + WriteBufferSize: 0, + HandshakeTimeout: wac.msgTimeout, + Proxy: wac.Proxy, + } + + headers := http.Header{"Origin": []string{"https://web.whatsapp.com"}} + wsConn, _, err := dialer.Dial("wss://web.whatsapp.com/ws", headers) + if err != nil { + return errors.Wrap(err, "couldn't dial whatsapp web websocket") + } + + wsConn.SetCloseHandler(func(code int, text string) error { + // from default CloseHandler + message := websocket.FormatCloseMessage(code, "") + err := wsConn.WriteControl(websocket.CloseMessage, message, time.Now().Add(time.Second)) + + // our close handling + _, _ = wac.Disconnect() + wac.handle(&ErrConnectionClosed{Code: code, Text: text}) + return err + }) + + wac.ws = &websocketWrapper{ + conn: wsConn, + close: make(chan struct{}), + } + + wac.listener = &listenerWrapper{ + m: make(map[string]chan string), + } + + wac.wg = &sync.WaitGroup{} + wac.wg.Add(2) + go wac.readPump() + go wac.keepAlive(20000, 60000) + + wac.loggedIn = false + return nil +} + +func (wac *Conn) Disconnect() (Session, error) { + if !wac.connected { + return Session{}, ErrNotConnected + } + wac.connected = false + wac.loggedIn = false + + close(wac.ws.close) //signal close + wac.wg.Wait() //wait for close + + err := wac.ws.conn.Close() + wac.ws = nil + + if wac.session == nil { + return Session{}, err + } + return *wac.session, err +} + +func (wac *Conn) AdminTest() (bool, error) { + if !wac.connected { + return false, ErrNotConnected + } + + if !wac.loggedIn { + return false, ErrInvalidSession + } + + result, err := wac.sendAdminTest() + return result, err +} + +func (wac *Conn) keepAlive(minIntervalMs int, maxIntervalMs int) { + defer wac.wg.Done() + + for { + err := wac.sendKeepAlive() + if err != nil { + wac.handle(errors.Wrap(err, "keepAlive failed")) + //TODO: Consequences? + } + interval := rand.Intn(maxIntervalMs-minIntervalMs) + minIntervalMs + select { + case <-time.After(time.Duration(interval) * time.Millisecond): + case <-wac.ws.close: + return + } + } +} + +// IsConnected returns whether the server connection is established or not +func (wac *Conn) IsConnected() bool { + return wac.connected +} + +// GetConnected returns whether the server connection is established or not +// +// Deprecated: function name is not go idiomatic, use IsConnected instead +func (wac *Conn) GetConnected() bool { + return wac.connected +} + +//IsLoggedIn returns whether the you are logged in or not +func (wac *Conn) IsLoggedIn() bool { + return wac.loggedIn +} + +// GetLoggedIn returns whether the you are logged in or not +// +// Deprecated: function name is not go idiomatic, use IsLoggedIn instead. +func (wac *Conn) GetLoggedIn() bool { + return wac.loggedIn +} diff --git a/vendor/github.com/Rhymen/go-whatsapp/contact.go b/vendor/github.com/Rhymen/go-whatsapp/contact.go new file mode 100644 index 00000000..67140723 --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/contact.go @@ -0,0 +1,322 @@ +package whatsapp + +import ( + "fmt" + "strconv" + "strings" + "time" + + "github.com/Rhymen/go-whatsapp/binary" +) + +type Presence string + +const ( + PresenceAvailable Presence = "available" + PresenceUnavailable Presence = "unavailable" + PresenceComposing Presence = "composing" + PresenceRecording Presence = "recording" + PresencePaused Presence = "paused" +) + +//TODO: filename? WhatsApp uses Store.Contacts for these functions +// functions probably shouldn't return a string, maybe build a struct / return json +// check for further queries +func (wac *Conn) GetProfilePicThumb(jid string) (<-chan string, error) { + data := []interface{}{"query", "ProfilePicThumb", jid} + return wac.writeJson(data) +} + +func (wac *Conn) GetStatus(jid string) (<-chan string, error) { + data := []interface{}{"query", "Status", jid} + return wac.writeJson(data) +} + +func (wac *Conn) SubscribePresence(jid string) (<-chan string, error) { + data := []interface{}{"action", "presence", "subscribe", jid} + return wac.writeJson(data) +} + +func (wac *Conn) Search(search string, count, page int) (*binary.Node, error) { + return wac.query("search", "", "", "", "", search, count, page) +} + +func (wac *Conn) LoadMessages(jid, messageId string, count int) (*binary.Node, error) { + return wac.query("message", jid, "", "before", "true", "", count, 0) +} + +func (wac *Conn) LoadMessagesBefore(jid, messageId string, count int) (*binary.Node, error) { + return wac.query("message", jid, messageId, "before", "true", "", count, 0) +} + +func (wac *Conn) LoadMessagesAfter(jid, messageId string, count int) (*binary.Node, error) { + return wac.query("message", jid, messageId, "after", "true", "", count, 0) +} + +func (wac *Conn) LoadMediaInfo(jid, messageId, owner string) (*binary.Node, error) { + return wac.query("media", jid, messageId, "", owner, "", 0, 0) +} + +func (wac *Conn) Presence(jid string, presence Presence) (<-chan string, error) { + ts := time.Now().Unix() + tag := fmt.Sprintf("%d.--%d", ts, wac.msgCount) + + content := binary.Node{ + Description: "presence", + Attributes: map[string]string{ + "type": string(presence), + }, + } + switch presence { + case PresenceComposing: + fallthrough + case PresenceRecording: + fallthrough + case PresencePaused: + content.Attributes["to"] = jid + } + + n := binary.Node{ + Description: "action", + Attributes: map[string]string{ + "type": "set", + "epoch": strconv.Itoa(wac.msgCount), + }, + Content: []interface{}{content}, + } + + return wac.writeBinary(n, group, ignore, tag) +} + +func (wac *Conn) Exist(jid string) (<-chan string, error) { + data := []interface{}{"query", "exist", jid} + return wac.writeJson(data) +} + +func (wac *Conn) Emoji() (*binary.Node, error) { + return wac.query("emoji", "", "", "", "", "", 0, 0) +} + +func (wac *Conn) Contacts() (*binary.Node, error) { + return wac.query("contacts", "", "", "", "", "", 0, 0) +} + +func (wac *Conn) Chats() (*binary.Node, error) { + return wac.query("chat", "", "", "", "", "", 0, 0) +} + +func (wac *Conn) Read(jid, id string) (<-chan string, error) { + ts := time.Now().Unix() + tag := fmt.Sprintf("%d.--%d", ts, wac.msgCount) + + n := binary.Node{ + Description: "action", + Attributes: map[string]string{ + "type": "set", + "epoch": strconv.Itoa(wac.msgCount), + }, + Content: []interface{}{binary.Node{ + Description: "read", + Attributes: map[string]string{ + "count": "1", + "index": id, + "jid": jid, + "owner": "false", + }, + }}, + } + + return wac.writeBinary(n, group, ignore, tag) +} + +func (wac *Conn) query(t, jid, messageId, kind, owner, search string, count, page int) (*binary.Node, error) { + ts := time.Now().Unix() + tag := fmt.Sprintf("%d.--%d", ts, wac.msgCount) + + n := binary.Node{ + Description: "query", + Attributes: map[string]string{ + "type": t, + "epoch": strconv.Itoa(wac.msgCount), + }, + } + + if jid != "" { + n.Attributes["jid"] = jid + } + + if messageId != "" { + n.Attributes["index"] = messageId + } + + if kind != "" { + n.Attributes["kind"] = kind + } + + if owner != "" { + n.Attributes["owner"] = owner + } + + if search != "" { + n.Attributes["search"] = search + } + + if count != 0 { + n.Attributes["count"] = strconv.Itoa(count) + } + + if page != 0 { + n.Attributes["page"] = strconv.Itoa(page) + } + + metric := group + if t == "media" { + metric = queryMedia + } + + ch, err := wac.writeBinary(n, metric, ignore, tag) + if err != nil { + return nil, err + } + + msg, err := wac.decryptBinaryMessage([]byte(<-ch)) + if err != nil { + return nil, err + } + + //TODO: use parseProtoMessage + return msg, nil +} + +func (wac *Conn) setGroup(t, jid, subject string, participants []string) (<-chan string, error) { + ts := time.Now().Unix() + tag := fmt.Sprintf("%d.--%d", ts, wac.msgCount) + + //TODO: get proto or improve encoder to handle []interface{} + + p := buildParticipantNodes(participants) + + g := binary.Node{ + Description: "group", + Attributes: map[string]string{ + "author": wac.session.Wid, + "id": tag, + "type": t, + }, + Content: p, + } + + if jid != "" { + g.Attributes["jid"] = jid + } + + if subject != "" { + g.Attributes["subject"] = subject + } + + n := binary.Node{ + Description: "action", + Attributes: map[string]string{ + "type": "set", + "epoch": strconv.Itoa(wac.msgCount), + }, + Content: []interface{}{g}, + } + + return wac.writeBinary(n, group, ignore, tag) +} + +func buildParticipantNodes(participants []string) []binary.Node { + l := len(participants) + if participants == nil || l == 0 { + return nil + } + + p := make([]binary.Node, len(participants)) + for i, participant := range participants { + p[i] = binary.Node{ + Description: "participant", + Attributes: map[string]string{ + "jid": participant, + }, + } + } + return p +} + +func (wac *Conn) BlockContact(jid string) (<-chan string, error) { + return wac.handleBlockContact("add", jid) +} + +func (wac *Conn) UnblockContact(jid string) (<-chan string, error) { + return wac.handleBlockContact("remove", jid) +} + +func (wac *Conn) handleBlockContact(action, jid string) (<-chan string, error) { + ts := time.Now().Unix() + tag := fmt.Sprintf("%d.--%d", ts, wac.msgCount) + + netsplit := strings.Split(jid, "@") + cusjid := netsplit[0] + "@c.us" + + n := binary.Node{ + Description: "action", + Attributes: map[string]string{ + "type": "set", + "epoch": strconv.Itoa(wac.msgCount), + }, + Content: []interface{}{ + binary.Node{ + Description: "block", + Attributes: map[string]string{ + "type": action, + }, + Content: []binary.Node{ + { + Description: "user", + Attributes: map[string]string{ + "jid": cusjid, + }, + Content: nil, + }, + }, + }, + }, + } + + return wac.writeBinary(n, contact, ignore, tag) +} + +// Search product details on order +func (wac *Conn) SearchProductDetails(id, orderId, token string) (<-chan string, error) { + data := []interface{}{"query", "order", map[string]string{ + "id": id, + "orderId": orderId, + "imageHeight": strconv.Itoa(80), + "imageWidth": strconv.Itoa(80), + "token": token, + }} + return wac.writeJson(data) +} + +// Order search and get product catalog reh +func (wac *Conn) SearchOrder(catalogWid, stanzaId string) (<-chan string, error) { + data := []interface{}{"query", "bizCatalog", map[string]string{ + "catalogWid": catalogWid, + "limit": strconv.Itoa(10), + "height": strconv.Itoa(100), + "width": strconv.Itoa(100), + "stanza_id": stanzaId, + "type": "get_product_catalog_reh", + }} + return wac.writeJson(data) +} + +// Company details for Whatsapp Business +func (wac *Conn) BusinessProfile(wid string) (<-chan string, error) { + query := map[string]string{ + "wid": wid, + } + data := []interface{}{"query", "businessProfile", []map[string]string{query}} + return wac.writeJson(data) +} diff --git a/vendor/github.com/Rhymen/go-whatsapp/crypto/cbc/cbc.go b/vendor/github.com/Rhymen/go-whatsapp/crypto/cbc/cbc.go new file mode 100644 index 00000000..cc5427c3 --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/crypto/cbc/cbc.go @@ -0,0 +1,101 @@ +/* +CBC describes a block cipher mode. In cryptography, a block cipher mode of operation is an algorithm that uses a +block cipher to provide an information service such as confidentiality or authenticity. A block cipher by itself +is only suitable for the secure cryptographic transformation (encryption or decryption) of one fixed-length group of +bits called a block. A mode of operation describes how to repeatedly apply a cipher's single-block operation to +securely transform amounts of data larger than a block. + +This package simplifies the usage of AES-256-CBC. +*/ +package cbc + +/* +Some code is provided by the GitHub user locked (github.com/locked): +https://gist.github.com/locked/b066aa1ddeb2b28e855e +Thanks! +*/ +import ( + "bytes" + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "fmt" + "io" +) + +/* +Decrypt is a function that decrypts a given cipher text with a provided key and initialization vector(iv). +*/ +func Decrypt(key, iv, ciphertext []byte) ([]byte, error) { + block, err := aes.NewCipher(key) + + if err != nil { + return nil, err + } + + if len(ciphertext) < aes.BlockSize { + return nil, fmt.Errorf("ciphertext is shorter then block size: %d / %d", len(ciphertext), aes.BlockSize) + } + + if iv == nil { + iv = ciphertext[:aes.BlockSize] + ciphertext = ciphertext[aes.BlockSize:] + } + + cbc := cipher.NewCBCDecrypter(block, iv) + cbc.CryptBlocks(ciphertext, ciphertext) + + return unpad(ciphertext) +} + +/* +Encrypt is a function that encrypts plaintext with a given key and an optional initialization vector(iv). +*/ +func Encrypt(key, iv, plaintext []byte) ([]byte, error) { + plaintext = pad(plaintext, aes.BlockSize) + + if len(plaintext)%aes.BlockSize != 0 { + return nil, fmt.Errorf("plaintext is not a multiple of the block size: %d / %d", len(plaintext), aes.BlockSize) + } + + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + + var ciphertext []byte + if iv == nil { + ciphertext = make([]byte, aes.BlockSize+len(plaintext)) + iv := ciphertext[:aes.BlockSize] + if _, err := io.ReadFull(rand.Reader, iv); err != nil { + return nil, err + } + + cbc := cipher.NewCBCEncrypter(block, iv) + cbc.CryptBlocks(ciphertext[aes.BlockSize:], plaintext) + } else { + ciphertext = make([]byte, len(plaintext)) + + cbc := cipher.NewCBCEncrypter(block, iv) + cbc.CryptBlocks(ciphertext, plaintext) + } + + return ciphertext, nil +} + +func pad(ciphertext []byte, blockSize int) []byte { + padding := blockSize - len(ciphertext)%blockSize + padtext := bytes.Repeat([]byte{byte(padding)}, padding) + return append(ciphertext, padtext...) +} + +func unpad(src []byte) ([]byte, error) { + length := len(src) + padLen := int(src[length-1]) + + if padLen > length { + return nil, fmt.Errorf("padding is greater then the length: %d / %d", padLen, length) + } + + return src[:(length - padLen)], nil +} diff --git a/vendor/github.com/Rhymen/go-whatsapp/crypto/curve25519/curve.go b/vendor/github.com/Rhymen/go-whatsapp/crypto/curve25519/curve.go new file mode 100644 index 00000000..5ddf9c9a --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/crypto/curve25519/curve.go @@ -0,0 +1,44 @@ +/* +In cryptography, Curve25519 is an elliptic curve offering 128 bits of security and designed for use with the elliptic +curve Diffie–Hellman (ECDH) key agreement scheme. It is one of the fastest ECC curves and is not covered by any known +patents. The reference implementation is public domain software. The original Curve25519 paper defined it +as a Diffie–Hellman (DH) function. +*/ +package curve25519 + +import ( + "crypto/rand" + "golang.org/x/crypto/curve25519" + "io" +) + +/* +GenerateKey generates a public private key pair using Curve25519. +*/ +func GenerateKey() (privateKey *[32]byte, publicKey *[32]byte, err error) { + var pub, priv [32]byte + + _, err = io.ReadFull(rand.Reader, priv[:]) + if err != nil { + return nil, nil, err + } + + priv[0] &= 248 + priv[31] &= 127 + priv[31] |= 64 + + curve25519.ScalarBaseMult(&pub, &priv) + + return &priv, &pub, nil +} + +/* +GenerateSharedSecret generates the shared secret with a given public private key pair. +*/ +func GenerateSharedSecret(priv, pub [32]byte) []byte { + var secret [32]byte + + curve25519.ScalarMult(&secret, &priv, &pub) + + return secret[:] +} diff --git a/vendor/github.com/Rhymen/go-whatsapp/crypto/hkdf/hkdf.go b/vendor/github.com/Rhymen/go-whatsapp/crypto/hkdf/hkdf.go new file mode 100644 index 00000000..3d7361f0 --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/crypto/hkdf/hkdf.go @@ -0,0 +1,47 @@ +/* +HKDF is a simple key derivation function (KDF) based on +a hash-based message authentication code (HMAC). It was initially proposed by its authors as a building block in +various protocols and applications, as well as to discourage the proliferation of multiple KDF mechanisms. +The main approach HKDF follows is the "extract-then-expand" paradigm, where the KDF logically consists of two modules: +the first stage takes the input keying material and "extracts" from it a fixed-length pseudorandom key, and then the +second stage "expands" this key into several additional pseudorandom keys (the output of the KDF). +*/ +package hkdf + +import ( + "crypto/sha256" + "fmt" + "golang.org/x/crypto/hkdf" + "io" +) + +/* +Expand expands a given key with the HKDF algorithm. +*/ +func Expand(key []byte, length int, info string) ([]byte, error) { + var h io.Reader + if info == "" { + /* + Only used during initial login + Pseudorandom Key is provided by server and has not to be created + */ + h = hkdf.Expand(sha256.New, key, []byte(info)) + } else { + /* + Used every other time + Pseudorandom Key is created during kdf.New + This is the normal that crypto/hkdf is used + */ + h = hkdf.New(sha256.New, key, nil, []byte(info)) + } + out := make([]byte, length) + n, err := io.ReadAtLeast(h, out, length) + if err != nil { + return nil, err + } + if n != length { + return nil, fmt.Errorf("new key to short") + } + + return out, nil +} diff --git a/vendor/github.com/Rhymen/go-whatsapp/errors.go b/vendor/github.com/Rhymen/go-whatsapp/errors.go new file mode 100644 index 00000000..2f58a771 --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/errors.go @@ -0,0 +1,42 @@ +package whatsapp + +import ( + "fmt" + + "github.com/pkg/errors" +) + +var ( + ErrAlreadyConnected = errors.New("already connected") + ErrAlreadyLoggedIn = errors.New("already logged in") + ErrInvalidSession = errors.New("invalid session") + ErrLoginInProgress = errors.New("login or restore already running") + ErrNotConnected = errors.New("not connected") + ErrInvalidWsData = errors.New("received invalid data") + ErrInvalidWsState = errors.New("can't handle binary data when not logged in") + ErrConnectionTimeout = errors.New("connection timed out") + ErrMissingMessageTag = errors.New("no messageTag specified or to short") + ErrInvalidHmac = errors.New("invalid hmac") + ErrInvalidServerResponse = errors.New("invalid response received from server") + ErrServerRespondedWith404 = errors.New("server responded with status 404") + ErrInvalidWebsocket = errors.New("invalid websocket") + ErrMessageTypeNotImplemented = errors.New("message type not implemented") + ErrOptionsNotProvided = errors.New("new conn options not provided") +) + +type ErrConnectionFailed struct { + Err error +} + +func (e *ErrConnectionFailed) Error() string { + return fmt.Sprintf("connection to WhatsApp servers failed: %v", e.Err) +} + +type ErrConnectionClosed struct { + Code int + Text string +} + +func (e *ErrConnectionClosed) Error() string { + return fmt.Sprintf("server closed connection,code: %d,text: %s", e.Code, e.Text) +} diff --git a/vendor/github.com/Rhymen/go-whatsapp/group.go b/vendor/github.com/Rhymen/go-whatsapp/group.go new file mode 100644 index 00000000..40e4515e --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/group.go @@ -0,0 +1,90 @@ +package whatsapp + +import ( + "encoding/json" + "fmt" + "time" +) + +func (wac *Conn) GetGroupMetaData(jid string) (<-chan string, error) { + data := []interface{}{"query", "GroupMetadata", jid} + return wac.writeJson(data) +} + +func (wac *Conn) CreateGroup(subject string, participants []string) (<-chan string, error) { + return wac.setGroup("create", "", subject, participants) +} + +func (wac *Conn) UpdateGroupSubject(subject string, jid string) (<-chan string, error) { + return wac.setGroup("subject", jid, subject, nil) +} + +func (wac *Conn) SetAdmin(jid string, participants []string) (<-chan string, error) { + return wac.setGroup("promote", jid, "", participants) +} + +func (wac *Conn) RemoveAdmin(jid string, participants []string) (<-chan string, error) { + return wac.setGroup("demote", jid, "", participants) +} + +func (wac *Conn) AddMember(jid string, participants []string) (<-chan string, error) { + return wac.setGroup("add", jid, "", participants) +} + +func (wac *Conn) RemoveMember(jid string, participants []string) (<-chan string, error) { + return wac.setGroup("remove", jid, "", participants) +} + +func (wac *Conn) LeaveGroup(jid string) (<-chan string, error) { + return wac.setGroup("leave", jid, "", nil) +} + +func (wac *Conn) GroupInviteLink(jid string) (string, error) { + request := []interface{}{"query", "inviteCode", jid} + ch, err := wac.writeJson(request) + if err != nil { + return "", err + } + + var response map[string]interface{} + + select { + case r := <-ch: + if err := json.Unmarshal([]byte(r), &response); err != nil { + return "", fmt.Errorf("error decoding response message: %v\n", err) + } + case <-time.After(wac.msgTimeout): + return "", fmt.Errorf("request timed out") + } + + if int(response["status"].(float64)) != 200 { + return "", fmt.Errorf("request responded with %d", response["status"]) + } + + return response["code"].(string), nil +} + +func (wac *Conn) GroupAcceptInviteCode(code string) (jid string, err error) { + request := []interface{}{"action", "invite", code} + ch, err := wac.writeJson(request) + if err != nil { + return "", err + } + + var response map[string]interface{} + + select { + case r := <-ch: + if err := json.Unmarshal([]byte(r), &response); err != nil { + return "", fmt.Errorf("error decoding response message: %v\n", err) + } + case <-time.After(wac.msgTimeout): + return "", fmt.Errorf("request timed out") + } + + if int(response["status"].(float64)) != 200 { + return "", fmt.Errorf("request responded with %d", response["status"]) + } + + return response["gid"].(string), nil +} diff --git a/vendor/github.com/Rhymen/go-whatsapp/handler.go b/vendor/github.com/Rhymen/go-whatsapp/handler.go new file mode 100644 index 00000000..1e447018 --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/handler.go @@ -0,0 +1,481 @@ +package whatsapp + +import ( + "fmt" + "os" + "strings" + + "github.com/Rhymen/go-whatsapp/binary" + "github.com/Rhymen/go-whatsapp/binary/proto" +) + +/* +The Handler interface is the minimal interface that needs to be implemented +to be accepted as a valid handler for our dispatching system. +The minimal handler is used to dispatch error messages. These errors occur on unexpected behavior by the websocket +connection or if we are unable to handle or interpret an incoming message. Error produced by user actions are not +dispatched through this handler. They are returned as an error on the specific function call. +*/ +type Handler interface { + HandleError(err error) +} + +type SyncHandler interface { + Handler + ShouldCallSynchronously() bool +} + +/* +The TextMessageHandler interface needs to be implemented to receive text messages dispatched by the dispatcher. +*/ +type TextMessageHandler interface { + Handler + HandleTextMessage(message TextMessage) +} + +/* +The ImageMessageHandler interface needs to be implemented to receive image messages dispatched by the dispatcher. +*/ +type ImageMessageHandler interface { + Handler + HandleImageMessage(message ImageMessage) +} + +/* +The VideoMessageHandler interface needs to be implemented to receive video messages dispatched by the dispatcher. +*/ +type VideoMessageHandler interface { + Handler + HandleVideoMessage(message VideoMessage) +} + +/* +The AudioMessageHandler interface needs to be implemented to receive audio messages dispatched by the dispatcher. +*/ +type AudioMessageHandler interface { + Handler + HandleAudioMessage(message AudioMessage) +} + +/* +The DocumentMessageHandler interface needs to be implemented to receive document messages dispatched by the dispatcher. +*/ +type DocumentMessageHandler interface { + Handler + HandleDocumentMessage(message DocumentMessage) +} + +/* +The LiveLocationMessageHandler interface needs to be implemented to receive live location messages dispatched by the dispatcher. +*/ +type LiveLocationMessageHandler interface { + Handler + HandleLiveLocationMessage(message LiveLocationMessage) +} + +/* +The LocationMessageHandler interface needs to be implemented to receive location messages dispatched by the dispatcher. +*/ +type LocationMessageHandler interface { + Handler + HandleLocationMessage(message LocationMessage) +} + +/* +The StickerMessageHandler interface needs to be implemented to receive sticker messages dispatched by the dispatcher. +*/ +type StickerMessageHandler interface { + Handler + HandleStickerMessage(message StickerMessage) +} + +/* +The ContactMessageHandler interface needs to be implemented to receive contact messages dispatched by the dispatcher. +*/ +type ContactMessageHandler interface { + Handler + HandleContactMessage(message ContactMessage) +} + +/* +The ProductMessageHandler interface needs to be implemented to receive product messages dispatched by the dispatcher. +*/ +type ProductMessageHandler interface { + Handler + HandleProductMessage(message ProductMessage) +} + +/* +The OrderMessageHandler interface needs to be implemented to receive order messages dispatched by the dispatcher. +*/ +type OrderMessageHandler interface { + Handler + HandleOrderMessage(message OrderMessage) +} + +/* +The JsonMessageHandler interface needs to be implemented to receive json messages dispatched by the dispatcher. +These json messages contain status updates of every kind sent by WhatsAppWeb servers. WhatsAppWeb uses these messages +to built a Store, which is used to save these "secondary" information. These messages may contain +presence (available, last see) information, or just the battery status of your phone. +*/ +type JsonMessageHandler interface { + Handler + HandleJsonMessage(message string) +} + +/** +The RawMessageHandler interface needs to be implemented to receive raw messages dispatched by the dispatcher. +Raw messages are the raw protobuf structs instead of the easy-to-use structs in TextMessageHandler, ImageMessageHandler, etc.. +*/ +type RawMessageHandler interface { + Handler + HandleRawMessage(message *proto.WebMessageInfo) +} + +/** +The ContactListHandler interface needs to be implemented to applky custom actions to contact lists dispatched by the dispatcher. +*/ +type ContactListHandler interface { + Handler + HandleContactList(contacts []Contact) +} + +/** +The ChatListHandler interface needs to be implemented to apply custom actions to chat lists dispatched by the dispatcher. +*/ +type ChatListHandler interface { + Handler + HandleChatList(contacts []Chat) +} + +/** +The BatteryMessageHandler interface needs to be implemented to receive percentage the device connected dispatched by the dispatcher. +*/ +type BatteryMessageHandler interface { + Handler + HandleBatteryMessage(battery BatteryMessage) +} + +/** +The NewContactHandler interface needs to be implemented to receive the contact's name for the first time. +*/ +type NewContactHandler interface { + Handler + HandleNewContact(contact Contact) +} + +/* +AddHandler adds an handler to the list of handler that receive dispatched messages. +The provided handler must at least implement the Handler interface. Additionally implemented +handlers(TextMessageHandler, ImageMessageHandler) are optional. At runtime it is checked if they are implemented +and they are called if so and needed. +*/ +func (wac *Conn) AddHandler(handler Handler) { + wac.handler = append(wac.handler, handler) +} + +// RemoveHandler removes a handler from the list of handlers that receive dispatched messages. +func (wac *Conn) RemoveHandler(handler Handler) bool { + i := -1 + for k, v := range wac.handler { + if v == handler { + i = k + break + } + } + if i > -1 { + wac.handler = append(wac.handler[:i], wac.handler[i+1:]...) + return true + } + return false +} + +// RemoveHandlers empties the list of handlers that receive dispatched messages. +func (wac *Conn) RemoveHandlers() { + wac.handler = make([]Handler, 0) +} + +func (wac *Conn) shouldCallSynchronously(handler Handler) bool { + sh, ok := handler.(SyncHandler) + return ok && sh.ShouldCallSynchronously() +} + +func (wac *Conn) handle(message interface{}) { + wac.handleWithCustomHandlers(message, wac.handler) +} + +func (wac *Conn) handleWithCustomHandlers(message interface{}, handlers []Handler) { + switch m := message.(type) { + case error: + for _, h := range handlers { + if wac.shouldCallSynchronously(h) { + h.HandleError(m) + } else { + go h.HandleError(m) + } + } + case string: + for _, h := range handlers { + if x, ok := h.(JsonMessageHandler); ok { + if wac.shouldCallSynchronously(h) { + x.HandleJsonMessage(m) + } else { + go x.HandleJsonMessage(m) + } + } + } + case TextMessage: + for _, h := range handlers { + if x, ok := h.(TextMessageHandler); ok { + if wac.shouldCallSynchronously(h) { + x.HandleTextMessage(m) + } else { + go x.HandleTextMessage(m) + } + } + } + case ImageMessage: + for _, h := range handlers { + if x, ok := h.(ImageMessageHandler); ok { + if wac.shouldCallSynchronously(h) { + x.HandleImageMessage(m) + } else { + go x.HandleImageMessage(m) + } + } + } + case VideoMessage: + for _, h := range handlers { + if x, ok := h.(VideoMessageHandler); ok { + if wac.shouldCallSynchronously(h) { + x.HandleVideoMessage(m) + } else { + go x.HandleVideoMessage(m) + } + } + } + case AudioMessage: + for _, h := range handlers { + if x, ok := h.(AudioMessageHandler); ok { + if wac.shouldCallSynchronously(h) { + x.HandleAudioMessage(m) + } else { + go x.HandleAudioMessage(m) + } + } + } + case DocumentMessage: + for _, h := range handlers { + if x, ok := h.(DocumentMessageHandler); ok { + if wac.shouldCallSynchronously(h) { + x.HandleDocumentMessage(m) + } else { + go x.HandleDocumentMessage(m) + } + } + } + case LocationMessage: + for _, h := range handlers { + if x, ok := h.(LocationMessageHandler); ok { + if wac.shouldCallSynchronously(h) { + x.HandleLocationMessage(m) + } else { + go x.HandleLocationMessage(m) + } + } + } + case LiveLocationMessage: + for _, h := range handlers { + if x, ok := h.(LiveLocationMessageHandler); ok { + if wac.shouldCallSynchronously(h) { + x.HandleLiveLocationMessage(m) + } else { + go x.HandleLiveLocationMessage(m) + } + } + } + + case StickerMessage: + for _, h := range handlers { + if x, ok := h.(StickerMessageHandler); ok { + if wac.shouldCallSynchronously(h) { + x.HandleStickerMessage(m) + } else { + go x.HandleStickerMessage(m) + } + } + } + + case ContactMessage: + for _, h := range handlers { + if x, ok := h.(ContactMessageHandler); ok { + if wac.shouldCallSynchronously(h) { + x.HandleContactMessage(m) + } else { + go x.HandleContactMessage(m) + } + } + } + + case BatteryMessage: + for _, h := range handlers { + if x, ok := h.(BatteryMessageHandler); ok { + if wac.shouldCallSynchronously(h) { + x.HandleBatteryMessage(m) + } else { + go x.HandleBatteryMessage(m) + } + } + } + + case Contact: + for _, h := range handlers { + if x, ok := h.(NewContactHandler); ok { + if wac.shouldCallSynchronously(h) { + x.HandleNewContact(m) + } else { + go x.HandleNewContact(m) + } + } + } + + case ProductMessage: + for _, h := range handlers { + if x, ok := h.(ProductMessageHandler); ok { + if wac.shouldCallSynchronously(h) { + x.HandleProductMessage(m) + } else { + go x.HandleProductMessage(m) + } + } + } + + case OrderMessage: + for _, h := range handlers { + if x, ok := h.(OrderMessageHandler); ok { + if wac.shouldCallSynchronously(h) { + x.HandleOrderMessage(m) + } else { + go x.HandleOrderMessage(m) + } + } + } + + case *proto.WebMessageInfo: + for _, h := range handlers { + if x, ok := h.(RawMessageHandler); ok { + if wac.shouldCallSynchronously(h) { + x.HandleRawMessage(m) + } else { + go x.HandleRawMessage(m) + } + } + } + } + +} + +func (wac *Conn) handleContacts(contacts interface{}) { + var contactList []Contact + c, ok := contacts.([]interface{}) + if !ok { + return + } + for _, contact := range c { + contactNode, ok := contact.(binary.Node) + if !ok { + continue + } + + jid := strings.Replace(contactNode.Attributes["jid"], "@c.us", "@s.whatsapp.net", 1) + contactList = append(contactList, Contact{ + jid, + contactNode.Attributes["notify"], + contactNode.Attributes["name"], + contactNode.Attributes["short"], + }) + } + for _, h := range wac.handler { + if x, ok := h.(ContactListHandler); ok { + if wac.shouldCallSynchronously(h) { + x.HandleContactList(contactList) + } else { + go x.HandleContactList(contactList) + } + } + } +} + +func (wac *Conn) handleChats(chats interface{}) { + var chatList []Chat + c, ok := chats.([]interface{}) + if !ok { + return + } + for _, chat := range c { + chatNode, ok := chat.(binary.Node) + if !ok { + continue + } + + jid := strings.Replace(chatNode.Attributes["jid"], "@c.us", "@s.whatsapp.net", 1) + chatList = append(chatList, Chat{ + jid, + chatNode.Attributes["name"], + chatNode.Attributes["count"], + chatNode.Attributes["t"], + chatNode.Attributes["mute"], + chatNode.Attributes["spam"], + }) + } + for _, h := range wac.handler { + if x, ok := h.(ChatListHandler); ok { + if wac.shouldCallSynchronously(h) { + x.HandleChatList(chatList) + } else { + go x.HandleChatList(chatList) + } + } + } +} + +func (wac *Conn) dispatch(msg interface{}) { + if msg == nil { + return + } + + switch message := msg.(type) { + case *binary.Node: + if message.Description == "action" { + if con, ok := message.Content.([]interface{}); ok { + for a := range con { + if v, ok := con[a].(*proto.WebMessageInfo); ok { + wac.handle(v) + wac.handle(ParseProtoMessage(v)) + } + + if v, ok := con[a].(binary.Node); ok { + wac.handle(ParseNodeMessage(v)) + } + } + } else if con, ok := message.Content.([]binary.Node); ok { + for a := range con { + wac.handle(ParseNodeMessage(con[a])) + } + } + } else if message.Description == "response" && message.Attributes["type"] == "contacts" { + wac.updateContacts(message.Content) + wac.handleContacts(message.Content) + } else if message.Description == "response" && message.Attributes["type"] == "chat" { + wac.updateChats(message.Content) + wac.handleChats(message.Content) + } + case error: + wac.handle(message) + case string: + wac.handle(message) + default: + fmt.Fprintf(os.Stderr, "unknown type in dipatcher chan: %T", msg) + } +} diff --git a/vendor/github.com/Rhymen/go-whatsapp/media.go b/vendor/github.com/Rhymen/go-whatsapp/media.go new file mode 100644 index 00000000..f72e7922 --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/media.go @@ -0,0 +1,221 @@ +package whatsapp + +import ( + "bytes" + "crypto/hmac" + "crypto/rand" + "crypto/sha256" + "encoding/base64" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net" + "net/http" + "net/url" + "time" + + "github.com/Rhymen/go-whatsapp/crypto/cbc" + "github.com/Rhymen/go-whatsapp/crypto/hkdf" +) + +func Download(url string, mediaKey []byte, appInfo MediaType, fileLength int) ([]byte, error) { + if url == "" { + return nil, fmt.Errorf("no url present") + } + file, mac, err := downloadMedia(url) + if err != nil { + return nil, err + } + iv, cipherKey, macKey, _, err := getMediaKeys(mediaKey, appInfo) + if err != nil { + return nil, err + } + if err = validateMedia(iv, file, macKey, mac); err != nil { + return nil, err + } + data, err := cbc.Decrypt(cipherKey, iv, file) + if err != nil { + return nil, err + } + if len(data) != fileLength { + return nil, fmt.Errorf("file length does not match. Expected: %v, got: %v", fileLength, len(data)) + } + return data, nil +} + +func validateMedia(iv []byte, file []byte, macKey []byte, mac []byte) error { + h := hmac.New(sha256.New, macKey) + n, err := h.Write(append(iv, file...)) + if err != nil { + return err + } + if n < 10 { + return fmt.Errorf("hash to short") + } + if !hmac.Equal(h.Sum(nil)[:10], mac) { + return fmt.Errorf("invalid media hmac") + } + return nil +} + +func getMediaKeys(mediaKey []byte, appInfo MediaType) (iv, cipherKey, macKey, refKey []byte, err error) { + mediaKeyExpanded, err := hkdf.Expand(mediaKey, 112, string(appInfo)) + if err != nil { + return nil, nil, nil, nil, err + } + return mediaKeyExpanded[:16], mediaKeyExpanded[16:48], mediaKeyExpanded[48:80], mediaKeyExpanded[80:], nil +} + +func downloadMedia(url string) (file []byte, mac []byte, err error) { + resp, err := http.Get(url) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return nil, nil, fmt.Errorf("download failed with status code %d", resp.StatusCode) + } + if resp.ContentLength <= 10 { + return nil, nil, fmt.Errorf("file to short") + } + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, nil, err + } + + n := len(data) + return data[:n-10], data[n-10 : n], nil +} + +type MediaConn struct { + Status int `json:"status"` + MediaConn struct { + Auth string `json:"auth"` + TTL int `json:"ttl"` + Hosts []struct { + Hostname string `json:"hostname"` + IPs []struct { + IP4 net.IP `json:"ip4"` + IP6 net.IP `json:"ip6"` + } `json:"ips"` + } `json:"hosts"` + } `json:"media_conn"` +} + +func (wac *Conn) queryMediaConn() (hostname, auth string, ttl int, err error) { + queryReq := []interface{}{"query", "mediaConn"} + ch, err := wac.writeJson(queryReq) + if err != nil { + return "", "", 0, err + } + + var resp MediaConn + select { + case r := <-ch: + if err = json.Unmarshal([]byte(r), &resp); err != nil { + return "", "", 0, fmt.Errorf("error decoding query media conn response: %v", err) + } + case <-time.After(wac.msgTimeout): + return "", "", 0, fmt.Errorf("query media conn timed out") + } + + if resp.Status != http.StatusOK { + return "", "", 0, fmt.Errorf("query media conn responded with %d", resp.Status) + } + + for _, h := range resp.MediaConn.Hosts { + if h.Hostname != "" { + return h.Hostname, resp.MediaConn.Auth, resp.MediaConn.TTL, nil + } + } + + return "", "", 0, fmt.Errorf("query media conn responded with no host") +} + +var mediaTypeMap = map[MediaType]string{ + MediaImage: "/mms/image", + MediaVideo: "/mms/video", + MediaDocument: "/mms/document", + MediaAudio: "/mms/audio", +} + +func (wac *Conn) Upload(reader io.Reader, appInfo MediaType) (downloadURL string, mediaKey []byte, fileEncSha256 []byte, fileSha256 []byte, fileLength uint64, err error) { + data, err := ioutil.ReadAll(reader) + if err != nil { + return "", nil, nil, nil, 0, err + } + + mediaKey = make([]byte, 32) + rand.Read(mediaKey) + + iv, cipherKey, macKey, _, err := getMediaKeys(mediaKey, appInfo) + if err != nil { + return "", nil, nil, nil, 0, err + } + + enc, err := cbc.Encrypt(cipherKey, iv, data) + if err != nil { + return "", nil, nil, nil, 0, err + } + + fileLength = uint64(len(data)) + + h := hmac.New(sha256.New, macKey) + h.Write(append(iv, enc...)) + mac := h.Sum(nil)[:10] + + sha := sha256.New() + sha.Write(data) + fileSha256 = sha.Sum(nil) + + sha.Reset() + sha.Write(append(enc, mac...)) + fileEncSha256 = sha.Sum(nil) + + hostname, auth, _, err := wac.queryMediaConn() + if err != nil { + return "", nil, nil, nil, 0, err + } + + token := base64.URLEncoding.EncodeToString(fileEncSha256) + q := url.Values{ + "auth": []string{auth}, + "token": []string{token}, + } + path := mediaTypeMap[appInfo] + uploadURL := url.URL{ + Scheme: "https", + Host: hostname, + Path: fmt.Sprintf("%s/%s", path, token), + RawQuery: q.Encode(), + } + + body := bytes.NewReader(append(enc, mac...)) + + req, err := http.NewRequest(http.MethodPost, uploadURL.String(), body) + if err != nil { + return "", nil, nil, nil, 0, err + } + + req.Header.Set("Origin", "https://web.whatsapp.com") + req.Header.Set("Referer", "https://web.whatsapp.com/") + + client := &http.Client{} + // Submit the request + res, err := client.Do(req) + if err != nil { + return "", nil, nil, nil, 0, err + } + + if res.StatusCode != http.StatusOK { + return "", nil, nil, nil, 0, fmt.Errorf("upload failed with status code %d", res.StatusCode) + } + + var jsonRes map[string]string + if err := json.NewDecoder(res.Body).Decode(&jsonRes); err != nil { + return "", nil, nil, nil, 0, err + } + + return jsonRes["url"], mediaKey, fileEncSha256, fileSha256, fileLength, nil +} diff --git a/vendor/github.com/Rhymen/go-whatsapp/message.go b/vendor/github.com/Rhymen/go-whatsapp/message.go new file mode 100644 index 00000000..1acf881b --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/message.go @@ -0,0 +1,1005 @@ +package whatsapp + +import ( + "encoding/hex" + "encoding/json" + "fmt" + "io" + "math/rand" + "strconv" + "strings" + "time" + + "github.com/Rhymen/go-whatsapp/binary" + "github.com/Rhymen/go-whatsapp/binary/proto" +) + +type MediaType string + +const ( + MediaImage MediaType = "WhatsApp Image Keys" + MediaVideo MediaType = "WhatsApp Video Keys" + MediaAudio MediaType = "WhatsApp Audio Keys" + MediaDocument MediaType = "WhatsApp Document Keys" +) + +func (wac *Conn) Send(msg interface{}) (string, error) { + var msgProto *proto.WebMessageInfo + + switch m := msg.(type) { + case *proto.WebMessageInfo: + msgProto = m + case TextMessage: + msgProto = getTextProto(m) + case ImageMessage: + var err error + m.url, m.mediaKey, m.fileEncSha256, m.fileSha256, m.fileLength, err = wac.Upload(m.Content, MediaImage) + if err != nil { + return "ERROR", fmt.Errorf("image upload failed: %v", err) + } + msgProto = getImageProto(m) + case VideoMessage: + var err error + m.url, m.mediaKey, m.fileEncSha256, m.fileSha256, m.fileLength, err = wac.Upload(m.Content, MediaVideo) + if err != nil { + return "ERROR", fmt.Errorf("video upload failed: %v", err) + } + msgProto = getVideoProto(m) + case DocumentMessage: + var err error + m.url, m.mediaKey, m.fileEncSha256, m.fileSha256, m.fileLength, err = wac.Upload(m.Content, MediaDocument) + if err != nil { + return "ERROR", fmt.Errorf("document upload failed: %v", err) + } + msgProto = getDocumentProto(m) + case AudioMessage: + var err error + m.url, m.mediaKey, m.fileEncSha256, m.fileSha256, m.fileLength, err = wac.Upload(m.Content, MediaAudio) + if err != nil { + return "ERROR", fmt.Errorf("audio upload failed: %v", err) + } + msgProto = getAudioProto(m) + case LocationMessage: + msgProto = GetLocationProto(m) + case LiveLocationMessage: + msgProto = GetLiveLocationProto(m) + case ContactMessage: + msgProto = getContactMessageProto(m) + case ProductMessage: + msgProto = getProductMessageProto(m) + case OrderMessage: + msgProto = getOrderMessageProto(m) + default: + return "ERROR", fmt.Errorf("cannot match type %T, use message types declared in the package", msg) + } + status := proto.WebMessageInfo_PENDING + msgProto.Status = &status + ch, err := wac.sendProto(msgProto) + if err != nil { + return "ERROR", fmt.Errorf("could not send proto: %v", err) + } + + select { + case response := <-ch: + var resp map[string]interface{} + if err = json.Unmarshal([]byte(response), &resp); err != nil { + return "ERROR", fmt.Errorf("error decoding sending response: %v\n", err) + } + if int(resp["status"].(float64)) != 200 { + return "ERROR", fmt.Errorf("message sending responded with %v", resp["status"]) + } + if int(resp["status"].(float64)) == 200 { + return getMessageInfo(msgProto).Id, nil + } + case <-time.After(wac.msgTimeout): + return "ERROR", fmt.Errorf("sending message timed out") + } + + return "ERROR", nil +} + +func (wac *Conn) sendProto(p *proto.WebMessageInfo) (<-chan string, error) { + n := binary.Node{ + Description: "action", + Attributes: map[string]string{ + "type": "relay", + "epoch": strconv.Itoa(wac.msgCount), + }, + Content: []interface{}{p}, + } + return wac.writeBinary(n, message, ignore, p.Key.GetId()) +} + +// RevokeMessage revokes a message (marks as "message removed") for everyone +func (wac *Conn) RevokeMessage(remotejid, msgid string, fromme bool) (revokeid string, err error) { + // create a revocation ID (required) + rawrevocationID := make([]byte, 10) + rand.Read(rawrevocationID) + revocationID := strings.ToUpper(hex.EncodeToString(rawrevocationID)) + // + ts := uint64(time.Now().Unix()) + status := proto.WebMessageInfo_PENDING + mtype := proto.ProtocolMessage_REVOKE + + revoker := &proto.WebMessageInfo{ + Key: &proto.MessageKey{ + FromMe: &fromme, + Id: &revocationID, + RemoteJid: &remotejid, + }, + MessageTimestamp: &ts, + Message: &proto.Message{ + ProtocolMessage: &proto.ProtocolMessage{ + Type: &mtype, + Key: &proto.MessageKey{ + FromMe: &fromme, + Id: &msgid, + RemoteJid: &remotejid, + }, + }, + }, + Status: &status, + } + if _, err := wac.Send(revoker); err != nil { + return revocationID, err + } + return revocationID, nil +} + +// DeleteMessage deletes a single message for the user (removes the msgbox). To +// delete the message for everyone, use RevokeMessage +func (wac *Conn) DeleteMessage(remotejid, msgid string, fromMe bool) error { + ch, err := wac.deleteChatProto(remotejid, msgid, fromMe) + if err != nil { + return fmt.Errorf("could not send proto: %v", err) + } + + select { + case response := <-ch: + var resp map[string]interface{} + if err = json.Unmarshal([]byte(response), &resp); err != nil { + return fmt.Errorf("error decoding deletion response: %v", err) + } + if int(resp["status"].(float64)) != 200 { + return fmt.Errorf("message deletion responded with %v", resp["status"]) + } + if int(resp["status"].(float64)) == 200 { + return nil + } + case <-time.After(wac.msgTimeout): + return fmt.Errorf("deleting message timed out") + } + + return nil +} + +func (wac *Conn) deleteChatProto(remotejid, msgid string, fromMe bool) (<-chan string, error) { + tag := fmt.Sprintf("%s.--%d", wac.timeTag, wac.msgCount) + + owner := "true" + if !fromMe { + owner = "false" + } + n := binary.Node{ + Description: "action", + Attributes: map[string]string{ + "epoch": strconv.Itoa(wac.msgCount), + "type": "set", + }, + Content: []interface{}{ + binary.Node{ + Description: "chat", + Attributes: map[string]string{ + "type": "clear", + "jid": remotejid, + "media": "true", + }, + Content: []binary.Node{ + { + Description: "item", + Attributes: map[string]string{ + "owner": owner, + "index": msgid, + }, + }, + }, + }, + }, + } + return wac.writeBinary(n, chat, expires|skipOffline, tag) +} + +func init() { + rand.Seed(time.Now().UTC().UnixNano()) +} + +/* +MessageInfo contains general message information. It is part of every of every message type. +*/ +type MessageInfo struct { + Id string + RemoteJid string + SenderJid string + FromMe bool + Timestamp uint64 + PushName string + Status MessageStatus + + Source *proto.WebMessageInfo +} + +type MessageStatus int + +const ( + Error MessageStatus = 0 + Pending = 1 + ServerAck = 2 + DeliveryAck = 3 + Read = 4 + Played = 5 +) + +func getMessageInfo(msg *proto.WebMessageInfo) MessageInfo { + return MessageInfo{ + Id: msg.GetKey().GetId(), + RemoteJid: msg.GetKey().GetRemoteJid(), + SenderJid: msg.GetParticipant(), + FromMe: msg.GetKey().GetFromMe(), + Timestamp: msg.GetMessageTimestamp(), + Status: MessageStatus(msg.GetStatus()), + PushName: msg.GetPushName(), + Source: msg, + } +} + +func getInfoProto(info *MessageInfo) *proto.WebMessageInfo { + if info.Id == "" || len(info.Id) < 2 { + b := make([]byte, 10) + rand.Read(b) + info.Id = strings.ToUpper(hex.EncodeToString(b)) + } + if info.Timestamp == 0 { + info.Timestamp = uint64(time.Now().Unix()) + } + info.FromMe = true + + status := proto.WebMessageInfo_WebMessageInfoStatus(info.Status) + + return &proto.WebMessageInfo{ + Key: &proto.MessageKey{ + FromMe: &info.FromMe, + RemoteJid: &info.RemoteJid, + Id: &info.Id, + }, + MessageTimestamp: &info.Timestamp, + Status: &status, + } +} + +/* +ContextInfo represents contextinfo of every message +*/ +type ContextInfo struct { + QuotedMessageID string //StanzaId + QuotedMessage *proto.Message + Participant string + IsForwarded bool +} + +func getMessageContext(msg *proto.ContextInfo) ContextInfo { + + return ContextInfo{ + QuotedMessageID: msg.GetStanzaId(), //StanzaId + QuotedMessage: msg.GetQuotedMessage(), + Participant: msg.GetParticipant(), + IsForwarded: msg.GetIsForwarded(), + } +} + +func getContextInfoProto(context *ContextInfo) *proto.ContextInfo { + if len(context.QuotedMessageID) > 0 { + contextInfo := &proto.ContextInfo{ + StanzaId: &context.QuotedMessageID, + } + + if &context.QuotedMessage != nil { + contextInfo.QuotedMessage = context.QuotedMessage + contextInfo.Participant = &context.Participant + } + + return contextInfo + } + + return nil +} + +/* +TextMessage represents a text message. +*/ +type TextMessage struct { + Info MessageInfo + Text string + ContextInfo ContextInfo +} + +func getTextMessage(msg *proto.WebMessageInfo) TextMessage { + text := TextMessage{Info: getMessageInfo(msg)} + if m := msg.GetMessage().GetExtendedTextMessage(); m != nil { + text.Text = m.GetText() + + text.ContextInfo = getMessageContext(m.GetContextInfo()) + } else { + text.Text = msg.GetMessage().GetConversation() + + } + + return text +} + +func getTextProto(msg TextMessage) *proto.WebMessageInfo { + p := getInfoProto(&msg.Info) + contextInfo := getContextInfoProto(&msg.ContextInfo) + + if contextInfo == nil { + p.Message = &proto.Message{ + Conversation: &msg.Text, + } + } else { + p.Message = &proto.Message{ + ExtendedTextMessage: &proto.ExtendedTextMessage{ + Text: &msg.Text, + ContextInfo: contextInfo, + }, + } + } + + return p +} + +/* +ImageMessage represents a image message. Unexported fields are needed for media up/downloading and media validation. +Provide a io.Reader as Content for message sending. +*/ +type ImageMessage struct { + Info MessageInfo + Caption string + Thumbnail []byte + Type string + Content io.Reader + url string + mediaKey []byte + fileEncSha256 []byte + fileSha256 []byte + fileLength uint64 + ContextInfo ContextInfo +} + +func getImageMessage(msg *proto.WebMessageInfo) ImageMessage { + image := msg.GetMessage().GetImageMessage() + + imageMessage := ImageMessage{ + Info: getMessageInfo(msg), + Caption: image.GetCaption(), + Thumbnail: image.GetJpegThumbnail(), + url: image.GetUrl(), + mediaKey: image.GetMediaKey(), + Type: image.GetMimetype(), + fileEncSha256: image.GetFileEncSha256(), + fileSha256: image.GetFileSha256(), + fileLength: image.GetFileLength(), + ContextInfo: getMessageContext(image.GetContextInfo()), + } + + return imageMessage +} + +func getImageProto(msg ImageMessage) *proto.WebMessageInfo { + p := getInfoProto(&msg.Info) + contextInfo := getContextInfoProto(&msg.ContextInfo) + + p.Message = &proto.Message{ + ImageMessage: &proto.ImageMessage{ + Caption: &msg.Caption, + JpegThumbnail: msg.Thumbnail, + Url: &msg.url, + MediaKey: msg.mediaKey, + Mimetype: &msg.Type, + FileEncSha256: msg.fileEncSha256, + FileSha256: msg.fileSha256, + FileLength: &msg.fileLength, + ContextInfo: contextInfo, + }, + } + return p +} + +/* +Download is the function to retrieve media data. The media gets downloaded, validated and returned. +*/ +func (m *ImageMessage) Download() ([]byte, error) { + return Download(m.url, m.mediaKey, MediaImage, int(m.fileLength)) +} + +/* +VideoMessage represents a video message. Unexported fields are needed for media up/downloading and media validation. +Provide a io.Reader as Content for message sending. +*/ +type VideoMessage struct { + Info MessageInfo + Caption string + Thumbnail []byte + Length uint32 + Type string + Content io.Reader + GifPlayback bool + url string + mediaKey []byte + fileEncSha256 []byte + fileSha256 []byte + fileLength uint64 + ContextInfo ContextInfo +} + +func getVideoMessage(msg *proto.WebMessageInfo) VideoMessage { + vid := msg.GetMessage().GetVideoMessage() + + videoMessage := VideoMessage{ + Info: getMessageInfo(msg), + Caption: vid.GetCaption(), + Thumbnail: vid.GetJpegThumbnail(), + GifPlayback: vid.GetGifPlayback(), + url: vid.GetUrl(), + mediaKey: vid.GetMediaKey(), + Length: vid.GetSeconds(), + Type: vid.GetMimetype(), + fileEncSha256: vid.GetFileEncSha256(), + fileSha256: vid.GetFileSha256(), + fileLength: vid.GetFileLength(), + ContextInfo: getMessageContext(vid.GetContextInfo()), + } + + return videoMessage +} + +func getVideoProto(msg VideoMessage) *proto.WebMessageInfo { + p := getInfoProto(&msg.Info) + contextInfo := getContextInfoProto(&msg.ContextInfo) + + p.Message = &proto.Message{ + VideoMessage: &proto.VideoMessage{ + Caption: &msg.Caption, + JpegThumbnail: msg.Thumbnail, + Url: &msg.url, + GifPlayback: &msg.GifPlayback, + MediaKey: msg.mediaKey, + Seconds: &msg.Length, + FileEncSha256: msg.fileEncSha256, + FileSha256: msg.fileSha256, + FileLength: &msg.fileLength, + Mimetype: &msg.Type, + ContextInfo: contextInfo, + }, + } + return p +} + +/* +Download is the function to retrieve media data. The media gets downloaded, validated and returned. +*/ +func (m *VideoMessage) Download() ([]byte, error) { + return Download(m.url, m.mediaKey, MediaVideo, int(m.fileLength)) +} + +/* +AudioMessage represents a audio message. Unexported fields are needed for media up/downloading and media validation. +Provide a io.Reader as Content for message sending. +*/ +type AudioMessage struct { + Info MessageInfo + Length uint32 + Type string + Content io.Reader + Ptt bool + url string + mediaKey []byte + fileEncSha256 []byte + fileSha256 []byte + fileLength uint64 + ContextInfo ContextInfo +} + +func getAudioMessage(msg *proto.WebMessageInfo) AudioMessage { + aud := msg.GetMessage().GetAudioMessage() + + audioMessage := AudioMessage{ + Info: getMessageInfo(msg), + url: aud.GetUrl(), + mediaKey: aud.GetMediaKey(), + Length: aud.GetSeconds(), + Type: aud.GetMimetype(), + fileEncSha256: aud.GetFileEncSha256(), + fileSha256: aud.GetFileSha256(), + fileLength: aud.GetFileLength(), + ContextInfo: getMessageContext(aud.GetContextInfo()), + } + + return audioMessage +} + +func getAudioProto(msg AudioMessage) *proto.WebMessageInfo { + p := getInfoProto(&msg.Info) + contextInfo := getContextInfoProto(&msg.ContextInfo) + p.Message = &proto.Message{ + AudioMessage: &proto.AudioMessage{ + Url: &msg.url, + MediaKey: msg.mediaKey, + Seconds: &msg.Length, + FileEncSha256: msg.fileEncSha256, + FileSha256: msg.fileSha256, + FileLength: &msg.fileLength, + Mimetype: &msg.Type, + ContextInfo: contextInfo, + Ptt: &msg.Ptt, + }, + } + return p +} + +/* +Download is the function to retrieve media data. The media gets downloaded, validated and returned. +*/ +func (m *AudioMessage) Download() ([]byte, error) { + return Download(m.url, m.mediaKey, MediaAudio, int(m.fileLength)) +} + +/* +DocumentMessage represents a document message. Unexported fields are needed for media up/downloading and media +validation. Provide a io.Reader as Content for message sending. +*/ +type DocumentMessage struct { + Info MessageInfo + Title string + PageCount uint32 + Type string + FileName string + Thumbnail []byte + Content io.Reader + url string + mediaKey []byte + fileEncSha256 []byte + fileSha256 []byte + fileLength uint64 + ContextInfo ContextInfo +} + +func getDocumentMessage(msg *proto.WebMessageInfo) DocumentMessage { + doc := msg.GetMessage().GetDocumentMessage() + + documentMessage := DocumentMessage{ + Info: getMessageInfo(msg), + Title: doc.GetTitle(), + PageCount: doc.GetPageCount(), + Type: doc.GetMimetype(), + FileName: doc.GetFileName(), + Thumbnail: doc.GetJpegThumbnail(), + url: doc.GetUrl(), + mediaKey: doc.GetMediaKey(), + fileEncSha256: doc.GetFileEncSha256(), + fileSha256: doc.GetFileSha256(), + fileLength: doc.GetFileLength(), + ContextInfo: getMessageContext(doc.GetContextInfo()), + } + + return documentMessage +} + +func getDocumentProto(msg DocumentMessage) *proto.WebMessageInfo { + p := getInfoProto(&msg.Info) + contextInfo := getContextInfoProto(&msg.ContextInfo) + p.Message = &proto.Message{ + DocumentMessage: &proto.DocumentMessage{ + JpegThumbnail: msg.Thumbnail, + Url: &msg.url, + MediaKey: msg.mediaKey, + FileEncSha256: msg.fileEncSha256, + FileSha256: msg.fileSha256, + FileLength: &msg.fileLength, + PageCount: &msg.PageCount, + Title: &msg.Title, + Mimetype: &msg.Type, + ContextInfo: contextInfo, + }, + } + return p +} + +/* +Download is the function to retrieve media data. The media gets downloaded, validated and returned. +*/ +func (m *DocumentMessage) Download() ([]byte, error) { + return Download(m.url, m.mediaKey, MediaDocument, int(m.fileLength)) +} + +/* +LocationMessage represents a location message +*/ +type LocationMessage struct { + Info MessageInfo + DegreesLatitude float64 + DegreesLongitude float64 + Name string + Address string + Url string + JpegThumbnail []byte + ContextInfo ContextInfo +} + +func GetLocationMessage(msg *proto.WebMessageInfo) LocationMessage { + loc := msg.GetMessage().GetLocationMessage() + + locationMessage := LocationMessage{ + Info: getMessageInfo(msg), + DegreesLatitude: loc.GetDegreesLatitude(), + DegreesLongitude: loc.GetDegreesLongitude(), + Name: loc.GetName(), + Address: loc.GetAddress(), + Url: loc.GetUrl(), + JpegThumbnail: loc.GetJpegThumbnail(), + ContextInfo: getMessageContext(loc.GetContextInfo()), + } + + return locationMessage +} + +func GetLocationProto(msg LocationMessage) *proto.WebMessageInfo { + p := getInfoProto(&msg.Info) + contextInfo := getContextInfoProto(&msg.ContextInfo) + + p.Message = &proto.Message{ + LocationMessage: &proto.LocationMessage{ + DegreesLatitude: &msg.DegreesLatitude, + DegreesLongitude: &msg.DegreesLongitude, + Name: &msg.Name, + Address: &msg.Address, + Url: &msg.Url, + JpegThumbnail: msg.JpegThumbnail, + ContextInfo: contextInfo, + }, + } + return p +} + +/* +LiveLocationMessage represents a live location message +*/ +type LiveLocationMessage struct { + Info MessageInfo + DegreesLatitude float64 + DegreesLongitude float64 + AccuracyInMeters uint32 + SpeedInMps float32 + DegreesClockwiseFromMagneticNorth uint32 + Caption string + SequenceNumber int64 + JpegThumbnail []byte + ContextInfo ContextInfo +} + +func GetLiveLocationMessage(msg *proto.WebMessageInfo) LiveLocationMessage { + loc := msg.GetMessage().GetLiveLocationMessage() + + liveLocationMessage := LiveLocationMessage{ + Info: getMessageInfo(msg), + DegreesLatitude: loc.GetDegreesLatitude(), + DegreesLongitude: loc.GetDegreesLongitude(), + AccuracyInMeters: loc.GetAccuracyInMeters(), + SpeedInMps: loc.GetSpeedInMps(), + DegreesClockwiseFromMagneticNorth: loc.GetDegreesClockwiseFromMagneticNorth(), + Caption: loc.GetCaption(), + SequenceNumber: loc.GetSequenceNumber(), + JpegThumbnail: loc.GetJpegThumbnail(), + ContextInfo: getMessageContext(loc.GetContextInfo()), + } + + return liveLocationMessage +} + +func GetLiveLocationProto(msg LiveLocationMessage) *proto.WebMessageInfo { + p := getInfoProto(&msg.Info) + contextInfo := getContextInfoProto(&msg.ContextInfo) + p.Message = &proto.Message{ + LiveLocationMessage: &proto.LiveLocationMessage{ + DegreesLatitude: &msg.DegreesLatitude, + DegreesLongitude: &msg.DegreesLongitude, + AccuracyInMeters: &msg.AccuracyInMeters, + SpeedInMps: &msg.SpeedInMps, + DegreesClockwiseFromMagneticNorth: &msg.DegreesClockwiseFromMagneticNorth, + Caption: &msg.Caption, + SequenceNumber: &msg.SequenceNumber, + JpegThumbnail: msg.JpegThumbnail, + ContextInfo: contextInfo, + }, + } + return p +} + +/* +StickerMessage represents a sticker message. +*/ +type StickerMessage struct { + Info MessageInfo + + Type string + Content io.Reader + url string + mediaKey []byte + fileEncSha256 []byte + fileSha256 []byte + fileLength uint64 + + ContextInfo ContextInfo +} + +func getStickerMessage(msg *proto.WebMessageInfo) StickerMessage { + sticker := msg.GetMessage().GetStickerMessage() + + stickerMessage := StickerMessage{ + Info: getMessageInfo(msg), + url: sticker.GetUrl(), + mediaKey: sticker.GetMediaKey(), + Type: sticker.GetMimetype(), + fileEncSha256: sticker.GetFileEncSha256(), + fileSha256: sticker.GetFileSha256(), + fileLength: sticker.GetFileLength(), + ContextInfo: getMessageContext(sticker.GetContextInfo()), + } + + return stickerMessage +} + +/* +Download is the function to retrieve Sticker media data. The media gets downloaded, validated and returned. +*/ + +func (m *StickerMessage) Download() ([]byte, error) { + return Download(m.url, m.mediaKey, MediaImage, int(m.fileLength)) +} + +/* +ContactMessage represents a contact message. +*/ +type ContactMessage struct { + Info MessageInfo + + DisplayName string + Vcard string + + ContextInfo ContextInfo +} + +func getContactMessage(msg *proto.WebMessageInfo) ContactMessage { + contact := msg.GetMessage().GetContactMessage() + + contactMessage := ContactMessage{ + Info: getMessageInfo(msg), + + DisplayName: contact.GetDisplayName(), + Vcard: contact.GetVcard(), + + ContextInfo: getMessageContext(contact.GetContextInfo()), + } + + return contactMessage +} + +func getContactMessageProto(msg ContactMessage) *proto.WebMessageInfo { + p := getInfoProto(&msg.Info) + contextInfo := getContextInfoProto(&msg.ContextInfo) + + p.Message = &proto.Message{ + ContactMessage: &proto.ContactMessage{ + DisplayName: &msg.DisplayName, + Vcard: &msg.Vcard, + ContextInfo: contextInfo, + }, + } + + return p +} + +/* +OrderMessage represents a order message. +*/ + +type OrderMessage struct { + Info MessageInfo + OrderId string + Thumbnail []byte + ItemCount int32 + Status proto.OrderMessage_OrderMessageOrderStatus + Surface proto.OrderMessage_OrderMessageOrderSurface + Message string + OrderTitle string + SellerJid string + Token string + TotalAmount1000 int64 + TotalCurrencyCode string + ContextInfo ContextInfo +} + +func getOrderMessage(msg *proto.WebMessageInfo) OrderMessage { + order := msg.GetMessage().GetOrderMessage() + + orderMessage := OrderMessage{ + Info: getMessageInfo(msg), + OrderId: order.GetOrderId(), + Thumbnail: order.GetThumbnail(), + ItemCount: order.GetItemCount(), + Status: order.GetStatus(), + Surface: order.GetSurface(), + Message: order.GetMessage(), + OrderTitle: order.GetOrderTitle(), + SellerJid: order.GetSellerJid(), + Token: order.GetToken(), + TotalAmount1000: order.GetTotalAmount1000(), + TotalCurrencyCode: order.GetTotalCurrencyCode(), + ContextInfo: getMessageContext(order.GetContextInfo()), + } + + return orderMessage +} + +func getOrderMessageProto(msg OrderMessage) *proto.WebMessageInfo { + p := getInfoProto(&msg.Info) + contextInfo := getContextInfoProto(&msg.ContextInfo) + + p.Message = &proto.Message{ + OrderMessage: &proto.OrderMessage{ + Thumbnail: msg.Thumbnail, + ItemCount: &msg.ItemCount, + Status: &msg.Status, + Surface: &msg.Surface, + Message: &msg.Message, + OrderTitle: &msg.OrderTitle, + SellerJid: &msg.SellerJid, + Token: &msg.Token, + TotalAmount1000: &msg.TotalAmount1000, + TotalCurrencyCode: &msg.TotalCurrencyCode, + ContextInfo: contextInfo, + }, + } + + return p +} + +/* +ProductMessage represents a product message. +*/ + +type ProductMessage struct { + Info MessageInfo + Product *proto.ProductSnapshot + BusinessOwnerJid string + Catalog *proto.CatalogSnapshot + ContextInfo ContextInfo +} + +func getProductMessage(msg *proto.WebMessageInfo) ProductMessage { + prod := msg.GetMessage().GetProductMessage() + + productMessage := ProductMessage{ + Info: getMessageInfo(msg), + Product: prod.GetProduct(), + BusinessOwnerJid: prod.GetBusinessOwnerJid(), + Catalog: prod.GetCatalog(), + ContextInfo: getMessageContext(prod.GetContextInfo()), + } + + return productMessage +} + +func getProductMessageProto(msg ProductMessage) *proto.WebMessageInfo { + p := getInfoProto(&msg.Info) + contextInfo := getContextInfoProto(&msg.ContextInfo) + + p.Message = &proto.Message{ + ProductMessage: &proto.ProductMessage{ + Product: msg.Product, + BusinessOwnerJid: &msg.BusinessOwnerJid, + Catalog: msg.Catalog, + ContextInfo: contextInfo, + }, + } + + return p +} + +func ParseProtoMessage(msg *proto.WebMessageInfo) interface{} { + + switch { + + case msg.GetMessage().GetAudioMessage() != nil: + return getAudioMessage(msg) + + case msg.GetMessage().GetImageMessage() != nil: + return getImageMessage(msg) + + case msg.GetMessage().GetVideoMessage() != nil: + return getVideoMessage(msg) + + case msg.GetMessage().GetDocumentMessage() != nil: + return getDocumentMessage(msg) + + case msg.GetMessage().GetConversation() != "": + return getTextMessage(msg) + + case msg.GetMessage().GetExtendedTextMessage() != nil: + return getTextMessage(msg) + + case msg.GetMessage().GetLocationMessage() != nil: + return GetLocationMessage(msg) + + case msg.GetMessage().GetLiveLocationMessage() != nil: + return GetLiveLocationMessage(msg) + + case msg.GetMessage().GetStickerMessage() != nil: + return getStickerMessage(msg) + + case msg.GetMessage().GetContactMessage() != nil: + return getContactMessage(msg) + + case msg.GetMessage().GetProductMessage() != nil: + return getProductMessage(msg) + + case msg.GetMessage().GetOrderMessage() != nil: + return getOrderMessage(msg) + + default: + //cannot match message + return ErrMessageTypeNotImplemented + } +} + +/* +BatteryMessage represents a battery level and charging state. +*/ +type BatteryMessage struct { + Plugged bool + Powersave bool + Percentage int +} + +func getBatteryMessage(msg map[string]string) BatteryMessage { + plugged, _ := strconv.ParseBool(msg["live"]) + powersave, _ := strconv.ParseBool(msg["powersave"]) + percentage, _ := strconv.Atoi(msg["value"]) + batteryMessage := BatteryMessage{ + Plugged: plugged, + Powersave: powersave, + Percentage: percentage, + } + + return batteryMessage +} + +func getNewContact(msg map[string]string) Contact { + contact := Contact{ + Jid: msg["jid"], + Notify: msg["notify"], + } + + return contact +} + +func ParseNodeMessage(msg binary.Node) interface{} { + switch msg.Description { + case "battery": + return getBatteryMessage(msg.Attributes) + case "user": + return getNewContact(msg.Attributes) + default: + //cannot match message + } + + return nil +} diff --git a/vendor/github.com/Rhymen/go-whatsapp/profile.go b/vendor/github.com/Rhymen/go-whatsapp/profile.go new file mode 100644 index 00000000..5af00f6d --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/profile.go @@ -0,0 +1,65 @@ +package whatsapp + +import ( + "fmt" + "strconv" + "time" + + "github.com/Rhymen/go-whatsapp/binary" +) + +// Pictures must be JPG 640x640 and 96x96, respectively +func (wac *Conn) UploadProfilePic(image, preview []byte) (<-chan string, error) { + tag := fmt.Sprintf("%d.--%d", time.Now().Unix(), wac.msgCount*19) + n := binary.Node{ + Description: "action", + Attributes: map[string]string{ + "type": "set", + "epoch": strconv.Itoa(wac.msgCount), + }, + Content: []interface{}{ + binary.Node{ + Description: "picture", + Attributes: map[string]string{ + "id": tag, + "jid": wac.Info.Wid, + "type": "set", + }, + Content: []binary.Node{ + { + Description: "image", + Attributes: nil, + Content: image, + }, + { + Description: "preview", + Attributes: nil, + Content: preview, + }, + }, + }, + }, + } + return wac.writeBinary(n, profile, 136, tag) +} + +func (wac *Conn) UpdateProfileName(name string) (<-chan string, error) { + tag := fmt.Sprintf("%d.--%d", time.Now().Unix(), wac.msgCount*19) + n := binary.Node{ + Description: "action", + Attributes: map[string]string{ + "type": "set", + "epoch": strconv.Itoa(wac.msgCount), + }, + Content: []interface{}{ + binary.Node{ + Description: "profile", + Attributes: map[string]string{ + "name": name, + }, + Content: []binary.Node{}, + }, + }, + } + return wac.writeBinary(n, profile, ignore, tag) +} diff --git a/vendor/github.com/Rhymen/go-whatsapp/read.go b/vendor/github.com/Rhymen/go-whatsapp/read.go new file mode 100644 index 00000000..a69147a6 --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/read.go @@ -0,0 +1,142 @@ +package whatsapp + +import ( + "crypto/hmac" + "crypto/sha256" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "net/http" + "strings" + + "github.com/Rhymen/go-whatsapp/binary" + "github.com/Rhymen/go-whatsapp/crypto/cbc" + "github.com/gorilla/websocket" + "github.com/pkg/errors" +) + +func (wac *Conn) readPump() { + defer func() { + wac.wg.Done() + _, _ = wac.Disconnect() + }() + + var readErr error + var msgType int + var reader io.Reader + + for { + readerFound := make(chan struct{}) + go func() { + if wac.ws != nil { + msgType, reader, readErr = wac.ws.conn.NextReader() + } + close(readerFound) + }() + select { + case <-readerFound: + if readErr != nil { + wac.handle(&ErrConnectionFailed{Err: readErr}) + return + } + msg, err := ioutil.ReadAll(reader) + if err != nil { + wac.handle(errors.Wrap(err, "error reading message from Reader")) + continue + } + err = wac.processReadData(msgType, msg) + if err != nil { + wac.handle(errors.Wrap(err, "error processing data")) + } + case <-wac.ws.close: + return + } + } +} + +func (wac *Conn) processReadData(msgType int, msg []byte) error { + data := strings.SplitN(string(msg), ",", 2) + + if data[0][0] == '!' { //Keep-Alive Timestamp + data = append(data, data[0][1:]) //data[1] + data[0] = "!" + } + + if len(data) == 2 && len(data[1]) == 0 { + return nil + } + + if len(data) != 2 || len(data[1]) == 0 { + return ErrInvalidWsData + } + + wac.listener.RLock() + listener, hasListener := wac.listener.m[data[0]] + wac.listener.RUnlock() + + if hasListener { + // listener only exists for TextMessages query messages out of contact.go + // If these binary query messages can be handled another way, + // then the TextMessages, which are all JSON encoded, can directly + // be unmarshalled. The listener chan could then be changed from type + // chan string to something like chan map[string]interface{}. The unmarshalling + // in several places, especially in session.go, would then be gone. + listener <- data[1] + close(listener) + wac.removeListener(data[0]) + } else if msgType == websocket.BinaryMessage { + wac.loginSessionLock.RLock() + sess := wac.session + wac.loginSessionLock.RUnlock() + if sess == nil || sess.MacKey == nil || sess.EncKey == nil { + return ErrInvalidWsState + } + message, err := wac.decryptBinaryMessage([]byte(data[1])) + if err != nil { + return errors.Wrap(err, "error decoding binary") + } + wac.dispatch(message) + } else { //RAW json status updates + wac.handle(string(data[1])) + } + return nil +} + +func (wac *Conn) decryptBinaryMessage(msg []byte) (*binary.Node, error) { + //message validation + h2 := hmac.New(sha256.New, wac.session.MacKey) + if len(msg) < 33 { + var response struct { + Status int `json:"status"` + } + + if err := json.Unmarshal(msg, &response); err == nil { + if response.Status == http.StatusNotFound { + return nil, ErrServerRespondedWith404 + } + return nil, errors.New(fmt.Sprintf("server responded with %d", response.Status)) + } + + return nil, ErrInvalidServerResponse + + } + h2.Write([]byte(msg[32:])) + if !hmac.Equal(h2.Sum(nil), msg[:32]) { + return nil, ErrInvalidHmac + } + + // message decrypt + d, err := cbc.Decrypt(wac.session.EncKey, nil, msg[32:]) + if err != nil { + return nil, errors.Wrap(err, "decrypting message with AES-CBC failed") + } + + // message unmarshal + message, err := binary.Unmarshal(d) + if err != nil { + return nil, errors.Wrap(err, "could not decode binary") + } + + return message, nil +} diff --git a/vendor/github.com/Rhymen/go-whatsapp/session.go b/vendor/github.com/Rhymen/go-whatsapp/session.go new file mode 100644 index 00000000..215fb599 --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/session.go @@ -0,0 +1,532 @@ +package whatsapp + +import ( + "crypto/hmac" + "crypto/rand" + "crypto/sha256" + "encoding/base64" + "encoding/json" + "fmt" + "strconv" + "strings" + "sync/atomic" + "time" + + "github.com/Rhymen/go-whatsapp/crypto/cbc" + "github.com/Rhymen/go-whatsapp/crypto/curve25519" + "github.com/Rhymen/go-whatsapp/crypto/hkdf" +) + +//represents the WhatsAppWeb client version +var waVersion = []int{2, 2142, 12} + +/* +Session contains session individual information. To be able to resume the connection without scanning the qr code +every time you should save the Session returned by Login and use RestoreWithSession the next time you want to login. +Every successful created connection returns a new Session. The Session(ClientToken, ServerToken) is altered after +every re-login and should be saved every time. +*/ +type Session struct { + ClientId string + ClientToken string + ServerToken string + EncKey []byte + MacKey []byte + Wid string +} + +type Info struct { + Battery int + Platform string + Connected bool + Pushname string + Wid string + Lc string + Phone *PhoneInfo + Plugged bool + Tos int + Lg string + Is24h bool +} + +type PhoneInfo struct { + Mcc string + Mnc string + OsVersion string + DeviceManufacturer string + DeviceModel string + OsBuildNumber string + WaVersion string +} + +func newInfoFromReq(info map[string]interface{}) *Info { + phoneInfo := info["phone"].(map[string]interface{}) + + ret := &Info{ + Battery: int(info["battery"].(float64)), + Platform: info["platform"].(string), + Connected: info["connected"].(bool), + Pushname: info["pushname"].(string), + Wid: info["wid"].(string), + Lc: info["lc"].(string), + Phone: &PhoneInfo{ + phoneInfo["mcc"].(string), + phoneInfo["mnc"].(string), + phoneInfo["os_version"].(string), + phoneInfo["device_manufacturer"].(string), + phoneInfo["device_model"].(string), + phoneInfo["os_build_number"].(string), + phoneInfo["wa_version"].(string), + }, + Plugged: info["plugged"].(bool), + Lg: info["lg"].(string), + Tos: int(info["tos"].(float64)), + } + + if is24h, ok := info["is24h"]; ok { + ret.Is24h = is24h.(bool) + } + + return ret +} + +/* +CheckCurrentServerVersion is based on the login method logic in order to establish the websocket connection and get +the current version from the server with the `admin init` command. This can be very useful for automations in which +you need to quickly perceive new versions (mostly patches) and update your application so it suddenly stops working. +*/ +func CheckCurrentServerVersion() ([]int, error) { + wac, err := NewConn(5 * time.Second) + if err != nil { + return nil, fmt.Errorf("fail to create connection") + } + + clientId := make([]byte, 16) + if _, err = rand.Read(clientId); err != nil { + return nil, fmt.Errorf("error creating random ClientId: %v", err) + } + + b64ClientId := base64.StdEncoding.EncodeToString(clientId) + login := []interface{}{"admin", "init", waVersion, []string{wac.longClientName, wac.shortClientName, wac.clientVersion}, b64ClientId, true} + loginChan, err := wac.writeJson(login) + if err != nil { + return nil, fmt.Errorf("error writing login: %s", err.Error()) + } + + // Retrieve an answer from the websocket + var r string + select { + case r = <-loginChan: + case <-time.After(wac.msgTimeout): + return nil, fmt.Errorf("login connection timed out") + } + + var resp map[string]interface{} + if err = json.Unmarshal([]byte(r), &resp); err != nil { + return nil, fmt.Errorf("error decoding login: %s", err.Error()) + } + + // Take the curr property as X.Y.Z and split it into as int slice + curr := resp["curr"].(string) + currArray := strings.Split(curr, ".") + version := make([]int, len(currArray)) + for i := range version { + version[i], _ = strconv.Atoi(currArray[i]) + } + + return version, nil +} + +/* +SetClientName sets the long and short client names that are sent to WhatsApp when logging in and displayed in the +WhatsApp Web device list. As the values are only sent when logging in, changing them after logging in is not possible. +*/ +func (wac *Conn) SetClientName(long, short string, version string) error { + if wac.session != nil && (wac.session.EncKey != nil || wac.session.MacKey != nil) { + return fmt.Errorf("cannot change client name after logging in") + } + wac.longClientName, wac.shortClientName, wac.clientVersion = long, short, version + return nil +} + +/* +SetClientVersion sets WhatsApp client version +Default value is 0.4.2080 +*/ +func (wac *Conn) SetClientVersion(major int, minor int, patch int) { + waVersion = []int{major, minor, patch} +} + +// GetClientVersion returns WhatsApp client version +func (wac *Conn) GetClientVersion() []int { + return waVersion +} + +/* +Login is the function that creates a new whatsapp session and logs you in. If you do not want to scan the qr code +every time, you should save the returned session and use RestoreWithSession the next time. Login takes a writable channel +as an parameter. This channel is used to push the data represented by the qr code back to the user. The received data +should be displayed as an qr code in a way you prefer. To print a qr code to console you can use: +github.com/Baozisoftware/qrcode-terminal-go Example login procedure: + wac, err := whatsapp.NewConn(5 * time.Second) + if err != nil { + panic(err) + } + + qr := make(chan string) + go func() { + terminal := qrcodeTerminal.New() + terminal.Get(<-qr).Print() + }() + + session, err := wac.Login(qr) + if err != nil { + fmt.Fprintf(os.Stderr, "error during login: %v\n", err) + } + fmt.Printf("login successful, session: %v\n", session) +*/ +func (wac *Conn) Login(qrChan chan<- string) (Session, error) { + session := Session{} + //Makes sure that only a single Login or Restore can happen at the same time + if !atomic.CompareAndSwapUint32(&wac.sessionLock, 0, 1) { + return session, ErrLoginInProgress + } + defer atomic.StoreUint32(&wac.sessionLock, 0) + + if wac.loggedIn { + return session, ErrAlreadyLoggedIn + } + + if err := wac.connect(); err != nil && err != ErrAlreadyConnected { + return session, err + } + + //logged in?!? + if wac.session != nil && (wac.session.EncKey != nil || wac.session.MacKey != nil) { + return session, fmt.Errorf("already logged in") + } + + clientId := make([]byte, 16) + _, err := rand.Read(clientId) + if err != nil { + return session, fmt.Errorf("error creating random ClientId: %v", err) + } + + session.ClientId = base64.StdEncoding.EncodeToString(clientId) + login := []interface{}{"admin", "init", waVersion, []string{wac.longClientName, wac.shortClientName, wac.clientVersion}, session.ClientId, true} + loginChan, err := wac.writeJson(login) + if err != nil { + return session, fmt.Errorf("error writing login: %v\n", err) + } + + var r string + select { + case r = <-loginChan: + case <-time.After(wac.msgTimeout): + return session, fmt.Errorf("login connection timed out") + } + + var resp map[string]interface{} + if err = json.Unmarshal([]byte(r), &resp); err != nil { + return session, fmt.Errorf("error decoding login resp: %v\n", err) + } + + var ref string + if rref, ok := resp["ref"].(string); ok { + ref = rref + } else { + return session, fmt.Errorf("error decoding login resp: invalid resp['ref']\n") + } + + priv, pub, err := curve25519.GenerateKey() + if err != nil { + return session, fmt.Errorf("error generating keys: %v\n", err) + } + + //listener for Login response + s1 := make(chan string, 1) + wac.listener.Lock() + wac.listener.m["s1"] = s1 + wac.listener.Unlock() + + qrChan <- fmt.Sprintf("%v,%v,%v", ref, base64.StdEncoding.EncodeToString(pub[:]), session.ClientId) + + var resp2 []interface{} + select { + case r1 := <-s1: + wac.loginSessionLock.Lock() + defer wac.loginSessionLock.Unlock() + if err := json.Unmarshal([]byte(r1), &resp2); err != nil { + return session, fmt.Errorf("error decoding qr code resp: %v", err) + } + case <-time.After(time.Duration(resp["ttl"].(float64)) * time.Millisecond): + return session, fmt.Errorf("qr code scan timed out") + } + + info := resp2[1].(map[string]interface{}) + + wac.Info = newInfoFromReq(info) + + session.ClientToken = info["clientToken"].(string) + session.ServerToken = info["serverToken"].(string) + session.Wid = info["wid"].(string) + s := info["secret"].(string) + decodedSecret, err := base64.StdEncoding.DecodeString(s) + if err != nil { + return session, fmt.Errorf("error decoding secret: %v", err) + } + + var pubKey [32]byte + copy(pubKey[:], decodedSecret[:32]) + + sharedSecret := curve25519.GenerateSharedSecret(*priv, pubKey) + + hash := sha256.New + + nullKey := make([]byte, 32) + h := hmac.New(hash, nullKey) + h.Write(sharedSecret) + + sharedSecretExtended, err := hkdf.Expand(h.Sum(nil), 80, "") + if err != nil { + return session, fmt.Errorf("hkdf error: %v", err) + } + + //login validation + checkSecret := make([]byte, 112) + copy(checkSecret[:32], decodedSecret[:32]) + copy(checkSecret[32:], decodedSecret[64:]) + h2 := hmac.New(hash, sharedSecretExtended[32:64]) + h2.Write(checkSecret) + if !hmac.Equal(h2.Sum(nil), decodedSecret[32:64]) { + return session, fmt.Errorf("abort login") + } + + keysEncrypted := make([]byte, 96) + copy(keysEncrypted[:16], sharedSecretExtended[64:]) + copy(keysEncrypted[16:], decodedSecret[64:]) + + keyDecrypted, err := cbc.Decrypt(sharedSecretExtended[:32], nil, keysEncrypted) + if err != nil { + return session, fmt.Errorf("error decryptAes: %v", err) + } + + session.EncKey = keyDecrypted[:32] + session.MacKey = keyDecrypted[32:64] + wac.session = &session + wac.loggedIn = true + + return session, nil +} + +//TODO: GoDoc +/* +Basically the old RestoreSession functionality +*/ +func (wac *Conn) RestoreWithSession(session Session) (_ Session, err error) { + if wac.loggedIn { + return Session{}, ErrAlreadyLoggedIn + } + old := wac.session + defer func() { + if err != nil { + wac.session = old + } + }() + wac.session = &session + + if err = wac.Restore(); err != nil { + wac.session = nil + return Session{}, err + } + return *wac.session, nil +} + +/*//TODO: GoDoc +RestoreWithSession is the function that restores a given session. It will try to reestablish the connection to the +WhatsAppWeb servers with the provided session. If it succeeds it will return a new session. This new session has to be +saved because the Client and Server-Token will change after every login. Logging in with old tokens is possible, but not +suggested. If so, a challenge has to be resolved which is just another possible point of failure. +*/ +func (wac *Conn) Restore() error { + //Makes sure that only a single Login or Restore can happen at the same time + if !atomic.CompareAndSwapUint32(&wac.sessionLock, 0, 1) { + return ErrLoginInProgress + } + defer atomic.StoreUint32(&wac.sessionLock, 0) + + if wac.session == nil { + return ErrInvalidSession + } + + if err := wac.connect(); err != nil && err != ErrAlreadyConnected { + return err + } + + if wac.loggedIn { + return ErrAlreadyLoggedIn + } + + //listener for Conn or challenge; s1 is not allowed to drop + s1 := make(chan string, 1) + wac.listener.Lock() + wac.listener.m["s1"] = s1 + wac.listener.Unlock() + + //admin init + init := []interface{}{"admin", "init", waVersion, []string{wac.longClientName, wac.shortClientName, wac.clientVersion}, wac.session.ClientId, true} + initChan, err := wac.writeJson(init) + if err != nil { + return fmt.Errorf("error writing admin init: %v\n", err) + } + + //admin login with takeover + login := []interface{}{"admin", "login", wac.session.ClientToken, wac.session.ServerToken, wac.session.ClientId, "takeover"} + loginChan, err := wac.writeJson(login) + if err != nil { + return fmt.Errorf("error writing admin login: %v\n", err) + } + + select { + case r := <-initChan: + var resp map[string]interface{} + if err = json.Unmarshal([]byte(r), &resp); err != nil { + return fmt.Errorf("error decoding login connResp: %v\n", err) + } + + if int(resp["status"].(float64)) != 200 { + wac.timeTag = "" + return fmt.Errorf("init responded with %d", resp["status"]) + } + case <-time.After(wac.msgTimeout): + wac.timeTag = "" + return fmt.Errorf("restore session init timed out") + } + + //wait for s1 + var connResp []interface{} + select { + case r1 := <-s1: + if err := json.Unmarshal([]byte(r1), &connResp); err != nil { + wac.timeTag = "" + return fmt.Errorf("error decoding s1 message: %v\n", err) + } + case <-time.After(wac.msgTimeout): + wac.timeTag = "" + //check for an error message + select { + case r := <-loginChan: + var resp map[string]interface{} + if err = json.Unmarshal([]byte(r), &resp); err != nil { + return fmt.Errorf("error decoding login connResp: %v\n", err) + } + if int(resp["status"].(float64)) != 200 { + return fmt.Errorf("admin login responded with %d", int(resp["status"].(float64))) + } + default: + // not even an error message – assume timeout + return fmt.Errorf("restore session connection timed out") + } + } + + //check if challenge is present + if len(connResp) == 2 && connResp[0] == "Cmd" && connResp[1].(map[string]interface{})["type"] == "challenge" { + s2 := make(chan string, 1) + wac.listener.Lock() + wac.listener.m["s2"] = s2 + wac.listener.Unlock() + + if err := wac.resolveChallenge(connResp[1].(map[string]interface{})["challenge"].(string)); err != nil { + wac.timeTag = "" + return fmt.Errorf("error resolving challenge: %v\n", err) + } + + select { + case r := <-s2: + if err := json.Unmarshal([]byte(r), &connResp); err != nil { + wac.timeTag = "" + return fmt.Errorf("error decoding s2 message: %v\n", err) + } + case <-time.After(wac.msgTimeout): + wac.timeTag = "" + return fmt.Errorf("restore session challenge timed out") + } + } + + //check for login 200 --> login success + select { + case r := <-loginChan: + var resp map[string]interface{} + if err = json.Unmarshal([]byte(r), &resp); err != nil { + wac.timeTag = "" + return fmt.Errorf("error decoding login connResp: %v\n", err) + } + + if int(resp["status"].(float64)) != 200 { + wac.timeTag = "" + return fmt.Errorf("admin login responded with %d", resp["status"]) + } + case <-time.After(wac.msgTimeout): + wac.timeTag = "" + return fmt.Errorf("restore session login timed out") + } + + info := connResp[1].(map[string]interface{}) + + wac.Info = newInfoFromReq(info) + + //set new tokens + wac.session.ClientToken = info["clientToken"].(string) + wac.session.ServerToken = info["serverToken"].(string) + wac.session.Wid = info["wid"].(string) + wac.loggedIn = true + + return nil +} + +func (wac *Conn) resolveChallenge(challenge string) error { + decoded, err := base64.StdEncoding.DecodeString(challenge) + if err != nil { + return err + } + + h2 := hmac.New(sha256.New, wac.session.MacKey) + h2.Write([]byte(decoded)) + + ch := []interface{}{"admin", "challenge", base64.StdEncoding.EncodeToString(h2.Sum(nil)), wac.session.ServerToken, wac.session.ClientId} + challengeChan, err := wac.writeJson(ch) + if err != nil { + return fmt.Errorf("error writing challenge: %v\n", err) + } + + select { + case r := <-challengeChan: + var resp map[string]interface{} + if err := json.Unmarshal([]byte(r), &resp); err != nil { + return fmt.Errorf("error decoding login resp: %v\n", err) + } + if int(resp["status"].(float64)) != 200 { + return fmt.Errorf("challenge responded with %d\n", resp["status"]) + } + case <-time.After(wac.msgTimeout): + return fmt.Errorf("connection timed out") + } + + return nil +} + +/* +Logout is the function to logout from a WhatsApp session. Logging out means invalidating the current session. +The session can not be resumed and will disappear on your phone in the WhatsAppWeb client list. +*/ +func (wac *Conn) Logout() error { + login := []interface{}{"admin", "Conn", "disconnect"} + _, err := wac.writeJson(login) + if err != nil { + return fmt.Errorf("error writing logout: %v\n", err) + } + + wac.loggedIn = false + + return nil +} diff --git a/vendor/github.com/Rhymen/go-whatsapp/store.go b/vendor/github.com/Rhymen/go-whatsapp/store.go new file mode 100644 index 00000000..994d0581 --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/store.go @@ -0,0 +1,80 @@ +package whatsapp + +import ( + "github.com/Rhymen/go-whatsapp/binary" + "strings" +) + +type Store struct { + Contacts map[string]Contact + Chats map[string]Chat +} + +type Contact struct { + Jid string + Notify string + Name string + Short string +} + +type Chat struct { + Jid string + Name string + Unread string + LastMessageTime string + IsMuted string + IsMarkedSpam string +} + +func newStore() *Store { + return &Store{ + make(map[string]Contact), + make(map[string]Chat), + } +} + +func (wac *Conn) updateContacts(contacts interface{}) { + c, ok := contacts.([]interface{}) + if !ok { + return + } + + for _, contact := range c { + contactNode, ok := contact.(binary.Node) + if !ok { + continue + } + + jid := strings.Replace(contactNode.Attributes["jid"], "@c.us", "@s.whatsapp.net", 1) + wac.Store.Contacts[jid] = Contact{ + jid, + contactNode.Attributes["notify"], + contactNode.Attributes["name"], + contactNode.Attributes["short"], + } + } +} + +func (wac *Conn) updateChats(chats interface{}) { + c, ok := chats.([]interface{}) + if !ok { + return + } + + for _, chat := range c { + chatNode, ok := chat.(binary.Node) + if !ok { + continue + } + + jid := strings.Replace(chatNode.Attributes["jid"], "@c.us", "@s.whatsapp.net", 1) + wac.Store.Chats[jid] = Chat{ + jid, + chatNode.Attributes["name"], + chatNode.Attributes["count"], + chatNode.Attributes["t"], + chatNode.Attributes["mute"], + chatNode.Attributes["spam"], + } + } +} diff --git a/vendor/github.com/Rhymen/go-whatsapp/write.go b/vendor/github.com/Rhymen/go-whatsapp/write.go new file mode 100644 index 00000000..e427825c --- /dev/null +++ b/vendor/github.com/Rhymen/go-whatsapp/write.go @@ -0,0 +1,195 @@ +package whatsapp + +import ( + "crypto/hmac" + "crypto/sha256" + "encoding/json" + "fmt" + "strconv" + + "time" + + "github.com/Rhymen/go-whatsapp/binary" + "github.com/Rhymen/go-whatsapp/crypto/cbc" + "github.com/gorilla/websocket" + "github.com/pkg/errors" +) + +func (wac *Conn) addListener(ch chan string, messageTag string) { + wac.listener.Lock() + wac.listener.m[messageTag] = ch + wac.listener.Unlock() +} + +func (wac *Conn) removeListener(answerMessageTag string) { + wac.listener.Lock() + delete(wac.listener.m, answerMessageTag) + wac.listener.Unlock() +} + +//writeJson enqueues a json message into the writeChan +func (wac *Conn) writeJson(data []interface{}) (<-chan string, error) { + + ch := make(chan string, 1) + + wac.writerLock.Lock() + defer wac.writerLock.Unlock() + + d, err := json.Marshal(data) + if err != nil { + close(ch) + return ch, err + } + + ts := time.Now().Unix() + messageTag := fmt.Sprintf("%d.--%d", ts, wac.msgCount) + bytes := []byte(fmt.Sprintf("%s,%s", messageTag, d)) + + if wac.timeTag == "" { + tss := fmt.Sprintf("%d", ts) + wac.timeTag = tss[len(tss)-3:] + } + + wac.addListener(ch, messageTag) + + err = wac.write(websocket.TextMessage, bytes) + if err != nil { + close(ch) + wac.removeListener(messageTag) + return ch, err + } + + wac.msgCount++ + return ch, nil +} + +func (wac *Conn) writeBinary(node binary.Node, metric metric, flag flag, messageTag string) (<-chan string, error) { + + ch := make(chan string, 1) + + if len(messageTag) < 2 { + close(ch) + return ch, ErrMissingMessageTag + } + + wac.writerLock.Lock() + defer wac.writerLock.Unlock() + + data, err := wac.encryptBinaryMessage(node) + if err != nil { + close(ch) + return ch, errors.Wrap(err, "encryptBinaryMessage(node) failed") + } + + bytes := []byte(messageTag + ",") + bytes = append(bytes, byte(metric), byte(flag)) + bytes = append(bytes, data...) + + wac.addListener(ch, messageTag) + + err = wac.write(websocket.BinaryMessage, bytes) + if err != nil { + close(ch) + wac.removeListener(messageTag) + return ch, errors.Wrap(err, "failed to write message") + } + + wac.msgCount++ + return ch, nil +} + +func (wac *Conn) sendKeepAlive() error { + + respChan := make(chan string, 1) + wac.addListener(respChan, "!") + + bytes := []byte("?,,") + err := wac.write(websocket.TextMessage, bytes) + if err != nil { + close(respChan) + wac.removeListener("!") + return errors.Wrap(err, "error sending keepAlive") + } + + select { + case resp := <-respChan: + msecs, err := strconv.ParseInt(resp, 10, 64) + if err != nil { + return errors.Wrap(err, "Error converting time string to uint") + } + wac.ServerLastSeen = time.Unix(msecs/1000, (msecs%1000)*int64(time.Millisecond)) + + case <-time.After(wac.msgTimeout): + return ErrConnectionTimeout + } + + return nil +} + +/* + When phone is unreachable, WhatsAppWeb sends ["admin","test"] time after time to try a successful contact. + Tested with Airplane mode and no connection at all. +*/ +func (wac *Conn) sendAdminTest() (bool, error) { + data := []interface{}{"admin", "test"} + + r, err := wac.writeJson(data) + if err != nil { + return false, errors.Wrap(err, "error sending admin test") + } + + var response []interface{} + + select { + case resp := <-r: + if err := json.Unmarshal([]byte(resp), &response); err != nil { + return false, fmt.Errorf("error decoding response message: %v\n", err) + } + case <-time.After(wac.msgTimeout): + return false, ErrConnectionTimeout + } + + if len(response) == 2 && response[0].(string) == "Pong" && response[1].(bool) == true { + return true, nil + } else { + return false, nil + } +} + +func (wac *Conn) write(messageType int, data []byte) error { + + if wac == nil || wac.ws == nil { + return ErrInvalidWebsocket + } + + wac.ws.Lock() + err := wac.ws.conn.WriteMessage(messageType, data) + wac.ws.Unlock() + + if err != nil { + return errors.Wrap(err, "error writing to websocket") + } + + return nil +} + +func (wac *Conn) encryptBinaryMessage(node binary.Node) (data []byte, err error) { + b, err := binary.Marshal(node) + if err != nil { + return nil, errors.Wrap(err, "binary node marshal failed") + } + + cipher, err := cbc.Encrypt(wac.session.EncKey, nil, b) + if err != nil { + return nil, errors.Wrap(err, "encrypt failed") + } + + h := hmac.New(sha256.New, wac.session.MacKey) + h.Write(cipher) + hash := h.Sum(nil) + + data = append(data, hash[:32]...) + data = append(data, cipher...) + + return data, nil +} diff --git a/vendor/github.com/skip2/go-qrcode/.gitignore b/vendor/github.com/skip2/go-qrcode/.gitignore new file mode 100644 index 00000000..bc1be2bb --- /dev/null +++ b/vendor/github.com/skip2/go-qrcode/.gitignore @@ -0,0 +1,4 @@ +*.sw* +*.png +*.directory +qrcode/qrcode diff --git a/vendor/github.com/skip2/go-qrcode/.travis.yml b/vendor/github.com/skip2/go-qrcode/.travis.yml new file mode 100644 index 00000000..7ced8fb1 --- /dev/null +++ b/vendor/github.com/skip2/go-qrcode/.travis.yml @@ -0,0 +1,8 @@ +language: go + +go: + - 1.7 + +script: + - go test -v ./... + diff --git a/vendor/github.com/skip2/go-qrcode/LICENSE b/vendor/github.com/skip2/go-qrcode/LICENSE new file mode 100644 index 00000000..342c5e5a --- /dev/null +++ b/vendor/github.com/skip2/go-qrcode/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2014 Tom Harwood + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/github.com/skip2/go-qrcode/README.md b/vendor/github.com/skip2/go-qrcode/README.md new file mode 100644 index 00000000..8281ed3e --- /dev/null +++ b/vendor/github.com/skip2/go-qrcode/README.md @@ -0,0 +1,80 @@ +# go-qrcode # + + + +Package qrcode implements a QR Code encoder. [![Build Status](https://travis-ci.org/skip2/go-qrcode.svg?branch=master)](https://travis-ci.org/skip2/go-qrcode) + +A QR Code is a matrix (two-dimensional) barcode. Arbitrary content may be encoded, with URLs being a popular choice :) + +Each QR Code contains error recovery information to aid reading damaged or obscured codes. There are four levels of error recovery: Low, medium, high and highest. QR Codes with a higher recovery level are more robust to damage, at the cost of being physically larger. + +## Install + + go get -u github.com/skip2/go-qrcode/... + +A command-line tool `qrcode` will be built into `$GOPATH/bin/`. + +## Usage + + import qrcode "github.com/skip2/go-qrcode" + +- **Create a PNG image:** + + var png []byte + png, err := qrcode.Encode("https://example.org", qrcode.Medium, 256) + +- **Create a PNG image and write to a file:** + + err := qrcode.WriteFile("https://example.org", qrcode.Medium, 256, "qr.png") + +- **Create a PNG image with custom colors and write to file:** + + err := qrcode.WriteColorFile("https://example.org", qrcode.Medium, 256, color.Black, color.White, "qr.png") + +All examples use the qrcode.Medium error Recovery Level and create a fixed +256x256px size QR Code. The last function creates a white on black instead of black +on white QR Code. + +The maximum capacity of a QR Code varies according to the content encoded and +the error recovery level. The maximum capacity is 2,953 bytes, 4,296 +alphanumeric characters, 7,089 numeric digits, or a combination of these. + +## Documentation + +[![godoc](https://godoc.org/github.com/skip2/go-qrcode?status.png)](https://godoc.org/github.com/skip2/go-qrcode) + +## Demoapp + +[http://go-qrcode.appspot.com](http://go-qrcode.appspot.com) + +## CLI + +A command-line tool `qrcode` will be built into `$GOPATH/bin/`. + +``` +qrcode -- QR Code encoder in Go +https://github.com/skip2/go-qrcode + +Flags: + -o string + out PNG file prefix, empty for stdout + -s int + image size (pixel) (default 256) + +Usage: + 1. Arguments except for flags are joined by " " and used to generate QR code. + Default output is STDOUT, pipe to imagemagick command "display" to display + on any X server. + + qrcode hello word | display + + 2. Save to file if "display" not available: + + qrcode "homepage: https://github.com/skip2/go-qrcode" > out.png +``` + +## Links + +- [http://en.wikipedia.org/wiki/QR_code](http://en.wikipedia.org/wiki/QR_code) +- [ISO/IEC 18004:2006](http://www.iso.org/iso/catalogue_detail.htm?csnumber=43655) - Main QR Code specification (approx CHF 198,00)
+- [https://github.com/qpliu/qrencode-go/](https://github.com/qpliu/qrencode-go/) - alternative Go QR encoding library based on [ZXing](https://github.com/zxing/zxing) diff --git a/vendor/github.com/skip2/go-qrcode/bitset/bitset.go b/vendor/github.com/skip2/go-qrcode/bitset/bitset.go new file mode 100644 index 00000000..fba3bf4d --- /dev/null +++ b/vendor/github.com/skip2/go-qrcode/bitset/bitset.go @@ -0,0 +1,273 @@ +// go-qrcode +// Copyright 2014 Tom Harwood + +// Package bitset implements an append only bit array. +// +// To create a Bitset and append some bits: +// // Bitset Contents +// b := bitset.New() // {} +// b.AppendBools(true, true, false) // {1, 1, 0} +// b.AppendBools(true) // {1, 1, 0, 1} +// b.AppendValue(0x02, 4) // {1, 1, 0, 1, 0, 0, 1, 0} +// +// To read values: +// +// len := b.Len() // 8 +// v := b.At(0) // 1 +// v = b.At(1) // 1 +// v = b.At(2) // 0 +// v = b.At(8) // 0 +package bitset + +import ( + "bytes" + "fmt" + "log" +) + +const ( + b0 = false + b1 = true +) + +// Bitset stores an array of bits. +type Bitset struct { + // The number of bits stored. + numBits int + + // Storage for individual bits. + bits []byte +} + +// New returns an initialised Bitset with optional initial bits v. +func New(v ...bool) *Bitset { + b := &Bitset{numBits: 0, bits: make([]byte, 0)} + b.AppendBools(v...) + + return b +} + +// Clone returns a copy. +func Clone(from *Bitset) *Bitset { + return &Bitset{numBits: from.numBits, bits: from.bits[:]} +} + +// Substr returns a substring, consisting of the bits from indexes start to end. +func (b *Bitset) Substr(start int, end int) *Bitset { + if start > end || end > b.numBits { + log.Panicf("Out of range start=%d end=%d numBits=%d", start, end, b.numBits) + } + + result := New() + result.ensureCapacity(end - start) + + for i := start; i < end; i++ { + if b.At(i) { + result.bits[result.numBits/8] |= 0x80 >> uint(result.numBits%8) + } + result.numBits++ + } + + return result +} + +// NewFromBase2String constructs and returns a Bitset from a string. The string +// consists of '1', '0' or ' ' characters, e.g. "1010 0101". The '1' and '0' +// characters represent true/false bits respectively, and ' ' characters are +// ignored. +// +// The function panics if the input string contains other characters. +func NewFromBase2String(b2string string) *Bitset { + b := &Bitset{numBits: 0, bits: make([]byte, 0)} + + for _, c := range b2string { + switch c { + case '1': + b.AppendBools(true) + case '0': + b.AppendBools(false) + case ' ': + default: + log.Panicf("Invalid char %c in NewFromBase2String", c) + } + } + + return b +} + +// AppendBytes appends a list of whole bytes. +func (b *Bitset) AppendBytes(data []byte) { + for _, d := range data { + b.AppendByte(d, 8) + } +} + +// AppendByte appends the numBits least significant bits from value. +func (b *Bitset) AppendByte(value byte, numBits int) { + b.ensureCapacity(numBits) + + if numBits > 8 { + log.Panicf("numBits %d out of range 0-8", numBits) + } + + for i := numBits - 1; i >= 0; i-- { + if value&(1<> uint(b.numBits%8) + } + + b.numBits++ + } +} + +// AppendUint32 appends the numBits least significant bits from value. +func (b *Bitset) AppendUint32(value uint32, numBits int) { + b.ensureCapacity(numBits) + + if numBits > 32 { + log.Panicf("numBits %d out of range 0-32", numBits) + } + + for i := numBits - 1; i >= 0; i-- { + if value&(1<> uint(b.numBits%8) + } + + b.numBits++ + } +} + +// ensureCapacity ensures the Bitset can store an additional |numBits|. +// +// The underlying array is expanded if necessary. To prevent frequent +// reallocation, expanding the underlying array at least doubles its capacity. +func (b *Bitset) ensureCapacity(numBits int) { + numBits += b.numBits + + newNumBytes := numBits / 8 + if numBits%8 != 0 { + newNumBytes++ + } + + if len(b.bits) >= newNumBytes { + return + } + + b.bits = append(b.bits, make([]byte, newNumBytes+2*len(b.bits))...) +} + +// Append bits copied from |other|. +// +// The new length is b.Len() + other.Len(). +func (b *Bitset) Append(other *Bitset) { + b.ensureCapacity(other.numBits) + + for i := 0; i < other.numBits; i++ { + if other.At(i) { + b.bits[b.numBits/8] |= 0x80 >> uint(b.numBits%8) + } + b.numBits++ + } +} + +// AppendBools appends bits to the Bitset. +func (b *Bitset) AppendBools(bits ...bool) { + b.ensureCapacity(len(bits)) + + for _, v := range bits { + if v { + b.bits[b.numBits/8] |= 0x80 >> uint(b.numBits%8) + } + b.numBits++ + } +} + +// AppendNumBools appends num bits of value value. +func (b *Bitset) AppendNumBools(num int, value bool) { + for i := 0; i < num; i++ { + b.AppendBools(value) + } +} + +// String returns a human readable representation of the Bitset's contents. +func (b *Bitset) String() string { + var bitString string + for i := 0; i < b.numBits; i++ { + if (i % 8) == 0 { + bitString += " " + } + + if (b.bits[i/8] & (0x80 >> byte(i%8))) != 0 { + bitString += "1" + } else { + bitString += "0" + } + } + + return fmt.Sprintf("numBits=%d, bits=%s", b.numBits, bitString) +} + +// Len returns the length of the Bitset in bits. +func (b *Bitset) Len() int { + return b.numBits +} + +// Bits returns the contents of the Bitset. +func (b *Bitset) Bits() []bool { + result := make([]bool, b.numBits) + + var i int + for i = 0; i < b.numBits; i++ { + result[i] = (b.bits[i/8] & (0x80 >> byte(i%8))) != 0 + } + + return result +} + +// At returns the value of the bit at |index|. +func (b *Bitset) At(index int) bool { + if index >= b.numBits { + log.Panicf("Index %d out of range", index) + } + + return (b.bits[index/8] & (0x80 >> byte(index%8))) != 0 +} + +// Equals returns true if the Bitset equals other. +func (b *Bitset) Equals(other *Bitset) bool { + if b.numBits != other.numBits { + return false + } + + if !bytes.Equal(b.bits[0:b.numBits/8], other.bits[0:b.numBits/8]) { + return false + } + + for i := 8 * (b.numBits / 8); i < b.numBits; i++ { + a := (b.bits[i/8] & (0x80 >> byte(i%8))) + b := (other.bits[i/8] & (0x80 >> byte(i%8))) + + if a != b { + return false + } + } + + return true +} + +// ByteAt returns a byte consisting of upto 8 bits starting at index. +func (b *Bitset) ByteAt(index int) byte { + if index < 0 || index >= b.numBits { + log.Panicf("Index %d out of range", index) + } + + var result byte + + for i := index; i < index+8 && i < b.numBits; i++ { + result <<= 1 + if b.At(i) { + result |= 1 + } + } + + return result +} diff --git a/vendor/github.com/skip2/go-qrcode/encoder.go b/vendor/github.com/skip2/go-qrcode/encoder.go new file mode 100644 index 00000000..713378c0 --- /dev/null +++ b/vendor/github.com/skip2/go-qrcode/encoder.go @@ -0,0 +1,455 @@ +// go-qrcode +// Copyright 2014 Tom Harwood + +package qrcode + +import ( + "errors" + "log" + + bitset "github.com/skip2/go-qrcode/bitset" +) + +// Data encoding. +// +// The main data portion of a QR Code consists of one or more segments of data. +// A segment consists of: +// +// - The segment Data Mode: numeric, alphanumeric, or byte. +// - The length of segment in bits. +// - Encoded data. +// +// For example, the string "123ZZ#!#!" may be represented as: +// +// [numeric, 3, "123"] [alphanumeric, 2, "ZZ"] [byte, 4, "#!#!"] +// +// Multiple data modes exist to minimise the size of encoded data. For example, +// 8-bit bytes require 8 bits to encode each, but base 10 numeric data can be +// encoded at a higher density of 3 numbers (e.g. 123) per 10 bits. +// +// Some data can be represented in multiple modes. Numeric data can be +// represented in all three modes, whereas alphanumeric data (e.g. 'A') can be +// represented in alphanumeric and byte mode. +// +// Starting a new segment (to use a different Data Mode) has a cost, the bits to +// state the new segment Data Mode and length. To minimise each QR Code's symbol +// size, an optimisation routine coalesces segment types where possible, to +// reduce the encoded data length. +// +// There are several other data modes available (e.g. Kanji mode) which are not +// implemented here. + +// A segment encoding mode. +type dataMode uint8 + +const ( + // Each dataMode is a subset of the subsequent dataMode: + // dataModeNone < dataModeNumeric < dataModeAlphanumeric < dataModeByte + // + // This ordering is important for determining which data modes a character can + // be encoded with. E.g. 'E' can be encoded in both dataModeAlphanumeric and + // dataModeByte. + dataModeNone dataMode = 1 << iota + dataModeNumeric + dataModeAlphanumeric + dataModeByte +) + +// dataModeString returns d as a short printable string. +func dataModeString(d dataMode) string { + switch d { + case dataModeNone: + return "none" + case dataModeNumeric: + return "numeric" + case dataModeAlphanumeric: + return "alphanumeric" + case dataModeByte: + return "byte" + } + + return "unknown" +} + +type dataEncoderType uint8 + +const ( + dataEncoderType1To9 dataEncoderType = iota + dataEncoderType10To26 + dataEncoderType27To40 +) + +// segment is a single segment of data. +type segment struct { + // Data Mode (e.g. numeric). + dataMode dataMode + + // segment data (e.g. "abc"). + data []byte +} + +// A dataEncoder encodes data for a particular QR Code version. +type dataEncoder struct { + // Minimum & maximum versions supported. + minVersion int + maxVersion int + + // Mode indicator bit sequences. + numericModeIndicator *bitset.Bitset + alphanumericModeIndicator *bitset.Bitset + byteModeIndicator *bitset.Bitset + + // Character count lengths. + numNumericCharCountBits int + numAlphanumericCharCountBits int + numByteCharCountBits int + + // The raw input data. + data []byte + + // The data classified into unoptimised segments. + actual []segment + + // The data classified into optimised segments. + optimised []segment +} + +// newDataEncoder constructs a dataEncoder. +func newDataEncoder(t dataEncoderType) *dataEncoder { + d := &dataEncoder{} + + switch t { + case dataEncoderType1To9: + d = &dataEncoder{ + minVersion: 1, + maxVersion: 9, + numericModeIndicator: bitset.New(b0, b0, b0, b1), + alphanumericModeIndicator: bitset.New(b0, b0, b1, b0), + byteModeIndicator: bitset.New(b0, b1, b0, b0), + numNumericCharCountBits: 10, + numAlphanumericCharCountBits: 9, + numByteCharCountBits: 8, + } + case dataEncoderType10To26: + d = &dataEncoder{ + minVersion: 10, + maxVersion: 26, + numericModeIndicator: bitset.New(b0, b0, b0, b1), + alphanumericModeIndicator: bitset.New(b0, b0, b1, b0), + byteModeIndicator: bitset.New(b0, b1, b0, b0), + numNumericCharCountBits: 12, + numAlphanumericCharCountBits: 11, + numByteCharCountBits: 16, + } + case dataEncoderType27To40: + d = &dataEncoder{ + minVersion: 27, + maxVersion: 40, + numericModeIndicator: bitset.New(b0, b0, b0, b1), + alphanumericModeIndicator: bitset.New(b0, b0, b1, b0), + byteModeIndicator: bitset.New(b0, b1, b0, b0), + numNumericCharCountBits: 14, + numAlphanumericCharCountBits: 13, + numByteCharCountBits: 16, + } + default: + log.Panic("Unknown dataEncoderType") + } + + return d +} + +// encode data as one or more segments and return the encoded data. +// +// The returned data does not include the terminator bit sequence. +func (d *dataEncoder) encode(data []byte) (*bitset.Bitset, error) { + d.data = data + d.actual = nil + d.optimised = nil + + if len(data) == 0 { + return nil, errors.New("no data to encode") + } + + // Classify data into unoptimised segments. + d.classifyDataModes() + + // Optimise segments. + err := d.optimiseDataModes() + if err != nil { + return nil, err + } + + // Encode data. + encoded := bitset.New() + for _, s := range d.optimised { + d.encodeDataRaw(s.data, s.dataMode, encoded) + } + + return encoded, nil +} + +// classifyDataModes classifies the raw data into unoptimised segments. +// e.g. "123ZZ#!#!" => +// [numeric, 3, "123"] [alphanumeric, 2, "ZZ"] [byte, 4, "#!#!"]. +func (d *dataEncoder) classifyDataModes() { + var start int + mode := dataModeNone + + for i, v := range d.data { + newMode := dataModeNone + switch { + case v >= 0x30 && v <= 0x39: + newMode = dataModeNumeric + case v == 0x20 || v == 0x24 || v == 0x25 || v == 0x2a || v == 0x2b || v == + 0x2d || v == 0x2e || v == 0x2f || v == 0x3a || (v >= 0x41 && v <= 0x5a): + newMode = dataModeAlphanumeric + default: + newMode = dataModeByte + } + + if newMode != mode { + if i > 0 { + d.actual = append(d.actual, segment{dataMode: mode, data: d.data[start:i]}) + + start = i + } + + mode = newMode + } + } + + d.actual = append(d.actual, segment{dataMode: mode, data: d.data[start:len(d.data)]}) +} + +// optimiseDataModes optimises the list of segments to reduce the overall output +// encoded data length. +// +// The algorithm coalesces adjacent segments. segments are only coalesced when +// the Data Modes are compatible, and when the coalesced segment has a shorter +// encoded length than separate segments. +// +// Multiple segments may be coalesced. For example a string of alternating +// alphanumeric/numeric segments ANANANANA can be optimised to just A. +func (d *dataEncoder) optimiseDataModes() error { + for i := 0; i < len(d.actual); { + mode := d.actual[i].dataMode + numChars := len(d.actual[i].data) + + j := i + 1 + for j < len(d.actual) { + nextNumChars := len(d.actual[j].data) + nextMode := d.actual[j].dataMode + + if nextMode > mode { + break + } + + coalescedLength, err := d.encodedLength(mode, numChars+nextNumChars) + + if err != nil { + return err + } + + seperateLength1, err := d.encodedLength(mode, numChars) + + if err != nil { + return err + } + + seperateLength2, err := d.encodedLength(nextMode, nextNumChars) + + if err != nil { + return err + } + + if coalescedLength < seperateLength1+seperateLength2 { + j++ + numChars += nextNumChars + } else { + break + } + } + + optimised := segment{dataMode: mode, + data: make([]byte, 0, numChars)} + + for k := i; k < j; k++ { + optimised.data = append(optimised.data, d.actual[k].data...) + } + + d.optimised = append(d.optimised, optimised) + + i = j + } + + return nil +} + +// encodeDataRaw encodes data in dataMode. The encoded data is appended to +// encoded. +func (d *dataEncoder) encodeDataRaw(data []byte, dataMode dataMode, encoded *bitset.Bitset) { + modeIndicator := d.modeIndicator(dataMode) + charCountBits := d.charCountBits(dataMode) + + // Append mode indicator. + encoded.Append(modeIndicator) + + // Append character count. + encoded.AppendUint32(uint32(len(data)), charCountBits) + + // Append data. + switch dataMode { + case dataModeNumeric: + for i := 0; i < len(data); i += 3 { + charsRemaining := len(data) - i + + var value uint32 + bitsUsed := 1 + + for j := 0; j < charsRemaining && j < 3; j++ { + value *= 10 + value += uint32(data[i+j] - 0x30) + bitsUsed += 3 + } + encoded.AppendUint32(value, bitsUsed) + } + case dataModeAlphanumeric: + for i := 0; i < len(data); i += 2 { + charsRemaining := len(data) - i + + var value uint32 + for j := 0; j < charsRemaining && j < 2; j++ { + value *= 45 + value += encodeAlphanumericCharacter(data[i+j]) + } + + bitsUsed := 6 + if charsRemaining > 1 { + bitsUsed = 11 + } + + encoded.AppendUint32(value, bitsUsed) + } + case dataModeByte: + for _, b := range data { + encoded.AppendByte(b, 8) + } + } +} + +// modeIndicator returns the segment header bits for a segment of type dataMode. +func (d *dataEncoder) modeIndicator(dataMode dataMode) *bitset.Bitset { + switch dataMode { + case dataModeNumeric: + return d.numericModeIndicator + case dataModeAlphanumeric: + return d.alphanumericModeIndicator + case dataModeByte: + return d.byteModeIndicator + default: + log.Panic("Unknown data mode") + } + + return nil +} + +// charCountBits returns the number of bits used to encode the length of a data +// segment of type dataMode. +func (d *dataEncoder) charCountBits(dataMode dataMode) int { + switch dataMode { + case dataModeNumeric: + return d.numNumericCharCountBits + case dataModeAlphanumeric: + return d.numAlphanumericCharCountBits + case dataModeByte: + return d.numByteCharCountBits + default: + log.Panic("Unknown data mode") + } + + return 0 +} + +// encodedLength returns the number of bits required to encode n symbols in +// dataMode. +// +// The number of bits required is affected by: +// - QR code type - Mode Indicator length. +// - Data mode - number of bits used to represent data length. +// - Data mode - how the data is encoded. +// - Number of symbols encoded. +// +// An error is returned if the mode is not supported, or the length requested is +// too long to be represented. +func (d *dataEncoder) encodedLength(dataMode dataMode, n int) (int, error) { + modeIndicator := d.modeIndicator(dataMode) + charCountBits := d.charCountBits(dataMode) + + if modeIndicator == nil { + return 0, errors.New("mode not supported") + } + + maxLength := (1 << uint8(charCountBits)) - 1 + + if n > maxLength { + return 0, errors.New("length too long to be represented") + } + + length := modeIndicator.Len() + charCountBits + + switch dataMode { + case dataModeNumeric: + length += 10 * (n / 3) + + if n%3 != 0 { + length += 1 + 3*(n%3) + } + case dataModeAlphanumeric: + length += 11 * (n / 2) + length += 6 * (n % 2) + case dataModeByte: + length += 8 * n + } + + return length, nil +} + +// encodeAlphanumericChar returns the QR Code encoded value of v. +// +// v must be a QR Code defined alphanumeric character: 0-9, A-Z, SP, $%*+-./ or +// :. The characters are mapped to values in the range 0-44 respectively. +func encodeAlphanumericCharacter(v byte) uint32 { + c := uint32(v) + + switch { + case c >= '0' && c <= '9': + // 0-9 encoded as 0-9. + return c - '0' + case c >= 'A' && c <= 'Z': + // A-Z encoded as 10-35. + return c - 'A' + 10 + case c == ' ': + return 36 + case c == '$': + return 37 + case c == '%': + return 38 + case c == '*': + return 39 + case c == '+': + return 40 + case c == '-': + return 41 + case c == '.': + return 42 + case c == '/': + return 43 + case c == ':': + return 44 + default: + log.Panicf("encodeAlphanumericCharacter() with non alphanumeric char %v.", v) + } + + return 0 +} diff --git a/vendor/github.com/skip2/go-qrcode/qrcode.go b/vendor/github.com/skip2/go-qrcode/qrcode.go new file mode 100644 index 00000000..9428d863 --- /dev/null +++ b/vendor/github.com/skip2/go-qrcode/qrcode.go @@ -0,0 +1,589 @@ +// go-qrcode +// Copyright 2014 Tom Harwood + +/* +Package qrcode implements a QR Code encoder. + +A QR Code is a matrix (two-dimensional) barcode. Arbitrary content may be +encoded. + +A QR Code contains error recovery information to aid reading damaged or +obscured codes. There are four levels of error recovery: qrcode.{Low, Medium, +High, Highest}. QR Codes with a higher recovery level are more robust to damage, +at the cost of being physically larger. + +Three functions cover most use cases: + +- Create a PNG image: + + var png []byte + png, err := qrcode.Encode("https://example.org", qrcode.Medium, 256) + +- Create a PNG image and write to a file: + + err := qrcode.WriteFile("https://example.org", qrcode.Medium, 256, "qr.png") + +- Create a PNG image with custom colors and write to file: + + err := qrcode.WriteColorFile("https://example.org", qrcode.Medium, 256, color.Black, color.White, "qr.png") + +All examples use the qrcode.Medium error Recovery Level and create a fixed +256x256px size QR Code. The last function creates a white on black instead of black +on white QR Code. + +To generate a variable sized image instead, specify a negative size (in place of +the 256 above), such as -4 or -5. Larger negative numbers create larger images: +A size of -5 sets each module (QR Code "pixel") to be 5px wide/high. + +- Create a PNG image (variable size, with minimum white padding) and write to a file: + + err := qrcode.WriteFile("https://example.org", qrcode.Medium, -5, "qr.png") + +The maximum capacity of a QR Code varies according to the content encoded and +the error recovery level. The maximum capacity is 2,953 bytes, 4,296 +alphanumeric characters, 7,089 numeric digits, or a combination of these. + +This package implements a subset of QR Code 2005, as defined in ISO/IEC +18004:2006. +*/ +package qrcode + +import ( + "bytes" + "errors" + "image" + "image/color" + "image/png" + "io" + "io/ioutil" + "log" + "os" + + bitset "github.com/skip2/go-qrcode/bitset" + reedsolomon "github.com/skip2/go-qrcode/reedsolomon" +) + +// Encode a QR Code and return a raw PNG image. +// +// size is both the image width and height in pixels. If size is too small then +// a larger image is silently returned. Negative values for size cause a +// variable sized image to be returned: See the documentation for Image(). +// +// To serve over HTTP, remember to send a Content-Type: image/png header. +func Encode(content string, level RecoveryLevel, size int) ([]byte, error) { + var q *QRCode + + q, err := New(content, level) + + if err != nil { + return nil, err + } + + return q.PNG(size) +} + +// WriteFile encodes, then writes a QR Code to the given filename in PNG format. +// +// size is both the image width and height in pixels. If size is too small then +// a larger image is silently written. Negative values for size cause a variable +// sized image to be written: See the documentation for Image(). +func WriteFile(content string, level RecoveryLevel, size int, filename string) error { + var q *QRCode + + q, err := New(content, level) + + if err != nil { + return err + } + + return q.WriteFile(size, filename) +} + +// WriteColorFile encodes, then writes a QR Code to the given filename in PNG format. +// With WriteColorFile you can also specify the colors you want to use. +// +// size is both the image width and height in pixels. If size is too small then +// a larger image is silently written. Negative values for size cause a variable +// sized image to be written: See the documentation for Image(). +func WriteColorFile(content string, level RecoveryLevel, size int, background, + foreground color.Color, filename string) error { + + var q *QRCode + + q, err := New(content, level) + + q.BackgroundColor = background + q.ForegroundColor = foreground + + if err != nil { + return err + } + + return q.WriteFile(size, filename) +} + +// A QRCode represents a valid encoded QRCode. +type QRCode struct { + // Original content encoded. + Content string + + // QR Code type. + Level RecoveryLevel + VersionNumber int + + // User settable drawing options. + ForegroundColor color.Color + BackgroundColor color.Color + + encoder *dataEncoder + version qrCodeVersion + + data *bitset.Bitset + symbol *symbol + mask int +} + +// New constructs a QRCode. +// +// var q *qrcode.QRCode +// q, err := qrcode.New("my content", qrcode.Medium) +// +// An error occurs if the content is too long. +func New(content string, level RecoveryLevel) (*QRCode, error) { + encoders := []dataEncoderType{dataEncoderType1To9, dataEncoderType10To26, + dataEncoderType27To40} + + var encoder *dataEncoder + var encoded *bitset.Bitset + var chosenVersion *qrCodeVersion + var err error + + for _, t := range encoders { + encoder = newDataEncoder(t) + encoded, err = encoder.encode([]byte(content)) + + if err != nil { + continue + } + + chosenVersion = chooseQRCodeVersion(level, encoder, encoded.Len()) + + if chosenVersion != nil { + break + } + } + + if err != nil { + return nil, err + } else if chosenVersion == nil { + return nil, errors.New("content too long to encode") + } + + q := &QRCode{ + Content: content, + + Level: level, + VersionNumber: chosenVersion.version, + + ForegroundColor: color.Black, + BackgroundColor: color.White, + + encoder: encoder, + data: encoded, + version: *chosenVersion, + } + + q.encode(chosenVersion.numTerminatorBitsRequired(encoded.Len())) + + return q, nil +} + +func newWithForcedVersion(content string, version int, level RecoveryLevel) (*QRCode, error) { + var encoder *dataEncoder + + switch { + case version >= 1 && version <= 9: + encoder = newDataEncoder(dataEncoderType1To9) + case version >= 10 && version <= 26: + encoder = newDataEncoder(dataEncoderType10To26) + case version >= 27 && version <= 40: + encoder = newDataEncoder(dataEncoderType27To40) + default: + log.Fatalf("Invalid version %d (expected 1-40 inclusive)", version) + } + + var encoded *bitset.Bitset + encoded, err := encoder.encode([]byte(content)) + + if err != nil { + return nil, err + } + + chosenVersion := getQRCodeVersion(level, version) + + if chosenVersion == nil { + return nil, errors.New("cannot find QR Code version") + } + + q := &QRCode{ + Content: content, + + Level: level, + VersionNumber: chosenVersion.version, + + ForegroundColor: color.Black, + BackgroundColor: color.White, + + encoder: encoder, + data: encoded, + version: *chosenVersion, + } + + q.encode(chosenVersion.numTerminatorBitsRequired(encoded.Len())) + + return q, nil +} + +// Bitmap returns the QR Code as a 2D array of 1-bit pixels. +// +// bitmap[y][x] is true if the pixel at (x, y) is set. +// +// The bitmap includes the required "quiet zone" around the QR Code to aid +// decoding. +func (q *QRCode) Bitmap() [][]bool { + return q.symbol.bitmap() +} + +// Image returns the QR Code as an image.Image. +// +// A positive size sets a fixed image width and height (e.g. 256 yields an +// 256x256px image). +// +// Depending on the amount of data encoded, fixed size images can have different +// amounts of padding (white space around the QR Code). As an alternative, a +// variable sized image can be generated instead: +// +// A negative size causes a variable sized image to be returned. The image +// returned is the minimum size required for the QR Code. Choose a larger +// negative number to increase the scale of the image. e.g. a size of -5 causes +// each module (QR Code "pixel") to be 5px in size. +func (q *QRCode) Image(size int) image.Image { + // Minimum pixels (both width and height) required. + realSize := q.symbol.size + + // Variable size support. + if size < 0 { + size = size * -1 * realSize + } + + // Actual pixels available to draw the symbol. Automatically increase the + // image size if it's not large enough. + if size < realSize { + size = realSize + } + + // Size of each module drawn. + pixelsPerModule := size / realSize + + // Center the symbol within the image. + offset := (size - realSize*pixelsPerModule) / 2 + + rect := image.Rectangle{Min: image.Point{0, 0}, Max: image.Point{size, size}} + + // Saves a few bytes to have them in this order + p := color.Palette([]color.Color{q.BackgroundColor, q.ForegroundColor}) + img := image.NewPaletted(rect, p) + fgClr := uint8(img.Palette.Index(q.ForegroundColor)) + + bitmap := q.symbol.bitmap() + for y, row := range bitmap { + for x, v := range row { + if v { + startX := x*pixelsPerModule + offset + startY := y*pixelsPerModule + offset + for i := startX; i < startX+pixelsPerModule; i++ { + for j := startY; j < startY+pixelsPerModule; j++ { + pos := img.PixOffset(i, j) + img.Pix[pos] = fgClr + } + } + } + } + } + + return img +} + +// PNG returns the QR Code as a PNG image. +// +// size is both the image width and height in pixels. If size is too small then +// a larger image is silently returned. Negative values for size cause a +// variable sized image to be returned: See the documentation for Image(). +func (q *QRCode) PNG(size int) ([]byte, error) { + img := q.Image(size) + + encoder := png.Encoder{CompressionLevel: png.BestCompression} + + var b bytes.Buffer + err := encoder.Encode(&b, img) + + if err != nil { + return nil, err + } + + return b.Bytes(), nil +} + +// Write writes the QR Code as a PNG image to io.Writer. +// +// size is both the image width and height in pixels. If size is too small then +// a larger image is silently written. Negative values for size cause a +// variable sized image to be written: See the documentation for Image(). +func (q *QRCode) Write(size int, out io.Writer) error { + var png []byte + + png, err := q.PNG(size) + + if err != nil { + return err + } + _, err = out.Write(png) + return err +} + +// WriteFile writes the QR Code as a PNG image to the specified file. +// +// size is both the image width and height in pixels. If size is too small then +// a larger image is silently written. Negative values for size cause a +// variable sized image to be written: See the documentation for Image(). +func (q *QRCode) WriteFile(size int, filename string) error { + var png []byte + + png, err := q.PNG(size) + + if err != nil { + return err + } + + return ioutil.WriteFile(filename, png, os.FileMode(0644)) +} + +// encode completes the steps required to encode the QR Code. These include +// adding the terminator bits and padding, splitting the data into blocks and +// applying the error correction, and selecting the best data mask. +func (q *QRCode) encode(numTerminatorBits int) { + q.addTerminatorBits(numTerminatorBits) + q.addPadding() + + encoded := q.encodeBlocks() + + const numMasks int = 8 + penalty := 0 + + for mask := 0; mask < numMasks; mask++ { + var s *symbol + var err error + + s, err = buildRegularSymbol(q.version, mask, encoded) + + if err != nil { + log.Panic(err.Error()) + } + + numEmptyModules := s.numEmptyModules() + if numEmptyModules != 0 { + log.Panicf("bug: numEmptyModules is %d (expected 0) (version=%d)", + numEmptyModules, q.VersionNumber) + } + + p := s.penaltyScore() + + //log.Printf("mask=%d p=%3d p1=%3d p2=%3d p3=%3d p4=%d\n", mask, p, s.penalty1(), s.penalty2(), s.penalty3(), s.penalty4()) + + if q.symbol == nil || p < penalty { + q.symbol = s + q.mask = mask + penalty = p + } + } +} + +// addTerminatorBits adds final terminator bits to the encoded data. +// +// The number of terminator bits required is determined when the QR Code version +// is chosen (which itself depends on the length of the data encoded). The +// terminator bits are thus added after the QR Code version +// is chosen, rather than at the data encoding stage. +func (q *QRCode) addTerminatorBits(numTerminatorBits int) { + q.data.AppendNumBools(numTerminatorBits, false) +} + +// encodeBlocks takes the completed (terminated & padded) encoded data, splits +// the data into blocks (as specified by the QR Code version), applies error +// correction to each block, then interleaves the blocks together. +// +// The QR Code's final data sequence is returned. +func (q *QRCode) encodeBlocks() *bitset.Bitset { + // Split into blocks. + type dataBlock struct { + data *bitset.Bitset + ecStartOffset int + } + + block := make([]dataBlock, q.version.numBlocks()) + + start := 0 + end := 0 + blockID := 0 + + for _, b := range q.version.block { + for j := 0; j < b.numBlocks; j++ { + start = end + end = start + b.numDataCodewords*8 + + // Apply error correction to each block. + numErrorCodewords := b.numCodewords - b.numDataCodewords + block[blockID].data = reedsolomon.Encode(q.data.Substr(start, end), numErrorCodewords) + block[blockID].ecStartOffset = end - start + + blockID++ + } + } + + // Interleave the blocks. + + result := bitset.New() + + // Combine data blocks. + working := true + for i := 0; working; i += 8 { + working = false + + for j, b := range block { + if i >= block[j].ecStartOffset { + continue + } + + result.Append(b.data.Substr(i, i+8)) + + working = true + } + } + + // Combine error correction blocks. + working = true + for i := 0; working; i += 8 { + working = false + + for j, b := range block { + offset := i + block[j].ecStartOffset + if offset >= block[j].data.Len() { + continue + } + + result.Append(b.data.Substr(offset, offset+8)) + + working = true + } + } + + // Append remainder bits. + result.AppendNumBools(q.version.numRemainderBits, false) + + return result +} + +// max returns the maximum of a and b. +func max(a int, b int) int { + if a > b { + return a + } + + return b +} + +// addPadding pads the encoded data upto the full length required. +func (q *QRCode) addPadding() { + numDataBits := q.version.numDataBits() + + if q.data.Len() == numDataBits { + return + } + + // Pad to the nearest codeword boundary. + q.data.AppendNumBools(q.version.numBitsToPadToCodeword(q.data.Len()), false) + + // Pad codewords 0b11101100 and 0b00010001. + padding := [2]*bitset.Bitset{ + bitset.New(true, true, true, false, true, true, false, false), + bitset.New(false, false, false, true, false, false, false, true), + } + + // Insert pad codewords alternately. + i := 0 + for numDataBits-q.data.Len() >= 8 { + q.data.Append(padding[i]) + + i = 1 - i // Alternate between 0 and 1. + } + + if q.data.Len() != numDataBits { + log.Panicf("BUG: got len %d, expected %d", q.data.Len(), numDataBits) + } +} + +// ToString produces a multi-line string that forms a QR-code image. +func (q *QRCode) ToString(inverseColor bool) string { + bits := q.Bitmap() + var buf bytes.Buffer + for y := range bits { + for x := range bits[y] { + if bits[y][x] != inverseColor { + buf.WriteString(" ") + } else { + buf.WriteString("β–ˆβ–ˆ") + } + } + buf.WriteString("\n") + } + return buf.String() +} + +// ToSmallString produces a multi-line string that forms a QR-code image, a +// factor two smaller in x and y then ToString. +func (q *QRCode) ToSmallString(inverseColor bool) string { + bits := q.Bitmap() + var buf bytes.Buffer + // if there is an odd number of rows, the last one needs special treatment + for y := 0; y < len(bits)-1; y += 2 { + for x := range bits[y] { + if bits[y][x] == bits[y+1][x] { + if bits[y][x] != inverseColor { + buf.WriteString(" ") + } else { + buf.WriteString("β–ˆ") + } + } else { + if bits[y][x] != inverseColor { + buf.WriteString("β–„") + } else { + buf.WriteString("β–€") + } + } + } + buf.WriteString("\n") + } + // special treatment for the last row if odd + if len(bits)%2 == 1 { + y := len(bits) - 1 + for x := range bits[y] { + if bits[y][x] != inverseColor { + buf.WriteString(" ") + } else { + buf.WriteString("β–€") + } + } + buf.WriteString("\n") + } + return buf.String() +} diff --git a/vendor/github.com/skip2/go-qrcode/reedsolomon/gf2_8.go b/vendor/github.com/skip2/go-qrcode/reedsolomon/gf2_8.go new file mode 100644 index 00000000..6a7003f7 --- /dev/null +++ b/vendor/github.com/skip2/go-qrcode/reedsolomon/gf2_8.go @@ -0,0 +1,387 @@ +// go-qrcode +// Copyright 2014 Tom Harwood + +package reedsolomon + +// Addition, subtraction, multiplication, and division in GF(2^8). +// Operations are performed modulo x^8 + x^4 + x^3 + x^2 + 1. + +// http://en.wikipedia.org/wiki/Finite_field_arithmetic + +import "log" + +const ( + gfZero = gfElement(0) + gfOne = gfElement(1) +) + +var ( + gfExpTable = [256]gfElement{ + /* 0 - 9 */ 1, 2, 4, 8, 16, 32, 64, 128, 29, 58, + /* 10 - 19 */ 116, 232, 205, 135, 19, 38, 76, 152, 45, 90, + /* 20 - 29 */ 180, 117, 234, 201, 143, 3, 6, 12, 24, 48, + /* 30 - 39 */ 96, 192, 157, 39, 78, 156, 37, 74, 148, 53, + /* 40 - 49 */ 106, 212, 181, 119, 238, 193, 159, 35, 70, 140, + /* 50 - 59 */ 5, 10, 20, 40, 80, 160, 93, 186, 105, 210, + /* 60 - 69 */ 185, 111, 222, 161, 95, 190, 97, 194, 153, 47, + /* 70 - 79 */ 94, 188, 101, 202, 137, 15, 30, 60, 120, 240, + /* 80 - 89 */ 253, 231, 211, 187, 107, 214, 177, 127, 254, 225, + /* 90 - 99 */ 223, 163, 91, 182, 113, 226, 217, 175, 67, 134, + /* 100 - 109 */ 17, 34, 68, 136, 13, 26, 52, 104, 208, 189, + /* 110 - 119 */ 103, 206, 129, 31, 62, 124, 248, 237, 199, 147, + /* 120 - 129 */ 59, 118, 236, 197, 151, 51, 102, 204, 133, 23, + /* 130 - 139 */ 46, 92, 184, 109, 218, 169, 79, 158, 33, 66, + /* 140 - 149 */ 132, 21, 42, 84, 168, 77, 154, 41, 82, 164, + /* 150 - 159 */ 85, 170, 73, 146, 57, 114, 228, 213, 183, 115, + /* 160 - 169 */ 230, 209, 191, 99, 198, 145, 63, 126, 252, 229, + /* 170 - 179 */ 215, 179, 123, 246, 241, 255, 227, 219, 171, 75, + /* 180 - 189 */ 150, 49, 98, 196, 149, 55, 110, 220, 165, 87, + /* 190 - 199 */ 174, 65, 130, 25, 50, 100, 200, 141, 7, 14, + /* 200 - 209 */ 28, 56, 112, 224, 221, 167, 83, 166, 81, 162, + /* 210 - 219 */ 89, 178, 121, 242, 249, 239, 195, 155, 43, 86, + /* 220 - 229 */ 172, 69, 138, 9, 18, 36, 72, 144, 61, 122, + /* 230 - 239 */ 244, 245, 247, 243, 251, 235, 203, 139, 11, 22, + /* 240 - 249 */ 44, 88, 176, 125, 250, 233, 207, 131, 27, 54, + /* 250 - 255 */ 108, 216, 173, 71, 142, 1} + + gfLogTable = [256]int{ + /* 0 - 9 */ -1, 0, 1, 25, 2, 50, 26, 198, 3, 223, + /* 10 - 19 */ 51, 238, 27, 104, 199, 75, 4, 100, 224, 14, + /* 20 - 29 */ 52, 141, 239, 129, 28, 193, 105, 248, 200, 8, + /* 30 - 39 */ 76, 113, 5, 138, 101, 47, 225, 36, 15, 33, + /* 40 - 49 */ 53, 147, 142, 218, 240, 18, 130, 69, 29, 181, + /* 50 - 59 */ 194, 125, 106, 39, 249, 185, 201, 154, 9, 120, + /* 60 - 69 */ 77, 228, 114, 166, 6, 191, 139, 98, 102, 221, + /* 70 - 79 */ 48, 253, 226, 152, 37, 179, 16, 145, 34, 136, + /* 80 - 89 */ 54, 208, 148, 206, 143, 150, 219, 189, 241, 210, + /* 90 - 99 */ 19, 92, 131, 56, 70, 64, 30, 66, 182, 163, + /* 100 - 109 */ 195, 72, 126, 110, 107, 58, 40, 84, 250, 133, + /* 110 - 119 */ 186, 61, 202, 94, 155, 159, 10, 21, 121, 43, + /* 120 - 129 */ 78, 212, 229, 172, 115, 243, 167, 87, 7, 112, + /* 130 - 139 */ 192, 247, 140, 128, 99, 13, 103, 74, 222, 237, + /* 140 - 149 */ 49, 197, 254, 24, 227, 165, 153, 119, 38, 184, + /* 150 - 159 */ 180, 124, 17, 68, 146, 217, 35, 32, 137, 46, + /* 160 - 169 */ 55, 63, 209, 91, 149, 188, 207, 205, 144, 135, + /* 170 - 179 */ 151, 178, 220, 252, 190, 97, 242, 86, 211, 171, + /* 180 - 189 */ 20, 42, 93, 158, 132, 60, 57, 83, 71, 109, + /* 190 - 199 */ 65, 162, 31, 45, 67, 216, 183, 123, 164, 118, + /* 200 - 209 */ 196, 23, 73, 236, 127, 12, 111, 246, 108, 161, + /* 210 - 219 */ 59, 82, 41, 157, 85, 170, 251, 96, 134, 177, + /* 220 - 229 */ 187, 204, 62, 90, 203, 89, 95, 176, 156, 169, + /* 230 - 239 */ 160, 81, 11, 245, 22, 235, 122, 117, 44, 215, + /* 240 - 249 */ 79, 174, 213, 233, 230, 231, 173, 232, 116, 214, + /* 250 - 255 */ 244, 234, 168, 80, 88, 175} +) + +// gfElement is an element in GF(2^8). +type gfElement uint8 + +// newGFElement creates and returns a new gfElement. +func newGFElement(data byte) gfElement { + return gfElement(data) +} + +// gfAdd returns a + b. +func gfAdd(a, b gfElement) gfElement { + return a ^ b +} + +// gfSub returns a - b. +// +// Note addition is equivalent to subtraction in GF(2). +func gfSub(a, b gfElement) gfElement { + return a ^ b +} + +// gfMultiply returns a * b. +func gfMultiply(a, b gfElement) gfElement { + if a == gfZero || b == gfZero { + return gfZero + } + + return gfExpTable[(gfLogTable[a]+gfLogTable[b])%255] +} + +// gfDivide returns a / b. +// +// Divide by zero results in a panic. +func gfDivide(a, b gfElement) gfElement { + if a == gfZero { + return gfZero + } else if b == gfZero { + log.Panicln("Divide by zero") + } + + return gfMultiply(a, gfInverse(b)) +} + +// gfInverse returns the multiplicative inverse of a, a^-1. +// +// a * a^-1 = 1 +func gfInverse(a gfElement) gfElement { + if a == gfZero { + log.Panicln("No multiplicative inverse of 0") + } + + return gfExpTable[255-gfLogTable[a]] +} + +// a^i | bits | polynomial | decimal +// -------------------------------------------------------------------------- +// 0 | 000000000 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 0x^2 0x^1 0x^0 | 0 +// a^0 | 000000001 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 1 +// a^1 | 000000010 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 0x^2 1x^1 0x^0 | 2 +// a^2 | 000000100 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 1x^2 0x^1 0x^0 | 4 +// a^3 | 000001000 | 0x^8 0x^7 0x^6 0x^5 0x^4 1x^3 0x^2 0x^1 0x^0 | 8 +// a^4 | 000010000 | 0x^8 0x^7 0x^6 0x^5 1x^4 0x^3 0x^2 0x^1 0x^0 | 16 +// a^5 | 000100000 | 0x^8 0x^7 0x^6 1x^5 0x^4 0x^3 0x^2 0x^1 0x^0 | 32 +// a^6 | 001000000 | 0x^8 0x^7 1x^6 0x^5 0x^4 0x^3 0x^2 0x^1 0x^0 | 64 +// a^7 | 010000000 | 0x^8 1x^7 0x^6 0x^5 0x^4 0x^3 0x^2 0x^1 0x^0 | 128 +// a^8 | 000011101 | 0x^8 0x^7 0x^6 0x^5 1x^4 1x^3 1x^2 0x^1 1x^0 | 29 +// a^9 | 000111010 | 0x^8 0x^7 0x^6 1x^5 1x^4 1x^3 0x^2 1x^1 0x^0 | 58 +// a^10 | 001110100 | 0x^8 0x^7 1x^6 1x^5 1x^4 0x^3 1x^2 0x^1 0x^0 | 116 +// a^11 | 011101000 | 0x^8 1x^7 1x^6 1x^5 0x^4 1x^3 0x^2 0x^1 0x^0 | 232 +// a^12 | 011001101 | 0x^8 1x^7 1x^6 0x^5 0x^4 1x^3 1x^2 0x^1 1x^0 | 205 +// a^13 | 010000111 | 0x^8 1x^7 0x^6 0x^5 0x^4 0x^3 1x^2 1x^1 1x^0 | 135 +// a^14 | 000010011 | 0x^8 0x^7 0x^6 0x^5 1x^4 0x^3 0x^2 1x^1 1x^0 | 19 +// a^15 | 000100110 | 0x^8 0x^7 0x^6 1x^5 0x^4 0x^3 1x^2 1x^1 0x^0 | 38 +// a^16 | 001001100 | 0x^8 0x^7 1x^6 0x^5 0x^4 1x^3 1x^2 0x^1 0x^0 | 76 +// a^17 | 010011000 | 0x^8 1x^7 0x^6 0x^5 1x^4 1x^3 0x^2 0x^1 0x^0 | 152 +// a^18 | 000101101 | 0x^8 0x^7 0x^6 1x^5 0x^4 1x^3 1x^2 0x^1 1x^0 | 45 +// a^19 | 001011010 | 0x^8 0x^7 1x^6 0x^5 1x^4 1x^3 0x^2 1x^1 0x^0 | 90 +// a^20 | 010110100 | 0x^8 1x^7 0x^6 1x^5 1x^4 0x^3 1x^2 0x^1 0x^0 | 180 +// a^21 | 001110101 | 0x^8 0x^7 1x^6 1x^5 1x^4 0x^3 1x^2 0x^1 1x^0 | 117 +// a^22 | 011101010 | 0x^8 1x^7 1x^6 1x^5 0x^4 1x^3 0x^2 1x^1 0x^0 | 234 +// a^23 | 011001001 | 0x^8 1x^7 1x^6 0x^5 0x^4 1x^3 0x^2 0x^1 1x^0 | 201 +// a^24 | 010001111 | 0x^8 1x^7 0x^6 0x^5 0x^4 1x^3 1x^2 1x^1 1x^0 | 143 +// a^25 | 000000011 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 0x^2 1x^1 1x^0 | 3 +// a^26 | 000000110 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 1x^2 1x^1 0x^0 | 6 +// a^27 | 000001100 | 0x^8 0x^7 0x^6 0x^5 0x^4 1x^3 1x^2 0x^1 0x^0 | 12 +// a^28 | 000011000 | 0x^8 0x^7 0x^6 0x^5 1x^4 1x^3 0x^2 0x^1 0x^0 | 24 +// a^29 | 000110000 | 0x^8 0x^7 0x^6 1x^5 1x^4 0x^3 0x^2 0x^1 0x^0 | 48 +// a^30 | 001100000 | 0x^8 0x^7 1x^6 1x^5 0x^4 0x^3 0x^2 0x^1 0x^0 | 96 +// a^31 | 011000000 | 0x^8 1x^7 1x^6 0x^5 0x^4 0x^3 0x^2 0x^1 0x^0 | 192 +// a^32 | 010011101 | 0x^8 1x^7 0x^6 0x^5 1x^4 1x^3 1x^2 0x^1 1x^0 | 157 +// a^33 | 000100111 | 0x^8 0x^7 0x^6 1x^5 0x^4 0x^3 1x^2 1x^1 1x^0 | 39 +// a^34 | 001001110 | 0x^8 0x^7 1x^6 0x^5 0x^4 1x^3 1x^2 1x^1 0x^0 | 78 +// a^35 | 010011100 | 0x^8 1x^7 0x^6 0x^5 1x^4 1x^3 1x^2 0x^1 0x^0 | 156 +// a^36 | 000100101 | 0x^8 0x^7 0x^6 1x^5 0x^4 0x^3 1x^2 0x^1 1x^0 | 37 +// a^37 | 001001010 | 0x^8 0x^7 1x^6 0x^5 0x^4 1x^3 0x^2 1x^1 0x^0 | 74 +// a^38 | 010010100 | 0x^8 1x^7 0x^6 0x^5 1x^4 0x^3 1x^2 0x^1 0x^0 | 148 +// a^39 | 000110101 | 0x^8 0x^7 0x^6 1x^5 1x^4 0x^3 1x^2 0x^1 1x^0 | 53 +// a^40 | 001101010 | 0x^8 0x^7 1x^6 1x^5 0x^4 1x^3 0x^2 1x^1 0x^0 | 106 +// a^41 | 011010100 | 0x^8 1x^7 1x^6 0x^5 1x^4 0x^3 1x^2 0x^1 0x^0 | 212 +// a^42 | 010110101 | 0x^8 1x^7 0x^6 1x^5 1x^4 0x^3 1x^2 0x^1 1x^0 | 181 +// a^43 | 001110111 | 0x^8 0x^7 1x^6 1x^5 1x^4 0x^3 1x^2 1x^1 1x^0 | 119 +// a^44 | 011101110 | 0x^8 1x^7 1x^6 1x^5 0x^4 1x^3 1x^2 1x^1 0x^0 | 238 +// a^45 | 011000001 | 0x^8 1x^7 1x^6 0x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 193 +// a^46 | 010011111 | 0x^8 1x^7 0x^6 0x^5 1x^4 1x^3 1x^2 1x^1 1x^0 | 159 +// a^47 | 000100011 | 0x^8 0x^7 0x^6 1x^5 0x^4 0x^3 0x^2 1x^1 1x^0 | 35 +// a^48 | 001000110 | 0x^8 0x^7 1x^6 0x^5 0x^4 0x^3 1x^2 1x^1 0x^0 | 70 +// a^49 | 010001100 | 0x^8 1x^7 0x^6 0x^5 0x^4 1x^3 1x^2 0x^1 0x^0 | 140 +// a^50 | 000000101 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 1x^2 0x^1 1x^0 | 5 +// a^51 | 000001010 | 0x^8 0x^7 0x^6 0x^5 0x^4 1x^3 0x^2 1x^1 0x^0 | 10 +// a^52 | 000010100 | 0x^8 0x^7 0x^6 0x^5 1x^4 0x^3 1x^2 0x^1 0x^0 | 20 +// a^53 | 000101000 | 0x^8 0x^7 0x^6 1x^5 0x^4 1x^3 0x^2 0x^1 0x^0 | 40 +// a^54 | 001010000 | 0x^8 0x^7 1x^6 0x^5 1x^4 0x^3 0x^2 0x^1 0x^0 | 80 +// a^55 | 010100000 | 0x^8 1x^7 0x^6 1x^5 0x^4 0x^3 0x^2 0x^1 0x^0 | 160 +// a^56 | 001011101 | 0x^8 0x^7 1x^6 0x^5 1x^4 1x^3 1x^2 0x^1 1x^0 | 93 +// a^57 | 010111010 | 0x^8 1x^7 0x^6 1x^5 1x^4 1x^3 0x^2 1x^1 0x^0 | 186 +// a^58 | 001101001 | 0x^8 0x^7 1x^6 1x^5 0x^4 1x^3 0x^2 0x^1 1x^0 | 105 +// a^59 | 011010010 | 0x^8 1x^7 1x^6 0x^5 1x^4 0x^3 0x^2 1x^1 0x^0 | 210 +// a^60 | 010111001 | 0x^8 1x^7 0x^6 1x^5 1x^4 1x^3 0x^2 0x^1 1x^0 | 185 +// a^61 | 001101111 | 0x^8 0x^7 1x^6 1x^5 0x^4 1x^3 1x^2 1x^1 1x^0 | 111 +// a^62 | 011011110 | 0x^8 1x^7 1x^6 0x^5 1x^4 1x^3 1x^2 1x^1 0x^0 | 222 +// a^63 | 010100001 | 0x^8 1x^7 0x^6 1x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 161 +// a^64 | 001011111 | 0x^8 0x^7 1x^6 0x^5 1x^4 1x^3 1x^2 1x^1 1x^0 | 95 +// a^65 | 010111110 | 0x^8 1x^7 0x^6 1x^5 1x^4 1x^3 1x^2 1x^1 0x^0 | 190 +// a^66 | 001100001 | 0x^8 0x^7 1x^6 1x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 97 +// a^67 | 011000010 | 0x^8 1x^7 1x^6 0x^5 0x^4 0x^3 0x^2 1x^1 0x^0 | 194 +// a^68 | 010011001 | 0x^8 1x^7 0x^6 0x^5 1x^4 1x^3 0x^2 0x^1 1x^0 | 153 +// a^69 | 000101111 | 0x^8 0x^7 0x^6 1x^5 0x^4 1x^3 1x^2 1x^1 1x^0 | 47 +// a^70 | 001011110 | 0x^8 0x^7 1x^6 0x^5 1x^4 1x^3 1x^2 1x^1 0x^0 | 94 +// a^71 | 010111100 | 0x^8 1x^7 0x^6 1x^5 1x^4 1x^3 1x^2 0x^1 0x^0 | 188 +// a^72 | 001100101 | 0x^8 0x^7 1x^6 1x^5 0x^4 0x^3 1x^2 0x^1 1x^0 | 101 +// a^73 | 011001010 | 0x^8 1x^7 1x^6 0x^5 0x^4 1x^3 0x^2 1x^1 0x^0 | 202 +// a^74 | 010001001 | 0x^8 1x^7 0x^6 0x^5 0x^4 1x^3 0x^2 0x^1 1x^0 | 137 +// a^75 | 000001111 | 0x^8 0x^7 0x^6 0x^5 0x^4 1x^3 1x^2 1x^1 1x^0 | 15 +// a^76 | 000011110 | 0x^8 0x^7 0x^6 0x^5 1x^4 1x^3 1x^2 1x^1 0x^0 | 30 +// a^77 | 000111100 | 0x^8 0x^7 0x^6 1x^5 1x^4 1x^3 1x^2 0x^1 0x^0 | 60 +// a^78 | 001111000 | 0x^8 0x^7 1x^6 1x^5 1x^4 1x^3 0x^2 0x^1 0x^0 | 120 +// a^79 | 011110000 | 0x^8 1x^7 1x^6 1x^5 1x^4 0x^3 0x^2 0x^1 0x^0 | 240 +// a^80 | 011111101 | 0x^8 1x^7 1x^6 1x^5 1x^4 1x^3 1x^2 0x^1 1x^0 | 253 +// a^81 | 011100111 | 0x^8 1x^7 1x^6 1x^5 0x^4 0x^3 1x^2 1x^1 1x^0 | 231 +// a^82 | 011010011 | 0x^8 1x^7 1x^6 0x^5 1x^4 0x^3 0x^2 1x^1 1x^0 | 211 +// a^83 | 010111011 | 0x^8 1x^7 0x^6 1x^5 1x^4 1x^3 0x^2 1x^1 1x^0 | 187 +// a^84 | 001101011 | 0x^8 0x^7 1x^6 1x^5 0x^4 1x^3 0x^2 1x^1 1x^0 | 107 +// a^85 | 011010110 | 0x^8 1x^7 1x^6 0x^5 1x^4 0x^3 1x^2 1x^1 0x^0 | 214 +// a^86 | 010110001 | 0x^8 1x^7 0x^6 1x^5 1x^4 0x^3 0x^2 0x^1 1x^0 | 177 +// a^87 | 001111111 | 0x^8 0x^7 1x^6 1x^5 1x^4 1x^3 1x^2 1x^1 1x^0 | 127 +// a^88 | 011111110 | 0x^8 1x^7 1x^6 1x^5 1x^4 1x^3 1x^2 1x^1 0x^0 | 254 +// a^89 | 011100001 | 0x^8 1x^7 1x^6 1x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 225 +// a^90 | 011011111 | 0x^8 1x^7 1x^6 0x^5 1x^4 1x^3 1x^2 1x^1 1x^0 | 223 +// a^91 | 010100011 | 0x^8 1x^7 0x^6 1x^5 0x^4 0x^3 0x^2 1x^1 1x^0 | 163 +// a^92 | 001011011 | 0x^8 0x^7 1x^6 0x^5 1x^4 1x^3 0x^2 1x^1 1x^0 | 91 +// a^93 | 010110110 | 0x^8 1x^7 0x^6 1x^5 1x^4 0x^3 1x^2 1x^1 0x^0 | 182 +// a^94 | 001110001 | 0x^8 0x^7 1x^6 1x^5 1x^4 0x^3 0x^2 0x^1 1x^0 | 113 +// a^95 | 011100010 | 0x^8 1x^7 1x^6 1x^5 0x^4 0x^3 0x^2 1x^1 0x^0 | 226 +// a^96 | 011011001 | 0x^8 1x^7 1x^6 0x^5 1x^4 1x^3 0x^2 0x^1 1x^0 | 217 +// a^97 | 010101111 | 0x^8 1x^7 0x^6 1x^5 0x^4 1x^3 1x^2 1x^1 1x^0 | 175 +// a^98 | 001000011 | 0x^8 0x^7 1x^6 0x^5 0x^4 0x^3 0x^2 1x^1 1x^0 | 67 +// a^99 | 010000110 | 0x^8 1x^7 0x^6 0x^5 0x^4 0x^3 1x^2 1x^1 0x^0 | 134 +// a^100 | 000010001 | 0x^8 0x^7 0x^6 0x^5 1x^4 0x^3 0x^2 0x^1 1x^0 | 17 +// a^101 | 000100010 | 0x^8 0x^7 0x^6 1x^5 0x^4 0x^3 0x^2 1x^1 0x^0 | 34 +// a^102 | 001000100 | 0x^8 0x^7 1x^6 0x^5 0x^4 0x^3 1x^2 0x^1 0x^0 | 68 +// a^103 | 010001000 | 0x^8 1x^7 0x^6 0x^5 0x^4 1x^3 0x^2 0x^1 0x^0 | 136 +// a^104 | 000001101 | 0x^8 0x^7 0x^6 0x^5 0x^4 1x^3 1x^2 0x^1 1x^0 | 13 +// a^105 | 000011010 | 0x^8 0x^7 0x^6 0x^5 1x^4 1x^3 0x^2 1x^1 0x^0 | 26 +// a^106 | 000110100 | 0x^8 0x^7 0x^6 1x^5 1x^4 0x^3 1x^2 0x^1 0x^0 | 52 +// a^107 | 001101000 | 0x^8 0x^7 1x^6 1x^5 0x^4 1x^3 0x^2 0x^1 0x^0 | 104 +// a^108 | 011010000 | 0x^8 1x^7 1x^6 0x^5 1x^4 0x^3 0x^2 0x^1 0x^0 | 208 +// a^109 | 010111101 | 0x^8 1x^7 0x^6 1x^5 1x^4 1x^3 1x^2 0x^1 1x^0 | 189 +// a^110 | 001100111 | 0x^8 0x^7 1x^6 1x^5 0x^4 0x^3 1x^2 1x^1 1x^0 | 103 +// a^111 | 011001110 | 0x^8 1x^7 1x^6 0x^5 0x^4 1x^3 1x^2 1x^1 0x^0 | 206 +// a^112 | 010000001 | 0x^8 1x^7 0x^6 0x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 129 +// a^113 | 000011111 | 0x^8 0x^7 0x^6 0x^5 1x^4 1x^3 1x^2 1x^1 1x^0 | 31 +// a^114 | 000111110 | 0x^8 0x^7 0x^6 1x^5 1x^4 1x^3 1x^2 1x^1 0x^0 | 62 +// a^115 | 001111100 | 0x^8 0x^7 1x^6 1x^5 1x^4 1x^3 1x^2 0x^1 0x^0 | 124 +// a^116 | 011111000 | 0x^8 1x^7 1x^6 1x^5 1x^4 1x^3 0x^2 0x^1 0x^0 | 248 +// a^117 | 011101101 | 0x^8 1x^7 1x^6 1x^5 0x^4 1x^3 1x^2 0x^1 1x^0 | 237 +// a^118 | 011000111 | 0x^8 1x^7 1x^6 0x^5 0x^4 0x^3 1x^2 1x^1 1x^0 | 199 +// a^119 | 010010011 | 0x^8 1x^7 0x^6 0x^5 1x^4 0x^3 0x^2 1x^1 1x^0 | 147 +// a^120 | 000111011 | 0x^8 0x^7 0x^6 1x^5 1x^4 1x^3 0x^2 1x^1 1x^0 | 59 +// a^121 | 001110110 | 0x^8 0x^7 1x^6 1x^5 1x^4 0x^3 1x^2 1x^1 0x^0 | 118 +// a^122 | 011101100 | 0x^8 1x^7 1x^6 1x^5 0x^4 1x^3 1x^2 0x^1 0x^0 | 236 +// a^123 | 011000101 | 0x^8 1x^7 1x^6 0x^5 0x^4 0x^3 1x^2 0x^1 1x^0 | 197 +// a^124 | 010010111 | 0x^8 1x^7 0x^6 0x^5 1x^4 0x^3 1x^2 1x^1 1x^0 | 151 +// a^125 | 000110011 | 0x^8 0x^7 0x^6 1x^5 1x^4 0x^3 0x^2 1x^1 1x^0 | 51 +// a^126 | 001100110 | 0x^8 0x^7 1x^6 1x^5 0x^4 0x^3 1x^2 1x^1 0x^0 | 102 +// a^127 | 011001100 | 0x^8 1x^7 1x^6 0x^5 0x^4 1x^3 1x^2 0x^1 0x^0 | 204 +// a^128 | 010000101 | 0x^8 1x^7 0x^6 0x^5 0x^4 0x^3 1x^2 0x^1 1x^0 | 133 +// a^129 | 000010111 | 0x^8 0x^7 0x^6 0x^5 1x^4 0x^3 1x^2 1x^1 1x^0 | 23 +// a^130 | 000101110 | 0x^8 0x^7 0x^6 1x^5 0x^4 1x^3 1x^2 1x^1 0x^0 | 46 +// a^131 | 001011100 | 0x^8 0x^7 1x^6 0x^5 1x^4 1x^3 1x^2 0x^1 0x^0 | 92 +// a^132 | 010111000 | 0x^8 1x^7 0x^6 1x^5 1x^4 1x^3 0x^2 0x^1 0x^0 | 184 +// a^133 | 001101101 | 0x^8 0x^7 1x^6 1x^5 0x^4 1x^3 1x^2 0x^1 1x^0 | 109 +// a^134 | 011011010 | 0x^8 1x^7 1x^6 0x^5 1x^4 1x^3 0x^2 1x^1 0x^0 | 218 +// a^135 | 010101001 | 0x^8 1x^7 0x^6 1x^5 0x^4 1x^3 0x^2 0x^1 1x^0 | 169 +// a^136 | 001001111 | 0x^8 0x^7 1x^6 0x^5 0x^4 1x^3 1x^2 1x^1 1x^0 | 79 +// a^137 | 010011110 | 0x^8 1x^7 0x^6 0x^5 1x^4 1x^3 1x^2 1x^1 0x^0 | 158 +// a^138 | 000100001 | 0x^8 0x^7 0x^6 1x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 33 +// a^139 | 001000010 | 0x^8 0x^7 1x^6 0x^5 0x^4 0x^3 0x^2 1x^1 0x^0 | 66 +// a^140 | 010000100 | 0x^8 1x^7 0x^6 0x^5 0x^4 0x^3 1x^2 0x^1 0x^0 | 132 +// a^141 | 000010101 | 0x^8 0x^7 0x^6 0x^5 1x^4 0x^3 1x^2 0x^1 1x^0 | 21 +// a^142 | 000101010 | 0x^8 0x^7 0x^6 1x^5 0x^4 1x^3 0x^2 1x^1 0x^0 | 42 +// a^143 | 001010100 | 0x^8 0x^7 1x^6 0x^5 1x^4 0x^3 1x^2 0x^1 0x^0 | 84 +// a^144 | 010101000 | 0x^8 1x^7 0x^6 1x^5 0x^4 1x^3 0x^2 0x^1 0x^0 | 168 +// a^145 | 001001101 | 0x^8 0x^7 1x^6 0x^5 0x^4 1x^3 1x^2 0x^1 1x^0 | 77 +// a^146 | 010011010 | 0x^8 1x^7 0x^6 0x^5 1x^4 1x^3 0x^2 1x^1 0x^0 | 154 +// a^147 | 000101001 | 0x^8 0x^7 0x^6 1x^5 0x^4 1x^3 0x^2 0x^1 1x^0 | 41 +// a^148 | 001010010 | 0x^8 0x^7 1x^6 0x^5 1x^4 0x^3 0x^2 1x^1 0x^0 | 82 +// a^149 | 010100100 | 0x^8 1x^7 0x^6 1x^5 0x^4 0x^3 1x^2 0x^1 0x^0 | 164 +// a^150 | 001010101 | 0x^8 0x^7 1x^6 0x^5 1x^4 0x^3 1x^2 0x^1 1x^0 | 85 +// a^151 | 010101010 | 0x^8 1x^7 0x^6 1x^5 0x^4 1x^3 0x^2 1x^1 0x^0 | 170 +// a^152 | 001001001 | 0x^8 0x^7 1x^6 0x^5 0x^4 1x^3 0x^2 0x^1 1x^0 | 73 +// a^153 | 010010010 | 0x^8 1x^7 0x^6 0x^5 1x^4 0x^3 0x^2 1x^1 0x^0 | 146 +// a^154 | 000111001 | 0x^8 0x^7 0x^6 1x^5 1x^4 1x^3 0x^2 0x^1 1x^0 | 57 +// a^155 | 001110010 | 0x^8 0x^7 1x^6 1x^5 1x^4 0x^3 0x^2 1x^1 0x^0 | 114 +// a^156 | 011100100 | 0x^8 1x^7 1x^6 1x^5 0x^4 0x^3 1x^2 0x^1 0x^0 | 228 +// a^157 | 011010101 | 0x^8 1x^7 1x^6 0x^5 1x^4 0x^3 1x^2 0x^1 1x^0 | 213 +// a^158 | 010110111 | 0x^8 1x^7 0x^6 1x^5 1x^4 0x^3 1x^2 1x^1 1x^0 | 183 +// a^159 | 001110011 | 0x^8 0x^7 1x^6 1x^5 1x^4 0x^3 0x^2 1x^1 1x^0 | 115 +// a^160 | 011100110 | 0x^8 1x^7 1x^6 1x^5 0x^4 0x^3 1x^2 1x^1 0x^0 | 230 +// a^161 | 011010001 | 0x^8 1x^7 1x^6 0x^5 1x^4 0x^3 0x^2 0x^1 1x^0 | 209 +// a^162 | 010111111 | 0x^8 1x^7 0x^6 1x^5 1x^4 1x^3 1x^2 1x^1 1x^0 | 191 +// a^163 | 001100011 | 0x^8 0x^7 1x^6 1x^5 0x^4 0x^3 0x^2 1x^1 1x^0 | 99 +// a^164 | 011000110 | 0x^8 1x^7 1x^6 0x^5 0x^4 0x^3 1x^2 1x^1 0x^0 | 198 +// a^165 | 010010001 | 0x^8 1x^7 0x^6 0x^5 1x^4 0x^3 0x^2 0x^1 1x^0 | 145 +// a^166 | 000111111 | 0x^8 0x^7 0x^6 1x^5 1x^4 1x^3 1x^2 1x^1 1x^0 | 63 +// a^167 | 001111110 | 0x^8 0x^7 1x^6 1x^5 1x^4 1x^3 1x^2 1x^1 0x^0 | 126 +// a^168 | 011111100 | 0x^8 1x^7 1x^6 1x^5 1x^4 1x^3 1x^2 0x^1 0x^0 | 252 +// a^169 | 011100101 | 0x^8 1x^7 1x^6 1x^5 0x^4 0x^3 1x^2 0x^1 1x^0 | 229 +// a^170 | 011010111 | 0x^8 1x^7 1x^6 0x^5 1x^4 0x^3 1x^2 1x^1 1x^0 | 215 +// a^171 | 010110011 | 0x^8 1x^7 0x^6 1x^5 1x^4 0x^3 0x^2 1x^1 1x^0 | 179 +// a^172 | 001111011 | 0x^8 0x^7 1x^6 1x^5 1x^4 1x^3 0x^2 1x^1 1x^0 | 123 +// a^173 | 011110110 | 0x^8 1x^7 1x^6 1x^5 1x^4 0x^3 1x^2 1x^1 0x^0 | 246 +// a^174 | 011110001 | 0x^8 1x^7 1x^6 1x^5 1x^4 0x^3 0x^2 0x^1 1x^0 | 241 +// a^175 | 011111111 | 0x^8 1x^7 1x^6 1x^5 1x^4 1x^3 1x^2 1x^1 1x^0 | 255 +// a^176 | 011100011 | 0x^8 1x^7 1x^6 1x^5 0x^4 0x^3 0x^2 1x^1 1x^0 | 227 +// a^177 | 011011011 | 0x^8 1x^7 1x^6 0x^5 1x^4 1x^3 0x^2 1x^1 1x^0 | 219 +// a^178 | 010101011 | 0x^8 1x^7 0x^6 1x^5 0x^4 1x^3 0x^2 1x^1 1x^0 | 171 +// a^179 | 001001011 | 0x^8 0x^7 1x^6 0x^5 0x^4 1x^3 0x^2 1x^1 1x^0 | 75 +// a^180 | 010010110 | 0x^8 1x^7 0x^6 0x^5 1x^4 0x^3 1x^2 1x^1 0x^0 | 150 +// a^181 | 000110001 | 0x^8 0x^7 0x^6 1x^5 1x^4 0x^3 0x^2 0x^1 1x^0 | 49 +// a^182 | 001100010 | 0x^8 0x^7 1x^6 1x^5 0x^4 0x^3 0x^2 1x^1 0x^0 | 98 +// a^183 | 011000100 | 0x^8 1x^7 1x^6 0x^5 0x^4 0x^3 1x^2 0x^1 0x^0 | 196 +// a^184 | 010010101 | 0x^8 1x^7 0x^6 0x^5 1x^4 0x^3 1x^2 0x^1 1x^0 | 149 +// a^185 | 000110111 | 0x^8 0x^7 0x^6 1x^5 1x^4 0x^3 1x^2 1x^1 1x^0 | 55 +// a^186 | 001101110 | 0x^8 0x^7 1x^6 1x^5 0x^4 1x^3 1x^2 1x^1 0x^0 | 110 +// a^187 | 011011100 | 0x^8 1x^7 1x^6 0x^5 1x^4 1x^3 1x^2 0x^1 0x^0 | 220 +// a^188 | 010100101 | 0x^8 1x^7 0x^6 1x^5 0x^4 0x^3 1x^2 0x^1 1x^0 | 165 +// a^189 | 001010111 | 0x^8 0x^7 1x^6 0x^5 1x^4 0x^3 1x^2 1x^1 1x^0 | 87 +// a^190 | 010101110 | 0x^8 1x^7 0x^6 1x^5 0x^4 1x^3 1x^2 1x^1 0x^0 | 174 +// a^191 | 001000001 | 0x^8 0x^7 1x^6 0x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 65 +// a^192 | 010000010 | 0x^8 1x^7 0x^6 0x^5 0x^4 0x^3 0x^2 1x^1 0x^0 | 130 +// a^193 | 000011001 | 0x^8 0x^7 0x^6 0x^5 1x^4 1x^3 0x^2 0x^1 1x^0 | 25 +// a^194 | 000110010 | 0x^8 0x^7 0x^6 1x^5 1x^4 0x^3 0x^2 1x^1 0x^0 | 50 +// a^195 | 001100100 | 0x^8 0x^7 1x^6 1x^5 0x^4 0x^3 1x^2 0x^1 0x^0 | 100 +// a^196 | 011001000 | 0x^8 1x^7 1x^6 0x^5 0x^4 1x^3 0x^2 0x^1 0x^0 | 200 +// a^197 | 010001101 | 0x^8 1x^7 0x^6 0x^5 0x^4 1x^3 1x^2 0x^1 1x^0 | 141 +// a^198 | 000000111 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 1x^2 1x^1 1x^0 | 7 +// a^199 | 000001110 | 0x^8 0x^7 0x^6 0x^5 0x^4 1x^3 1x^2 1x^1 0x^0 | 14 +// a^200 | 000011100 | 0x^8 0x^7 0x^6 0x^5 1x^4 1x^3 1x^2 0x^1 0x^0 | 28 +// a^201 | 000111000 | 0x^8 0x^7 0x^6 1x^5 1x^4 1x^3 0x^2 0x^1 0x^0 | 56 +// a^202 | 001110000 | 0x^8 0x^7 1x^6 1x^5 1x^4 0x^3 0x^2 0x^1 0x^0 | 112 +// a^203 | 011100000 | 0x^8 1x^7 1x^6 1x^5 0x^4 0x^3 0x^2 0x^1 0x^0 | 224 +// a^204 | 011011101 | 0x^8 1x^7 1x^6 0x^5 1x^4 1x^3 1x^2 0x^1 1x^0 | 221 +// a^205 | 010100111 | 0x^8 1x^7 0x^6 1x^5 0x^4 0x^3 1x^2 1x^1 1x^0 | 167 +// a^206 | 001010011 | 0x^8 0x^7 1x^6 0x^5 1x^4 0x^3 0x^2 1x^1 1x^0 | 83 +// a^207 | 010100110 | 0x^8 1x^7 0x^6 1x^5 0x^4 0x^3 1x^2 1x^1 0x^0 | 166 +// a^208 | 001010001 | 0x^8 0x^7 1x^6 0x^5 1x^4 0x^3 0x^2 0x^1 1x^0 | 81 +// a^209 | 010100010 | 0x^8 1x^7 0x^6 1x^5 0x^4 0x^3 0x^2 1x^1 0x^0 | 162 +// a^210 | 001011001 | 0x^8 0x^7 1x^6 0x^5 1x^4 1x^3 0x^2 0x^1 1x^0 | 89 +// a^211 | 010110010 | 0x^8 1x^7 0x^6 1x^5 1x^4 0x^3 0x^2 1x^1 0x^0 | 178 +// a^212 | 001111001 | 0x^8 0x^7 1x^6 1x^5 1x^4 1x^3 0x^2 0x^1 1x^0 | 121 +// a^213 | 011110010 | 0x^8 1x^7 1x^6 1x^5 1x^4 0x^3 0x^2 1x^1 0x^0 | 242 +// a^214 | 011111001 | 0x^8 1x^7 1x^6 1x^5 1x^4 1x^3 0x^2 0x^1 1x^0 | 249 +// a^215 | 011101111 | 0x^8 1x^7 1x^6 1x^5 0x^4 1x^3 1x^2 1x^1 1x^0 | 239 +// a^216 | 011000011 | 0x^8 1x^7 1x^6 0x^5 0x^4 0x^3 0x^2 1x^1 1x^0 | 195 +// a^217 | 010011011 | 0x^8 1x^7 0x^6 0x^5 1x^4 1x^3 0x^2 1x^1 1x^0 | 155 +// a^218 | 000101011 | 0x^8 0x^7 0x^6 1x^5 0x^4 1x^3 0x^2 1x^1 1x^0 | 43 +// a^219 | 001010110 | 0x^8 0x^7 1x^6 0x^5 1x^4 0x^3 1x^2 1x^1 0x^0 | 86 +// a^220 | 010101100 | 0x^8 1x^7 0x^6 1x^5 0x^4 1x^3 1x^2 0x^1 0x^0 | 172 +// a^221 | 001000101 | 0x^8 0x^7 1x^6 0x^5 0x^4 0x^3 1x^2 0x^1 1x^0 | 69 +// a^222 | 010001010 | 0x^8 1x^7 0x^6 0x^5 0x^4 1x^3 0x^2 1x^1 0x^0 | 138 +// a^223 | 000001001 | 0x^8 0x^7 0x^6 0x^5 0x^4 1x^3 0x^2 0x^1 1x^0 | 9 +// a^224 | 000010010 | 0x^8 0x^7 0x^6 0x^5 1x^4 0x^3 0x^2 1x^1 0x^0 | 18 +// a^225 | 000100100 | 0x^8 0x^7 0x^6 1x^5 0x^4 0x^3 1x^2 0x^1 0x^0 | 36 +// a^226 | 001001000 | 0x^8 0x^7 1x^6 0x^5 0x^4 1x^3 0x^2 0x^1 0x^0 | 72 +// a^227 | 010010000 | 0x^8 1x^7 0x^6 0x^5 1x^4 0x^3 0x^2 0x^1 0x^0 | 144 +// a^228 | 000111101 | 0x^8 0x^7 0x^6 1x^5 1x^4 1x^3 1x^2 0x^1 1x^0 | 61 +// a^229 | 001111010 | 0x^8 0x^7 1x^6 1x^5 1x^4 1x^3 0x^2 1x^1 0x^0 | 122 +// a^230 | 011110100 | 0x^8 1x^7 1x^6 1x^5 1x^4 0x^3 1x^2 0x^1 0x^0 | 244 +// a^231 | 011110101 | 0x^8 1x^7 1x^6 1x^5 1x^4 0x^3 1x^2 0x^1 1x^0 | 245 +// a^232 | 011110111 | 0x^8 1x^7 1x^6 1x^5 1x^4 0x^3 1x^2 1x^1 1x^0 | 247 +// a^233 | 011110011 | 0x^8 1x^7 1x^6 1x^5 1x^4 0x^3 0x^2 1x^1 1x^0 | 243 +// a^234 | 011111011 | 0x^8 1x^7 1x^6 1x^5 1x^4 1x^3 0x^2 1x^1 1x^0 | 251 +// a^235 | 011101011 | 0x^8 1x^7 1x^6 1x^5 0x^4 1x^3 0x^2 1x^1 1x^0 | 235 +// a^236 | 011001011 | 0x^8 1x^7 1x^6 0x^5 0x^4 1x^3 0x^2 1x^1 1x^0 | 203 +// a^237 | 010001011 | 0x^8 1x^7 0x^6 0x^5 0x^4 1x^3 0x^2 1x^1 1x^0 | 139 +// a^238 | 000001011 | 0x^8 0x^7 0x^6 0x^5 0x^4 1x^3 0x^2 1x^1 1x^0 | 11 +// a^239 | 000010110 | 0x^8 0x^7 0x^6 0x^5 1x^4 0x^3 1x^2 1x^1 0x^0 | 22 +// a^240 | 000101100 | 0x^8 0x^7 0x^6 1x^5 0x^4 1x^3 1x^2 0x^1 0x^0 | 44 +// a^241 | 001011000 | 0x^8 0x^7 1x^6 0x^5 1x^4 1x^3 0x^2 0x^1 0x^0 | 88 +// a^242 | 010110000 | 0x^8 1x^7 0x^6 1x^5 1x^4 0x^3 0x^2 0x^1 0x^0 | 176 +// a^243 | 001111101 | 0x^8 0x^7 1x^6 1x^5 1x^4 1x^3 1x^2 0x^1 1x^0 | 125 +// a^244 | 011111010 | 0x^8 1x^7 1x^6 1x^5 1x^4 1x^3 0x^2 1x^1 0x^0 | 250 +// a^245 | 011101001 | 0x^8 1x^7 1x^6 1x^5 0x^4 1x^3 0x^2 0x^1 1x^0 | 233 +// a^246 | 011001111 | 0x^8 1x^7 1x^6 0x^5 0x^4 1x^3 1x^2 1x^1 1x^0 | 207 +// a^247 | 010000011 | 0x^8 1x^7 0x^6 0x^5 0x^4 0x^3 0x^2 1x^1 1x^0 | 131 +// a^248 | 000011011 | 0x^8 0x^7 0x^6 0x^5 1x^4 1x^3 0x^2 1x^1 1x^0 | 27 +// a^249 | 000110110 | 0x^8 0x^7 0x^6 1x^5 1x^4 0x^3 1x^2 1x^1 0x^0 | 54 +// a^250 | 001101100 | 0x^8 0x^7 1x^6 1x^5 0x^4 1x^3 1x^2 0x^1 0x^0 | 108 +// a^251 | 011011000 | 0x^8 1x^7 1x^6 0x^5 1x^4 1x^3 0x^2 0x^1 0x^0 | 216 +// a^252 | 010101101 | 0x^8 1x^7 0x^6 1x^5 0x^4 1x^3 1x^2 0x^1 1x^0 | 173 +// a^253 | 001000111 | 0x^8 0x^7 1x^6 0x^5 0x^4 0x^3 1x^2 1x^1 1x^0 | 71 +// a^254 | 010001110 | 0x^8 1x^7 0x^6 0x^5 0x^4 1x^3 1x^2 1x^1 0x^0 | 142 +// a^255 | 000000001 | 0x^8 0x^7 0x^6 0x^5 0x^4 0x^3 0x^2 0x^1 1x^0 | 1 diff --git a/vendor/github.com/skip2/go-qrcode/reedsolomon/gf_poly.go b/vendor/github.com/skip2/go-qrcode/reedsolomon/gf_poly.go new file mode 100644 index 00000000..962f5454 --- /dev/null +++ b/vendor/github.com/skip2/go-qrcode/reedsolomon/gf_poly.go @@ -0,0 +1,216 @@ +// go-qrcode +// Copyright 2014 Tom Harwood + +package reedsolomon + +import ( + "fmt" + "log" + + bitset "github.com/skip2/go-qrcode/bitset" +) + +// gfPoly is a polynomial over GF(2^8). +type gfPoly struct { + // The ith value is the coefficient of the ith degree of x. + // term[0]*(x^0) + term[1]*(x^1) + term[2]*(x^2) ... + term []gfElement +} + +// newGFPolyFromData returns |data| as a polynomial over GF(2^8). +// +// Each data byte becomes the coefficient of an x term. +// +// For an n byte input the polynomial is: +// data[n-1]*(x^n-1) + data[n-2]*(x^n-2) ... + data[0]*(x^0). +func newGFPolyFromData(data *bitset.Bitset) gfPoly { + numTotalBytes := data.Len() / 8 + if data.Len()%8 != 0 { + numTotalBytes++ + } + + result := gfPoly{term: make([]gfElement, numTotalBytes)} + + i := numTotalBytes - 1 + for j := 0; j < data.Len(); j += 8 { + result.term[i] = gfElement(data.ByteAt(j)) + i-- + } + + return result +} + +// newGFPolyMonomial returns term*(x^degree). +func newGFPolyMonomial(term gfElement, degree int) gfPoly { + if term == gfZero { + return gfPoly{} + } + + result := gfPoly{term: make([]gfElement, degree+1)} + result.term[degree] = term + + return result +} + +func (e gfPoly) data(numTerms int) []byte { + result := make([]byte, numTerms) + + i := numTerms - len(e.term) + for j := len(e.term) - 1; j >= 0; j-- { + result[i] = byte(e.term[j]) + i++ + } + + return result +} + +// numTerms returns the number of +func (e gfPoly) numTerms() int { + return len(e.term) +} + +// gfPolyMultiply returns a * b. +func gfPolyMultiply(a, b gfPoly) gfPoly { + numATerms := a.numTerms() + numBTerms := b.numTerms() + + result := gfPoly{term: make([]gfElement, numATerms+numBTerms)} + + for i := 0; i < numATerms; i++ { + for j := 0; j < numBTerms; j++ { + if a.term[i] != 0 && b.term[j] != 0 { + monomial := gfPoly{term: make([]gfElement, i+j+1)} + monomial.term[i+j] = gfMultiply(a.term[i], b.term[j]) + + result = gfPolyAdd(result, monomial) + } + } + } + + return result.normalised() +} + +// gfPolyRemainder return the remainder of numerator / denominator. +func gfPolyRemainder(numerator, denominator gfPoly) gfPoly { + if denominator.equals(gfPoly{}) { + log.Panicln("Remainder by zero") + } + + remainder := numerator + + for remainder.numTerms() >= denominator.numTerms() { + degree := remainder.numTerms() - denominator.numTerms() + coefficient := gfDivide(remainder.term[remainder.numTerms()-1], + denominator.term[denominator.numTerms()-1]) + + divisor := gfPolyMultiply(denominator, + newGFPolyMonomial(coefficient, degree)) + + remainder = gfPolyAdd(remainder, divisor) + } + + return remainder.normalised() +} + +// gfPolyAdd returns a + b. +func gfPolyAdd(a, b gfPoly) gfPoly { + numATerms := a.numTerms() + numBTerms := b.numTerms() + + numTerms := numATerms + if numBTerms > numTerms { + numTerms = numBTerms + } + + result := gfPoly{term: make([]gfElement, numTerms)} + + for i := 0; i < numTerms; i++ { + switch { + case numATerms > i && numBTerms > i: + result.term[i] = gfAdd(a.term[i], b.term[i]) + case numATerms > i: + result.term[i] = a.term[i] + default: + result.term[i] = b.term[i] + } + } + + return result.normalised() +} + +func (e gfPoly) normalised() gfPoly { + numTerms := e.numTerms() + maxNonzeroTerm := numTerms - 1 + + for i := numTerms - 1; i >= 0; i-- { + if e.term[i] != 0 { + break + } + + maxNonzeroTerm = i - 1 + } + + if maxNonzeroTerm < 0 { + return gfPoly{} + } else if maxNonzeroTerm < numTerms-1 { + e.term = e.term[0 : maxNonzeroTerm+1] + } + + return e +} + +func (e gfPoly) string(useIndexForm bool) string { + var str string + numTerms := e.numTerms() + + for i := numTerms - 1; i >= 0; i-- { + if e.term[i] > 0 { + if len(str) > 0 { + str += " + " + } + + if !useIndexForm { + str += fmt.Sprintf("%dx^%d", e.term[i], i) + } else { + str += fmt.Sprintf("a^%dx^%d", gfLogTable[e.term[i]], i) + } + } + } + + if len(str) == 0 { + str = "0" + } + + return str +} + +// equals returns true if e == other. +func (e gfPoly) equals(other gfPoly) bool { + var minecPoly *gfPoly + var maxecPoly *gfPoly + + if e.numTerms() > other.numTerms() { + minecPoly = &other + maxecPoly = &e + } else { + minecPoly = &e + maxecPoly = &other + } + + numMinTerms := minecPoly.numTerms() + numMaxTerms := maxecPoly.numTerms() + + for i := 0; i < numMinTerms; i++ { + if e.term[i] != other.term[i] { + return false + } + } + + for i := numMinTerms; i < numMaxTerms; i++ { + if maxecPoly.term[i] != 0 { + return false + } + } + + return true +} diff --git a/vendor/github.com/skip2/go-qrcode/reedsolomon/reed_solomon.go b/vendor/github.com/skip2/go-qrcode/reedsolomon/reed_solomon.go new file mode 100644 index 00000000..561697b4 --- /dev/null +++ b/vendor/github.com/skip2/go-qrcode/reedsolomon/reed_solomon.go @@ -0,0 +1,73 @@ +// go-qrcode +// Copyright 2014 Tom Harwood + +// Package reedsolomon provides error correction encoding for QR Code 2005. +// +// QR Code 2005 uses a Reed-Solomon error correcting code to detect and correct +// errors encountered during decoding. +// +// The generated RS codes are systematic, and consist of the input data with +// error correction bytes appended. +package reedsolomon + +import ( + "log" + + bitset "github.com/skip2/go-qrcode/bitset" +) + +// Encode data for QR Code 2005 using the appropriate Reed-Solomon code. +// +// numECBytes is the number of error correction bytes to append, and is +// determined by the target QR Code's version and error correction level. +// +// ISO/IEC 18004 table 9 specifies the numECBytes required. e.g. a 1-L code has +// numECBytes=7. +func Encode(data *bitset.Bitset, numECBytes int) *bitset.Bitset { + // Create a polynomial representing |data|. + // + // The bytes are interpreted as the sequence of coefficients of a polynomial. + // The last byte's value becomes the x^0 coefficient, the second to last + // becomes the x^1 coefficient and so on. + ecpoly := newGFPolyFromData(data) + ecpoly = gfPolyMultiply(ecpoly, newGFPolyMonomial(gfOne, numECBytes)) + + // Pick the generator polynomial. + generator := rsGeneratorPoly(numECBytes) + + // Generate the error correction bytes. + remainder := gfPolyRemainder(ecpoly, generator) + + // Combine the data & error correcting bytes. + // The mathematically correct answer is: + // + // result := gfPolyAdd(ecpoly, remainder). + // + // The encoding used by QR Code 2005 is slightly different this result: To + // preserve the original |data| bit sequence exactly, the data and remainder + // are combined manually below. This ensures any most significant zero bits + // are preserved (and not optimised away). + result := bitset.Clone(data) + result.AppendBytes(remainder.data(numECBytes)) + + return result +} + +// rsGeneratorPoly returns the Reed-Solomon generator polynomial with |degree|. +// +// The generator polynomial is calculated as: +// (x + a^0)(x + a^1)...(x + a^degree-1) +func rsGeneratorPoly(degree int) gfPoly { + if degree < 2 { + log.Panic("degree < 2") + } + + generator := gfPoly{term: []gfElement{1}} + + for i := 0; i < degree; i++ { + nextPoly := gfPoly{term: []gfElement{gfExpTable[i], 1}} + generator = gfPolyMultiply(generator, nextPoly) + } + + return generator +} diff --git a/vendor/github.com/skip2/go-qrcode/regular_symbol.go b/vendor/github.com/skip2/go-qrcode/regular_symbol.go new file mode 100644 index 00000000..134be18e --- /dev/null +++ b/vendor/github.com/skip2/go-qrcode/regular_symbol.go @@ -0,0 +1,309 @@ +// go-qrcode +// Copyright 2014 Tom Harwood + +package qrcode + +import ( + bitset "github.com/skip2/go-qrcode/bitset" +) + +type regularSymbol struct { + version qrCodeVersion + mask int + + data *bitset.Bitset + + symbol *symbol + size int +} + +// Abbreviated true/false. +const ( + b0 = false + b1 = true +) + +var ( + alignmentPatternCenter = [][]int{ + {}, // Version 0 doesn't exist. + {}, // Version 1 doesn't use alignment patterns. + {6, 18}, + {6, 22}, + {6, 26}, + {6, 30}, + {6, 34}, + {6, 22, 38}, + {6, 24, 42}, + {6, 26, 46}, + {6, 28, 50}, + {6, 30, 54}, + {6, 32, 58}, + {6, 34, 62}, + {6, 26, 46, 66}, + {6, 26, 48, 70}, + {6, 26, 50, 74}, + {6, 30, 54, 78}, + {6, 30, 56, 82}, + {6, 30, 58, 86}, + {6, 34, 62, 90}, + {6, 28, 50, 72, 94}, + {6, 26, 50, 74, 98}, + {6, 30, 54, 78, 102}, + {6, 28, 54, 80, 106}, + {6, 32, 58, 84, 110}, + {6, 30, 58, 86, 114}, + {6, 34, 62, 90, 118}, + {6, 26, 50, 74, 98, 122}, + {6, 30, 54, 78, 102, 126}, + {6, 26, 52, 78, 104, 130}, + {6, 30, 56, 82, 108, 134}, + {6, 34, 60, 86, 112, 138}, + {6, 30, 58, 86, 114, 142}, + {6, 34, 62, 90, 118, 146}, + {6, 30, 54, 78, 102, 126, 150}, + {6, 24, 50, 76, 102, 128, 154}, + {6, 28, 54, 80, 106, 132, 158}, + {6, 32, 58, 84, 110, 136, 162}, + {6, 26, 54, 82, 110, 138, 166}, + {6, 30, 58, 86, 114, 142, 170}, + } + + finderPattern = [][]bool{ + {b1, b1, b1, b1, b1, b1, b1}, + {b1, b0, b0, b0, b0, b0, b1}, + {b1, b0, b1, b1, b1, b0, b1}, + {b1, b0, b1, b1, b1, b0, b1}, + {b1, b0, b1, b1, b1, b0, b1}, + {b1, b0, b0, b0, b0, b0, b1}, + {b1, b1, b1, b1, b1, b1, b1}, + } + + finderPatternSize = 7 + + finderPatternHorizontalBorder = [][]bool{ + {b0, b0, b0, b0, b0, b0, b0, b0}, + } + + finderPatternVerticalBorder = [][]bool{ + {b0}, + {b0}, + {b0}, + {b0}, + {b0}, + {b0}, + {b0}, + {b0}, + } + + alignmentPattern = [][]bool{ + {b1, b1, b1, b1, b1}, + {b1, b0, b0, b0, b1}, + {b1, b0, b1, b0, b1}, + {b1, b0, b0, b0, b1}, + {b1, b1, b1, b1, b1}, + } +) + +func buildRegularSymbol(version qrCodeVersion, mask int, + data *bitset.Bitset) (*symbol, error) { + m := ®ularSymbol{ + version: version, + mask: mask, + data: data, + + symbol: newSymbol(version.symbolSize(), version.quietZoneSize()), + size: version.symbolSize(), + } + + m.addFinderPatterns() + m.addAlignmentPatterns() + m.addTimingPatterns() + m.addFormatInfo() + m.addVersionInfo() + + ok, err := m.addData() + if !ok { + return nil, err + } + + return m.symbol, nil +} + +func (m *regularSymbol) addFinderPatterns() { + fpSize := finderPatternSize + fp := finderPattern + fpHBorder := finderPatternHorizontalBorder + fpVBorder := finderPatternVerticalBorder + + // Top left Finder Pattern. + m.symbol.set2dPattern(0, 0, fp) + m.symbol.set2dPattern(0, fpSize, fpHBorder) + m.symbol.set2dPattern(fpSize, 0, fpVBorder) + + // Top right Finder Pattern. + m.symbol.set2dPattern(m.size-fpSize, 0, fp) + m.symbol.set2dPattern(m.size-fpSize-1, fpSize, fpHBorder) + m.symbol.set2dPattern(m.size-fpSize-1, 0, fpVBorder) + + // Bottom left Finder Pattern. + m.symbol.set2dPattern(0, m.size-fpSize, fp) + m.symbol.set2dPattern(0, m.size-fpSize-1, fpHBorder) + m.symbol.set2dPattern(fpSize, m.size-fpSize-1, fpVBorder) +} + +func (m *regularSymbol) addAlignmentPatterns() { + for _, x := range alignmentPatternCenter[m.version.version] { + for _, y := range alignmentPatternCenter[m.version.version] { + if !m.symbol.empty(x, y) { + continue + } + + m.symbol.set2dPattern(x-2, y-2, alignmentPattern) + } + } +} + +func (m *regularSymbol) addTimingPatterns() { + value := true + + for i := finderPatternSize + 1; i < m.size-finderPatternSize; i++ { + m.symbol.set(i, finderPatternSize-1, value) + m.symbol.set(finderPatternSize-1, i, value) + + value = !value + } +} + +func (m *regularSymbol) addFormatInfo() { + fpSize := finderPatternSize + l := formatInfoLengthBits - 1 + + f := m.version.formatInfo(m.mask) + + // Bits 0-7, under the top right finder pattern. + for i := 0; i <= 7; i++ { + m.symbol.set(m.size-i-1, fpSize+1, f.At(l-i)) + } + + // Bits 0-5, right of the top left finder pattern. + for i := 0; i <= 5; i++ { + m.symbol.set(fpSize+1, i, f.At(l-i)) + } + + // Bits 6-8 on the corner of the top left finder pattern. + m.symbol.set(fpSize+1, fpSize, f.At(l-6)) + m.symbol.set(fpSize+1, fpSize+1, f.At(l-7)) + m.symbol.set(fpSize, fpSize+1, f.At(l-8)) + + // Bits 9-14 on the underside of the top left finder pattern. + for i := 9; i <= 14; i++ { + m.symbol.set(14-i, fpSize+1, f.At(l-i)) + } + + // Bits 8-14 on the right side of the bottom left finder pattern. + for i := 8; i <= 14; i++ { + m.symbol.set(fpSize+1, m.size-fpSize+i-8, f.At(l-i)) + } + + // Always dark symbol. + m.symbol.set(fpSize+1, m.size-fpSize-1, true) +} + +func (m *regularSymbol) addVersionInfo() { + fpSize := finderPatternSize + + v := m.version.versionInfo() + l := versionInfoLengthBits - 1 + + if v == nil { + return + } + + for i := 0; i < v.Len(); i++ { + // Above the bottom left finder pattern. + m.symbol.set(i/3, m.size-fpSize-4+i%3, v.At(l-i)) + + // Left of the top right finder pattern. + m.symbol.set(m.size-fpSize-4+i%3, i/3, v.At(l-i)) + } +} + +type direction uint8 + +const ( + up direction = iota + down +) + +func (m *regularSymbol) addData() (bool, error) { + xOffset := 1 + dir := up + + x := m.size - 2 + y := m.size - 1 + + for i := 0; i < m.data.Len(); i++ { + var mask bool + switch m.mask { + case 0: + mask = (y+x+xOffset)%2 == 0 + case 1: + mask = y%2 == 0 + case 2: + mask = (x+xOffset)%3 == 0 + case 3: + mask = (y+x+xOffset)%3 == 0 + case 4: + mask = (y/2+(x+xOffset)/3)%2 == 0 + case 5: + mask = (y*(x+xOffset))%2+(y*(x+xOffset))%3 == 0 + case 6: + mask = ((y*(x+xOffset))%2+((y*(x+xOffset))%3))%2 == 0 + case 7: + mask = ((y+x+xOffset)%2+((y*(x+xOffset))%3))%2 == 0 + } + + // != is equivalent to XOR. + m.symbol.set(x+xOffset, y, mask != m.data.At(i)) + + if i == m.data.Len()-1 { + break + } + + // Find next free bit in the symbol. + for { + if xOffset == 1 { + xOffset = 0 + } else { + xOffset = 1 + + if dir == up { + if y > 0 { + y-- + } else { + dir = down + x -= 2 + } + } else { + if y < m.size-1 { + y++ + } else { + dir = up + x -= 2 + } + } + } + + // Skip over the vertical timing pattern entirely. + if x == 5 { + x-- + } + + if m.symbol.empty(x+xOffset, y) { + break + } + } + } + + return true, nil +} diff --git a/vendor/github.com/skip2/go-qrcode/symbol.go b/vendor/github.com/skip2/go-qrcode/symbol.go new file mode 100644 index 00000000..0cb1327c --- /dev/null +++ b/vendor/github.com/skip2/go-qrcode/symbol.go @@ -0,0 +1,309 @@ +// go-qrcode +// Copyright 2014 Tom Harwood + +package qrcode + +// symbol is a 2D array of bits representing a QR Code symbol. +// +// A symbol consists of size*size modules, with each module normally drawn as a +// black or white square. The symbol also has a border of quietZoneSize modules. +// +// A (fictional) size=2, quietZoneSize=1 QR Code looks like: +// +// +----+ +// | | +// | ab | +// | cd | +// | | +// +----+ +// +// For ease of implementation, the functions to set/get bits ignore the border, +// so (0,0)=a, (0,1)=b, (1,0)=c, and (1,1)=d. The entire symbol (including the +// border) is returned by bitmap(). +// +type symbol struct { + // Value of module at [y][x]. True is set. + module [][]bool + + // True if the module at [y][x] is used (to either true or false). + // Used to identify unused modules. + isUsed [][]bool + + // Combined width/height of the symbol and quiet zones. + // + // size = symbolSize + 2*quietZoneSize. + size int + + // Width/height of the symbol only. + symbolSize int + + // Width/height of a single quiet zone. + quietZoneSize int +} + +// newSymbol constructs a symbol of size size*size, with a border of +// quietZoneSize. +func newSymbol(size int, quietZoneSize int) *symbol { + var m symbol + + m.module = make([][]bool, size+2*quietZoneSize) + m.isUsed = make([][]bool, size+2*quietZoneSize) + + for i := range m.module { + m.module[i] = make([]bool, size+2*quietZoneSize) + m.isUsed[i] = make([]bool, size+2*quietZoneSize) + } + + m.size = size + 2*quietZoneSize + m.symbolSize = size + m.quietZoneSize = quietZoneSize + + return &m +} + +// get returns the module value at (x, y). +func (m *symbol) get(x int, y int) (v bool) { + v = m.module[y+m.quietZoneSize][x+m.quietZoneSize] + return +} + +// empty returns true if the module at (x, y) has not been set (to either true +// or false). +func (m *symbol) empty(x int, y int) bool { + return !m.isUsed[y+m.quietZoneSize][x+m.quietZoneSize] +} + +// numEmptyModules returns the number of empty modules. +// +// Initially numEmptyModules is symbolSize * symbolSize. After every module has +// been set (to either true or false), the number of empty modules is zero. +func (m *symbol) numEmptyModules() int { + var count int + for y := 0; y < m.symbolSize; y++ { + for x := 0; x < m.symbolSize; x++ { + if !m.isUsed[y+m.quietZoneSize][x+m.quietZoneSize] { + count++ + } + } + } + + return count +} + +// set sets the module at (x, y) to v. +func (m *symbol) set(x int, y int, v bool) { + m.module[y+m.quietZoneSize][x+m.quietZoneSize] = v + m.isUsed[y+m.quietZoneSize][x+m.quietZoneSize] = true +} + +// set2dPattern sets a 2D array of modules, starting at (x, y). +func (m *symbol) set2dPattern(x int, y int, v [][]bool) { + for j, row := range v { + for i, value := range row { + m.set(x+i, y+j, value) + } + } +} + +// bitmap returns the entire symbol, including the quiet zone. +func (m *symbol) bitmap() [][]bool { + module := make([][]bool, len(m.module)) + + for i := range m.module { + module[i] = m.module[i][:] + } + + return module +} + +// string returns a pictorial representation of the symbol, suitable for +// printing in a TTY. +func (m *symbol) string() string { + var result string + + for _, row := range m.module { + for _, value := range row { + switch value { + case true: + result += " " + case false: + // Unicode 'FULL BLOCK' (U+2588). + result += "β–ˆβ–ˆ" + } + } + result += "\n" + } + + return result +} + +// Constants used to weight penalty calculations. Specified by ISO/IEC +// 18004:2006. +const ( + penaltyWeight1 = 3 + penaltyWeight2 = 3 + penaltyWeight3 = 40 + penaltyWeight4 = 10 +) + +// penaltyScore returns the penalty score of the symbol. The penalty score +// consists of the sum of the four individual penalty types. +func (m *symbol) penaltyScore() int { + return m.penalty1() + m.penalty2() + m.penalty3() + m.penalty4() +} + +// penalty1 returns the penalty score for "adjacent modules in row/column with +// same colour". +// +// The numbers of adjacent matching modules and scores are: +// 0-5: score = 0 +// 6+ : score = penaltyWeight1 + (numAdjacentModules - 5) +func (m *symbol) penalty1() int { + penalty := 0 + + for x := 0; x < m.symbolSize; x++ { + lastValue := m.get(x, 0) + count := 1 + + for y := 1; y < m.symbolSize; y++ { + v := m.get(x, y) + + if v != lastValue { + count = 1 + lastValue = v + } else { + count++ + if count == 6 { + penalty += penaltyWeight1 + 1 + } else if count > 6 { + penalty++ + } + } + } + } + + for y := 0; y < m.symbolSize; y++ { + lastValue := m.get(0, y) + count := 1 + + for x := 1; x < m.symbolSize; x++ { + v := m.get(x, y) + + if v != lastValue { + count = 1 + lastValue = v + } else { + count++ + if count == 6 { + penalty += penaltyWeight1 + 1 + } else if count > 6 { + penalty++ + } + } + } + } + + return penalty +} + +// penalty2 returns the penalty score for "block of modules in the same colour". +// +// m*n: score = penaltyWeight2 * (m-1) * (n-1). +func (m *symbol) penalty2() int { + penalty := 0 + + for y := 1; y < m.symbolSize; y++ { + for x := 1; x < m.symbolSize; x++ { + topLeft := m.get(x-1, y-1) + above := m.get(x, y-1) + left := m.get(x-1, y) + current := m.get(x, y) + + if current == left && current == above && current == topLeft { + penalty++ + } + } + } + + return penalty * penaltyWeight2 +} + +// penalty3 returns the penalty score for "1:1:3:1:1 ratio +// (dark:light:dark:light:dark) pattern in row/column, preceded or followed by +// light area 4 modules wide". +// +// Existence of the pattern scores penaltyWeight3. +func (m *symbol) penalty3() int { + penalty := 0 + + for y := 0; y < m.symbolSize; y++ { + var bitBuffer int16 = 0x00 + + for x := 0; x < m.symbolSize; x++ { + bitBuffer <<= 1 + if v := m.get(x, y); v { + bitBuffer |= 1 + } + + switch bitBuffer & 0x7ff { + // 0b000 0101 1101 or 0b10111010000 + // 0x05d or 0x5d0 + case 0x05d, 0x5d0: + penalty += penaltyWeight3 + bitBuffer = 0xFF + default: + if x == m.symbolSize-1 && (bitBuffer&0x7f) == 0x5d { + penalty += penaltyWeight3 + bitBuffer = 0xFF + } + } + } + } + + for x := 0; x < m.symbolSize; x++ { + var bitBuffer int16 = 0x00 + + for y := 0; y < m.symbolSize; y++ { + bitBuffer <<= 1 + if v := m.get(x, y); v { + bitBuffer |= 1 + } + + switch bitBuffer & 0x7ff { + // 0b000 0101 1101 or 0b10111010000 + // 0x05d or 0x5d0 + case 0x05d, 0x5d0: + penalty += penaltyWeight3 + bitBuffer = 0xFF + default: + if y == m.symbolSize-1 && (bitBuffer&0x7f) == 0x5d { + penalty += penaltyWeight3 + bitBuffer = 0xFF + } + } + } + } + + return penalty +} + +// penalty4 returns the penalty score... +func (m *symbol) penalty4() int { + numModules := m.symbolSize * m.symbolSize + numDarkModules := 0 + + for x := 0; x < m.symbolSize; x++ { + for y := 0; y < m.symbolSize; y++ { + if v := m.get(x, y); v { + numDarkModules++ + } + } + } + + numDarkModuleDeviation := numModules/2 - numDarkModules + if numDarkModuleDeviation < 0 { + numDarkModuleDeviation *= -1 + } + + return penaltyWeight4 * (numDarkModuleDeviation / (numModules / 20)) +} diff --git a/vendor/github.com/skip2/go-qrcode/version.go b/vendor/github.com/skip2/go-qrcode/version.go new file mode 100644 index 00000000..738cf3d3 --- /dev/null +++ b/vendor/github.com/skip2/go-qrcode/version.go @@ -0,0 +1,3050 @@ +// go-qrcode +// Copyright 2014 Tom Harwood + +package qrcode + +import ( + "log" + + bitset "github.com/skip2/go-qrcode/bitset" +) + +// Error detection/recovery capacity. +// +// There are several levels of error detection/recovery capacity. Higher levels +// of error recovery are able to correct more errors, with the trade-off of +// increased symbol size. +type RecoveryLevel int + +const ( + // Level L: 7% error recovery. + Low RecoveryLevel = iota + + // Level M: 15% error recovery. Good default choice. + Medium + + // Level Q: 25% error recovery. + High + + // Level H: 30% error recovery. + Highest +) + +// qrCodeVersion describes the data length and encoding order of a single QR +// Code version. There are 40 versions numbers x 4 recovery levels == 160 +// possible qrCodeVersion structures. +type qrCodeVersion struct { + // Version number (1-40 inclusive). + version int + + // Error recovery level. + level RecoveryLevel + + dataEncoderType dataEncoderType + + // Encoded data can be split into multiple blocks. Each block contains data + // and error recovery bytes. + // + // Larger QR Codes contain more blocks. + block []block + + // Number of bits required to pad the combined data & error correction bit + // stream up to the symbol's full capacity. + numRemainderBits int +} + +type block struct { + numBlocks int + + // Total codewords (numCodewords == numErrorCodewords+numDataCodewords). + numCodewords int + + // Number of data codewords. + numDataCodewords int +} + +var ( + versions = []qrCodeVersion{ + { + 1, + Low, + dataEncoderType1To9, + []block{ + { + 1, + 26, + 19, + }, + }, + 0, + }, + { + 1, + Medium, + dataEncoderType1To9, + []block{ + { + 1, + 26, + 16, + }, + }, + 0, + }, + { + 1, + High, + dataEncoderType1To9, + []block{ + { + 1, + 26, + 13, + }, + }, + 0, + }, + { + 1, + Highest, + dataEncoderType1To9, + []block{ + { + 1, + 26, + 9, + }, + }, + 0, + }, + { + 2, + Low, + dataEncoderType1To9, + []block{ + { + 1, + 44, + 34, + }, + }, + 7, + }, + { + 2, + Medium, + dataEncoderType1To9, + []block{ + { + 1, + 44, + 28, + }, + }, + 7, + }, + { + 2, + High, + dataEncoderType1To9, + []block{ + { + 1, + 44, + 22, + }, + }, + 7, + }, + { + 2, + Highest, + dataEncoderType1To9, + []block{ + { + 1, + 44, + 16, + }, + }, + 7, + }, + { + 3, + Low, + dataEncoderType1To9, + []block{ + { + 1, + 70, + 55, + }, + }, + 7, + }, + { + 3, + Medium, + dataEncoderType1To9, + []block{ + { + 1, + 70, + 44, + }, + }, + 7, + }, + { + 3, + High, + dataEncoderType1To9, + []block{ + { + 2, + 35, + 17, + }, + }, + 7, + }, + { + 3, + Highest, + dataEncoderType1To9, + []block{ + { + 2, + 35, + 13, + }, + }, + 7, + }, + { + 4, + Low, + dataEncoderType1To9, + []block{ + { + 1, + 100, + 80, + }, + }, + 7, + }, + { + 4, + Medium, + dataEncoderType1To9, + []block{ + { + 2, + 50, + 32, + }, + }, + 7, + }, + { + 4, + High, + dataEncoderType1To9, + []block{ + { + 2, + 50, + 24, + }, + }, + 7, + }, + { + 4, + Highest, + dataEncoderType1To9, + []block{ + { + 4, + 25, + 9, + }, + }, + 7, + }, + { + 5, + Low, + dataEncoderType1To9, + []block{ + { + 1, + 134, + 108, + }, + }, + 7, + }, + { + 5, + Medium, + dataEncoderType1To9, + []block{ + { + 2, + 67, + 43, + }, + }, + 7, + }, + { + 5, + High, + dataEncoderType1To9, + []block{ + { + 2, + 33, + 15, + }, + { + 2, + 34, + 16, + }, + }, + 7, + }, + { + 5, + Highest, + dataEncoderType1To9, + []block{ + { + 2, + 33, + 11, + }, + { + 2, + 34, + 12, + }, + }, + 7, + }, + { + 6, + Low, + dataEncoderType1To9, + []block{ + { + 2, + 86, + 68, + }, + }, + 7, + }, + { + 6, + Medium, + dataEncoderType1To9, + []block{ + { + 4, + 43, + 27, + }, + }, + 7, + }, + { + 6, + High, + dataEncoderType1To9, + []block{ + { + 4, + 43, + 19, + }, + }, + 7, + }, + { + 6, + Highest, + dataEncoderType1To9, + []block{ + { + 4, + 43, + 15, + }, + }, + 7, + }, + { + 7, + Low, + dataEncoderType1To9, + []block{ + { + 2, + 98, + 78, + }, + }, + 0, + }, + { + 7, + Medium, + dataEncoderType1To9, + []block{ + { + 4, + 49, + 31, + }, + }, + 0, + }, + { + 7, + High, + dataEncoderType1To9, + []block{ + { + 2, + 32, + 14, + }, + { + 4, + 33, + 15, + }, + }, + 0, + }, + { + 7, + Highest, + dataEncoderType1To9, + []block{ + { + 4, + 39, + 13, + }, + { + 1, + 40, + 14, + }, + }, + 0, + }, + { + 8, + Low, + dataEncoderType1To9, + []block{ + { + 2, + 121, + 97, + }, + }, + 0, + }, + { + 8, + Medium, + dataEncoderType1To9, + []block{ + { + 2, + 60, + 38, + }, + { + 2, + 61, + 39, + }, + }, + 0, + }, + { + 8, + High, + dataEncoderType1To9, + []block{ + { + 4, + 40, + 18, + }, + { + 2, + 41, + 19, + }, + }, + 0, + }, + { + 8, + Highest, + dataEncoderType1To9, + []block{ + { + 4, + 40, + 14, + }, + { + 2, + 41, + 15, + }, + }, + 0, + }, + { + 9, + Low, + dataEncoderType1To9, + []block{ + { + 2, + 146, + 116, + }, + }, + 0, + }, + { + 9, + Medium, + dataEncoderType1To9, + []block{ + { + 3, + 58, + 36, + }, + { + 2, + 59, + 37, + }, + }, + 0, + }, + { + 9, + High, + dataEncoderType1To9, + []block{ + { + 4, + 36, + 16, + }, + { + 4, + 37, + 17, + }, + }, + 0, + }, + { + 9, + Highest, + dataEncoderType1To9, + []block{ + { + 4, + 36, + 12, + }, + { + 4, + 37, + 13, + }, + }, + 0, + }, + { + 10, + Low, + dataEncoderType10To26, + []block{ + { + 2, + 86, + 68, + }, + { + 2, + 87, + 69, + }, + }, + 0, + }, + { + 10, + Medium, + dataEncoderType10To26, + []block{ + { + 4, + 69, + 43, + }, + { + 1, + 70, + 44, + }, + }, + 0, + }, + { + 10, + High, + dataEncoderType10To26, + []block{ + { + 6, + 43, + 19, + }, + { + 2, + 44, + 20, + }, + }, + 0, + }, + { + 10, + Highest, + dataEncoderType10To26, + []block{ + { + 6, + 43, + 15, + }, + { + 2, + 44, + 16, + }, + }, + 0, + }, + { + 11, + Low, + dataEncoderType10To26, + []block{ + { + 4, + 101, + 81, + }, + }, + 0, + }, + { + 11, + Medium, + dataEncoderType10To26, + []block{ + { + 1, + 80, + 50, + }, + { + 4, + 81, + 51, + }, + }, + 0, + }, + { + 11, + High, + dataEncoderType10To26, + []block{ + { + 4, + 50, + 22, + }, + { + 4, + 51, + 23, + }, + }, + 0, + }, + { + 11, + Highest, + dataEncoderType10To26, + []block{ + { + 3, + 36, + 12, + }, + { + 8, + 37, + 13, + }, + }, + 0, + }, + { + 12, + Low, + dataEncoderType10To26, + []block{ + { + 2, + 116, + 92, + }, + { + 2, + 117, + 93, + }, + }, + 0, + }, + { + 12, + Medium, + dataEncoderType10To26, + []block{ + { + 6, + 58, + 36, + }, + { + 2, + 59, + 37, + }, + }, + 0, + }, + { + 12, + High, + dataEncoderType10To26, + []block{ + { + 4, + 46, + 20, + }, + { + 6, + 47, + 21, + }, + }, + 0, + }, + { + 12, + Highest, + dataEncoderType10To26, + []block{ + { + 7, + 42, + 14, + }, + { + 4, + 43, + 15, + }, + }, + 0, + }, + { + 13, + Low, + dataEncoderType10To26, + []block{ + { + 4, + 133, + 107, + }, + }, + 0, + }, + { + 13, + Medium, + dataEncoderType10To26, + []block{ + { + 8, + 59, + 37, + }, + { + 1, + 60, + 38, + }, + }, + 0, + }, + { + 13, + High, + dataEncoderType10To26, + []block{ + { + 8, + 44, + 20, + }, + { + 4, + 45, + 21, + }, + }, + 0, + }, + { + 13, + Highest, + dataEncoderType10To26, + []block{ + { + 12, + 33, + 11, + }, + { + 4, + 34, + 12, + }, + }, + 0, + }, + { + 14, + Low, + dataEncoderType10To26, + []block{ + { + 3, + 145, + 115, + }, + { + 1, + 146, + 116, + }, + }, + 3, + }, + { + 14, + Medium, + dataEncoderType10To26, + []block{ + { + 4, + 64, + 40, + }, + { + 5, + 65, + 41, + }, + }, + 3, + }, + { + 14, + High, + dataEncoderType10To26, + []block{ + { + 11, + 36, + 16, + }, + { + 5, + 37, + 17, + }, + }, + 3, + }, + { + 14, + Highest, + dataEncoderType10To26, + []block{ + { + 11, + 36, + 12, + }, + { + 5, + 37, + 13, + }, + }, + 3, + }, + { + 15, + Low, + dataEncoderType10To26, + []block{ + { + 5, + 109, + 87, + }, + { + 1, + 110, + 88, + }, + }, + 3, + }, + { + 15, + Medium, + dataEncoderType10To26, + []block{ + { + 5, + 65, + 41, + }, + { + 5, + 66, + 42, + }, + }, + 3, + }, + { + 15, + High, + dataEncoderType10To26, + []block{ + { + 5, + 54, + 24, + }, + { + 7, + 55, + 25, + }, + }, + 3, + }, + { + 15, + Highest, + dataEncoderType10To26, + []block{ + { + 11, + 36, + 12, + }, + { + 7, + 37, + 13, + }, + }, + 3, + }, + { + 16, + Low, + dataEncoderType10To26, + []block{ + { + 5, + 122, + 98, + }, + { + 1, + 123, + 99, + }, + }, + 3, + }, + { + 16, + Medium, + dataEncoderType10To26, + []block{ + { + 7, + 73, + 45, + }, + { + 3, + 74, + 46, + }, + }, + 3, + }, + { + 16, + High, + dataEncoderType10To26, + []block{ + { + 15, + 43, + 19, + }, + { + 2, + 44, + 20, + }, + }, + 3, + }, + { + 16, + Highest, + dataEncoderType10To26, + []block{ + { + 3, + 45, + 15, + }, + { + 13, + 46, + 16, + }, + }, + 3, + }, + { + 17, + Low, + dataEncoderType10To26, + []block{ + { + 1, + 135, + 107, + }, + { + 5, + 136, + 108, + }, + }, + 3, + }, + { + 17, + Medium, + dataEncoderType10To26, + []block{ + { + 10, + 74, + 46, + }, + { + 1, + 75, + 47, + }, + }, + 3, + }, + { + 17, + High, + dataEncoderType10To26, + []block{ + { + 1, + 50, + 22, + }, + { + 15, + 51, + 23, + }, + }, + 3, + }, + { + 17, + Highest, + dataEncoderType10To26, + []block{ + { + 2, + 42, + 14, + }, + { + 17, + 43, + 15, + }, + }, + 3, + }, + { + 18, + Low, + dataEncoderType10To26, + []block{ + { + 5, + 150, + 120, + }, + { + 1, + 151, + 121, + }, + }, + 3, + }, + { + 18, + Medium, + dataEncoderType10To26, + []block{ + { + 9, + 69, + 43, + }, + { + 4, + 70, + 44, + }, + }, + 3, + }, + { + 18, + High, + dataEncoderType10To26, + []block{ + { + 17, + 50, + 22, + }, + { + 1, + 51, + 23, + }, + }, + 3, + }, + { + 18, + Highest, + dataEncoderType10To26, + []block{ + { + 2, + 42, + 14, + }, + { + 19, + 43, + 15, + }, + }, + 3, + }, + { + 19, + Low, + dataEncoderType10To26, + []block{ + { + 3, + 141, + 113, + }, + { + 4, + 142, + 114, + }, + }, + 3, + }, + { + 19, + Medium, + dataEncoderType10To26, + []block{ + { + 3, + 70, + 44, + }, + { + 11, + 71, + 45, + }, + }, + 3, + }, + { + 19, + High, + dataEncoderType10To26, + []block{ + { + 17, + 47, + 21, + }, + { + 4, + 48, + 22, + }, + }, + 3, + }, + { + 19, + Highest, + dataEncoderType10To26, + []block{ + { + 9, + 39, + 13, + }, + { + 16, + 40, + 14, + }, + }, + 3, + }, + { + 20, + Low, + dataEncoderType10To26, + []block{ + { + 3, + 135, + 107, + }, + { + 5, + 136, + 108, + }, + }, + 3, + }, + { + 20, + Medium, + dataEncoderType10To26, + []block{ + { + 3, + 67, + 41, + }, + { + 13, + 68, + 42, + }, + }, + 3, + }, + { + 20, + High, + dataEncoderType10To26, + []block{ + { + 15, + 54, + 24, + }, + { + 5, + 55, + 25, + }, + }, + 3, + }, + { + 20, + Highest, + dataEncoderType10To26, + []block{ + { + 15, + 43, + 15, + }, + { + 10, + 44, + 16, + }, + }, + 3, + }, + { + 21, + Low, + dataEncoderType10To26, + []block{ + { + 4, + 144, + 116, + }, + { + 4, + 145, + 117, + }, + }, + 4, + }, + { + 21, + Medium, + dataEncoderType10To26, + []block{ + { + 17, + 68, + 42, + }, + }, + 4, + }, + { + 21, + High, + dataEncoderType10To26, + []block{ + { + 17, + 50, + 22, + }, + { + 6, + 51, + 23, + }, + }, + 4, + }, + { + 21, + Highest, + dataEncoderType10To26, + []block{ + { + 19, + 46, + 16, + }, + { + 6, + 47, + 17, + }, + }, + 4, + }, + { + 22, + Low, + dataEncoderType10To26, + []block{ + { + 2, + 139, + 111, + }, + { + 7, + 140, + 112, + }, + }, + 4, + }, + { + 22, + Medium, + dataEncoderType10To26, + []block{ + { + 17, + 74, + 46, + }, + }, + 4, + }, + { + 22, + High, + dataEncoderType10To26, + []block{ + { + 7, + 54, + 24, + }, + { + 16, + 55, + 25, + }, + }, + 4, + }, + { + 22, + Highest, + dataEncoderType10To26, + []block{ + { + 34, + 37, + 13, + }, + }, + 4, + }, + { + 23, + Low, + dataEncoderType10To26, + []block{ + { + 4, + 151, + 121, + }, + { + 5, + 152, + 122, + }, + }, + 4, + }, + { + 23, + Medium, + dataEncoderType10To26, + []block{ + { + 4, + 75, + 47, + }, + { + 14, + 76, + 48, + }, + }, + 4, + }, + { + 23, + High, + dataEncoderType10To26, + []block{ + { + 11, + 54, + 24, + }, + { + 14, + 55, + 25, + }, + }, + 4, + }, + { + 23, + Highest, + dataEncoderType10To26, + []block{ + { + 16, + 45, + 15, + }, + { + 14, + 46, + 16, + }, + }, + 4, + }, + { + 24, + Low, + dataEncoderType10To26, + []block{ + { + 6, + 147, + 117, + }, + { + 4, + 148, + 118, + }, + }, + 4, + }, + { + 24, + Medium, + dataEncoderType10To26, + []block{ + { + 6, + 73, + 45, + }, + { + 14, + 74, + 46, + }, + }, + 4, + }, + { + 24, + High, + dataEncoderType10To26, + []block{ + { + 11, + 54, + 24, + }, + { + 16, + 55, + 25, + }, + }, + 4, + }, + { + 24, + Highest, + dataEncoderType10To26, + []block{ + { + 30, + 46, + 16, + }, + { + 2, + 47, + 17, + }, + }, + 4, + }, + { + 25, + Low, + dataEncoderType10To26, + []block{ + { + 8, + 132, + 106, + }, + { + 4, + 133, + 107, + }, + }, + 4, + }, + { + 25, + Medium, + dataEncoderType10To26, + []block{ + { + 8, + 75, + 47, + }, + { + 13, + 76, + 48, + }, + }, + 4, + }, + { + 25, + High, + dataEncoderType10To26, + []block{ + { + 7, + 54, + 24, + }, + { + 22, + 55, + 25, + }, + }, + 4, + }, + { + 25, + Highest, + dataEncoderType10To26, + []block{ + { + 22, + 45, + 15, + }, + { + 13, + 46, + 16, + }, + }, + 4, + }, + { + 26, + Low, + dataEncoderType10To26, + []block{ + { + 10, + 142, + 114, + }, + { + 2, + 143, + 115, + }, + }, + 4, + }, + { + 26, + Medium, + dataEncoderType10To26, + []block{ + { + 19, + 74, + 46, + }, + { + 4, + 75, + 47, + }, + }, + 4, + }, + { + 26, + High, + dataEncoderType10To26, + []block{ + { + 28, + 50, + 22, + }, + { + 6, + 51, + 23, + }, + }, + 4, + }, + { + 26, + Highest, + dataEncoderType10To26, + []block{ + { + 33, + 46, + 16, + }, + { + 4, + 47, + 17, + }, + }, + 4, + }, + { + 27, + Low, + dataEncoderType27To40, + []block{ + { + 8, + 152, + 122, + }, + { + 4, + 153, + 123, + }, + }, + 4, + }, + { + 27, + Medium, + dataEncoderType27To40, + []block{ + { + 22, + 73, + 45, + }, + { + 3, + 74, + 46, + }, + }, + 4, + }, + { + 27, + High, + dataEncoderType27To40, + []block{ + { + 8, + 53, + 23, + }, + { + 26, + 54, + 24, + }, + }, + 4, + }, + { + 27, + Highest, + dataEncoderType27To40, + []block{ + { + 12, + 45, + 15, + }, + { + 28, + 46, + 16, + }, + }, + 4, + }, + { + 28, + Low, + dataEncoderType27To40, + []block{ + { + 3, + 147, + 117, + }, + { + 10, + 148, + 118, + }, + }, + 3, + }, + { + 28, + Medium, + dataEncoderType27To40, + []block{ + { + 3, + 73, + 45, + }, + { + 23, + 74, + 46, + }, + }, + 3, + }, + { + 28, + High, + dataEncoderType27To40, + []block{ + { + 4, + 54, + 24, + }, + { + 31, + 55, + 25, + }, + }, + 3, + }, + { + 28, + Highest, + dataEncoderType27To40, + []block{ + { + 11, + 45, + 15, + }, + { + 31, + 46, + 16, + }, + }, + 3, + }, + { + 29, + Low, + dataEncoderType27To40, + []block{ + { + 7, + 146, + 116, + }, + { + 7, + 147, + 117, + }, + }, + 3, + }, + { + 29, + Medium, + dataEncoderType27To40, + []block{ + { + 21, + 73, + 45, + }, + { + 7, + 74, + 46, + }, + }, + 3, + }, + { + 29, + High, + dataEncoderType27To40, + []block{ + { + 1, + 53, + 23, + }, + { + 37, + 54, + 24, + }, + }, + 3, + }, + { + 29, + Highest, + dataEncoderType27To40, + []block{ + { + 19, + 45, + 15, + }, + { + 26, + 46, + 16, + }, + }, + 3, + }, + { + 30, + Low, + dataEncoderType27To40, + []block{ + { + 5, + 145, + 115, + }, + { + 10, + 146, + 116, + }, + }, + 3, + }, + { + 30, + Medium, + dataEncoderType27To40, + []block{ + { + 19, + 75, + 47, + }, + { + 10, + 76, + 48, + }, + }, + 3, + }, + { + 30, + High, + dataEncoderType27To40, + []block{ + { + 15, + 54, + 24, + }, + { + 25, + 55, + 25, + }, + }, + 3, + }, + { + 30, + Highest, + dataEncoderType27To40, + []block{ + { + 23, + 45, + 15, + }, + { + 25, + 46, + 16, + }, + }, + 3, + }, + { + 31, + Low, + dataEncoderType27To40, + []block{ + { + 13, + 145, + 115, + }, + { + 3, + 146, + 116, + }, + }, + 3, + }, + { + 31, + Medium, + dataEncoderType27To40, + []block{ + { + 2, + 74, + 46, + }, + { + 29, + 75, + 47, + }, + }, + 3, + }, + { + 31, + High, + dataEncoderType27To40, + []block{ + { + 42, + 54, + 24, + }, + { + 1, + 55, + 25, + }, + }, + 3, + }, + { + 31, + Highest, + dataEncoderType27To40, + []block{ + { + 23, + 45, + 15, + }, + { + 28, + 46, + 16, + }, + }, + 3, + }, + { + 32, + Low, + dataEncoderType27To40, + []block{ + { + 17, + 145, + 115, + }, + }, + 3, + }, + { + 32, + Medium, + dataEncoderType27To40, + []block{ + { + 10, + 74, + 46, + }, + { + 23, + 75, + 47, + }, + }, + 3, + }, + { + 32, + High, + dataEncoderType27To40, + []block{ + { + 10, + 54, + 24, + }, + { + 35, + 55, + 25, + }, + }, + 3, + }, + { + 32, + Highest, + dataEncoderType27To40, + []block{ + { + 19, + 45, + 15, + }, + { + 35, + 46, + 16, + }, + }, + 3, + }, + { + 33, + Low, + dataEncoderType27To40, + []block{ + { + 17, + 145, + 115, + }, + { + 1, + 146, + 116, + }, + }, + 3, + }, + { + 33, + Medium, + dataEncoderType27To40, + []block{ + { + 14, + 74, + 46, + }, + { + 21, + 75, + 47, + }, + }, + 3, + }, + { + 33, + High, + dataEncoderType27To40, + []block{ + { + 29, + 54, + 24, + }, + { + 19, + 55, + 25, + }, + }, + 3, + }, + { + 33, + Highest, + dataEncoderType27To40, + []block{ + { + 11, + 45, + 15, + }, + { + 46, + 46, + 16, + }, + }, + 3, + }, + { + 34, + Low, + dataEncoderType27To40, + []block{ + { + 13, + 145, + 115, + }, + { + 6, + 146, + 116, + }, + }, + 3, + }, + { + 34, + Medium, + dataEncoderType27To40, + []block{ + { + 14, + 74, + 46, + }, + { + 23, + 75, + 47, + }, + }, + 3, + }, + { + 34, + High, + dataEncoderType27To40, + []block{ + { + 44, + 54, + 24, + }, + { + 7, + 55, + 25, + }, + }, + 3, + }, + { + 34, + Highest, + dataEncoderType27To40, + []block{ + { + 59, + 46, + 16, + }, + { + 1, + 47, + 17, + }, + }, + 3, + }, + { + 35, + Low, + dataEncoderType27To40, + []block{ + { + 12, + 151, + 121, + }, + { + 7, + 152, + 122, + }, + }, + 0, + }, + { + 35, + Medium, + dataEncoderType27To40, + []block{ + { + 12, + 75, + 47, + }, + { + 26, + 76, + 48, + }, + }, + 0, + }, + { + 35, + High, + dataEncoderType27To40, + []block{ + { + 39, + 54, + 24, + }, + { + 14, + 55, + 25, + }, + }, + 0, + }, + { + 35, + Highest, + dataEncoderType27To40, + []block{ + { + 22, + 45, + 15, + }, + { + 41, + 46, + 16, + }, + }, + 0, + }, + { + 36, + Low, + dataEncoderType27To40, + []block{ + { + 6, + 151, + 121, + }, + { + 14, + 152, + 122, + }, + }, + 0, + }, + { + 36, + Medium, + dataEncoderType27To40, + []block{ + { + 6, + 75, + 47, + }, + { + 34, + 76, + 48, + }, + }, + 0, + }, + { + 36, + High, + dataEncoderType27To40, + []block{ + { + 46, + 54, + 24, + }, + { + 10, + 55, + 25, + }, + }, + 0, + }, + { + 36, + Highest, + dataEncoderType27To40, + []block{ + { + 2, + 45, + 15, + }, + { + 64, + 46, + 16, + }, + }, + 0, + }, + { + 37, + Low, + dataEncoderType27To40, + []block{ + { + 17, + 152, + 122, + }, + { + 4, + 153, + 123, + }, + }, + 0, + }, + { + 37, + Medium, + dataEncoderType27To40, + []block{ + { + 29, + 74, + 46, + }, + { + 14, + 75, + 47, + }, + }, + 0, + }, + { + 37, + High, + dataEncoderType27To40, + []block{ + { + 49, + 54, + 24, + }, + { + 10, + 55, + 25, + }, + }, + 0, + }, + { + 37, + Highest, + dataEncoderType27To40, + []block{ + { + 24, + 45, + 15, + }, + { + 46, + 46, + 16, + }, + }, + 0, + }, + { + 38, + Low, + dataEncoderType27To40, + []block{ + { + 4, + 152, + 122, + }, + { + 18, + 153, + 123, + }, + }, + 0, + }, + { + 38, + Medium, + dataEncoderType27To40, + []block{ + { + 13, + 74, + 46, + }, + { + 32, + 75, + 47, + }, + }, + 0, + }, + { + 38, + High, + dataEncoderType27To40, + []block{ + { + 48, + 54, + 24, + }, + { + 14, + 55, + 25, + }, + }, + 0, + }, + { + 38, + Highest, + dataEncoderType27To40, + []block{ + { + 42, + 45, + 15, + }, + { + 32, + 46, + 16, + }, + }, + 0, + }, + { + 39, + Low, + dataEncoderType27To40, + []block{ + { + 20, + 147, + 117, + }, + { + 4, + 148, + 118, + }, + }, + 0, + }, + { + 39, + Medium, + dataEncoderType27To40, + []block{ + { + 40, + 75, + 47, + }, + { + 7, + 76, + 48, + }, + }, + 0, + }, + { + 39, + High, + dataEncoderType27To40, + []block{ + { + 43, + 54, + 24, + }, + { + 22, + 55, + 25, + }, + }, + 0, + }, + { + 39, + Highest, + dataEncoderType27To40, + []block{ + { + 10, + 45, + 15, + }, + { + 67, + 46, + 16, + }, + }, + 0, + }, + { + 40, + Low, + dataEncoderType27To40, + []block{ + { + 19, + 148, + 118, + }, + { + 6, + 149, + 119, + }, + }, + 0, + }, + { + 40, + Medium, + dataEncoderType27To40, + []block{ + { + 18, + 75, + 47, + }, + { + 31, + 76, + 48, + }, + }, + 0, + }, + { + 40, + High, + dataEncoderType27To40, + []block{ + { + 34, + 54, + 24, + }, + { + 34, + 55, + 25, + }, + }, + 0, + }, + { + 40, + Highest, + dataEncoderType27To40, + []block{ + { + 20, + 45, + 15, + }, + { + 61, + 46, + 16, + }, + }, + 0, + }, + } +) + +var ( + // Each QR Code contains a 15-bit Format Information value. The 15 bits + // consist of 5 data bits concatenated with 10 error correction bits. + // + // The 5 data bits consist of: + // - 2 bits for the error correction level (L=01, M=00, G=11, H=10). + // - 3 bits for the data mask pattern identifier. + // + // formatBitSequence is a mapping from the 5 data bits to the completed 15-bit + // Format Information value. + // + // For example, a QR Code using error correction level L, and data mask + // pattern identifier 001: + // + // 01 | 001 = 01001 = 0x9 + // formatBitSequence[0x9].qrCode = 0x72f3 = 111001011110011 + formatBitSequence = []struct { + regular uint32 + micro uint32 + }{ + {0x5412, 0x4445}, + {0x5125, 0x4172}, + {0x5e7c, 0x4e2b}, + {0x5b4b, 0x4b1c}, + {0x45f9, 0x55ae}, + {0x40ce, 0x5099}, + {0x4f97, 0x5fc0}, + {0x4aa0, 0x5af7}, + {0x77c4, 0x6793}, + {0x72f3, 0x62a4}, + {0x7daa, 0x6dfd}, + {0x789d, 0x68ca}, + {0x662f, 0x7678}, + {0x6318, 0x734f}, + {0x6c41, 0x7c16}, + {0x6976, 0x7921}, + {0x1689, 0x06de}, + {0x13be, 0x03e9}, + {0x1ce7, 0x0cb0}, + {0x19d0, 0x0987}, + {0x0762, 0x1735}, + {0x0255, 0x1202}, + {0x0d0c, 0x1d5b}, + {0x083b, 0x186c}, + {0x355f, 0x2508}, + {0x3068, 0x203f}, + {0x3f31, 0x2f66}, + {0x3a06, 0x2a51}, + {0x24b4, 0x34e3}, + {0x2183, 0x31d4}, + {0x2eda, 0x3e8d}, + {0x2bed, 0x3bba}, + } + + // QR Codes version 7 and higher contain an 18-bit Version Information value, + // consisting of a 6 data bits and 12 error correction bits. + // + // versionBitSequence is a mapping from QR Code version to the completed + // 18-bit Version Information value. + // + // For example, a QR code of version 7: + // versionBitSequence[0x7] = 0x07c94 = 000111110010010100 + versionBitSequence = []uint32{ + 0x00000, + 0x00000, + 0x00000, + 0x00000, + 0x00000, + 0x00000, + 0x00000, + 0x07c94, + 0x085bc, + 0x09a99, + 0x0a4d3, + 0x0bbf6, + 0x0c762, + 0x0d847, + 0x0e60d, + 0x0f928, + 0x10b78, + 0x1145d, + 0x12a17, + 0x13532, + 0x149a6, + 0x15683, + 0x168c9, + 0x177ec, + 0x18ec4, + 0x191e1, + 0x1afab, + 0x1b08e, + 0x1cc1a, + 0x1d33f, + 0x1ed75, + 0x1f250, + 0x209d5, + 0x216f0, + 0x228ba, + 0x2379f, + 0x24b0b, + 0x2542e, + 0x26a64, + 0x27541, + 0x28c69, + } +) + +const ( + formatInfoLengthBits = 15 + versionInfoLengthBits = 18 +) + +// formatInfo returns the 15-bit Format Information value for a QR +// code. +func (v qrCodeVersion) formatInfo(maskPattern int) *bitset.Bitset { + formatID := 0 + + switch v.level { + case Low: + formatID = 0x08 // 0b01000 + case Medium: + formatID = 0x00 // 0b00000 + case High: + formatID = 0x18 // 0b11000 + case Highest: + formatID = 0x10 // 0b10000 + default: + log.Panicf("Invalid level %d", v.level) + } + + if maskPattern < 0 || maskPattern > 7 { + log.Panicf("Invalid maskPattern %d", maskPattern) + } + + formatID |= maskPattern & 0x7 + + result := bitset.New() + + result.AppendUint32(formatBitSequence[formatID].regular, formatInfoLengthBits) + + return result +} + +// versionInfo returns the 18-bit Version Information value for a QR Code. +// +// Version Information is applicable only to QR Codes versions 7-40 inclusive. +// nil is returned if Version Information is not required. +func (v qrCodeVersion) versionInfo() *bitset.Bitset { + if v.version < 7 { + return nil + } + + result := bitset.New() + result.AppendUint32(versionBitSequence[v.version], 18) + + return result +} + +// numDataBits returns the data capacity in bits. +func (v qrCodeVersion) numDataBits() int { + numDataBits := 0 + for _, b := range v.block { + numDataBits += 8 * b.numBlocks * b.numDataCodewords // 8 bits in a byte + } + + return numDataBits +} + +// chooseQRCodeVersion chooses the most suitable QR Code version for a stated +// data length in bits, the error recovery level required, and the data encoder +// used. +// +// The chosen QR Code version is the smallest version able to fit numDataBits +// and the optional terminator bits required by the specified encoder. +// +// On success the chosen QR Code version is returned. +func chooseQRCodeVersion(level RecoveryLevel, encoder *dataEncoder, numDataBits int) *qrCodeVersion { + var chosenVersion *qrCodeVersion + + for _, v := range versions { + if v.level != level { + continue + } else if v.version < encoder.minVersion { + continue + } else if v.version > encoder.maxVersion { + break + } + + numFreeBits := v.numDataBits() - numDataBits + + if numFreeBits >= 0 { + chosenVersion = &v + break + } + } + + return chosenVersion +} + +func (v qrCodeVersion) numTerminatorBitsRequired(numDataBits int) int { + numFreeBits := v.numDataBits() - numDataBits + + var numTerminatorBits int + + switch { + case numFreeBits >= 4: + numTerminatorBits = 4 + default: + numTerminatorBits = numFreeBits + } + + return numTerminatorBits +} + +// numBlocks returns the number of blocks. +func (v qrCodeVersion) numBlocks() int { + numBlocks := 0 + + for _, b := range v.block { + numBlocks += b.numBlocks + } + + return numBlocks +} + +// numBitsToPadToCodeword returns the number of bits required to pad data of +// length numDataBits upto the nearest codeword size. +func (v qrCodeVersion) numBitsToPadToCodeword(numDataBits int) int { + if numDataBits == v.numDataBits() { + return 0 + } + + return (8 - numDataBits%8) % 8 +} + +// symbolSize returns the size of the QR Code symbol in number of modules (which +// is both the width and height, since QR codes are square). The QR Code has +// size symbolSize() x symbolSize() pixels. This does not include the quiet +// zone. +func (v qrCodeVersion) symbolSize() int { + return 21 + (v.version-1)*4 +} + +// quietZoneSize returns the number of pixels of border space on each side of +// the QR Code. The quiet space assists with decoding. +func (v qrCodeVersion) quietZoneSize() int { + return 4 +} + +// getQRCodeVersion returns the QR Code version by version number and recovery +// level. Returns nil if the requested combination is not defined. +func getQRCodeVersion(level RecoveryLevel, version int) *qrCodeVersion { + for _, v := range versions { + if v.level == level && v.version == version { + return &v + } + } + + return nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 02564492..eb282720 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -5,6 +5,9 @@ filippo.io/edwards25519/field # github.com/42wim/go-gitter v0.0.0-20170828205020-017310c2d557 ## explicit github.com/42wim/go-gitter +# github.com/Baozisoftware/qrcode-terminal-go v0.0.0-20170407111555-c0650d8dff0f +## explicit +github.com/Baozisoftware/qrcode-terminal-go # github.com/Benau/go_rlottie v0.0.0-20210807002906-98c1b2421989 ## explicit github.com/Benau/go_rlottie @@ -26,6 +29,15 @@ github.com/Philipp15b/go-steam/protocol/steamlang github.com/Philipp15b/go-steam/rwu github.com/Philipp15b/go-steam/socialcache github.com/Philipp15b/go-steam/steamid +# github.com/Rhymen/go-whatsapp v0.1.2-0.20211102134409-31a2e740845c +## explicit; go 1.13 +github.com/Rhymen/go-whatsapp +github.com/Rhymen/go-whatsapp/binary +github.com/Rhymen/go-whatsapp/binary/proto +github.com/Rhymen/go-whatsapp/binary/token +github.com/Rhymen/go-whatsapp/crypto/cbc +github.com/Rhymen/go-whatsapp/crypto/curve25519 +github.com/Rhymen/go-whatsapp/crypto/hkdf # github.com/SevereCloud/vksdk/v2 v2.13.1 ## explicit; go 1.16 github.com/SevereCloud/vksdk/v2 @@ -357,6 +369,11 @@ github.com/sirupsen/logrus # github.com/sizeofint/webpanimation v0.0.0-20210809145948-1d2b32119882 ## explicit; go 1.16 github.com/sizeofint/webpanimation +# github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9 +## explicit +github.com/skip2/go-qrcode +github.com/skip2/go-qrcode/bitset +github.com/skip2/go-qrcode/reedsolomon # github.com/slack-go/slack v0.10.2 ## explicit; go 1.16 github.com/slack-go/slack