/*eslint-disable block-scoped-var, id-length, no-control-regex, no-magic-numbers, no-prototype-builtins, no-redeclare, no-shadow, no-var, sort-vars*/
"use strict";

var $protobuf = require("protobufjs/minimal");

// Common aliases
var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;

// Exported root namespace
var $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {});

$root.proto = (function() {

    /**
     * Namespace proto.
     * @exports proto
     * @namespace
     */
    var proto = {};

    proto.AppVersion = (function() {

        /**
         * Properties of an AppVersion.
         * @memberof proto
         * @interface IAppVersion
         * @property {number|null} [primary] AppVersion primary
         * @property {number|null} [secondary] AppVersion secondary
         * @property {number|null} [tertiary] AppVersion tertiary
         * @property {number|null} [quaternary] AppVersion quaternary
         * @property {number|null} [quinary] AppVersion quinary
         */

        /**
         * Constructs a new AppVersion.
         * @memberof proto
         * @classdesc Represents an AppVersion.
         * @implements IAppVersion
         * @constructor
         * @param {proto.IAppVersion=} [properties] Properties to set
         */
        function AppVersion(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * AppVersion primary.
         * @member {number} primary
         * @memberof proto.AppVersion
         * @instance
         */
        AppVersion.prototype.primary = 0;

        /**
         * AppVersion secondary.
         * @member {number} secondary
         * @memberof proto.AppVersion
         * @instance
         */
        AppVersion.prototype.secondary = 0;

        /**
         * AppVersion tertiary.
         * @member {number} tertiary
         * @memberof proto.AppVersion
         * @instance
         */
        AppVersion.prototype.tertiary = 0;

        /**
         * AppVersion quaternary.
         * @member {number} quaternary
         * @memberof proto.AppVersion
         * @instance
         */
        AppVersion.prototype.quaternary = 0;

        /**
         * AppVersion quinary.
         * @member {number} quinary
         * @memberof proto.AppVersion
         * @instance
         */
        AppVersion.prototype.quinary = 0;

        /**
         * Creates a new AppVersion instance using the specified properties.
         * @function create
         * @memberof proto.AppVersion
         * @static
         * @param {proto.IAppVersion=} [properties] Properties to set
         * @returns {proto.AppVersion} AppVersion instance
         */
        AppVersion.create = function create(properties) {
            return new AppVersion(properties);
        };

        /**
         * Encodes the specified AppVersion message. Does not implicitly {@link proto.AppVersion.verify|verify} messages.
         * @function encode
         * @memberof proto.AppVersion
         * @static
         * @param {proto.IAppVersion} message AppVersion message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AppVersion.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.primary != null && Object.hasOwnProperty.call(message, "primary"))
                writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.primary);
            if (message.secondary != null && Object.hasOwnProperty.call(message, "secondary"))
                writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.secondary);
            if (message.tertiary != null && Object.hasOwnProperty.call(message, "tertiary"))
                writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.tertiary);
            if (message.quaternary != null && Object.hasOwnProperty.call(message, "quaternary"))
                writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.quaternary);
            if (message.quinary != null && Object.hasOwnProperty.call(message, "quinary"))
                writer.uint32(/* id 5, wireType 0 =*/40).uint32(message.quinary);
            return writer;
        };

        /**
         * Encodes the specified AppVersion message, length delimited. Does not implicitly {@link proto.AppVersion.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.AppVersion
         * @static
         * @param {proto.IAppVersion} message AppVersion message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AppVersion.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an AppVersion message from the specified reader or buffer.
         * @function decode
         * @memberof proto.AppVersion
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.AppVersion} AppVersion
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AppVersion.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.AppVersion();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.primary = reader.uint32();
                    break;
                case 2:
                    message.secondary = reader.uint32();
                    break;
                case 3:
                    message.tertiary = reader.uint32();
                    break;
                case 4:
                    message.quaternary = reader.uint32();
                    break;
                case 5:
                    message.quinary = reader.uint32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an AppVersion message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.AppVersion
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.AppVersion} AppVersion
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AppVersion.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an AppVersion message.
         * @function verify
         * @memberof proto.AppVersion
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        AppVersion.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.primary != null && message.hasOwnProperty("primary"))
                if (!$util.isInteger(message.primary))
                    return "primary: integer expected";
            if (message.secondary != null && message.hasOwnProperty("secondary"))
                if (!$util.isInteger(message.secondary))
                    return "secondary: integer expected";
            if (message.tertiary != null && message.hasOwnProperty("tertiary"))
                if (!$util.isInteger(message.tertiary))
                    return "tertiary: integer expected";
            if (message.quaternary != null && message.hasOwnProperty("quaternary"))
                if (!$util.isInteger(message.quaternary))
                    return "quaternary: integer expected";
            if (message.quinary != null && message.hasOwnProperty("quinary"))
                if (!$util.isInteger(message.quinary))
                    return "quinary: integer expected";
            return null;
        };

        /**
         * Creates an AppVersion message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.AppVersion
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.AppVersion} AppVersion
         */
        AppVersion.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.AppVersion)
                return object;
            var message = new $root.proto.AppVersion();
            if (object.primary != null)
                message.primary = object.primary >>> 0;
            if (object.secondary != null)
                message.secondary = object.secondary >>> 0;
            if (object.tertiary != null)
                message.tertiary = object.tertiary >>> 0;
            if (object.quaternary != null)
                message.quaternary = object.quaternary >>> 0;
            if (object.quinary != null)
                message.quinary = object.quinary >>> 0;
            return message;
        };

        /**
         * Creates a plain object from an AppVersion message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.AppVersion
         * @static
         * @param {proto.AppVersion} message AppVersion
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        AppVersion.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.primary = 0;
                object.secondary = 0;
                object.tertiary = 0;
                object.quaternary = 0;
                object.quinary = 0;
            }
            if (message.primary != null && message.hasOwnProperty("primary"))
                object.primary = message.primary;
            if (message.secondary != null && message.hasOwnProperty("secondary"))
                object.secondary = message.secondary;
            if (message.tertiary != null && message.hasOwnProperty("tertiary"))
                object.tertiary = message.tertiary;
            if (message.quaternary != null && message.hasOwnProperty("quaternary"))
                object.quaternary = message.quaternary;
            if (message.quinary != null && message.hasOwnProperty("quinary"))
                object.quinary = message.quinary;
            return object;
        };

        /**
         * Converts this AppVersion to JSON.
         * @function toJSON
         * @memberof proto.AppVersion
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        AppVersion.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return AppVersion;
    })();

    proto.UserAgent = (function() {

        /**
         * Properties of a UserAgent.
         * @memberof proto
         * @interface IUserAgent
         * @property {proto.UserAgent.UserAgentPlatform|null} [platform] UserAgent platform
         * @property {proto.IAppVersion|null} [appVersion] UserAgent appVersion
         * @property {string|null} [mcc] UserAgent mcc
         * @property {string|null} [mnc] UserAgent mnc
         * @property {string|null} [osVersion] UserAgent osVersion
         * @property {string|null} [manufacturer] UserAgent manufacturer
         * @property {string|null} [device] UserAgent device
         * @property {string|null} [osBuildNumber] UserAgent osBuildNumber
         * @property {string|null} [phoneId] UserAgent phoneId
         * @property {proto.UserAgent.UserAgentReleaseChannel|null} [releaseChannel] UserAgent releaseChannel
         * @property {string|null} [localeLanguageIso6391] UserAgent localeLanguageIso6391
         * @property {string|null} [localeCountryIso31661Alpha2] UserAgent localeCountryIso31661Alpha2
         * @property {string|null} [deviceBoard] UserAgent deviceBoard
         */

        /**
         * Constructs a new UserAgent.
         * @memberof proto
         * @classdesc Represents a UserAgent.
         * @implements IUserAgent
         * @constructor
         * @param {proto.IUserAgent=} [properties] Properties to set
         */
        function UserAgent(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * UserAgent platform.
         * @member {proto.UserAgent.UserAgentPlatform} platform
         * @memberof proto.UserAgent
         * @instance
         */
        UserAgent.prototype.platform = 0;

        /**
         * UserAgent appVersion.
         * @member {proto.IAppVersion|null|undefined} appVersion
         * @memberof proto.UserAgent
         * @instance
         */
        UserAgent.prototype.appVersion = null;

        /**
         * UserAgent mcc.
         * @member {string} mcc
         * @memberof proto.UserAgent
         * @instance
         */
        UserAgent.prototype.mcc = "";

        /**
         * UserAgent mnc.
         * @member {string} mnc
         * @memberof proto.UserAgent
         * @instance
         */
        UserAgent.prototype.mnc = "";

        /**
         * UserAgent osVersion.
         * @member {string} osVersion
         * @memberof proto.UserAgent
         * @instance
         */
        UserAgent.prototype.osVersion = "";

        /**
         * UserAgent manufacturer.
         * @member {string} manufacturer
         * @memberof proto.UserAgent
         * @instance
         */
        UserAgent.prototype.manufacturer = "";

        /**
         * UserAgent device.
         * @member {string} device
         * @memberof proto.UserAgent
         * @instance
         */
        UserAgent.prototype.device = "";

        /**
         * UserAgent osBuildNumber.
         * @member {string} osBuildNumber
         * @memberof proto.UserAgent
         * @instance
         */
        UserAgent.prototype.osBuildNumber = "";

        /**
         * UserAgent phoneId.
         * @member {string} phoneId
         * @memberof proto.UserAgent
         * @instance
         */
        UserAgent.prototype.phoneId = "";

        /**
         * UserAgent releaseChannel.
         * @member {proto.UserAgent.UserAgentReleaseChannel} releaseChannel
         * @memberof proto.UserAgent
         * @instance
         */
        UserAgent.prototype.releaseChannel = 0;

        /**
         * UserAgent localeLanguageIso6391.
         * @member {string} localeLanguageIso6391
         * @memberof proto.UserAgent
         * @instance
         */
        UserAgent.prototype.localeLanguageIso6391 = "";

        /**
         * UserAgent localeCountryIso31661Alpha2.
         * @member {string} localeCountryIso31661Alpha2
         * @memberof proto.UserAgent
         * @instance
         */
        UserAgent.prototype.localeCountryIso31661Alpha2 = "";

        /**
         * UserAgent deviceBoard.
         * @member {string} deviceBoard
         * @memberof proto.UserAgent
         * @instance
         */
        UserAgent.prototype.deviceBoard = "";

        /**
         * Creates a new UserAgent instance using the specified properties.
         * @function create
         * @memberof proto.UserAgent
         * @static
         * @param {proto.IUserAgent=} [properties] Properties to set
         * @returns {proto.UserAgent} UserAgent instance
         */
        UserAgent.create = function create(properties) {
            return new UserAgent(properties);
        };

        /**
         * Encodes the specified UserAgent message. Does not implicitly {@link proto.UserAgent.verify|verify} messages.
         * @function encode
         * @memberof proto.UserAgent
         * @static
         * @param {proto.IUserAgent} message UserAgent message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        UserAgent.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.platform != null && Object.hasOwnProperty.call(message, "platform"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.platform);
            if (message.appVersion != null && Object.hasOwnProperty.call(message, "appVersion"))
                $root.proto.AppVersion.encode(message.appVersion, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.mcc != null && Object.hasOwnProperty.call(message, "mcc"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.mcc);
            if (message.mnc != null && Object.hasOwnProperty.call(message, "mnc"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.mnc);
            if (message.osVersion != null && Object.hasOwnProperty.call(message, "osVersion"))
                writer.uint32(/* id 5, wireType 2 =*/42).string(message.osVersion);
            if (message.manufacturer != null && Object.hasOwnProperty.call(message, "manufacturer"))
                writer.uint32(/* id 6, wireType 2 =*/50).string(message.manufacturer);
            if (message.device != null && Object.hasOwnProperty.call(message, "device"))
                writer.uint32(/* id 7, wireType 2 =*/58).string(message.device);
            if (message.osBuildNumber != null && Object.hasOwnProperty.call(message, "osBuildNumber"))
                writer.uint32(/* id 8, wireType 2 =*/66).string(message.osBuildNumber);
            if (message.phoneId != null && Object.hasOwnProperty.call(message, "phoneId"))
                writer.uint32(/* id 9, wireType 2 =*/74).string(message.phoneId);
            if (message.releaseChannel != null && Object.hasOwnProperty.call(message, "releaseChannel"))
                writer.uint32(/* id 10, wireType 0 =*/80).int32(message.releaseChannel);
            if (message.localeLanguageIso6391 != null && Object.hasOwnProperty.call(message, "localeLanguageIso6391"))
                writer.uint32(/* id 11, wireType 2 =*/90).string(message.localeLanguageIso6391);
            if (message.localeCountryIso31661Alpha2 != null && Object.hasOwnProperty.call(message, "localeCountryIso31661Alpha2"))
                writer.uint32(/* id 12, wireType 2 =*/98).string(message.localeCountryIso31661Alpha2);
            if (message.deviceBoard != null && Object.hasOwnProperty.call(message, "deviceBoard"))
                writer.uint32(/* id 13, wireType 2 =*/106).string(message.deviceBoard);
            return writer;
        };

        /**
         * Encodes the specified UserAgent message, length delimited. Does not implicitly {@link proto.UserAgent.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.UserAgent
         * @static
         * @param {proto.IUserAgent} message UserAgent message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        UserAgent.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a UserAgent message from the specified reader or buffer.
         * @function decode
         * @memberof proto.UserAgent
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.UserAgent} UserAgent
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        UserAgent.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.UserAgent();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.platform = reader.int32();
                    break;
                case 2:
                    message.appVersion = $root.proto.AppVersion.decode(reader, reader.uint32());
                    break;
                case 3:
                    message.mcc = reader.string();
                    break;
                case 4:
                    message.mnc = reader.string();
                    break;
                case 5:
                    message.osVersion = reader.string();
                    break;
                case 6:
                    message.manufacturer = reader.string();
                    break;
                case 7:
                    message.device = reader.string();
                    break;
                case 8:
                    message.osBuildNumber = reader.string();
                    break;
                case 9:
                    message.phoneId = reader.string();
                    break;
                case 10:
                    message.releaseChannel = reader.int32();
                    break;
                case 11:
                    message.localeLanguageIso6391 = reader.string();
                    break;
                case 12:
                    message.localeCountryIso31661Alpha2 = reader.string();
                    break;
                case 13:
                    message.deviceBoard = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a UserAgent message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.UserAgent
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.UserAgent} UserAgent
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        UserAgent.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a UserAgent message.
         * @function verify
         * @memberof proto.UserAgent
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        UserAgent.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.platform != null && message.hasOwnProperty("platform"))
                switch (message.platform) {
                default:
                    return "platform: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                case 8:
                case 9:
                case 10:
                case 11:
                case 12:
                case 13:
                case 14:
                case 15:
                case 16:
                case 17:
                case 18:
                case 19:
                case 20:
                case 21:
                case 22:
                case 23:
                case 24:
                case 25:
                case 26:
                case 27:
                case 28:
                    break;
                }
            if (message.appVersion != null && message.hasOwnProperty("appVersion")) {
                var error = $root.proto.AppVersion.verify(message.appVersion);
                if (error)
                    return "appVersion." + error;
            }
            if (message.mcc != null && message.hasOwnProperty("mcc"))
                if (!$util.isString(message.mcc))
                    return "mcc: string expected";
            if (message.mnc != null && message.hasOwnProperty("mnc"))
                if (!$util.isString(message.mnc))
                    return "mnc: string expected";
            if (message.osVersion != null && message.hasOwnProperty("osVersion"))
                if (!$util.isString(message.osVersion))
                    return "osVersion: string expected";
            if (message.manufacturer != null && message.hasOwnProperty("manufacturer"))
                if (!$util.isString(message.manufacturer))
                    return "manufacturer: string expected";
            if (message.device != null && message.hasOwnProperty("device"))
                if (!$util.isString(message.device))
                    return "device: string expected";
            if (message.osBuildNumber != null && message.hasOwnProperty("osBuildNumber"))
                if (!$util.isString(message.osBuildNumber))
                    return "osBuildNumber: string expected";
            if (message.phoneId != null && message.hasOwnProperty("phoneId"))
                if (!$util.isString(message.phoneId))
                    return "phoneId: string expected";
            if (message.releaseChannel != null && message.hasOwnProperty("releaseChannel"))
                switch (message.releaseChannel) {
                default:
                    return "releaseChannel: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.localeLanguageIso6391 != null && message.hasOwnProperty("localeLanguageIso6391"))
                if (!$util.isString(message.localeLanguageIso6391))
                    return "localeLanguageIso6391: string expected";
            if (message.localeCountryIso31661Alpha2 != null && message.hasOwnProperty("localeCountryIso31661Alpha2"))
                if (!$util.isString(message.localeCountryIso31661Alpha2))
                    return "localeCountryIso31661Alpha2: string expected";
            if (message.deviceBoard != null && message.hasOwnProperty("deviceBoard"))
                if (!$util.isString(message.deviceBoard))
                    return "deviceBoard: string expected";
            return null;
        };

        /**
         * Creates a UserAgent message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.UserAgent
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.UserAgent} UserAgent
         */
        UserAgent.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.UserAgent)
                return object;
            var message = new $root.proto.UserAgent();
            switch (object.platform) {
            case "ANDROID":
            case 0:
                message.platform = 0;
                break;
            case "IOS":
            case 1:
                message.platform = 1;
                break;
            case "WINDOWS_PHONE":
            case 2:
                message.platform = 2;
                break;
            case "BLACKBERRY":
            case 3:
                message.platform = 3;
                break;
            case "BLACKBERRYX":
            case 4:
                message.platform = 4;
                break;
            case "S40":
            case 5:
                message.platform = 5;
                break;
            case "S60":
            case 6:
                message.platform = 6;
                break;
            case "PYTHON_CLIENT":
            case 7:
                message.platform = 7;
                break;
            case "TIZEN":
            case 8:
                message.platform = 8;
                break;
            case "ENTERPRISE":
            case 9:
                message.platform = 9;
                break;
            case "SMB_ANDROID":
            case 10:
                message.platform = 10;
                break;
            case "KAIOS":
            case 11:
                message.platform = 11;
                break;
            case "SMB_IOS":
            case 12:
                message.platform = 12;
                break;
            case "WINDOWS":
            case 13:
                message.platform = 13;
                break;
            case "WEB":
            case 14:
                message.platform = 14;
                break;
            case "PORTAL":
            case 15:
                message.platform = 15;
                break;
            case "GREEN_ANDROID":
            case 16:
                message.platform = 16;
                break;
            case "GREEN_IPHONE":
            case 17:
                message.platform = 17;
                break;
            case "BLUE_ANDROID":
            case 18:
                message.platform = 18;
                break;
            case "BLUE_IPHONE":
            case 19:
                message.platform = 19;
                break;
            case "FBLITE_ANDROID":
            case 20:
                message.platform = 20;
                break;
            case "MLITE_ANDROID":
            case 21:
                message.platform = 21;
                break;
            case "IGLITE_ANDROID":
            case 22:
                message.platform = 22;
                break;
            case "PAGE":
            case 23:
                message.platform = 23;
                break;
            case "MACOS":
            case 24:
                message.platform = 24;
                break;
            case "OCULUS_MSG":
            case 25:
                message.platform = 25;
                break;
            case "OCULUS_CALL":
            case 26:
                message.platform = 26;
                break;
            case "MILAN":
            case 27:
                message.platform = 27;
                break;
            case "CAPI":
            case 28:
                message.platform = 28;
                break;
            }
            if (object.appVersion != null) {
                if (typeof object.appVersion !== "object")
                    throw TypeError(".proto.UserAgent.appVersion: object expected");
                message.appVersion = $root.proto.AppVersion.fromObject(object.appVersion);
            }
            if (object.mcc != null)
                message.mcc = String(object.mcc);
            if (object.mnc != null)
                message.mnc = String(object.mnc);
            if (object.osVersion != null)
                message.osVersion = String(object.osVersion);
            if (object.manufacturer != null)
                message.manufacturer = String(object.manufacturer);
            if (object.device != null)
                message.device = String(object.device);
            if (object.osBuildNumber != null)
                message.osBuildNumber = String(object.osBuildNumber);
            if (object.phoneId != null)
                message.phoneId = String(object.phoneId);
            switch (object.releaseChannel) {
            case "RELEASE":
            case 0:
                message.releaseChannel = 0;
                break;
            case "BETA":
            case 1:
                message.releaseChannel = 1;
                break;
            case "ALPHA":
            case 2:
                message.releaseChannel = 2;
                break;
            case "DEBUG":
            case 3:
                message.releaseChannel = 3;
                break;
            }
            if (object.localeLanguageIso6391 != null)
                message.localeLanguageIso6391 = String(object.localeLanguageIso6391);
            if (object.localeCountryIso31661Alpha2 != null)
                message.localeCountryIso31661Alpha2 = String(object.localeCountryIso31661Alpha2);
            if (object.deviceBoard != null)
                message.deviceBoard = String(object.deviceBoard);
            return message;
        };

        /**
         * Creates a plain object from a UserAgent message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.UserAgent
         * @static
         * @param {proto.UserAgent} message UserAgent
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        UserAgent.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.platform = options.enums === String ? "ANDROID" : 0;
                object.appVersion = null;
                object.mcc = "";
                object.mnc = "";
                object.osVersion = "";
                object.manufacturer = "";
                object.device = "";
                object.osBuildNumber = "";
                object.phoneId = "";
                object.releaseChannel = options.enums === String ? "RELEASE" : 0;
                object.localeLanguageIso6391 = "";
                object.localeCountryIso31661Alpha2 = "";
                object.deviceBoard = "";
            }
            if (message.platform != null && message.hasOwnProperty("platform"))
                object.platform = options.enums === String ? $root.proto.UserAgent.UserAgentPlatform[message.platform] : message.platform;
            if (message.appVersion != null && message.hasOwnProperty("appVersion"))
                object.appVersion = $root.proto.AppVersion.toObject(message.appVersion, options);
            if (message.mcc != null && message.hasOwnProperty("mcc"))
                object.mcc = message.mcc;
            if (message.mnc != null && message.hasOwnProperty("mnc"))
                object.mnc = message.mnc;
            if (message.osVersion != null && message.hasOwnProperty("osVersion"))
                object.osVersion = message.osVersion;
            if (message.manufacturer != null && message.hasOwnProperty("manufacturer"))
                object.manufacturer = message.manufacturer;
            if (message.device != null && message.hasOwnProperty("device"))
                object.device = message.device;
            if (message.osBuildNumber != null && message.hasOwnProperty("osBuildNumber"))
                object.osBuildNumber = message.osBuildNumber;
            if (message.phoneId != null && message.hasOwnProperty("phoneId"))
                object.phoneId = message.phoneId;
            if (message.releaseChannel != null && message.hasOwnProperty("releaseChannel"))
                object.releaseChannel = options.enums === String ? $root.proto.UserAgent.UserAgentReleaseChannel[message.releaseChannel] : message.releaseChannel;
            if (message.localeLanguageIso6391 != null && message.hasOwnProperty("localeLanguageIso6391"))
                object.localeLanguageIso6391 = message.localeLanguageIso6391;
            if (message.localeCountryIso31661Alpha2 != null && message.hasOwnProperty("localeCountryIso31661Alpha2"))
                object.localeCountryIso31661Alpha2 = message.localeCountryIso31661Alpha2;
            if (message.deviceBoard != null && message.hasOwnProperty("deviceBoard"))
                object.deviceBoard = message.deviceBoard;
            return object;
        };

        /**
         * Converts this UserAgent to JSON.
         * @function toJSON
         * @memberof proto.UserAgent
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        UserAgent.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * UserAgentPlatform enum.
         * @name proto.UserAgent.UserAgentPlatform
         * @enum {number}
         * @property {number} ANDROID=0 ANDROID value
         * @property {number} IOS=1 IOS value
         * @property {number} WINDOWS_PHONE=2 WINDOWS_PHONE value
         * @property {number} BLACKBERRY=3 BLACKBERRY value
         * @property {number} BLACKBERRYX=4 BLACKBERRYX value
         * @property {number} S40=5 S40 value
         * @property {number} S60=6 S60 value
         * @property {number} PYTHON_CLIENT=7 PYTHON_CLIENT value
         * @property {number} TIZEN=8 TIZEN value
         * @property {number} ENTERPRISE=9 ENTERPRISE value
         * @property {number} SMB_ANDROID=10 SMB_ANDROID value
         * @property {number} KAIOS=11 KAIOS value
         * @property {number} SMB_IOS=12 SMB_IOS value
         * @property {number} WINDOWS=13 WINDOWS value
         * @property {number} WEB=14 WEB value
         * @property {number} PORTAL=15 PORTAL value
         * @property {number} GREEN_ANDROID=16 GREEN_ANDROID value
         * @property {number} GREEN_IPHONE=17 GREEN_IPHONE value
         * @property {number} BLUE_ANDROID=18 BLUE_ANDROID value
         * @property {number} BLUE_IPHONE=19 BLUE_IPHONE value
         * @property {number} FBLITE_ANDROID=20 FBLITE_ANDROID value
         * @property {number} MLITE_ANDROID=21 MLITE_ANDROID value
         * @property {number} IGLITE_ANDROID=22 IGLITE_ANDROID value
         * @property {number} PAGE=23 PAGE value
         * @property {number} MACOS=24 MACOS value
         * @property {number} OCULUS_MSG=25 OCULUS_MSG value
         * @property {number} OCULUS_CALL=26 OCULUS_CALL value
         * @property {number} MILAN=27 MILAN value
         * @property {number} CAPI=28 CAPI value
         */
        UserAgent.UserAgentPlatform = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "ANDROID"] = 0;
            values[valuesById[1] = "IOS"] = 1;
            values[valuesById[2] = "WINDOWS_PHONE"] = 2;
            values[valuesById[3] = "BLACKBERRY"] = 3;
            values[valuesById[4] = "BLACKBERRYX"] = 4;
            values[valuesById[5] = "S40"] = 5;
            values[valuesById[6] = "S60"] = 6;
            values[valuesById[7] = "PYTHON_CLIENT"] = 7;
            values[valuesById[8] = "TIZEN"] = 8;
            values[valuesById[9] = "ENTERPRISE"] = 9;
            values[valuesById[10] = "SMB_ANDROID"] = 10;
            values[valuesById[11] = "KAIOS"] = 11;
            values[valuesById[12] = "SMB_IOS"] = 12;
            values[valuesById[13] = "WINDOWS"] = 13;
            values[valuesById[14] = "WEB"] = 14;
            values[valuesById[15] = "PORTAL"] = 15;
            values[valuesById[16] = "GREEN_ANDROID"] = 16;
            values[valuesById[17] = "GREEN_IPHONE"] = 17;
            values[valuesById[18] = "BLUE_ANDROID"] = 18;
            values[valuesById[19] = "BLUE_IPHONE"] = 19;
            values[valuesById[20] = "FBLITE_ANDROID"] = 20;
            values[valuesById[21] = "MLITE_ANDROID"] = 21;
            values[valuesById[22] = "IGLITE_ANDROID"] = 22;
            values[valuesById[23] = "PAGE"] = 23;
            values[valuesById[24] = "MACOS"] = 24;
            values[valuesById[25] = "OCULUS_MSG"] = 25;
            values[valuesById[26] = "OCULUS_CALL"] = 26;
            values[valuesById[27] = "MILAN"] = 27;
            values[valuesById[28] = "CAPI"] = 28;
            return values;
        })();

        /**
         * UserAgentReleaseChannel enum.
         * @name proto.UserAgent.UserAgentReleaseChannel
         * @enum {number}
         * @property {number} RELEASE=0 RELEASE value
         * @property {number} BETA=1 BETA value
         * @property {number} ALPHA=2 ALPHA value
         * @property {number} DEBUG=3 DEBUG value
         */
        UserAgent.UserAgentReleaseChannel = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "RELEASE"] = 0;
            values[valuesById[1] = "BETA"] = 1;
            values[valuesById[2] = "ALPHA"] = 2;
            values[valuesById[3] = "DEBUG"] = 3;
            return values;
        })();

        return UserAgent;
    })();

    proto.WebdPayload = (function() {

        /**
         * Properties of a WebdPayload.
         * @memberof proto
         * @interface IWebdPayload
         * @property {boolean|null} [usesParticipantInKey] WebdPayload usesParticipantInKey
         * @property {boolean|null} [supportsStarredMessages] WebdPayload supportsStarredMessages
         * @property {boolean|null} [supportsDocumentMessages] WebdPayload supportsDocumentMessages
         * @property {boolean|null} [supportsUrlMessages] WebdPayload supportsUrlMessages
         * @property {boolean|null} [supportsMediaRetry] WebdPayload supportsMediaRetry
         * @property {boolean|null} [supportsE2EImage] WebdPayload supportsE2EImage
         * @property {boolean|null} [supportsE2EVideo] WebdPayload supportsE2EVideo
         * @property {boolean|null} [supportsE2EAudio] WebdPayload supportsE2EAudio
         * @property {boolean|null} [supportsE2EDocument] WebdPayload supportsE2EDocument
         * @property {string|null} [documentTypes] WebdPayload documentTypes
         * @property {Uint8Array|null} [features] WebdPayload features
         */

        /**
         * Constructs a new WebdPayload.
         * @memberof proto
         * @classdesc Represents a WebdPayload.
         * @implements IWebdPayload
         * @constructor
         * @param {proto.IWebdPayload=} [properties] Properties to set
         */
        function WebdPayload(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * WebdPayload usesParticipantInKey.
         * @member {boolean} usesParticipantInKey
         * @memberof proto.WebdPayload
         * @instance
         */
        WebdPayload.prototype.usesParticipantInKey = false;

        /**
         * WebdPayload supportsStarredMessages.
         * @member {boolean} supportsStarredMessages
         * @memberof proto.WebdPayload
         * @instance
         */
        WebdPayload.prototype.supportsStarredMessages = false;

        /**
         * WebdPayload supportsDocumentMessages.
         * @member {boolean} supportsDocumentMessages
         * @memberof proto.WebdPayload
         * @instance
         */
        WebdPayload.prototype.supportsDocumentMessages = false;

        /**
         * WebdPayload supportsUrlMessages.
         * @member {boolean} supportsUrlMessages
         * @memberof proto.WebdPayload
         * @instance
         */
        WebdPayload.prototype.supportsUrlMessages = false;

        /**
         * WebdPayload supportsMediaRetry.
         * @member {boolean} supportsMediaRetry
         * @memberof proto.WebdPayload
         * @instance
         */
        WebdPayload.prototype.supportsMediaRetry = false;

        /**
         * WebdPayload supportsE2EImage.
         * @member {boolean} supportsE2EImage
         * @memberof proto.WebdPayload
         * @instance
         */
        WebdPayload.prototype.supportsE2EImage = false;

        /**
         * WebdPayload supportsE2EVideo.
         * @member {boolean} supportsE2EVideo
         * @memberof proto.WebdPayload
         * @instance
         */
        WebdPayload.prototype.supportsE2EVideo = false;

        /**
         * WebdPayload supportsE2EAudio.
         * @member {boolean} supportsE2EAudio
         * @memberof proto.WebdPayload
         * @instance
         */
        WebdPayload.prototype.supportsE2EAudio = false;

        /**
         * WebdPayload supportsE2EDocument.
         * @member {boolean} supportsE2EDocument
         * @memberof proto.WebdPayload
         * @instance
         */
        WebdPayload.prototype.supportsE2EDocument = false;

        /**
         * WebdPayload documentTypes.
         * @member {string} documentTypes
         * @memberof proto.WebdPayload
         * @instance
         */
        WebdPayload.prototype.documentTypes = "";

        /**
         * WebdPayload features.
         * @member {Uint8Array} features
         * @memberof proto.WebdPayload
         * @instance
         */
        WebdPayload.prototype.features = $util.newBuffer([]);

        /**
         * Creates a new WebdPayload instance using the specified properties.
         * @function create
         * @memberof proto.WebdPayload
         * @static
         * @param {proto.IWebdPayload=} [properties] Properties to set
         * @returns {proto.WebdPayload} WebdPayload instance
         */
        WebdPayload.create = function create(properties) {
            return new WebdPayload(properties);
        };

        /**
         * Encodes the specified WebdPayload message. Does not implicitly {@link proto.WebdPayload.verify|verify} messages.
         * @function encode
         * @memberof proto.WebdPayload
         * @static
         * @param {proto.IWebdPayload} message WebdPayload message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        WebdPayload.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.usesParticipantInKey != null && Object.hasOwnProperty.call(message, "usesParticipantInKey"))
                writer.uint32(/* id 1, wireType 0 =*/8).bool(message.usesParticipantInKey);
            if (message.supportsStarredMessages != null && Object.hasOwnProperty.call(message, "supportsStarredMessages"))
                writer.uint32(/* id 2, wireType 0 =*/16).bool(message.supportsStarredMessages);
            if (message.supportsDocumentMessages != null && Object.hasOwnProperty.call(message, "supportsDocumentMessages"))
                writer.uint32(/* id 3, wireType 0 =*/24).bool(message.supportsDocumentMessages);
            if (message.supportsUrlMessages != null && Object.hasOwnProperty.call(message, "supportsUrlMessages"))
                writer.uint32(/* id 4, wireType 0 =*/32).bool(message.supportsUrlMessages);
            if (message.supportsMediaRetry != null && Object.hasOwnProperty.call(message, "supportsMediaRetry"))
                writer.uint32(/* id 5, wireType 0 =*/40).bool(message.supportsMediaRetry);
            if (message.supportsE2EImage != null && Object.hasOwnProperty.call(message, "supportsE2EImage"))
                writer.uint32(/* id 6, wireType 0 =*/48).bool(message.supportsE2EImage);
            if (message.supportsE2EVideo != null && Object.hasOwnProperty.call(message, "supportsE2EVideo"))
                writer.uint32(/* id 7, wireType 0 =*/56).bool(message.supportsE2EVideo);
            if (message.supportsE2EAudio != null && Object.hasOwnProperty.call(message, "supportsE2EAudio"))
                writer.uint32(/* id 8, wireType 0 =*/64).bool(message.supportsE2EAudio);
            if (message.supportsE2EDocument != null && Object.hasOwnProperty.call(message, "supportsE2EDocument"))
                writer.uint32(/* id 9, wireType 0 =*/72).bool(message.supportsE2EDocument);
            if (message.documentTypes != null && Object.hasOwnProperty.call(message, "documentTypes"))
                writer.uint32(/* id 10, wireType 2 =*/82).string(message.documentTypes);
            if (message.features != null && Object.hasOwnProperty.call(message, "features"))
                writer.uint32(/* id 11, wireType 2 =*/90).bytes(message.features);
            return writer;
        };

        /**
         * Encodes the specified WebdPayload message, length delimited. Does not implicitly {@link proto.WebdPayload.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.WebdPayload
         * @static
         * @param {proto.IWebdPayload} message WebdPayload message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        WebdPayload.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a WebdPayload message from the specified reader or buffer.
         * @function decode
         * @memberof proto.WebdPayload
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.WebdPayload} WebdPayload
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        WebdPayload.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.WebdPayload();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.usesParticipantInKey = reader.bool();
                    break;
                case 2:
                    message.supportsStarredMessages = reader.bool();
                    break;
                case 3:
                    message.supportsDocumentMessages = reader.bool();
                    break;
                case 4:
                    message.supportsUrlMessages = reader.bool();
                    break;
                case 5:
                    message.supportsMediaRetry = reader.bool();
                    break;
                case 6:
                    message.supportsE2EImage = reader.bool();
                    break;
                case 7:
                    message.supportsE2EVideo = reader.bool();
                    break;
                case 8:
                    message.supportsE2EAudio = reader.bool();
                    break;
                case 9:
                    message.supportsE2EDocument = reader.bool();
                    break;
                case 10:
                    message.documentTypes = reader.string();
                    break;
                case 11:
                    message.features = reader.bytes();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a WebdPayload message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.WebdPayload
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.WebdPayload} WebdPayload
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        WebdPayload.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a WebdPayload message.
         * @function verify
         * @memberof proto.WebdPayload
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        WebdPayload.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.usesParticipantInKey != null && message.hasOwnProperty("usesParticipantInKey"))
                if (typeof message.usesParticipantInKey !== "boolean")
                    return "usesParticipantInKey: boolean expected";
            if (message.supportsStarredMessages != null && message.hasOwnProperty("supportsStarredMessages"))
                if (typeof message.supportsStarredMessages !== "boolean")
                    return "supportsStarredMessages: boolean expected";
            if (message.supportsDocumentMessages != null && message.hasOwnProperty("supportsDocumentMessages"))
                if (typeof message.supportsDocumentMessages !== "boolean")
                    return "supportsDocumentMessages: boolean expected";
            if (message.supportsUrlMessages != null && message.hasOwnProperty("supportsUrlMessages"))
                if (typeof message.supportsUrlMessages !== "boolean")
                    return "supportsUrlMessages: boolean expected";
            if (message.supportsMediaRetry != null && message.hasOwnProperty("supportsMediaRetry"))
                if (typeof message.supportsMediaRetry !== "boolean")
                    return "supportsMediaRetry: boolean expected";
            if (message.supportsE2EImage != null && message.hasOwnProperty("supportsE2EImage"))
                if (typeof message.supportsE2EImage !== "boolean")
                    return "supportsE2EImage: boolean expected";
            if (message.supportsE2EVideo != null && message.hasOwnProperty("supportsE2EVideo"))
                if (typeof message.supportsE2EVideo !== "boolean")
                    return "supportsE2EVideo: boolean expected";
            if (message.supportsE2EAudio != null && message.hasOwnProperty("supportsE2EAudio"))
                if (typeof message.supportsE2EAudio !== "boolean")
                    return "supportsE2EAudio: boolean expected";
            if (message.supportsE2EDocument != null && message.hasOwnProperty("supportsE2EDocument"))
                if (typeof message.supportsE2EDocument !== "boolean")
                    return "supportsE2EDocument: boolean expected";
            if (message.documentTypes != null && message.hasOwnProperty("documentTypes"))
                if (!$util.isString(message.documentTypes))
                    return "documentTypes: string expected";
            if (message.features != null && message.hasOwnProperty("features"))
                if (!(message.features && typeof message.features.length === "number" || $util.isString(message.features)))
                    return "features: buffer expected";
            return null;
        };

        /**
         * Creates a WebdPayload message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.WebdPayload
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.WebdPayload} WebdPayload
         */
        WebdPayload.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.WebdPayload)
                return object;
            var message = new $root.proto.WebdPayload();
            if (object.usesParticipantInKey != null)
                message.usesParticipantInKey = Boolean(object.usesParticipantInKey);
            if (object.supportsStarredMessages != null)
                message.supportsStarredMessages = Boolean(object.supportsStarredMessages);
            if (object.supportsDocumentMessages != null)
                message.supportsDocumentMessages = Boolean(object.supportsDocumentMessages);
            if (object.supportsUrlMessages != null)
                message.supportsUrlMessages = Boolean(object.supportsUrlMessages);
            if (object.supportsMediaRetry != null)
                message.supportsMediaRetry = Boolean(object.supportsMediaRetry);
            if (object.supportsE2EImage != null)
                message.supportsE2EImage = Boolean(object.supportsE2EImage);
            if (object.supportsE2EVideo != null)
                message.supportsE2EVideo = Boolean(object.supportsE2EVideo);
            if (object.supportsE2EAudio != null)
                message.supportsE2EAudio = Boolean(object.supportsE2EAudio);
            if (object.supportsE2EDocument != null)
                message.supportsE2EDocument = Boolean(object.supportsE2EDocument);
            if (object.documentTypes != null)
                message.documentTypes = String(object.documentTypes);
            if (object.features != null)
                if (typeof object.features === "string")
                    $util.base64.decode(object.features, message.features = $util.newBuffer($util.base64.length(object.features)), 0);
                else if (object.features.length)
                    message.features = object.features;
            return message;
        };

        /**
         * Creates a plain object from a WebdPayload message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.WebdPayload
         * @static
         * @param {proto.WebdPayload} message WebdPayload
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        WebdPayload.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.usesParticipantInKey = false;
                object.supportsStarredMessages = false;
                object.supportsDocumentMessages = false;
                object.supportsUrlMessages = false;
                object.supportsMediaRetry = false;
                object.supportsE2EImage = false;
                object.supportsE2EVideo = false;
                object.supportsE2EAudio = false;
                object.supportsE2EDocument = false;
                object.documentTypes = "";
                if (options.bytes === String)
                    object.features = "";
                else {
                    object.features = [];
                    if (options.bytes !== Array)
                        object.features = $util.newBuffer(object.features);
                }
            }
            if (message.usesParticipantInKey != null && message.hasOwnProperty("usesParticipantInKey"))
                object.usesParticipantInKey = message.usesParticipantInKey;
            if (message.supportsStarredMessages != null && message.hasOwnProperty("supportsStarredMessages"))
                object.supportsStarredMessages = message.supportsStarredMessages;
            if (message.supportsDocumentMessages != null && message.hasOwnProperty("supportsDocumentMessages"))
                object.supportsDocumentMessages = message.supportsDocumentMessages;
            if (message.supportsUrlMessages != null && message.hasOwnProperty("supportsUrlMessages"))
                object.supportsUrlMessages = message.supportsUrlMessages;
            if (message.supportsMediaRetry != null && message.hasOwnProperty("supportsMediaRetry"))
                object.supportsMediaRetry = message.supportsMediaRetry;
            if (message.supportsE2EImage != null && message.hasOwnProperty("supportsE2EImage"))
                object.supportsE2EImage = message.supportsE2EImage;
            if (message.supportsE2EVideo != null && message.hasOwnProperty("supportsE2EVideo"))
                object.supportsE2EVideo = message.supportsE2EVideo;
            if (message.supportsE2EAudio != null && message.hasOwnProperty("supportsE2EAudio"))
                object.supportsE2EAudio = message.supportsE2EAudio;
            if (message.supportsE2EDocument != null && message.hasOwnProperty("supportsE2EDocument"))
                object.supportsE2EDocument = message.supportsE2EDocument;
            if (message.documentTypes != null && message.hasOwnProperty("documentTypes"))
                object.documentTypes = message.documentTypes;
            if (message.features != null && message.hasOwnProperty("features"))
                object.features = options.bytes === String ? $util.base64.encode(message.features, 0, message.features.length) : options.bytes === Array ? Array.prototype.slice.call(message.features) : message.features;
            return object;
        };

        /**
         * Converts this WebdPayload to JSON.
         * @function toJSON
         * @memberof proto.WebdPayload
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        WebdPayload.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return WebdPayload;
    })();

    proto.WebInfo = (function() {

        /**
         * Properties of a WebInfo.
         * @memberof proto
         * @interface IWebInfo
         * @property {string|null} [refToken] WebInfo refToken
         * @property {string|null} [version] WebInfo version
         * @property {proto.IWebdPayload|null} [webdPayload] WebInfo webdPayload
         * @property {proto.WebInfo.WebInfoWebSubPlatform|null} [webSubPlatform] WebInfo webSubPlatform
         */

        /**
         * Constructs a new WebInfo.
         * @memberof proto
         * @classdesc Represents a WebInfo.
         * @implements IWebInfo
         * @constructor
         * @param {proto.IWebInfo=} [properties] Properties to set
         */
        function WebInfo(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * WebInfo refToken.
         * @member {string} refToken
         * @memberof proto.WebInfo
         * @instance
         */
        WebInfo.prototype.refToken = "";

        /**
         * WebInfo version.
         * @member {string} version
         * @memberof proto.WebInfo
         * @instance
         */
        WebInfo.prototype.version = "";

        /**
         * WebInfo webdPayload.
         * @member {proto.IWebdPayload|null|undefined} webdPayload
         * @memberof proto.WebInfo
         * @instance
         */
        WebInfo.prototype.webdPayload = null;

        /**
         * WebInfo webSubPlatform.
         * @member {proto.WebInfo.WebInfoWebSubPlatform} webSubPlatform
         * @memberof proto.WebInfo
         * @instance
         */
        WebInfo.prototype.webSubPlatform = 0;

        /**
         * Creates a new WebInfo instance using the specified properties.
         * @function create
         * @memberof proto.WebInfo
         * @static
         * @param {proto.IWebInfo=} [properties] Properties to set
         * @returns {proto.WebInfo} WebInfo instance
         */
        WebInfo.create = function create(properties) {
            return new WebInfo(properties);
        };

        /**
         * Encodes the specified WebInfo message. Does not implicitly {@link proto.WebInfo.verify|verify} messages.
         * @function encode
         * @memberof proto.WebInfo
         * @static
         * @param {proto.IWebInfo} message WebInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        WebInfo.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.refToken != null && Object.hasOwnProperty.call(message, "refToken"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.refToken);
            if (message.version != null && Object.hasOwnProperty.call(message, "version"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.version);
            if (message.webdPayload != null && Object.hasOwnProperty.call(message, "webdPayload"))
                $root.proto.WebdPayload.encode(message.webdPayload, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.webSubPlatform != null && Object.hasOwnProperty.call(message, "webSubPlatform"))
                writer.uint32(/* id 4, wireType 0 =*/32).int32(message.webSubPlatform);
            return writer;
        };

        /**
         * Encodes the specified WebInfo message, length delimited. Does not implicitly {@link proto.WebInfo.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.WebInfo
         * @static
         * @param {proto.IWebInfo} message WebInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        WebInfo.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a WebInfo message from the specified reader or buffer.
         * @function decode
         * @memberof proto.WebInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.WebInfo} WebInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        WebInfo.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.WebInfo();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.refToken = reader.string();
                    break;
                case 2:
                    message.version = reader.string();
                    break;
                case 3:
                    message.webdPayload = $root.proto.WebdPayload.decode(reader, reader.uint32());
                    break;
                case 4:
                    message.webSubPlatform = reader.int32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a WebInfo message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.WebInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.WebInfo} WebInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        WebInfo.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a WebInfo message.
         * @function verify
         * @memberof proto.WebInfo
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        WebInfo.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.refToken != null && message.hasOwnProperty("refToken"))
                if (!$util.isString(message.refToken))
                    return "refToken: string expected";
            if (message.version != null && message.hasOwnProperty("version"))
                if (!$util.isString(message.version))
                    return "version: string expected";
            if (message.webdPayload != null && message.hasOwnProperty("webdPayload")) {
                var error = $root.proto.WebdPayload.verify(message.webdPayload);
                if (error)
                    return "webdPayload." + error;
            }
            if (message.webSubPlatform != null && message.hasOwnProperty("webSubPlatform"))
                switch (message.webSubPlatform) {
                default:
                    return "webSubPlatform: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                    break;
                }
            return null;
        };

        /**
         * Creates a WebInfo message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.WebInfo
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.WebInfo} WebInfo
         */
        WebInfo.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.WebInfo)
                return object;
            var message = new $root.proto.WebInfo();
            if (object.refToken != null)
                message.refToken = String(object.refToken);
            if (object.version != null)
                message.version = String(object.version);
            if (object.webdPayload != null) {
                if (typeof object.webdPayload !== "object")
                    throw TypeError(".proto.WebInfo.webdPayload: object expected");
                message.webdPayload = $root.proto.WebdPayload.fromObject(object.webdPayload);
            }
            switch (object.webSubPlatform) {
            case "WEB_BROWSER":
            case 0:
                message.webSubPlatform = 0;
                break;
            case "APP_STORE":
            case 1:
                message.webSubPlatform = 1;
                break;
            case "WIN_STORE":
            case 2:
                message.webSubPlatform = 2;
                break;
            case "DARWIN":
            case 3:
                message.webSubPlatform = 3;
                break;
            case "WIN32":
            case 4:
                message.webSubPlatform = 4;
                break;
            }
            return message;
        };

        /**
         * Creates a plain object from a WebInfo message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.WebInfo
         * @static
         * @param {proto.WebInfo} message WebInfo
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        WebInfo.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.refToken = "";
                object.version = "";
                object.webdPayload = null;
                object.webSubPlatform = options.enums === String ? "WEB_BROWSER" : 0;
            }
            if (message.refToken != null && message.hasOwnProperty("refToken"))
                object.refToken = message.refToken;
            if (message.version != null && message.hasOwnProperty("version"))
                object.version = message.version;
            if (message.webdPayload != null && message.hasOwnProperty("webdPayload"))
                object.webdPayload = $root.proto.WebdPayload.toObject(message.webdPayload, options);
            if (message.webSubPlatform != null && message.hasOwnProperty("webSubPlatform"))
                object.webSubPlatform = options.enums === String ? $root.proto.WebInfo.WebInfoWebSubPlatform[message.webSubPlatform] : message.webSubPlatform;
            return object;
        };

        /**
         * Converts this WebInfo to JSON.
         * @function toJSON
         * @memberof proto.WebInfo
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        WebInfo.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * WebInfoWebSubPlatform enum.
         * @name proto.WebInfo.WebInfoWebSubPlatform
         * @enum {number}
         * @property {number} WEB_BROWSER=0 WEB_BROWSER value
         * @property {number} APP_STORE=1 APP_STORE value
         * @property {number} WIN_STORE=2 WIN_STORE value
         * @property {number} DARWIN=3 DARWIN value
         * @property {number} WIN32=4 WIN32 value
         */
        WebInfo.WebInfoWebSubPlatform = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "WEB_BROWSER"] = 0;
            values[valuesById[1] = "APP_STORE"] = 1;
            values[valuesById[2] = "WIN_STORE"] = 2;
            values[valuesById[3] = "DARWIN"] = 3;
            values[valuesById[4] = "WIN32"] = 4;
            return values;
        })();

        return WebInfo;
    })();

    proto.DNSSource = (function() {

        /**
         * Properties of a DNSSource.
         * @memberof proto
         * @interface IDNSSource
         * @property {proto.DNSSource.DNSSourceDNSResolutionMethod|null} [dnsMethod] DNSSource dnsMethod
         * @property {boolean|null} [appCached] DNSSource appCached
         */

        /**
         * Constructs a new DNSSource.
         * @memberof proto
         * @classdesc Represents a DNSSource.
         * @implements IDNSSource
         * @constructor
         * @param {proto.IDNSSource=} [properties] Properties to set
         */
        function DNSSource(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * DNSSource dnsMethod.
         * @member {proto.DNSSource.DNSSourceDNSResolutionMethod} dnsMethod
         * @memberof proto.DNSSource
         * @instance
         */
        DNSSource.prototype.dnsMethod = 0;

        /**
         * DNSSource appCached.
         * @member {boolean} appCached
         * @memberof proto.DNSSource
         * @instance
         */
        DNSSource.prototype.appCached = false;

        /**
         * Creates a new DNSSource instance using the specified properties.
         * @function create
         * @memberof proto.DNSSource
         * @static
         * @param {proto.IDNSSource=} [properties] Properties to set
         * @returns {proto.DNSSource} DNSSource instance
         */
        DNSSource.create = function create(properties) {
            return new DNSSource(properties);
        };

        /**
         * Encodes the specified DNSSource message. Does not implicitly {@link proto.DNSSource.verify|verify} messages.
         * @function encode
         * @memberof proto.DNSSource
         * @static
         * @param {proto.IDNSSource} message DNSSource message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        DNSSource.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.dnsMethod != null && Object.hasOwnProperty.call(message, "dnsMethod"))
                writer.uint32(/* id 15, wireType 0 =*/120).int32(message.dnsMethod);
            if (message.appCached != null && Object.hasOwnProperty.call(message, "appCached"))
                writer.uint32(/* id 16, wireType 0 =*/128).bool(message.appCached);
            return writer;
        };

        /**
         * Encodes the specified DNSSource message, length delimited. Does not implicitly {@link proto.DNSSource.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.DNSSource
         * @static
         * @param {proto.IDNSSource} message DNSSource message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        DNSSource.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a DNSSource message from the specified reader or buffer.
         * @function decode
         * @memberof proto.DNSSource
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.DNSSource} DNSSource
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        DNSSource.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.DNSSource();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 15:
                    message.dnsMethod = reader.int32();
                    break;
                case 16:
                    message.appCached = reader.bool();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a DNSSource message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.DNSSource
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.DNSSource} DNSSource
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        DNSSource.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a DNSSource message.
         * @function verify
         * @memberof proto.DNSSource
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        DNSSource.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.dnsMethod != null && message.hasOwnProperty("dnsMethod"))
                switch (message.dnsMethod) {
                default:
                    return "dnsMethod: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                    break;
                }
            if (message.appCached != null && message.hasOwnProperty("appCached"))
                if (typeof message.appCached !== "boolean")
                    return "appCached: boolean expected";
            return null;
        };

        /**
         * Creates a DNSSource message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.DNSSource
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.DNSSource} DNSSource
         */
        DNSSource.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.DNSSource)
                return object;
            var message = new $root.proto.DNSSource();
            switch (object.dnsMethod) {
            case "SYSTEM":
            case 0:
                message.dnsMethod = 0;
                break;
            case "GOOGLE":
            case 1:
                message.dnsMethod = 1;
                break;
            case "HARDCODED":
            case 2:
                message.dnsMethod = 2;
                break;
            case "OVERRIDE":
            case 3:
                message.dnsMethod = 3;
                break;
            case "FALLBACK":
            case 4:
                message.dnsMethod = 4;
                break;
            }
            if (object.appCached != null)
                message.appCached = Boolean(object.appCached);
            return message;
        };

        /**
         * Creates a plain object from a DNSSource message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.DNSSource
         * @static
         * @param {proto.DNSSource} message DNSSource
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        DNSSource.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.dnsMethod = options.enums === String ? "SYSTEM" : 0;
                object.appCached = false;
            }
            if (message.dnsMethod != null && message.hasOwnProperty("dnsMethod"))
                object.dnsMethod = options.enums === String ? $root.proto.DNSSource.DNSSourceDNSResolutionMethod[message.dnsMethod] : message.dnsMethod;
            if (message.appCached != null && message.hasOwnProperty("appCached"))
                object.appCached = message.appCached;
            return object;
        };

        /**
         * Converts this DNSSource to JSON.
         * @function toJSON
         * @memberof proto.DNSSource
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        DNSSource.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * DNSSourceDNSResolutionMethod enum.
         * @name proto.DNSSource.DNSSourceDNSResolutionMethod
         * @enum {number}
         * @property {number} SYSTEM=0 SYSTEM value
         * @property {number} GOOGLE=1 GOOGLE value
         * @property {number} HARDCODED=2 HARDCODED value
         * @property {number} OVERRIDE=3 OVERRIDE value
         * @property {number} FALLBACK=4 FALLBACK value
         */
        DNSSource.DNSSourceDNSResolutionMethod = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "SYSTEM"] = 0;
            values[valuesById[1] = "GOOGLE"] = 1;
            values[valuesById[2] = "HARDCODED"] = 2;
            values[valuesById[3] = "OVERRIDE"] = 3;
            values[valuesById[4] = "FALLBACK"] = 4;
            return values;
        })();

        return DNSSource;
    })();

    proto.CompanionRegData = (function() {

        /**
         * Properties of a CompanionRegData.
         * @memberof proto
         * @interface ICompanionRegData
         * @property {Uint8Array|null} [eRegid] CompanionRegData eRegid
         * @property {Uint8Array|null} [eKeytype] CompanionRegData eKeytype
         * @property {Uint8Array|null} [eIdent] CompanionRegData eIdent
         * @property {Uint8Array|null} [eSkeyId] CompanionRegData eSkeyId
         * @property {Uint8Array|null} [eSkeyVal] CompanionRegData eSkeyVal
         * @property {Uint8Array|null} [eSkeySig] CompanionRegData eSkeySig
         * @property {Uint8Array|null} [buildHash] CompanionRegData buildHash
         * @property {Uint8Array|null} [companionProps] CompanionRegData companionProps
         */

        /**
         * Constructs a new CompanionRegData.
         * @memberof proto
         * @classdesc Represents a CompanionRegData.
         * @implements ICompanionRegData
         * @constructor
         * @param {proto.ICompanionRegData=} [properties] Properties to set
         */
        function CompanionRegData(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * CompanionRegData eRegid.
         * @member {Uint8Array} eRegid
         * @memberof proto.CompanionRegData
         * @instance
         */
        CompanionRegData.prototype.eRegid = $util.newBuffer([]);

        /**
         * CompanionRegData eKeytype.
         * @member {Uint8Array} eKeytype
         * @memberof proto.CompanionRegData
         * @instance
         */
        CompanionRegData.prototype.eKeytype = $util.newBuffer([]);

        /**
         * CompanionRegData eIdent.
         * @member {Uint8Array} eIdent
         * @memberof proto.CompanionRegData
         * @instance
         */
        CompanionRegData.prototype.eIdent = $util.newBuffer([]);

        /**
         * CompanionRegData eSkeyId.
         * @member {Uint8Array} eSkeyId
         * @memberof proto.CompanionRegData
         * @instance
         */
        CompanionRegData.prototype.eSkeyId = $util.newBuffer([]);

        /**
         * CompanionRegData eSkeyVal.
         * @member {Uint8Array} eSkeyVal
         * @memberof proto.CompanionRegData
         * @instance
         */
        CompanionRegData.prototype.eSkeyVal = $util.newBuffer([]);

        /**
         * CompanionRegData eSkeySig.
         * @member {Uint8Array} eSkeySig
         * @memberof proto.CompanionRegData
         * @instance
         */
        CompanionRegData.prototype.eSkeySig = $util.newBuffer([]);

        /**
         * CompanionRegData buildHash.
         * @member {Uint8Array} buildHash
         * @memberof proto.CompanionRegData
         * @instance
         */
        CompanionRegData.prototype.buildHash = $util.newBuffer([]);

        /**
         * CompanionRegData companionProps.
         * @member {Uint8Array} companionProps
         * @memberof proto.CompanionRegData
         * @instance
         */
        CompanionRegData.prototype.companionProps = $util.newBuffer([]);

        /**
         * Creates a new CompanionRegData instance using the specified properties.
         * @function create
         * @memberof proto.CompanionRegData
         * @static
         * @param {proto.ICompanionRegData=} [properties] Properties to set
         * @returns {proto.CompanionRegData} CompanionRegData instance
         */
        CompanionRegData.create = function create(properties) {
            return new CompanionRegData(properties);
        };

        /**
         * Encodes the specified CompanionRegData message. Does not implicitly {@link proto.CompanionRegData.verify|verify} messages.
         * @function encode
         * @memberof proto.CompanionRegData
         * @static
         * @param {proto.ICompanionRegData} message CompanionRegData message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CompanionRegData.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.eRegid != null && Object.hasOwnProperty.call(message, "eRegid"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.eRegid);
            if (message.eKeytype != null && Object.hasOwnProperty.call(message, "eKeytype"))
                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.eKeytype);
            if (message.eIdent != null && Object.hasOwnProperty.call(message, "eIdent"))
                writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.eIdent);
            if (message.eSkeyId != null && Object.hasOwnProperty.call(message, "eSkeyId"))
                writer.uint32(/* id 4, wireType 2 =*/34).bytes(message.eSkeyId);
            if (message.eSkeyVal != null && Object.hasOwnProperty.call(message, "eSkeyVal"))
                writer.uint32(/* id 5, wireType 2 =*/42).bytes(message.eSkeyVal);
            if (message.eSkeySig != null && Object.hasOwnProperty.call(message, "eSkeySig"))
                writer.uint32(/* id 6, wireType 2 =*/50).bytes(message.eSkeySig);
            if (message.buildHash != null && Object.hasOwnProperty.call(message, "buildHash"))
                writer.uint32(/* id 7, wireType 2 =*/58).bytes(message.buildHash);
            if (message.companionProps != null && Object.hasOwnProperty.call(message, "companionProps"))
                writer.uint32(/* id 8, wireType 2 =*/66).bytes(message.companionProps);
            return writer;
        };

        /**
         * Encodes the specified CompanionRegData message, length delimited. Does not implicitly {@link proto.CompanionRegData.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.CompanionRegData
         * @static
         * @param {proto.ICompanionRegData} message CompanionRegData message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CompanionRegData.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a CompanionRegData message from the specified reader or buffer.
         * @function decode
         * @memberof proto.CompanionRegData
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.CompanionRegData} CompanionRegData
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CompanionRegData.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.CompanionRegData();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.eRegid = reader.bytes();
                    break;
                case 2:
                    message.eKeytype = reader.bytes();
                    break;
                case 3:
                    message.eIdent = reader.bytes();
                    break;
                case 4:
                    message.eSkeyId = reader.bytes();
                    break;
                case 5:
                    message.eSkeyVal = reader.bytes();
                    break;
                case 6:
                    message.eSkeySig = reader.bytes();
                    break;
                case 7:
                    message.buildHash = reader.bytes();
                    break;
                case 8:
                    message.companionProps = reader.bytes();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a CompanionRegData message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.CompanionRegData
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.CompanionRegData} CompanionRegData
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CompanionRegData.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a CompanionRegData message.
         * @function verify
         * @memberof proto.CompanionRegData
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        CompanionRegData.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.eRegid != null && message.hasOwnProperty("eRegid"))
                if (!(message.eRegid && typeof message.eRegid.length === "number" || $util.isString(message.eRegid)))
                    return "eRegid: buffer expected";
            if (message.eKeytype != null && message.hasOwnProperty("eKeytype"))
                if (!(message.eKeytype && typeof message.eKeytype.length === "number" || $util.isString(message.eKeytype)))
                    return "eKeytype: buffer expected";
            if (message.eIdent != null && message.hasOwnProperty("eIdent"))
                if (!(message.eIdent && typeof message.eIdent.length === "number" || $util.isString(message.eIdent)))
                    return "eIdent: buffer expected";
            if (message.eSkeyId != null && message.hasOwnProperty("eSkeyId"))
                if (!(message.eSkeyId && typeof message.eSkeyId.length === "number" || $util.isString(message.eSkeyId)))
                    return "eSkeyId: buffer expected";
            if (message.eSkeyVal != null && message.hasOwnProperty("eSkeyVal"))
                if (!(message.eSkeyVal && typeof message.eSkeyVal.length === "number" || $util.isString(message.eSkeyVal)))
                    return "eSkeyVal: buffer expected";
            if (message.eSkeySig != null && message.hasOwnProperty("eSkeySig"))
                if (!(message.eSkeySig && typeof message.eSkeySig.length === "number" || $util.isString(message.eSkeySig)))
                    return "eSkeySig: buffer expected";
            if (message.buildHash != null && message.hasOwnProperty("buildHash"))
                if (!(message.buildHash && typeof message.buildHash.length === "number" || $util.isString(message.buildHash)))
                    return "buildHash: buffer expected";
            if (message.companionProps != null && message.hasOwnProperty("companionProps"))
                if (!(message.companionProps && typeof message.companionProps.length === "number" || $util.isString(message.companionProps)))
                    return "companionProps: buffer expected";
            return null;
        };

        /**
         * Creates a CompanionRegData message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.CompanionRegData
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.CompanionRegData} CompanionRegData
         */
        CompanionRegData.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.CompanionRegData)
                return object;
            var message = new $root.proto.CompanionRegData();
            if (object.eRegid != null)
                if (typeof object.eRegid === "string")
                    $util.base64.decode(object.eRegid, message.eRegid = $util.newBuffer($util.base64.length(object.eRegid)), 0);
                else if (object.eRegid.length)
                    message.eRegid = object.eRegid;
            if (object.eKeytype != null)
                if (typeof object.eKeytype === "string")
                    $util.base64.decode(object.eKeytype, message.eKeytype = $util.newBuffer($util.base64.length(object.eKeytype)), 0);
                else if (object.eKeytype.length)
                    message.eKeytype = object.eKeytype;
            if (object.eIdent != null)
                if (typeof object.eIdent === "string")
                    $util.base64.decode(object.eIdent, message.eIdent = $util.newBuffer($util.base64.length(object.eIdent)), 0);
                else if (object.eIdent.length)
                    message.eIdent = object.eIdent;
            if (object.eSkeyId != null)
                if (typeof object.eSkeyId === "string")
                    $util.base64.decode(object.eSkeyId, message.eSkeyId = $util.newBuffer($util.base64.length(object.eSkeyId)), 0);
                else if (object.eSkeyId.length)
                    message.eSkeyId = object.eSkeyId;
            if (object.eSkeyVal != null)
                if (typeof object.eSkeyVal === "string")
                    $util.base64.decode(object.eSkeyVal, message.eSkeyVal = $util.newBuffer($util.base64.length(object.eSkeyVal)), 0);
                else if (object.eSkeyVal.length)
                    message.eSkeyVal = object.eSkeyVal;
            if (object.eSkeySig != null)
                if (typeof object.eSkeySig === "string")
                    $util.base64.decode(object.eSkeySig, message.eSkeySig = $util.newBuffer($util.base64.length(object.eSkeySig)), 0);
                else if (object.eSkeySig.length)
                    message.eSkeySig = object.eSkeySig;
            if (object.buildHash != null)
                if (typeof object.buildHash === "string")
                    $util.base64.decode(object.buildHash, message.buildHash = $util.newBuffer($util.base64.length(object.buildHash)), 0);
                else if (object.buildHash.length)
                    message.buildHash = object.buildHash;
            if (object.companionProps != null)
                if (typeof object.companionProps === "string")
                    $util.base64.decode(object.companionProps, message.companionProps = $util.newBuffer($util.base64.length(object.companionProps)), 0);
                else if (object.companionProps.length)
                    message.companionProps = object.companionProps;
            return message;
        };

        /**
         * Creates a plain object from a CompanionRegData message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.CompanionRegData
         * @static
         * @param {proto.CompanionRegData} message CompanionRegData
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        CompanionRegData.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object.eRegid = "";
                else {
                    object.eRegid = [];
                    if (options.bytes !== Array)
                        object.eRegid = $util.newBuffer(object.eRegid);
                }
                if (options.bytes === String)
                    object.eKeytype = "";
                else {
                    object.eKeytype = [];
                    if (options.bytes !== Array)
                        object.eKeytype = $util.newBuffer(object.eKeytype);
                }
                if (options.bytes === String)
                    object.eIdent = "";
                else {
                    object.eIdent = [];
                    if (options.bytes !== Array)
                        object.eIdent = $util.newBuffer(object.eIdent);
                }
                if (options.bytes === String)
                    object.eSkeyId = "";
                else {
                    object.eSkeyId = [];
                    if (options.bytes !== Array)
                        object.eSkeyId = $util.newBuffer(object.eSkeyId);
                }
                if (options.bytes === String)
                    object.eSkeyVal = "";
                else {
                    object.eSkeyVal = [];
                    if (options.bytes !== Array)
                        object.eSkeyVal = $util.newBuffer(object.eSkeyVal);
                }
                if (options.bytes === String)
                    object.eSkeySig = "";
                else {
                    object.eSkeySig = [];
                    if (options.bytes !== Array)
                        object.eSkeySig = $util.newBuffer(object.eSkeySig);
                }
                if (options.bytes === String)
                    object.buildHash = "";
                else {
                    object.buildHash = [];
                    if (options.bytes !== Array)
                        object.buildHash = $util.newBuffer(object.buildHash);
                }
                if (options.bytes === String)
                    object.companionProps = "";
                else {
                    object.companionProps = [];
                    if (options.bytes !== Array)
                        object.companionProps = $util.newBuffer(object.companionProps);
                }
            }
            if (message.eRegid != null && message.hasOwnProperty("eRegid"))
                object.eRegid = options.bytes === String ? $util.base64.encode(message.eRegid, 0, message.eRegid.length) : options.bytes === Array ? Array.prototype.slice.call(message.eRegid) : message.eRegid;
            if (message.eKeytype != null && message.hasOwnProperty("eKeytype"))
                object.eKeytype = options.bytes === String ? $util.base64.encode(message.eKeytype, 0, message.eKeytype.length) : options.bytes === Array ? Array.prototype.slice.call(message.eKeytype) : message.eKeytype;
            if (message.eIdent != null && message.hasOwnProperty("eIdent"))
                object.eIdent = options.bytes === String ? $util.base64.encode(message.eIdent, 0, message.eIdent.length) : options.bytes === Array ? Array.prototype.slice.call(message.eIdent) : message.eIdent;
            if (message.eSkeyId != null && message.hasOwnProperty("eSkeyId"))
                object.eSkeyId = options.bytes === String ? $util.base64.encode(message.eSkeyId, 0, message.eSkeyId.length) : options.bytes === Array ? Array.prototype.slice.call(message.eSkeyId) : message.eSkeyId;
            if (message.eSkeyVal != null && message.hasOwnProperty("eSkeyVal"))
                object.eSkeyVal = options.bytes === String ? $util.base64.encode(message.eSkeyVal, 0, message.eSkeyVal.length) : options.bytes === Array ? Array.prototype.slice.call(message.eSkeyVal) : message.eSkeyVal;
            if (message.eSkeySig != null && message.hasOwnProperty("eSkeySig"))
                object.eSkeySig = options.bytes === String ? $util.base64.encode(message.eSkeySig, 0, message.eSkeySig.length) : options.bytes === Array ? Array.prototype.slice.call(message.eSkeySig) : message.eSkeySig;
            if (message.buildHash != null && message.hasOwnProperty("buildHash"))
                object.buildHash = options.bytes === String ? $util.base64.encode(message.buildHash, 0, message.buildHash.length) : options.bytes === Array ? Array.prototype.slice.call(message.buildHash) : message.buildHash;
            if (message.companionProps != null && message.hasOwnProperty("companionProps"))
                object.companionProps = options.bytes === String ? $util.base64.encode(message.companionProps, 0, message.companionProps.length) : options.bytes === Array ? Array.prototype.slice.call(message.companionProps) : message.companionProps;
            return object;
        };

        /**
         * Converts this CompanionRegData to JSON.
         * @function toJSON
         * @memberof proto.CompanionRegData
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        CompanionRegData.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return CompanionRegData;
    })();

    proto.ClientPayload = (function() {

        /**
         * Properties of a ClientPayload.
         * @memberof proto
         * @interface IClientPayload
         * @property {number|Long|null} [username] ClientPayload username
         * @property {boolean|null} [passive] ClientPayload passive
         * @property {proto.IUserAgent|null} [userAgent] ClientPayload userAgent
         * @property {proto.IWebInfo|null} [webInfo] ClientPayload webInfo
         * @property {string|null} [pushName] ClientPayload pushName
         * @property {number|null} [sessionId] ClientPayload sessionId
         * @property {boolean|null} [shortConnect] ClientPayload shortConnect
         * @property {proto.ClientPayload.ClientPayloadConnectType|null} [connectType] ClientPayload connectType
         * @property {proto.ClientPayload.ClientPayloadConnectReason|null} [connectReason] ClientPayload connectReason
         * @property {Array.<number>|null} [shards] ClientPayload shards
         * @property {proto.IDNSSource|null} [dnsSource] ClientPayload dnsSource
         * @property {number|null} [connectAttemptCount] ClientPayload connectAttemptCount
         * @property {number|null} [agent] ClientPayload agent
         * @property {number|null} [device] ClientPayload device
         * @property {proto.ICompanionRegData|null} [regData] ClientPayload regData
         * @property {proto.ClientPayload.ClientPayloadProduct|null} [product] ClientPayload product
         * @property {Uint8Array|null} [fbCat] ClientPayload fbCat
         * @property {Uint8Array|null} [fbUserAgent] ClientPayload fbUserAgent
         * @property {boolean|null} [oc] ClientPayload oc
         * @property {number|null} [lc] ClientPayload lc
         * @property {proto.ClientPayload.ClientPayloadIOSAppExtension|null} [iosAppExtension] ClientPayload iosAppExtension
         * @property {number|Long|null} [fbAppId] ClientPayload fbAppId
         * @property {Uint8Array|null} [fbDeviceId] ClientPayload fbDeviceId
         */

        /**
         * Constructs a new ClientPayload.
         * @memberof proto
         * @classdesc Represents a ClientPayload.
         * @implements IClientPayload
         * @constructor
         * @param {proto.IClientPayload=} [properties] Properties to set
         */
        function ClientPayload(properties) {
            this.shards = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ClientPayload username.
         * @member {number|Long} username
         * @memberof proto.ClientPayload
         * @instance
         */
        ClientPayload.prototype.username = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * ClientPayload passive.
         * @member {boolean} passive
         * @memberof proto.ClientPayload
         * @instance
         */
        ClientPayload.prototype.passive = false;

        /**
         * ClientPayload userAgent.
         * @member {proto.IUserAgent|null|undefined} userAgent
         * @memberof proto.ClientPayload
         * @instance
         */
        ClientPayload.prototype.userAgent = null;

        /**
         * ClientPayload webInfo.
         * @member {proto.IWebInfo|null|undefined} webInfo
         * @memberof proto.ClientPayload
         * @instance
         */
        ClientPayload.prototype.webInfo = null;

        /**
         * ClientPayload pushName.
         * @member {string} pushName
         * @memberof proto.ClientPayload
         * @instance
         */
        ClientPayload.prototype.pushName = "";

        /**
         * ClientPayload sessionId.
         * @member {number} sessionId
         * @memberof proto.ClientPayload
         * @instance
         */
        ClientPayload.prototype.sessionId = 0;

        /**
         * ClientPayload shortConnect.
         * @member {boolean} shortConnect
         * @memberof proto.ClientPayload
         * @instance
         */
        ClientPayload.prototype.shortConnect = false;

        /**
         * ClientPayload connectType.
         * @member {proto.ClientPayload.ClientPayloadConnectType} connectType
         * @memberof proto.ClientPayload
         * @instance
         */
        ClientPayload.prototype.connectType = 0;

        /**
         * ClientPayload connectReason.
         * @member {proto.ClientPayload.ClientPayloadConnectReason} connectReason
         * @memberof proto.ClientPayload
         * @instance
         */
        ClientPayload.prototype.connectReason = 0;

        /**
         * ClientPayload shards.
         * @member {Array.<number>} shards
         * @memberof proto.ClientPayload
         * @instance
         */
        ClientPayload.prototype.shards = $util.emptyArray;

        /**
         * ClientPayload dnsSource.
         * @member {proto.IDNSSource|null|undefined} dnsSource
         * @memberof proto.ClientPayload
         * @instance
         */
        ClientPayload.prototype.dnsSource = null;

        /**
         * ClientPayload connectAttemptCount.
         * @member {number} connectAttemptCount
         * @memberof proto.ClientPayload
         * @instance
         */
        ClientPayload.prototype.connectAttemptCount = 0;

        /**
         * ClientPayload agent.
         * @member {number} agent
         * @memberof proto.ClientPayload
         * @instance
         */
        ClientPayload.prototype.agent = 0;

        /**
         * ClientPayload device.
         * @member {number} device
         * @memberof proto.ClientPayload
         * @instance
         */
        ClientPayload.prototype.device = 0;

        /**
         * ClientPayload regData.
         * @member {proto.ICompanionRegData|null|undefined} regData
         * @memberof proto.ClientPayload
         * @instance
         */
        ClientPayload.prototype.regData = null;

        /**
         * ClientPayload product.
         * @member {proto.ClientPayload.ClientPayloadProduct} product
         * @memberof proto.ClientPayload
         * @instance
         */
        ClientPayload.prototype.product = 0;

        /**
         * ClientPayload fbCat.
         * @member {Uint8Array} fbCat
         * @memberof proto.ClientPayload
         * @instance
         */
        ClientPayload.prototype.fbCat = $util.newBuffer([]);

        /**
         * ClientPayload fbUserAgent.
         * @member {Uint8Array} fbUserAgent
         * @memberof proto.ClientPayload
         * @instance
         */
        ClientPayload.prototype.fbUserAgent = $util.newBuffer([]);

        /**
         * ClientPayload oc.
         * @member {boolean} oc
         * @memberof proto.ClientPayload
         * @instance
         */
        ClientPayload.prototype.oc = false;

        /**
         * ClientPayload lc.
         * @member {number} lc
         * @memberof proto.ClientPayload
         * @instance
         */
        ClientPayload.prototype.lc = 0;

        /**
         * ClientPayload iosAppExtension.
         * @member {proto.ClientPayload.ClientPayloadIOSAppExtension} iosAppExtension
         * @memberof proto.ClientPayload
         * @instance
         */
        ClientPayload.prototype.iosAppExtension = 0;

        /**
         * ClientPayload fbAppId.
         * @member {number|Long} fbAppId
         * @memberof proto.ClientPayload
         * @instance
         */
        ClientPayload.prototype.fbAppId = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * ClientPayload fbDeviceId.
         * @member {Uint8Array} fbDeviceId
         * @memberof proto.ClientPayload
         * @instance
         */
        ClientPayload.prototype.fbDeviceId = $util.newBuffer([]);

        /**
         * Creates a new ClientPayload instance using the specified properties.
         * @function create
         * @memberof proto.ClientPayload
         * @static
         * @param {proto.IClientPayload=} [properties] Properties to set
         * @returns {proto.ClientPayload} ClientPayload instance
         */
        ClientPayload.create = function create(properties) {
            return new ClientPayload(properties);
        };

        /**
         * Encodes the specified ClientPayload message. Does not implicitly {@link proto.ClientPayload.verify|verify} messages.
         * @function encode
         * @memberof proto.ClientPayload
         * @static
         * @param {proto.IClientPayload} message ClientPayload message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ClientPayload.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.username != null && Object.hasOwnProperty.call(message, "username"))
                writer.uint32(/* id 1, wireType 0 =*/8).uint64(message.username);
            if (message.passive != null && Object.hasOwnProperty.call(message, "passive"))
                writer.uint32(/* id 3, wireType 0 =*/24).bool(message.passive);
            if (message.userAgent != null && Object.hasOwnProperty.call(message, "userAgent"))
                $root.proto.UserAgent.encode(message.userAgent, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim();
            if (message.webInfo != null && Object.hasOwnProperty.call(message, "webInfo"))
                $root.proto.WebInfo.encode(message.webInfo, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim();
            if (message.pushName != null && Object.hasOwnProperty.call(message, "pushName"))
                writer.uint32(/* id 7, wireType 2 =*/58).string(message.pushName);
            if (message.sessionId != null && Object.hasOwnProperty.call(message, "sessionId"))
                writer.uint32(/* id 9, wireType 5 =*/77).sfixed32(message.sessionId);
            if (message.shortConnect != null && Object.hasOwnProperty.call(message, "shortConnect"))
                writer.uint32(/* id 10, wireType 0 =*/80).bool(message.shortConnect);
            if (message.connectType != null && Object.hasOwnProperty.call(message, "connectType"))
                writer.uint32(/* id 12, wireType 0 =*/96).int32(message.connectType);
            if (message.connectReason != null && Object.hasOwnProperty.call(message, "connectReason"))
                writer.uint32(/* id 13, wireType 0 =*/104).int32(message.connectReason);
            if (message.shards != null && message.shards.length)
                for (var i = 0; i < message.shards.length; ++i)
                    writer.uint32(/* id 14, wireType 0 =*/112).int32(message.shards[i]);
            if (message.dnsSource != null && Object.hasOwnProperty.call(message, "dnsSource"))
                $root.proto.DNSSource.encode(message.dnsSource, writer.uint32(/* id 15, wireType 2 =*/122).fork()).ldelim();
            if (message.connectAttemptCount != null && Object.hasOwnProperty.call(message, "connectAttemptCount"))
                writer.uint32(/* id 16, wireType 0 =*/128).uint32(message.connectAttemptCount);
            if (message.agent != null && Object.hasOwnProperty.call(message, "agent"))
                writer.uint32(/* id 17, wireType 0 =*/136).uint32(message.agent);
            if (message.device != null && Object.hasOwnProperty.call(message, "device"))
                writer.uint32(/* id 18, wireType 0 =*/144).uint32(message.device);
            if (message.regData != null && Object.hasOwnProperty.call(message, "regData"))
                $root.proto.CompanionRegData.encode(message.regData, writer.uint32(/* id 19, wireType 2 =*/154).fork()).ldelim();
            if (message.product != null && Object.hasOwnProperty.call(message, "product"))
                writer.uint32(/* id 20, wireType 0 =*/160).int32(message.product);
            if (message.fbCat != null && Object.hasOwnProperty.call(message, "fbCat"))
                writer.uint32(/* id 21, wireType 2 =*/170).bytes(message.fbCat);
            if (message.fbUserAgent != null && Object.hasOwnProperty.call(message, "fbUserAgent"))
                writer.uint32(/* id 22, wireType 2 =*/178).bytes(message.fbUserAgent);
            if (message.oc != null && Object.hasOwnProperty.call(message, "oc"))
                writer.uint32(/* id 23, wireType 0 =*/184).bool(message.oc);
            if (message.lc != null && Object.hasOwnProperty.call(message, "lc"))
                writer.uint32(/* id 24, wireType 0 =*/192).uint32(message.lc);
            if (message.iosAppExtension != null && Object.hasOwnProperty.call(message, "iosAppExtension"))
                writer.uint32(/* id 30, wireType 0 =*/240).int32(message.iosAppExtension);
            if (message.fbAppId != null && Object.hasOwnProperty.call(message, "fbAppId"))
                writer.uint32(/* id 31, wireType 0 =*/248).uint64(message.fbAppId);
            if (message.fbDeviceId != null && Object.hasOwnProperty.call(message, "fbDeviceId"))
                writer.uint32(/* id 32, wireType 2 =*/258).bytes(message.fbDeviceId);
            return writer;
        };

        /**
         * Encodes the specified ClientPayload message, length delimited. Does not implicitly {@link proto.ClientPayload.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ClientPayload
         * @static
         * @param {proto.IClientPayload} message ClientPayload message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ClientPayload.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ClientPayload message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ClientPayload
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ClientPayload} ClientPayload
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ClientPayload.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ClientPayload();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.username = reader.uint64();
                    break;
                case 3:
                    message.passive = reader.bool();
                    break;
                case 5:
                    message.userAgent = $root.proto.UserAgent.decode(reader, reader.uint32());
                    break;
                case 6:
                    message.webInfo = $root.proto.WebInfo.decode(reader, reader.uint32());
                    break;
                case 7:
                    message.pushName = reader.string();
                    break;
                case 9:
                    message.sessionId = reader.sfixed32();
                    break;
                case 10:
                    message.shortConnect = reader.bool();
                    break;
                case 12:
                    message.connectType = reader.int32();
                    break;
                case 13:
                    message.connectReason = reader.int32();
                    break;
                case 14:
                    if (!(message.shards && message.shards.length))
                        message.shards = [];
                    if ((tag & 7) === 2) {
                        var end2 = reader.uint32() + reader.pos;
                        while (reader.pos < end2)
                            message.shards.push(reader.int32());
                    } else
                        message.shards.push(reader.int32());
                    break;
                case 15:
                    message.dnsSource = $root.proto.DNSSource.decode(reader, reader.uint32());
                    break;
                case 16:
                    message.connectAttemptCount = reader.uint32();
                    break;
                case 17:
                    message.agent = reader.uint32();
                    break;
                case 18:
                    message.device = reader.uint32();
                    break;
                case 19:
                    message.regData = $root.proto.CompanionRegData.decode(reader, reader.uint32());
                    break;
                case 20:
                    message.product = reader.int32();
                    break;
                case 21:
                    message.fbCat = reader.bytes();
                    break;
                case 22:
                    message.fbUserAgent = reader.bytes();
                    break;
                case 23:
                    message.oc = reader.bool();
                    break;
                case 24:
                    message.lc = reader.uint32();
                    break;
                case 30:
                    message.iosAppExtension = reader.int32();
                    break;
                case 31:
                    message.fbAppId = reader.uint64();
                    break;
                case 32:
                    message.fbDeviceId = reader.bytes();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ClientPayload message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ClientPayload
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ClientPayload} ClientPayload
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ClientPayload.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ClientPayload message.
         * @function verify
         * @memberof proto.ClientPayload
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ClientPayload.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.username != null && message.hasOwnProperty("username"))
                if (!$util.isInteger(message.username) && !(message.username && $util.isInteger(message.username.low) && $util.isInteger(message.username.high)))
                    return "username: integer|Long expected";
            if (message.passive != null && message.hasOwnProperty("passive"))
                if (typeof message.passive !== "boolean")
                    return "passive: boolean expected";
            if (message.userAgent != null && message.hasOwnProperty("userAgent")) {
                var error = $root.proto.UserAgent.verify(message.userAgent);
                if (error)
                    return "userAgent." + error;
            }
            if (message.webInfo != null && message.hasOwnProperty("webInfo")) {
                var error = $root.proto.WebInfo.verify(message.webInfo);
                if (error)
                    return "webInfo." + error;
            }
            if (message.pushName != null && message.hasOwnProperty("pushName"))
                if (!$util.isString(message.pushName))
                    return "pushName: string expected";
            if (message.sessionId != null && message.hasOwnProperty("sessionId"))
                if (!$util.isInteger(message.sessionId))
                    return "sessionId: integer expected";
            if (message.shortConnect != null && message.hasOwnProperty("shortConnect"))
                if (typeof message.shortConnect !== "boolean")
                    return "shortConnect: boolean expected";
            if (message.connectType != null && message.hasOwnProperty("connectType"))
                switch (message.connectType) {
                default:
                    return "connectType: enum value expected";
                case 0:
                case 1:
                case 100:
                case 101:
                case 102:
                case 103:
                case 104:
                case 105:
                case 106:
                case 107:
                case 108:
                case 109:
                case 110:
                case 111:
                case 112:
                    break;
                }
            if (message.connectReason != null && message.hasOwnProperty("connectReason"))
                switch (message.connectReason) {
                default:
                    return "connectReason: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                    break;
                }
            if (message.shards != null && message.hasOwnProperty("shards")) {
                if (!Array.isArray(message.shards))
                    return "shards: array expected";
                for (var i = 0; i < message.shards.length; ++i)
                    if (!$util.isInteger(message.shards[i]))
                        return "shards: integer[] expected";
            }
            if (message.dnsSource != null && message.hasOwnProperty("dnsSource")) {
                var error = $root.proto.DNSSource.verify(message.dnsSource);
                if (error)
                    return "dnsSource." + error;
            }
            if (message.connectAttemptCount != null && message.hasOwnProperty("connectAttemptCount"))
                if (!$util.isInteger(message.connectAttemptCount))
                    return "connectAttemptCount: integer expected";
            if (message.agent != null && message.hasOwnProperty("agent"))
                if (!$util.isInteger(message.agent))
                    return "agent: integer expected";
            if (message.device != null && message.hasOwnProperty("device"))
                if (!$util.isInteger(message.device))
                    return "device: integer expected";
            if (message.regData != null && message.hasOwnProperty("regData")) {
                var error = $root.proto.CompanionRegData.verify(message.regData);
                if (error)
                    return "regData." + error;
            }
            if (message.product != null && message.hasOwnProperty("product"))
                switch (message.product) {
                default:
                    return "product: enum value expected";
                case 0:
                case 1:
                    break;
                }
            if (message.fbCat != null && message.hasOwnProperty("fbCat"))
                if (!(message.fbCat && typeof message.fbCat.length === "number" || $util.isString(message.fbCat)))
                    return "fbCat: buffer expected";
            if (message.fbUserAgent != null && message.hasOwnProperty("fbUserAgent"))
                if (!(message.fbUserAgent && typeof message.fbUserAgent.length === "number" || $util.isString(message.fbUserAgent)))
                    return "fbUserAgent: buffer expected";
            if (message.oc != null && message.hasOwnProperty("oc"))
                if (typeof message.oc !== "boolean")
                    return "oc: boolean expected";
            if (message.lc != null && message.hasOwnProperty("lc"))
                if (!$util.isInteger(message.lc))
                    return "lc: integer expected";
            if (message.iosAppExtension != null && message.hasOwnProperty("iosAppExtension"))
                switch (message.iosAppExtension) {
                default:
                    return "iosAppExtension: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            if (message.fbAppId != null && message.hasOwnProperty("fbAppId"))
                if (!$util.isInteger(message.fbAppId) && !(message.fbAppId && $util.isInteger(message.fbAppId.low) && $util.isInteger(message.fbAppId.high)))
                    return "fbAppId: integer|Long expected";
            if (message.fbDeviceId != null && message.hasOwnProperty("fbDeviceId"))
                if (!(message.fbDeviceId && typeof message.fbDeviceId.length === "number" || $util.isString(message.fbDeviceId)))
                    return "fbDeviceId: buffer expected";
            return null;
        };

        /**
         * Creates a ClientPayload message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ClientPayload
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ClientPayload} ClientPayload
         */
        ClientPayload.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ClientPayload)
                return object;
            var message = new $root.proto.ClientPayload();
            if (object.username != null)
                if ($util.Long)
                    (message.username = $util.Long.fromValue(object.username)).unsigned = true;
                else if (typeof object.username === "string")
                    message.username = parseInt(object.username, 10);
                else if (typeof object.username === "number")
                    message.username = object.username;
                else if (typeof object.username === "object")
                    message.username = new $util.LongBits(object.username.low >>> 0, object.username.high >>> 0).toNumber(true);
            if (object.passive != null)
                message.passive = Boolean(object.passive);
            if (object.userAgent != null) {
                if (typeof object.userAgent !== "object")
                    throw TypeError(".proto.ClientPayload.userAgent: object expected");
                message.userAgent = $root.proto.UserAgent.fromObject(object.userAgent);
            }
            if (object.webInfo != null) {
                if (typeof object.webInfo !== "object")
                    throw TypeError(".proto.ClientPayload.webInfo: object expected");
                message.webInfo = $root.proto.WebInfo.fromObject(object.webInfo);
            }
            if (object.pushName != null)
                message.pushName = String(object.pushName);
            if (object.sessionId != null)
                message.sessionId = object.sessionId | 0;
            if (object.shortConnect != null)
                message.shortConnect = Boolean(object.shortConnect);
            switch (object.connectType) {
            case "CELLULAR_UNKNOWN":
            case 0:
                message.connectType = 0;
                break;
            case "WIFI_UNKNOWN":
            case 1:
                message.connectType = 1;
                break;
            case "CELLULAR_EDGE":
            case 100:
                message.connectType = 100;
                break;
            case "CELLULAR_IDEN":
            case 101:
                message.connectType = 101;
                break;
            case "CELLULAR_UMTS":
            case 102:
                message.connectType = 102;
                break;
            case "CELLULAR_EVDO":
            case 103:
                message.connectType = 103;
                break;
            case "CELLULAR_GPRS":
            case 104:
                message.connectType = 104;
                break;
            case "CELLULAR_HSDPA":
            case 105:
                message.connectType = 105;
                break;
            case "CELLULAR_HSUPA":
            case 106:
                message.connectType = 106;
                break;
            case "CELLULAR_HSPA":
            case 107:
                message.connectType = 107;
                break;
            case "CELLULAR_CDMA":
            case 108:
                message.connectType = 108;
                break;
            case "CELLULAR_1XRTT":
            case 109:
                message.connectType = 109;
                break;
            case "CELLULAR_EHRPD":
            case 110:
                message.connectType = 110;
                break;
            case "CELLULAR_LTE":
            case 111:
                message.connectType = 111;
                break;
            case "CELLULAR_HSPAP":
            case 112:
                message.connectType = 112;
                break;
            }
            switch (object.connectReason) {
            case "PUSH":
            case 0:
                message.connectReason = 0;
                break;
            case "USER_ACTIVATED":
            case 1:
                message.connectReason = 1;
                break;
            case "SCHEDULED":
            case 2:
                message.connectReason = 2;
                break;
            case "ERROR_RECONNECT":
            case 3:
                message.connectReason = 3;
                break;
            case "NETWORK_SWITCH":
            case 4:
                message.connectReason = 4;
                break;
            case "PING_RECONNECT":
            case 5:
                message.connectReason = 5;
                break;
            }
            if (object.shards) {
                if (!Array.isArray(object.shards))
                    throw TypeError(".proto.ClientPayload.shards: array expected");
                message.shards = [];
                for (var i = 0; i < object.shards.length; ++i)
                    message.shards[i] = object.shards[i] | 0;
            }
            if (object.dnsSource != null) {
                if (typeof object.dnsSource !== "object")
                    throw TypeError(".proto.ClientPayload.dnsSource: object expected");
                message.dnsSource = $root.proto.DNSSource.fromObject(object.dnsSource);
            }
            if (object.connectAttemptCount != null)
                message.connectAttemptCount = object.connectAttemptCount >>> 0;
            if (object.agent != null)
                message.agent = object.agent >>> 0;
            if (object.device != null)
                message.device = object.device >>> 0;
            if (object.regData != null) {
                if (typeof object.regData !== "object")
                    throw TypeError(".proto.ClientPayload.regData: object expected");
                message.regData = $root.proto.CompanionRegData.fromObject(object.regData);
            }
            switch (object.product) {
            case "WHATSAPP":
            case 0:
                message.product = 0;
                break;
            case "MESSENGER":
            case 1:
                message.product = 1;
                break;
            }
            if (object.fbCat != null)
                if (typeof object.fbCat === "string")
                    $util.base64.decode(object.fbCat, message.fbCat = $util.newBuffer($util.base64.length(object.fbCat)), 0);
                else if (object.fbCat.length)
                    message.fbCat = object.fbCat;
            if (object.fbUserAgent != null)
                if (typeof object.fbUserAgent === "string")
                    $util.base64.decode(object.fbUserAgent, message.fbUserAgent = $util.newBuffer($util.base64.length(object.fbUserAgent)), 0);
                else if (object.fbUserAgent.length)
                    message.fbUserAgent = object.fbUserAgent;
            if (object.oc != null)
                message.oc = Boolean(object.oc);
            if (object.lc != null)
                message.lc = object.lc >>> 0;
            switch (object.iosAppExtension) {
            case "SHARE_EXTENSION":
            case 0:
                message.iosAppExtension = 0;
                break;
            case "SERVICE_EXTENSION":
            case 1:
                message.iosAppExtension = 1;
                break;
            case "INTENTS_EXTENSION":
            case 2:
                message.iosAppExtension = 2;
                break;
            }
            if (object.fbAppId != null)
                if ($util.Long)
                    (message.fbAppId = $util.Long.fromValue(object.fbAppId)).unsigned = true;
                else if (typeof object.fbAppId === "string")
                    message.fbAppId = parseInt(object.fbAppId, 10);
                else if (typeof object.fbAppId === "number")
                    message.fbAppId = object.fbAppId;
                else if (typeof object.fbAppId === "object")
                    message.fbAppId = new $util.LongBits(object.fbAppId.low >>> 0, object.fbAppId.high >>> 0).toNumber(true);
            if (object.fbDeviceId != null)
                if (typeof object.fbDeviceId === "string")
                    $util.base64.decode(object.fbDeviceId, message.fbDeviceId = $util.newBuffer($util.base64.length(object.fbDeviceId)), 0);
                else if (object.fbDeviceId.length)
                    message.fbDeviceId = object.fbDeviceId;
            return message;
        };

        /**
         * Creates a plain object from a ClientPayload message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ClientPayload
         * @static
         * @param {proto.ClientPayload} message ClientPayload
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ClientPayload.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.shards = [];
            if (options.defaults) {
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.username = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.username = options.longs === String ? "0" : 0;
                object.passive = false;
                object.userAgent = null;
                object.webInfo = null;
                object.pushName = "";
                object.sessionId = 0;
                object.shortConnect = false;
                object.connectType = options.enums === String ? "CELLULAR_UNKNOWN" : 0;
                object.connectReason = options.enums === String ? "PUSH" : 0;
                object.dnsSource = null;
                object.connectAttemptCount = 0;
                object.agent = 0;
                object.device = 0;
                object.regData = null;
                object.product = options.enums === String ? "WHATSAPP" : 0;
                if (options.bytes === String)
                    object.fbCat = "";
                else {
                    object.fbCat = [];
                    if (options.bytes !== Array)
                        object.fbCat = $util.newBuffer(object.fbCat);
                }
                if (options.bytes === String)
                    object.fbUserAgent = "";
                else {
                    object.fbUserAgent = [];
                    if (options.bytes !== Array)
                        object.fbUserAgent = $util.newBuffer(object.fbUserAgent);
                }
                object.oc = false;
                object.lc = 0;
                object.iosAppExtension = options.enums === String ? "SHARE_EXTENSION" : 0;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.fbAppId = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.fbAppId = options.longs === String ? "0" : 0;
                if (options.bytes === String)
                    object.fbDeviceId = "";
                else {
                    object.fbDeviceId = [];
                    if (options.bytes !== Array)
                        object.fbDeviceId = $util.newBuffer(object.fbDeviceId);
                }
            }
            if (message.username != null && message.hasOwnProperty("username"))
                if (typeof message.username === "number")
                    object.username = options.longs === String ? String(message.username) : message.username;
                else
                    object.username = options.longs === String ? $util.Long.prototype.toString.call(message.username) : options.longs === Number ? new $util.LongBits(message.username.low >>> 0, message.username.high >>> 0).toNumber(true) : message.username;
            if (message.passive != null && message.hasOwnProperty("passive"))
                object.passive = message.passive;
            if (message.userAgent != null && message.hasOwnProperty("userAgent"))
                object.userAgent = $root.proto.UserAgent.toObject(message.userAgent, options);
            if (message.webInfo != null && message.hasOwnProperty("webInfo"))
                object.webInfo = $root.proto.WebInfo.toObject(message.webInfo, options);
            if (message.pushName != null && message.hasOwnProperty("pushName"))
                object.pushName = message.pushName;
            if (message.sessionId != null && message.hasOwnProperty("sessionId"))
                object.sessionId = message.sessionId;
            if (message.shortConnect != null && message.hasOwnProperty("shortConnect"))
                object.shortConnect = message.shortConnect;
            if (message.connectType != null && message.hasOwnProperty("connectType"))
                object.connectType = options.enums === String ? $root.proto.ClientPayload.ClientPayloadConnectType[message.connectType] : message.connectType;
            if (message.connectReason != null && message.hasOwnProperty("connectReason"))
                object.connectReason = options.enums === String ? $root.proto.ClientPayload.ClientPayloadConnectReason[message.connectReason] : message.connectReason;
            if (message.shards && message.shards.length) {
                object.shards = [];
                for (var j = 0; j < message.shards.length; ++j)
                    object.shards[j] = message.shards[j];
            }
            if (message.dnsSource != null && message.hasOwnProperty("dnsSource"))
                object.dnsSource = $root.proto.DNSSource.toObject(message.dnsSource, options);
            if (message.connectAttemptCount != null && message.hasOwnProperty("connectAttemptCount"))
                object.connectAttemptCount = message.connectAttemptCount;
            if (message.agent != null && message.hasOwnProperty("agent"))
                object.agent = message.agent;
            if (message.device != null && message.hasOwnProperty("device"))
                object.device = message.device;
            if (message.regData != null && message.hasOwnProperty("regData"))
                object.regData = $root.proto.CompanionRegData.toObject(message.regData, options);
            if (message.product != null && message.hasOwnProperty("product"))
                object.product = options.enums === String ? $root.proto.ClientPayload.ClientPayloadProduct[message.product] : message.product;
            if (message.fbCat != null && message.hasOwnProperty("fbCat"))
                object.fbCat = options.bytes === String ? $util.base64.encode(message.fbCat, 0, message.fbCat.length) : options.bytes === Array ? Array.prototype.slice.call(message.fbCat) : message.fbCat;
            if (message.fbUserAgent != null && message.hasOwnProperty("fbUserAgent"))
                object.fbUserAgent = options.bytes === String ? $util.base64.encode(message.fbUserAgent, 0, message.fbUserAgent.length) : options.bytes === Array ? Array.prototype.slice.call(message.fbUserAgent) : message.fbUserAgent;
            if (message.oc != null && message.hasOwnProperty("oc"))
                object.oc = message.oc;
            if (message.lc != null && message.hasOwnProperty("lc"))
                object.lc = message.lc;
            if (message.iosAppExtension != null && message.hasOwnProperty("iosAppExtension"))
                object.iosAppExtension = options.enums === String ? $root.proto.ClientPayload.ClientPayloadIOSAppExtension[message.iosAppExtension] : message.iosAppExtension;
            if (message.fbAppId != null && message.hasOwnProperty("fbAppId"))
                if (typeof message.fbAppId === "number")
                    object.fbAppId = options.longs === String ? String(message.fbAppId) : message.fbAppId;
                else
                    object.fbAppId = options.longs === String ? $util.Long.prototype.toString.call(message.fbAppId) : options.longs === Number ? new $util.LongBits(message.fbAppId.low >>> 0, message.fbAppId.high >>> 0).toNumber(true) : message.fbAppId;
            if (message.fbDeviceId != null && message.hasOwnProperty("fbDeviceId"))
                object.fbDeviceId = options.bytes === String ? $util.base64.encode(message.fbDeviceId, 0, message.fbDeviceId.length) : options.bytes === Array ? Array.prototype.slice.call(message.fbDeviceId) : message.fbDeviceId;
            return object;
        };

        /**
         * Converts this ClientPayload to JSON.
         * @function toJSON
         * @memberof proto.ClientPayload
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ClientPayload.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * ClientPayloadConnectType enum.
         * @name proto.ClientPayload.ClientPayloadConnectType
         * @enum {number}
         * @property {number} CELLULAR_UNKNOWN=0 CELLULAR_UNKNOWN value
         * @property {number} WIFI_UNKNOWN=1 WIFI_UNKNOWN value
         * @property {number} CELLULAR_EDGE=100 CELLULAR_EDGE value
         * @property {number} CELLULAR_IDEN=101 CELLULAR_IDEN value
         * @property {number} CELLULAR_UMTS=102 CELLULAR_UMTS value
         * @property {number} CELLULAR_EVDO=103 CELLULAR_EVDO value
         * @property {number} CELLULAR_GPRS=104 CELLULAR_GPRS value
         * @property {number} CELLULAR_HSDPA=105 CELLULAR_HSDPA value
         * @property {number} CELLULAR_HSUPA=106 CELLULAR_HSUPA value
         * @property {number} CELLULAR_HSPA=107 CELLULAR_HSPA value
         * @property {number} CELLULAR_CDMA=108 CELLULAR_CDMA value
         * @property {number} CELLULAR_1XRTT=109 CELLULAR_1XRTT value
         * @property {number} CELLULAR_EHRPD=110 CELLULAR_EHRPD value
         * @property {number} CELLULAR_LTE=111 CELLULAR_LTE value
         * @property {number} CELLULAR_HSPAP=112 CELLULAR_HSPAP value
         */
        ClientPayload.ClientPayloadConnectType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "CELLULAR_UNKNOWN"] = 0;
            values[valuesById[1] = "WIFI_UNKNOWN"] = 1;
            values[valuesById[100] = "CELLULAR_EDGE"] = 100;
            values[valuesById[101] = "CELLULAR_IDEN"] = 101;
            values[valuesById[102] = "CELLULAR_UMTS"] = 102;
            values[valuesById[103] = "CELLULAR_EVDO"] = 103;
            values[valuesById[104] = "CELLULAR_GPRS"] = 104;
            values[valuesById[105] = "CELLULAR_HSDPA"] = 105;
            values[valuesById[106] = "CELLULAR_HSUPA"] = 106;
            values[valuesById[107] = "CELLULAR_HSPA"] = 107;
            values[valuesById[108] = "CELLULAR_CDMA"] = 108;
            values[valuesById[109] = "CELLULAR_1XRTT"] = 109;
            values[valuesById[110] = "CELLULAR_EHRPD"] = 110;
            values[valuesById[111] = "CELLULAR_LTE"] = 111;
            values[valuesById[112] = "CELLULAR_HSPAP"] = 112;
            return values;
        })();

        /**
         * ClientPayloadConnectReason enum.
         * @name proto.ClientPayload.ClientPayloadConnectReason
         * @enum {number}
         * @property {number} PUSH=0 PUSH value
         * @property {number} USER_ACTIVATED=1 USER_ACTIVATED value
         * @property {number} SCHEDULED=2 SCHEDULED value
         * @property {number} ERROR_RECONNECT=3 ERROR_RECONNECT value
         * @property {number} NETWORK_SWITCH=4 NETWORK_SWITCH value
         * @property {number} PING_RECONNECT=5 PING_RECONNECT value
         */
        ClientPayload.ClientPayloadConnectReason = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "PUSH"] = 0;
            values[valuesById[1] = "USER_ACTIVATED"] = 1;
            values[valuesById[2] = "SCHEDULED"] = 2;
            values[valuesById[3] = "ERROR_RECONNECT"] = 3;
            values[valuesById[4] = "NETWORK_SWITCH"] = 4;
            values[valuesById[5] = "PING_RECONNECT"] = 5;
            return values;
        })();

        /**
         * ClientPayloadProduct enum.
         * @name proto.ClientPayload.ClientPayloadProduct
         * @enum {number}
         * @property {number} WHATSAPP=0 WHATSAPP value
         * @property {number} MESSENGER=1 MESSENGER value
         */
        ClientPayload.ClientPayloadProduct = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "WHATSAPP"] = 0;
            values[valuesById[1] = "MESSENGER"] = 1;
            return values;
        })();

        /**
         * ClientPayloadIOSAppExtension enum.
         * @name proto.ClientPayload.ClientPayloadIOSAppExtension
         * @enum {number}
         * @property {number} SHARE_EXTENSION=0 SHARE_EXTENSION value
         * @property {number} SERVICE_EXTENSION=1 SERVICE_EXTENSION value
         * @property {number} INTENTS_EXTENSION=2 INTENTS_EXTENSION value
         */
        ClientPayload.ClientPayloadIOSAppExtension = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "SHARE_EXTENSION"] = 0;
            values[valuesById[1] = "SERVICE_EXTENSION"] = 1;
            values[valuesById[2] = "INTENTS_EXTENSION"] = 2;
            return values;
        })();

        return ClientPayload;
    })();

    proto.Details = (function() {

        /**
         * Properties of a Details.
         * @memberof proto
         * @interface IDetails
         * @property {number|null} [serial] Details serial
         * @property {string|null} [issuer] Details issuer
         * @property {number|Long|null} [expires] Details expires
         * @property {string|null} [subject] Details subject
         * @property {Uint8Array|null} [key] Details key
         */

        /**
         * Constructs a new Details.
         * @memberof proto
         * @classdesc Represents a Details.
         * @implements IDetails
         * @constructor
         * @param {proto.IDetails=} [properties] Properties to set
         */
        function Details(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Details serial.
         * @member {number} serial
         * @memberof proto.Details
         * @instance
         */
        Details.prototype.serial = 0;

        /**
         * Details issuer.
         * @member {string} issuer
         * @memberof proto.Details
         * @instance
         */
        Details.prototype.issuer = "";

        /**
         * Details expires.
         * @member {number|Long} expires
         * @memberof proto.Details
         * @instance
         */
        Details.prototype.expires = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * Details subject.
         * @member {string} subject
         * @memberof proto.Details
         * @instance
         */
        Details.prototype.subject = "";

        /**
         * Details key.
         * @member {Uint8Array} key
         * @memberof proto.Details
         * @instance
         */
        Details.prototype.key = $util.newBuffer([]);

        /**
         * Creates a new Details instance using the specified properties.
         * @function create
         * @memberof proto.Details
         * @static
         * @param {proto.IDetails=} [properties] Properties to set
         * @returns {proto.Details} Details instance
         */
        Details.create = function create(properties) {
            return new Details(properties);
        };

        /**
         * Encodes the specified Details message. Does not implicitly {@link proto.Details.verify|verify} messages.
         * @function encode
         * @memberof proto.Details
         * @static
         * @param {proto.IDetails} message Details message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Details.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.serial != null && Object.hasOwnProperty.call(message, "serial"))
                writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.serial);
            if (message.issuer != null && Object.hasOwnProperty.call(message, "issuer"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.issuer);
            if (message.expires != null && Object.hasOwnProperty.call(message, "expires"))
                writer.uint32(/* id 3, wireType 0 =*/24).uint64(message.expires);
            if (message.subject != null && Object.hasOwnProperty.call(message, "subject"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.subject);
            if (message.key != null && Object.hasOwnProperty.call(message, "key"))
                writer.uint32(/* id 5, wireType 2 =*/42).bytes(message.key);
            return writer;
        };

        /**
         * Encodes the specified Details message, length delimited. Does not implicitly {@link proto.Details.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.Details
         * @static
         * @param {proto.IDetails} message Details message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Details.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a Details message from the specified reader or buffer.
         * @function decode
         * @memberof proto.Details
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.Details} Details
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Details.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Details();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.serial = reader.uint32();
                    break;
                case 2:
                    message.issuer = reader.string();
                    break;
                case 3:
                    message.expires = reader.uint64();
                    break;
                case 4:
                    message.subject = reader.string();
                    break;
                case 5:
                    message.key = reader.bytes();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a Details message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.Details
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.Details} Details
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Details.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a Details message.
         * @function verify
         * @memberof proto.Details
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        Details.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.serial != null && message.hasOwnProperty("serial"))
                if (!$util.isInteger(message.serial))
                    return "serial: integer expected";
            if (message.issuer != null && message.hasOwnProperty("issuer"))
                if (!$util.isString(message.issuer))
                    return "issuer: string expected";
            if (message.expires != null && message.hasOwnProperty("expires"))
                if (!$util.isInteger(message.expires) && !(message.expires && $util.isInteger(message.expires.low) && $util.isInteger(message.expires.high)))
                    return "expires: integer|Long expected";
            if (message.subject != null && message.hasOwnProperty("subject"))
                if (!$util.isString(message.subject))
                    return "subject: string expected";
            if (message.key != null && message.hasOwnProperty("key"))
                if (!(message.key && typeof message.key.length === "number" || $util.isString(message.key)))
                    return "key: buffer expected";
            return null;
        };

        /**
         * Creates a Details message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.Details
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.Details} Details
         */
        Details.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.Details)
                return object;
            var message = new $root.proto.Details();
            if (object.serial != null)
                message.serial = object.serial >>> 0;
            if (object.issuer != null)
                message.issuer = String(object.issuer);
            if (object.expires != null)
                if ($util.Long)
                    (message.expires = $util.Long.fromValue(object.expires)).unsigned = true;
                else if (typeof object.expires === "string")
                    message.expires = parseInt(object.expires, 10);
                else if (typeof object.expires === "number")
                    message.expires = object.expires;
                else if (typeof object.expires === "object")
                    message.expires = new $util.LongBits(object.expires.low >>> 0, object.expires.high >>> 0).toNumber(true);
            if (object.subject != null)
                message.subject = String(object.subject);
            if (object.key != null)
                if (typeof object.key === "string")
                    $util.base64.decode(object.key, message.key = $util.newBuffer($util.base64.length(object.key)), 0);
                else if (object.key.length)
                    message.key = object.key;
            return message;
        };

        /**
         * Creates a plain object from a Details message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.Details
         * @static
         * @param {proto.Details} message Details
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        Details.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.serial = 0;
                object.issuer = "";
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.expires = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.expires = options.longs === String ? "0" : 0;
                object.subject = "";
                if (options.bytes === String)
                    object.key = "";
                else {
                    object.key = [];
                    if (options.bytes !== Array)
                        object.key = $util.newBuffer(object.key);
                }
            }
            if (message.serial != null && message.hasOwnProperty("serial"))
                object.serial = message.serial;
            if (message.issuer != null && message.hasOwnProperty("issuer"))
                object.issuer = message.issuer;
            if (message.expires != null && message.hasOwnProperty("expires"))
                if (typeof message.expires === "number")
                    object.expires = options.longs === String ? String(message.expires) : message.expires;
                else
                    object.expires = options.longs === String ? $util.Long.prototype.toString.call(message.expires) : options.longs === Number ? new $util.LongBits(message.expires.low >>> 0, message.expires.high >>> 0).toNumber(true) : message.expires;
            if (message.subject != null && message.hasOwnProperty("subject"))
                object.subject = message.subject;
            if (message.key != null && message.hasOwnProperty("key"))
                object.key = options.bytes === String ? $util.base64.encode(message.key, 0, message.key.length) : options.bytes === Array ? Array.prototype.slice.call(message.key) : message.key;
            return object;
        };

        /**
         * Converts this Details to JSON.
         * @function toJSON
         * @memberof proto.Details
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        Details.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return Details;
    })();

    proto.NoiseCertificate = (function() {

        /**
         * Properties of a NoiseCertificate.
         * @memberof proto
         * @interface INoiseCertificate
         * @property {Uint8Array|null} [details] NoiseCertificate details
         * @property {Uint8Array|null} [signature] NoiseCertificate signature
         */

        /**
         * Constructs a new NoiseCertificate.
         * @memberof proto
         * @classdesc Represents a NoiseCertificate.
         * @implements INoiseCertificate
         * @constructor
         * @param {proto.INoiseCertificate=} [properties] Properties to set
         */
        function NoiseCertificate(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * NoiseCertificate details.
         * @member {Uint8Array} details
         * @memberof proto.NoiseCertificate
         * @instance
         */
        NoiseCertificate.prototype.details = $util.newBuffer([]);

        /**
         * NoiseCertificate signature.
         * @member {Uint8Array} signature
         * @memberof proto.NoiseCertificate
         * @instance
         */
        NoiseCertificate.prototype.signature = $util.newBuffer([]);

        /**
         * Creates a new NoiseCertificate instance using the specified properties.
         * @function create
         * @memberof proto.NoiseCertificate
         * @static
         * @param {proto.INoiseCertificate=} [properties] Properties to set
         * @returns {proto.NoiseCertificate} NoiseCertificate instance
         */
        NoiseCertificate.create = function create(properties) {
            return new NoiseCertificate(properties);
        };

        /**
         * Encodes the specified NoiseCertificate message. Does not implicitly {@link proto.NoiseCertificate.verify|verify} messages.
         * @function encode
         * @memberof proto.NoiseCertificate
         * @static
         * @param {proto.INoiseCertificate} message NoiseCertificate message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        NoiseCertificate.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.details != null && Object.hasOwnProperty.call(message, "details"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.details);
            if (message.signature != null && Object.hasOwnProperty.call(message, "signature"))
                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.signature);
            return writer;
        };

        /**
         * Encodes the specified NoiseCertificate message, length delimited. Does not implicitly {@link proto.NoiseCertificate.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.NoiseCertificate
         * @static
         * @param {proto.INoiseCertificate} message NoiseCertificate message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        NoiseCertificate.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a NoiseCertificate message from the specified reader or buffer.
         * @function decode
         * @memberof proto.NoiseCertificate
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.NoiseCertificate} NoiseCertificate
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        NoiseCertificate.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.NoiseCertificate();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.details = reader.bytes();
                    break;
                case 2:
                    message.signature = reader.bytes();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a NoiseCertificate message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.NoiseCertificate
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.NoiseCertificate} NoiseCertificate
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        NoiseCertificate.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a NoiseCertificate message.
         * @function verify
         * @memberof proto.NoiseCertificate
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        NoiseCertificate.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.details != null && message.hasOwnProperty("details"))
                if (!(message.details && typeof message.details.length === "number" || $util.isString(message.details)))
                    return "details: buffer expected";
            if (message.signature != null && message.hasOwnProperty("signature"))
                if (!(message.signature && typeof message.signature.length === "number" || $util.isString(message.signature)))
                    return "signature: buffer expected";
            return null;
        };

        /**
         * Creates a NoiseCertificate message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.NoiseCertificate
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.NoiseCertificate} NoiseCertificate
         */
        NoiseCertificate.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.NoiseCertificate)
                return object;
            var message = new $root.proto.NoiseCertificate();
            if (object.details != null)
                if (typeof object.details === "string")
                    $util.base64.decode(object.details, message.details = $util.newBuffer($util.base64.length(object.details)), 0);
                else if (object.details.length)
                    message.details = object.details;
            if (object.signature != null)
                if (typeof object.signature === "string")
                    $util.base64.decode(object.signature, message.signature = $util.newBuffer($util.base64.length(object.signature)), 0);
                else if (object.signature.length)
                    message.signature = object.signature;
            return message;
        };

        /**
         * Creates a plain object from a NoiseCertificate message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.NoiseCertificate
         * @static
         * @param {proto.NoiseCertificate} message NoiseCertificate
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        NoiseCertificate.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object.details = "";
                else {
                    object.details = [];
                    if (options.bytes !== Array)
                        object.details = $util.newBuffer(object.details);
                }
                if (options.bytes === String)
                    object.signature = "";
                else {
                    object.signature = [];
                    if (options.bytes !== Array)
                        object.signature = $util.newBuffer(object.signature);
                }
            }
            if (message.details != null && message.hasOwnProperty("details"))
                object.details = options.bytes === String ? $util.base64.encode(message.details, 0, message.details.length) : options.bytes === Array ? Array.prototype.slice.call(message.details) : message.details;
            if (message.signature != null && message.hasOwnProperty("signature"))
                object.signature = options.bytes === String ? $util.base64.encode(message.signature, 0, message.signature.length) : options.bytes === Array ? Array.prototype.slice.call(message.signature) : message.signature;
            return object;
        };

        /**
         * Converts this NoiseCertificate to JSON.
         * @function toJSON
         * @memberof proto.NoiseCertificate
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        NoiseCertificate.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return NoiseCertificate;
    })();

    proto.ClientHello = (function() {

        /**
         * Properties of a ClientHello.
         * @memberof proto
         * @interface IClientHello
         * @property {Uint8Array|null} [ephemeral] ClientHello ephemeral
         * @property {Uint8Array|null} ["static"] ClientHello static
         * @property {Uint8Array|null} [payload] ClientHello payload
         */

        /**
         * Constructs a new ClientHello.
         * @memberof proto
         * @classdesc Represents a ClientHello.
         * @implements IClientHello
         * @constructor
         * @param {proto.IClientHello=} [properties] Properties to set
         */
        function ClientHello(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ClientHello ephemeral.
         * @member {Uint8Array} ephemeral
         * @memberof proto.ClientHello
         * @instance
         */
        ClientHello.prototype.ephemeral = $util.newBuffer([]);

        /**
         * ClientHello static.
         * @member {Uint8Array} static
         * @memberof proto.ClientHello
         * @instance
         */
        ClientHello.prototype["static"] = $util.newBuffer([]);

        /**
         * ClientHello payload.
         * @member {Uint8Array} payload
         * @memberof proto.ClientHello
         * @instance
         */
        ClientHello.prototype.payload = $util.newBuffer([]);

        /**
         * Creates a new ClientHello instance using the specified properties.
         * @function create
         * @memberof proto.ClientHello
         * @static
         * @param {proto.IClientHello=} [properties] Properties to set
         * @returns {proto.ClientHello} ClientHello instance
         */
        ClientHello.create = function create(properties) {
            return new ClientHello(properties);
        };

        /**
         * Encodes the specified ClientHello message. Does not implicitly {@link proto.ClientHello.verify|verify} messages.
         * @function encode
         * @memberof proto.ClientHello
         * @static
         * @param {proto.IClientHello} message ClientHello message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ClientHello.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.ephemeral != null && Object.hasOwnProperty.call(message, "ephemeral"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.ephemeral);
            if (message["static"] != null && Object.hasOwnProperty.call(message, "static"))
                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message["static"]);
            if (message.payload != null && Object.hasOwnProperty.call(message, "payload"))
                writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.payload);
            return writer;
        };

        /**
         * Encodes the specified ClientHello message, length delimited. Does not implicitly {@link proto.ClientHello.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ClientHello
         * @static
         * @param {proto.IClientHello} message ClientHello message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ClientHello.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ClientHello message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ClientHello
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ClientHello} ClientHello
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ClientHello.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ClientHello();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.ephemeral = reader.bytes();
                    break;
                case 2:
                    message["static"] = reader.bytes();
                    break;
                case 3:
                    message.payload = reader.bytes();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ClientHello message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ClientHello
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ClientHello} ClientHello
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ClientHello.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ClientHello message.
         * @function verify
         * @memberof proto.ClientHello
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ClientHello.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.ephemeral != null && message.hasOwnProperty("ephemeral"))
                if (!(message.ephemeral && typeof message.ephemeral.length === "number" || $util.isString(message.ephemeral)))
                    return "ephemeral: buffer expected";
            if (message["static"] != null && message.hasOwnProperty("static"))
                if (!(message["static"] && typeof message["static"].length === "number" || $util.isString(message["static"])))
                    return "static: buffer expected";
            if (message.payload != null && message.hasOwnProperty("payload"))
                if (!(message.payload && typeof message.payload.length === "number" || $util.isString(message.payload)))
                    return "payload: buffer expected";
            return null;
        };

        /**
         * Creates a ClientHello message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ClientHello
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ClientHello} ClientHello
         */
        ClientHello.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ClientHello)
                return object;
            var message = new $root.proto.ClientHello();
            if (object.ephemeral != null)
                if (typeof object.ephemeral === "string")
                    $util.base64.decode(object.ephemeral, message.ephemeral = $util.newBuffer($util.base64.length(object.ephemeral)), 0);
                else if (object.ephemeral.length)
                    message.ephemeral = object.ephemeral;
            if (object["static"] != null)
                if (typeof object["static"] === "string")
                    $util.base64.decode(object["static"], message["static"] = $util.newBuffer($util.base64.length(object["static"])), 0);
                else if (object["static"].length)
                    message["static"] = object["static"];
            if (object.payload != null)
                if (typeof object.payload === "string")
                    $util.base64.decode(object.payload, message.payload = $util.newBuffer($util.base64.length(object.payload)), 0);
                else if (object.payload.length)
                    message.payload = object.payload;
            return message;
        };

        /**
         * Creates a plain object from a ClientHello message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ClientHello
         * @static
         * @param {proto.ClientHello} message ClientHello
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ClientHello.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object.ephemeral = "";
                else {
                    object.ephemeral = [];
                    if (options.bytes !== Array)
                        object.ephemeral = $util.newBuffer(object.ephemeral);
                }
                if (options.bytes === String)
                    object["static"] = "";
                else {
                    object["static"] = [];
                    if (options.bytes !== Array)
                        object["static"] = $util.newBuffer(object["static"]);
                }
                if (options.bytes === String)
                    object.payload = "";
                else {
                    object.payload = [];
                    if (options.bytes !== Array)
                        object.payload = $util.newBuffer(object.payload);
                }
            }
            if (message.ephemeral != null && message.hasOwnProperty("ephemeral"))
                object.ephemeral = options.bytes === String ? $util.base64.encode(message.ephemeral, 0, message.ephemeral.length) : options.bytes === Array ? Array.prototype.slice.call(message.ephemeral) : message.ephemeral;
            if (message["static"] != null && message.hasOwnProperty("static"))
                object["static"] = options.bytes === String ? $util.base64.encode(message["static"], 0, message["static"].length) : options.bytes === Array ? Array.prototype.slice.call(message["static"]) : message["static"];
            if (message.payload != null && message.hasOwnProperty("payload"))
                object.payload = options.bytes === String ? $util.base64.encode(message.payload, 0, message.payload.length) : options.bytes === Array ? Array.prototype.slice.call(message.payload) : message.payload;
            return object;
        };

        /**
         * Converts this ClientHello to JSON.
         * @function toJSON
         * @memberof proto.ClientHello
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ClientHello.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ClientHello;
    })();

    proto.ServerHello = (function() {

        /**
         * Properties of a ServerHello.
         * @memberof proto
         * @interface IServerHello
         * @property {Uint8Array|null} [ephemeral] ServerHello ephemeral
         * @property {Uint8Array|null} ["static"] ServerHello static
         * @property {Uint8Array|null} [payload] ServerHello payload
         */

        /**
         * Constructs a new ServerHello.
         * @memberof proto
         * @classdesc Represents a ServerHello.
         * @implements IServerHello
         * @constructor
         * @param {proto.IServerHello=} [properties] Properties to set
         */
        function ServerHello(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ServerHello ephemeral.
         * @member {Uint8Array} ephemeral
         * @memberof proto.ServerHello
         * @instance
         */
        ServerHello.prototype.ephemeral = $util.newBuffer([]);

        /**
         * ServerHello static.
         * @member {Uint8Array} static
         * @memberof proto.ServerHello
         * @instance
         */
        ServerHello.prototype["static"] = $util.newBuffer([]);

        /**
         * ServerHello payload.
         * @member {Uint8Array} payload
         * @memberof proto.ServerHello
         * @instance
         */
        ServerHello.prototype.payload = $util.newBuffer([]);

        /**
         * Creates a new ServerHello instance using the specified properties.
         * @function create
         * @memberof proto.ServerHello
         * @static
         * @param {proto.IServerHello=} [properties] Properties to set
         * @returns {proto.ServerHello} ServerHello instance
         */
        ServerHello.create = function create(properties) {
            return new ServerHello(properties);
        };

        /**
         * Encodes the specified ServerHello message. Does not implicitly {@link proto.ServerHello.verify|verify} messages.
         * @function encode
         * @memberof proto.ServerHello
         * @static
         * @param {proto.IServerHello} message ServerHello message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ServerHello.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.ephemeral != null && Object.hasOwnProperty.call(message, "ephemeral"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.ephemeral);
            if (message["static"] != null && Object.hasOwnProperty.call(message, "static"))
                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message["static"]);
            if (message.payload != null && Object.hasOwnProperty.call(message, "payload"))
                writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.payload);
            return writer;
        };

        /**
         * Encodes the specified ServerHello message, length delimited. Does not implicitly {@link proto.ServerHello.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ServerHello
         * @static
         * @param {proto.IServerHello} message ServerHello message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ServerHello.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ServerHello message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ServerHello
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ServerHello} ServerHello
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ServerHello.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ServerHello();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.ephemeral = reader.bytes();
                    break;
                case 2:
                    message["static"] = reader.bytes();
                    break;
                case 3:
                    message.payload = reader.bytes();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ServerHello message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ServerHello
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ServerHello} ServerHello
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ServerHello.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ServerHello message.
         * @function verify
         * @memberof proto.ServerHello
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ServerHello.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.ephemeral != null && message.hasOwnProperty("ephemeral"))
                if (!(message.ephemeral && typeof message.ephemeral.length === "number" || $util.isString(message.ephemeral)))
                    return "ephemeral: buffer expected";
            if (message["static"] != null && message.hasOwnProperty("static"))
                if (!(message["static"] && typeof message["static"].length === "number" || $util.isString(message["static"])))
                    return "static: buffer expected";
            if (message.payload != null && message.hasOwnProperty("payload"))
                if (!(message.payload && typeof message.payload.length === "number" || $util.isString(message.payload)))
                    return "payload: buffer expected";
            return null;
        };

        /**
         * Creates a ServerHello message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ServerHello
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ServerHello} ServerHello
         */
        ServerHello.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ServerHello)
                return object;
            var message = new $root.proto.ServerHello();
            if (object.ephemeral != null)
                if (typeof object.ephemeral === "string")
                    $util.base64.decode(object.ephemeral, message.ephemeral = $util.newBuffer($util.base64.length(object.ephemeral)), 0);
                else if (object.ephemeral.length)
                    message.ephemeral = object.ephemeral;
            if (object["static"] != null)
                if (typeof object["static"] === "string")
                    $util.base64.decode(object["static"], message["static"] = $util.newBuffer($util.base64.length(object["static"])), 0);
                else if (object["static"].length)
                    message["static"] = object["static"];
            if (object.payload != null)
                if (typeof object.payload === "string")
                    $util.base64.decode(object.payload, message.payload = $util.newBuffer($util.base64.length(object.payload)), 0);
                else if (object.payload.length)
                    message.payload = object.payload;
            return message;
        };

        /**
         * Creates a plain object from a ServerHello message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ServerHello
         * @static
         * @param {proto.ServerHello} message ServerHello
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ServerHello.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object.ephemeral = "";
                else {
                    object.ephemeral = [];
                    if (options.bytes !== Array)
                        object.ephemeral = $util.newBuffer(object.ephemeral);
                }
                if (options.bytes === String)
                    object["static"] = "";
                else {
                    object["static"] = [];
                    if (options.bytes !== Array)
                        object["static"] = $util.newBuffer(object["static"]);
                }
                if (options.bytes === String)
                    object.payload = "";
                else {
                    object.payload = [];
                    if (options.bytes !== Array)
                        object.payload = $util.newBuffer(object.payload);
                }
            }
            if (message.ephemeral != null && message.hasOwnProperty("ephemeral"))
                object.ephemeral = options.bytes === String ? $util.base64.encode(message.ephemeral, 0, message.ephemeral.length) : options.bytes === Array ? Array.prototype.slice.call(message.ephemeral) : message.ephemeral;
            if (message["static"] != null && message.hasOwnProperty("static"))
                object["static"] = options.bytes === String ? $util.base64.encode(message["static"], 0, message["static"].length) : options.bytes === Array ? Array.prototype.slice.call(message["static"]) : message["static"];
            if (message.payload != null && message.hasOwnProperty("payload"))
                object.payload = options.bytes === String ? $util.base64.encode(message.payload, 0, message.payload.length) : options.bytes === Array ? Array.prototype.slice.call(message.payload) : message.payload;
            return object;
        };

        /**
         * Converts this ServerHello to JSON.
         * @function toJSON
         * @memberof proto.ServerHello
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ServerHello.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ServerHello;
    })();

    proto.ClientFinish = (function() {

        /**
         * Properties of a ClientFinish.
         * @memberof proto
         * @interface IClientFinish
         * @property {Uint8Array|null} ["static"] ClientFinish static
         * @property {Uint8Array|null} [payload] ClientFinish payload
         */

        /**
         * Constructs a new ClientFinish.
         * @memberof proto
         * @classdesc Represents a ClientFinish.
         * @implements IClientFinish
         * @constructor
         * @param {proto.IClientFinish=} [properties] Properties to set
         */
        function ClientFinish(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ClientFinish static.
         * @member {Uint8Array} static
         * @memberof proto.ClientFinish
         * @instance
         */
        ClientFinish.prototype["static"] = $util.newBuffer([]);

        /**
         * ClientFinish payload.
         * @member {Uint8Array} payload
         * @memberof proto.ClientFinish
         * @instance
         */
        ClientFinish.prototype.payload = $util.newBuffer([]);

        /**
         * Creates a new ClientFinish instance using the specified properties.
         * @function create
         * @memberof proto.ClientFinish
         * @static
         * @param {proto.IClientFinish=} [properties] Properties to set
         * @returns {proto.ClientFinish} ClientFinish instance
         */
        ClientFinish.create = function create(properties) {
            return new ClientFinish(properties);
        };

        /**
         * Encodes the specified ClientFinish message. Does not implicitly {@link proto.ClientFinish.verify|verify} messages.
         * @function encode
         * @memberof proto.ClientFinish
         * @static
         * @param {proto.IClientFinish} message ClientFinish message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ClientFinish.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message["static"] != null && Object.hasOwnProperty.call(message, "static"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message["static"]);
            if (message.payload != null && Object.hasOwnProperty.call(message, "payload"))
                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.payload);
            return writer;
        };

        /**
         * Encodes the specified ClientFinish message, length delimited. Does not implicitly {@link proto.ClientFinish.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ClientFinish
         * @static
         * @param {proto.IClientFinish} message ClientFinish message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ClientFinish.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ClientFinish message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ClientFinish
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ClientFinish} ClientFinish
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ClientFinish.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ClientFinish();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message["static"] = reader.bytes();
                    break;
                case 2:
                    message.payload = reader.bytes();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ClientFinish message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ClientFinish
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ClientFinish} ClientFinish
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ClientFinish.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ClientFinish message.
         * @function verify
         * @memberof proto.ClientFinish
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ClientFinish.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message["static"] != null && message.hasOwnProperty("static"))
                if (!(message["static"] && typeof message["static"].length === "number" || $util.isString(message["static"])))
                    return "static: buffer expected";
            if (message.payload != null && message.hasOwnProperty("payload"))
                if (!(message.payload && typeof message.payload.length === "number" || $util.isString(message.payload)))
                    return "payload: buffer expected";
            return null;
        };

        /**
         * Creates a ClientFinish message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ClientFinish
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ClientFinish} ClientFinish
         */
        ClientFinish.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ClientFinish)
                return object;
            var message = new $root.proto.ClientFinish();
            if (object["static"] != null)
                if (typeof object["static"] === "string")
                    $util.base64.decode(object["static"], message["static"] = $util.newBuffer($util.base64.length(object["static"])), 0);
                else if (object["static"].length)
                    message["static"] = object["static"];
            if (object.payload != null)
                if (typeof object.payload === "string")
                    $util.base64.decode(object.payload, message.payload = $util.newBuffer($util.base64.length(object.payload)), 0);
                else if (object.payload.length)
                    message.payload = object.payload;
            return message;
        };

        /**
         * Creates a plain object from a ClientFinish message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ClientFinish
         * @static
         * @param {proto.ClientFinish} message ClientFinish
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ClientFinish.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object["static"] = "";
                else {
                    object["static"] = [];
                    if (options.bytes !== Array)
                        object["static"] = $util.newBuffer(object["static"]);
                }
                if (options.bytes === String)
                    object.payload = "";
                else {
                    object.payload = [];
                    if (options.bytes !== Array)
                        object.payload = $util.newBuffer(object.payload);
                }
            }
            if (message["static"] != null && message.hasOwnProperty("static"))
                object["static"] = options.bytes === String ? $util.base64.encode(message["static"], 0, message["static"].length) : options.bytes === Array ? Array.prototype.slice.call(message["static"]) : message["static"];
            if (message.payload != null && message.hasOwnProperty("payload"))
                object.payload = options.bytes === String ? $util.base64.encode(message.payload, 0, message.payload.length) : options.bytes === Array ? Array.prototype.slice.call(message.payload) : message.payload;
            return object;
        };

        /**
         * Converts this ClientFinish to JSON.
         * @function toJSON
         * @memberof proto.ClientFinish
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ClientFinish.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ClientFinish;
    })();

    proto.HandshakeMessage = (function() {

        /**
         * Properties of a HandshakeMessage.
         * @memberof proto
         * @interface IHandshakeMessage
         * @property {proto.IClientHello|null} [clientHello] HandshakeMessage clientHello
         * @property {proto.IServerHello|null} [serverHello] HandshakeMessage serverHello
         * @property {proto.IClientFinish|null} [clientFinish] HandshakeMessage clientFinish
         */

        /**
         * Constructs a new HandshakeMessage.
         * @memberof proto
         * @classdesc Represents a HandshakeMessage.
         * @implements IHandshakeMessage
         * @constructor
         * @param {proto.IHandshakeMessage=} [properties] Properties to set
         */
        function HandshakeMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * HandshakeMessage clientHello.
         * @member {proto.IClientHello|null|undefined} clientHello
         * @memberof proto.HandshakeMessage
         * @instance
         */
        HandshakeMessage.prototype.clientHello = null;

        /**
         * HandshakeMessage serverHello.
         * @member {proto.IServerHello|null|undefined} serverHello
         * @memberof proto.HandshakeMessage
         * @instance
         */
        HandshakeMessage.prototype.serverHello = null;

        /**
         * HandshakeMessage clientFinish.
         * @member {proto.IClientFinish|null|undefined} clientFinish
         * @memberof proto.HandshakeMessage
         * @instance
         */
        HandshakeMessage.prototype.clientFinish = null;

        /**
         * Creates a new HandshakeMessage instance using the specified properties.
         * @function create
         * @memberof proto.HandshakeMessage
         * @static
         * @param {proto.IHandshakeMessage=} [properties] Properties to set
         * @returns {proto.HandshakeMessage} HandshakeMessage instance
         */
        HandshakeMessage.create = function create(properties) {
            return new HandshakeMessage(properties);
        };

        /**
         * Encodes the specified HandshakeMessage message. Does not implicitly {@link proto.HandshakeMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.HandshakeMessage
         * @static
         * @param {proto.IHandshakeMessage} message HandshakeMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HandshakeMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.clientHello != null && Object.hasOwnProperty.call(message, "clientHello"))
                $root.proto.ClientHello.encode(message.clientHello, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.serverHello != null && Object.hasOwnProperty.call(message, "serverHello"))
                $root.proto.ServerHello.encode(message.serverHello, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.clientFinish != null && Object.hasOwnProperty.call(message, "clientFinish"))
                $root.proto.ClientFinish.encode(message.clientFinish, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified HandshakeMessage message, length delimited. Does not implicitly {@link proto.HandshakeMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.HandshakeMessage
         * @static
         * @param {proto.IHandshakeMessage} message HandshakeMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HandshakeMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a HandshakeMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.HandshakeMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.HandshakeMessage} HandshakeMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HandshakeMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HandshakeMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 2:
                    message.clientHello = $root.proto.ClientHello.decode(reader, reader.uint32());
                    break;
                case 3:
                    message.serverHello = $root.proto.ServerHello.decode(reader, reader.uint32());
                    break;
                case 4:
                    message.clientFinish = $root.proto.ClientFinish.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a HandshakeMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.HandshakeMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.HandshakeMessage} HandshakeMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HandshakeMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a HandshakeMessage message.
         * @function verify
         * @memberof proto.HandshakeMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        HandshakeMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.clientHello != null && message.hasOwnProperty("clientHello")) {
                var error = $root.proto.ClientHello.verify(message.clientHello);
                if (error)
                    return "clientHello." + error;
            }
            if (message.serverHello != null && message.hasOwnProperty("serverHello")) {
                var error = $root.proto.ServerHello.verify(message.serverHello);
                if (error)
                    return "serverHello." + error;
            }
            if (message.clientFinish != null && message.hasOwnProperty("clientFinish")) {
                var error = $root.proto.ClientFinish.verify(message.clientFinish);
                if (error)
                    return "clientFinish." + error;
            }
            return null;
        };

        /**
         * Creates a HandshakeMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.HandshakeMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.HandshakeMessage} HandshakeMessage
         */
        HandshakeMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.HandshakeMessage)
                return object;
            var message = new $root.proto.HandshakeMessage();
            if (object.clientHello != null) {
                if (typeof object.clientHello !== "object")
                    throw TypeError(".proto.HandshakeMessage.clientHello: object expected");
                message.clientHello = $root.proto.ClientHello.fromObject(object.clientHello);
            }
            if (object.serverHello != null) {
                if (typeof object.serverHello !== "object")
                    throw TypeError(".proto.HandshakeMessage.serverHello: object expected");
                message.serverHello = $root.proto.ServerHello.fromObject(object.serverHello);
            }
            if (object.clientFinish != null) {
                if (typeof object.clientFinish !== "object")
                    throw TypeError(".proto.HandshakeMessage.clientFinish: object expected");
                message.clientFinish = $root.proto.ClientFinish.fromObject(object.clientFinish);
            }
            return message;
        };

        /**
         * Creates a plain object from a HandshakeMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.HandshakeMessage
         * @static
         * @param {proto.HandshakeMessage} message HandshakeMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        HandshakeMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.clientHello = null;
                object.serverHello = null;
                object.clientFinish = null;
            }
            if (message.clientHello != null && message.hasOwnProperty("clientHello"))
                object.clientHello = $root.proto.ClientHello.toObject(message.clientHello, options);
            if (message.serverHello != null && message.hasOwnProperty("serverHello"))
                object.serverHello = $root.proto.ServerHello.toObject(message.serverHello, options);
            if (message.clientFinish != null && message.hasOwnProperty("clientFinish"))
                object.clientFinish = $root.proto.ClientFinish.toObject(message.clientFinish, options);
            return object;
        };

        /**
         * Converts this HandshakeMessage to JSON.
         * @function toJSON
         * @memberof proto.HandshakeMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        HandshakeMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return HandshakeMessage;
    })();

    proto.BizIdentityInfo = (function() {

        /**
         * Properties of a BizIdentityInfo.
         * @memberof proto
         * @interface IBizIdentityInfo
         * @property {proto.BizIdentityInfo.BizIdentityInfoVerifiedLevelValue|null} [vlevel] BizIdentityInfo vlevel
         * @property {proto.IVerifiedNameCertificate|null} [vnameCert] BizIdentityInfo vnameCert
         * @property {boolean|null} [signed] BizIdentityInfo signed
         * @property {boolean|null} [revoked] BizIdentityInfo revoked
         * @property {proto.BizIdentityInfo.BizIdentityInfoHostStorageType|null} [hostStorage] BizIdentityInfo hostStorage
         * @property {proto.BizIdentityInfo.BizIdentityInfoActualActorsType|null} [actualActors] BizIdentityInfo actualActors
         * @property {number|Long|null} [privacyModeTs] BizIdentityInfo privacyModeTs
         * @property {number|Long|null} [featureControls] BizIdentityInfo featureControls
         */

        /**
         * Constructs a new BizIdentityInfo.
         * @memberof proto
         * @classdesc Represents a BizIdentityInfo.
         * @implements IBizIdentityInfo
         * @constructor
         * @param {proto.IBizIdentityInfo=} [properties] Properties to set
         */
        function BizIdentityInfo(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * BizIdentityInfo vlevel.
         * @member {proto.BizIdentityInfo.BizIdentityInfoVerifiedLevelValue} vlevel
         * @memberof proto.BizIdentityInfo
         * @instance
         */
        BizIdentityInfo.prototype.vlevel = 0;

        /**
         * BizIdentityInfo vnameCert.
         * @member {proto.IVerifiedNameCertificate|null|undefined} vnameCert
         * @memberof proto.BizIdentityInfo
         * @instance
         */
        BizIdentityInfo.prototype.vnameCert = null;

        /**
         * BizIdentityInfo signed.
         * @member {boolean} signed
         * @memberof proto.BizIdentityInfo
         * @instance
         */
        BizIdentityInfo.prototype.signed = false;

        /**
         * BizIdentityInfo revoked.
         * @member {boolean} revoked
         * @memberof proto.BizIdentityInfo
         * @instance
         */
        BizIdentityInfo.prototype.revoked = false;

        /**
         * BizIdentityInfo hostStorage.
         * @member {proto.BizIdentityInfo.BizIdentityInfoHostStorageType} hostStorage
         * @memberof proto.BizIdentityInfo
         * @instance
         */
        BizIdentityInfo.prototype.hostStorage = 0;

        /**
         * BizIdentityInfo actualActors.
         * @member {proto.BizIdentityInfo.BizIdentityInfoActualActorsType} actualActors
         * @memberof proto.BizIdentityInfo
         * @instance
         */
        BizIdentityInfo.prototype.actualActors = 0;

        /**
         * BizIdentityInfo privacyModeTs.
         * @member {number|Long} privacyModeTs
         * @memberof proto.BizIdentityInfo
         * @instance
         */
        BizIdentityInfo.prototype.privacyModeTs = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * BizIdentityInfo featureControls.
         * @member {number|Long} featureControls
         * @memberof proto.BizIdentityInfo
         * @instance
         */
        BizIdentityInfo.prototype.featureControls = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * Creates a new BizIdentityInfo instance using the specified properties.
         * @function create
         * @memberof proto.BizIdentityInfo
         * @static
         * @param {proto.IBizIdentityInfo=} [properties] Properties to set
         * @returns {proto.BizIdentityInfo} BizIdentityInfo instance
         */
        BizIdentityInfo.create = function create(properties) {
            return new BizIdentityInfo(properties);
        };

        /**
         * Encodes the specified BizIdentityInfo message. Does not implicitly {@link proto.BizIdentityInfo.verify|verify} messages.
         * @function encode
         * @memberof proto.BizIdentityInfo
         * @static
         * @param {proto.IBizIdentityInfo} message BizIdentityInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        BizIdentityInfo.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.vlevel != null && Object.hasOwnProperty.call(message, "vlevel"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.vlevel);
            if (message.vnameCert != null && Object.hasOwnProperty.call(message, "vnameCert"))
                $root.proto.VerifiedNameCertificate.encode(message.vnameCert, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.signed != null && Object.hasOwnProperty.call(message, "signed"))
                writer.uint32(/* id 3, wireType 0 =*/24).bool(message.signed);
            if (message.revoked != null && Object.hasOwnProperty.call(message, "revoked"))
                writer.uint32(/* id 4, wireType 0 =*/32).bool(message.revoked);
            if (message.hostStorage != null && Object.hasOwnProperty.call(message, "hostStorage"))
                writer.uint32(/* id 5, wireType 0 =*/40).int32(message.hostStorage);
            if (message.actualActors != null && Object.hasOwnProperty.call(message, "actualActors"))
                writer.uint32(/* id 6, wireType 0 =*/48).int32(message.actualActors);
            if (message.privacyModeTs != null && Object.hasOwnProperty.call(message, "privacyModeTs"))
                writer.uint32(/* id 7, wireType 0 =*/56).uint64(message.privacyModeTs);
            if (message.featureControls != null && Object.hasOwnProperty.call(message, "featureControls"))
                writer.uint32(/* id 8, wireType 0 =*/64).uint64(message.featureControls);
            return writer;
        };

        /**
         * Encodes the specified BizIdentityInfo message, length delimited. Does not implicitly {@link proto.BizIdentityInfo.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.BizIdentityInfo
         * @static
         * @param {proto.IBizIdentityInfo} message BizIdentityInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        BizIdentityInfo.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a BizIdentityInfo message from the specified reader or buffer.
         * @function decode
         * @memberof proto.BizIdentityInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.BizIdentityInfo} BizIdentityInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        BizIdentityInfo.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.BizIdentityInfo();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.vlevel = reader.int32();
                    break;
                case 2:
                    message.vnameCert = $root.proto.VerifiedNameCertificate.decode(reader, reader.uint32());
                    break;
                case 3:
                    message.signed = reader.bool();
                    break;
                case 4:
                    message.revoked = reader.bool();
                    break;
                case 5:
                    message.hostStorage = reader.int32();
                    break;
                case 6:
                    message.actualActors = reader.int32();
                    break;
                case 7:
                    message.privacyModeTs = reader.uint64();
                    break;
                case 8:
                    message.featureControls = reader.uint64();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a BizIdentityInfo message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.BizIdentityInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.BizIdentityInfo} BizIdentityInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        BizIdentityInfo.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a BizIdentityInfo message.
         * @function verify
         * @memberof proto.BizIdentityInfo
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        BizIdentityInfo.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.vlevel != null && message.hasOwnProperty("vlevel"))
                switch (message.vlevel) {
                default:
                    return "vlevel: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            if (message.vnameCert != null && message.hasOwnProperty("vnameCert")) {
                var error = $root.proto.VerifiedNameCertificate.verify(message.vnameCert);
                if (error)
                    return "vnameCert." + error;
            }
            if (message.signed != null && message.hasOwnProperty("signed"))
                if (typeof message.signed !== "boolean")
                    return "signed: boolean expected";
            if (message.revoked != null && message.hasOwnProperty("revoked"))
                if (typeof message.revoked !== "boolean")
                    return "revoked: boolean expected";
            if (message.hostStorage != null && message.hasOwnProperty("hostStorage"))
                switch (message.hostStorage) {
                default:
                    return "hostStorage: enum value expected";
                case 0:
                case 1:
                    break;
                }
            if (message.actualActors != null && message.hasOwnProperty("actualActors"))
                switch (message.actualActors) {
                default:
                    return "actualActors: enum value expected";
                case 0:
                case 1:
                    break;
                }
            if (message.privacyModeTs != null && message.hasOwnProperty("privacyModeTs"))
                if (!$util.isInteger(message.privacyModeTs) && !(message.privacyModeTs && $util.isInteger(message.privacyModeTs.low) && $util.isInteger(message.privacyModeTs.high)))
                    return "privacyModeTs: integer|Long expected";
            if (message.featureControls != null && message.hasOwnProperty("featureControls"))
                if (!$util.isInteger(message.featureControls) && !(message.featureControls && $util.isInteger(message.featureControls.low) && $util.isInteger(message.featureControls.high)))
                    return "featureControls: integer|Long expected";
            return null;
        };

        /**
         * Creates a BizIdentityInfo message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.BizIdentityInfo
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.BizIdentityInfo} BizIdentityInfo
         */
        BizIdentityInfo.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.BizIdentityInfo)
                return object;
            var message = new $root.proto.BizIdentityInfo();
            switch (object.vlevel) {
            case "UNKNOWN":
            case 0:
                message.vlevel = 0;
                break;
            case "LOW":
            case 1:
                message.vlevel = 1;
                break;
            case "HIGH":
            case 2:
                message.vlevel = 2;
                break;
            }
            if (object.vnameCert != null) {
                if (typeof object.vnameCert !== "object")
                    throw TypeError(".proto.BizIdentityInfo.vnameCert: object expected");
                message.vnameCert = $root.proto.VerifiedNameCertificate.fromObject(object.vnameCert);
            }
            if (object.signed != null)
                message.signed = Boolean(object.signed);
            if (object.revoked != null)
                message.revoked = Boolean(object.revoked);
            switch (object.hostStorage) {
            case "ON_PREMISE":
            case 0:
                message.hostStorage = 0;
                break;
            case "FACEBOOK":
            case 1:
                message.hostStorage = 1;
                break;
            }
            switch (object.actualActors) {
            case "SELF":
            case 0:
                message.actualActors = 0;
                break;
            case "BSP":
            case 1:
                message.actualActors = 1;
                break;
            }
            if (object.privacyModeTs != null)
                if ($util.Long)
                    (message.privacyModeTs = $util.Long.fromValue(object.privacyModeTs)).unsigned = true;
                else if (typeof object.privacyModeTs === "string")
                    message.privacyModeTs = parseInt(object.privacyModeTs, 10);
                else if (typeof object.privacyModeTs === "number")
                    message.privacyModeTs = object.privacyModeTs;
                else if (typeof object.privacyModeTs === "object")
                    message.privacyModeTs = new $util.LongBits(object.privacyModeTs.low >>> 0, object.privacyModeTs.high >>> 0).toNumber(true);
            if (object.featureControls != null)
                if ($util.Long)
                    (message.featureControls = $util.Long.fromValue(object.featureControls)).unsigned = true;
                else if (typeof object.featureControls === "string")
                    message.featureControls = parseInt(object.featureControls, 10);
                else if (typeof object.featureControls === "number")
                    message.featureControls = object.featureControls;
                else if (typeof object.featureControls === "object")
                    message.featureControls = new $util.LongBits(object.featureControls.low >>> 0, object.featureControls.high >>> 0).toNumber(true);
            return message;
        };

        /**
         * Creates a plain object from a BizIdentityInfo message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.BizIdentityInfo
         * @static
         * @param {proto.BizIdentityInfo} message BizIdentityInfo
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        BizIdentityInfo.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.vlevel = options.enums === String ? "UNKNOWN" : 0;
                object.vnameCert = null;
                object.signed = false;
                object.revoked = false;
                object.hostStorage = options.enums === String ? "ON_PREMISE" : 0;
                object.actualActors = options.enums === String ? "SELF" : 0;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.privacyModeTs = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.privacyModeTs = options.longs === String ? "0" : 0;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.featureControls = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.featureControls = options.longs === String ? "0" : 0;
            }
            if (message.vlevel != null && message.hasOwnProperty("vlevel"))
                object.vlevel = options.enums === String ? $root.proto.BizIdentityInfo.BizIdentityInfoVerifiedLevelValue[message.vlevel] : message.vlevel;
            if (message.vnameCert != null && message.hasOwnProperty("vnameCert"))
                object.vnameCert = $root.proto.VerifiedNameCertificate.toObject(message.vnameCert, options);
            if (message.signed != null && message.hasOwnProperty("signed"))
                object.signed = message.signed;
            if (message.revoked != null && message.hasOwnProperty("revoked"))
                object.revoked = message.revoked;
            if (message.hostStorage != null && message.hasOwnProperty("hostStorage"))
                object.hostStorage = options.enums === String ? $root.proto.BizIdentityInfo.BizIdentityInfoHostStorageType[message.hostStorage] : message.hostStorage;
            if (message.actualActors != null && message.hasOwnProperty("actualActors"))
                object.actualActors = options.enums === String ? $root.proto.BizIdentityInfo.BizIdentityInfoActualActorsType[message.actualActors] : message.actualActors;
            if (message.privacyModeTs != null && message.hasOwnProperty("privacyModeTs"))
                if (typeof message.privacyModeTs === "number")
                    object.privacyModeTs = options.longs === String ? String(message.privacyModeTs) : message.privacyModeTs;
                else
                    object.privacyModeTs = options.longs === String ? $util.Long.prototype.toString.call(message.privacyModeTs) : options.longs === Number ? new $util.LongBits(message.privacyModeTs.low >>> 0, message.privacyModeTs.high >>> 0).toNumber(true) : message.privacyModeTs;
            if (message.featureControls != null && message.hasOwnProperty("featureControls"))
                if (typeof message.featureControls === "number")
                    object.featureControls = options.longs === String ? String(message.featureControls) : message.featureControls;
                else
                    object.featureControls = options.longs === String ? $util.Long.prototype.toString.call(message.featureControls) : options.longs === Number ? new $util.LongBits(message.featureControls.low >>> 0, message.featureControls.high >>> 0).toNumber(true) : message.featureControls;
            return object;
        };

        /**
         * Converts this BizIdentityInfo to JSON.
         * @function toJSON
         * @memberof proto.BizIdentityInfo
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        BizIdentityInfo.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * BizIdentityInfoVerifiedLevelValue enum.
         * @name proto.BizIdentityInfo.BizIdentityInfoVerifiedLevelValue
         * @enum {number}
         * @property {number} UNKNOWN=0 UNKNOWN value
         * @property {number} LOW=1 LOW value
         * @property {number} HIGH=2 HIGH value
         */
        BizIdentityInfo.BizIdentityInfoVerifiedLevelValue = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "UNKNOWN"] = 0;
            values[valuesById[1] = "LOW"] = 1;
            values[valuesById[2] = "HIGH"] = 2;
            return values;
        })();

        /**
         * BizIdentityInfoHostStorageType enum.
         * @name proto.BizIdentityInfo.BizIdentityInfoHostStorageType
         * @enum {number}
         * @property {number} ON_PREMISE=0 ON_PREMISE value
         * @property {number} FACEBOOK=1 FACEBOOK value
         */
        BizIdentityInfo.BizIdentityInfoHostStorageType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "ON_PREMISE"] = 0;
            values[valuesById[1] = "FACEBOOK"] = 1;
            return values;
        })();

        /**
         * BizIdentityInfoActualActorsType enum.
         * @name proto.BizIdentityInfo.BizIdentityInfoActualActorsType
         * @enum {number}
         * @property {number} SELF=0 SELF value
         * @property {number} BSP=1 BSP value
         */
        BizIdentityInfo.BizIdentityInfoActualActorsType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "SELF"] = 0;
            values[valuesById[1] = "BSP"] = 1;
            return values;
        })();

        return BizIdentityInfo;
    })();

    proto.BizAccountLinkInfo = (function() {

        /**
         * Properties of a BizAccountLinkInfo.
         * @memberof proto
         * @interface IBizAccountLinkInfo
         * @property {number|Long|null} [whatsappBizAcctFbid] BizAccountLinkInfo whatsappBizAcctFbid
         * @property {string|null} [whatsappAcctNumber] BizAccountLinkInfo whatsappAcctNumber
         * @property {number|Long|null} [issueTime] BizAccountLinkInfo issueTime
         * @property {proto.BizAccountLinkInfo.BizAccountLinkInfoHostStorageType|null} [hostStorage] BizAccountLinkInfo hostStorage
         * @property {proto.BizAccountLinkInfo.BizAccountLinkInfoAccountType|null} [accountType] BizAccountLinkInfo accountType
         */

        /**
         * Constructs a new BizAccountLinkInfo.
         * @memberof proto
         * @classdesc Represents a BizAccountLinkInfo.
         * @implements IBizAccountLinkInfo
         * @constructor
         * @param {proto.IBizAccountLinkInfo=} [properties] Properties to set
         */
        function BizAccountLinkInfo(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * BizAccountLinkInfo whatsappBizAcctFbid.
         * @member {number|Long} whatsappBizAcctFbid
         * @memberof proto.BizAccountLinkInfo
         * @instance
         */
        BizAccountLinkInfo.prototype.whatsappBizAcctFbid = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * BizAccountLinkInfo whatsappAcctNumber.
         * @member {string} whatsappAcctNumber
         * @memberof proto.BizAccountLinkInfo
         * @instance
         */
        BizAccountLinkInfo.prototype.whatsappAcctNumber = "";

        /**
         * BizAccountLinkInfo issueTime.
         * @member {number|Long} issueTime
         * @memberof proto.BizAccountLinkInfo
         * @instance
         */
        BizAccountLinkInfo.prototype.issueTime = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * BizAccountLinkInfo hostStorage.
         * @member {proto.BizAccountLinkInfo.BizAccountLinkInfoHostStorageType} hostStorage
         * @memberof proto.BizAccountLinkInfo
         * @instance
         */
        BizAccountLinkInfo.prototype.hostStorage = 0;

        /**
         * BizAccountLinkInfo accountType.
         * @member {proto.BizAccountLinkInfo.BizAccountLinkInfoAccountType} accountType
         * @memberof proto.BizAccountLinkInfo
         * @instance
         */
        BizAccountLinkInfo.prototype.accountType = 0;

        /**
         * Creates a new BizAccountLinkInfo instance using the specified properties.
         * @function create
         * @memberof proto.BizAccountLinkInfo
         * @static
         * @param {proto.IBizAccountLinkInfo=} [properties] Properties to set
         * @returns {proto.BizAccountLinkInfo} BizAccountLinkInfo instance
         */
        BizAccountLinkInfo.create = function create(properties) {
            return new BizAccountLinkInfo(properties);
        };

        /**
         * Encodes the specified BizAccountLinkInfo message. Does not implicitly {@link proto.BizAccountLinkInfo.verify|verify} messages.
         * @function encode
         * @memberof proto.BizAccountLinkInfo
         * @static
         * @param {proto.IBizAccountLinkInfo} message BizAccountLinkInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        BizAccountLinkInfo.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.whatsappBizAcctFbid != null && Object.hasOwnProperty.call(message, "whatsappBizAcctFbid"))
                writer.uint32(/* id 1, wireType 0 =*/8).uint64(message.whatsappBizAcctFbid);
            if (message.whatsappAcctNumber != null && Object.hasOwnProperty.call(message, "whatsappAcctNumber"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.whatsappAcctNumber);
            if (message.issueTime != null && Object.hasOwnProperty.call(message, "issueTime"))
                writer.uint32(/* id 3, wireType 0 =*/24).uint64(message.issueTime);
            if (message.hostStorage != null && Object.hasOwnProperty.call(message, "hostStorage"))
                writer.uint32(/* id 4, wireType 0 =*/32).int32(message.hostStorage);
            if (message.accountType != null && Object.hasOwnProperty.call(message, "accountType"))
                writer.uint32(/* id 5, wireType 0 =*/40).int32(message.accountType);
            return writer;
        };

        /**
         * Encodes the specified BizAccountLinkInfo message, length delimited. Does not implicitly {@link proto.BizAccountLinkInfo.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.BizAccountLinkInfo
         * @static
         * @param {proto.IBizAccountLinkInfo} message BizAccountLinkInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        BizAccountLinkInfo.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a BizAccountLinkInfo message from the specified reader or buffer.
         * @function decode
         * @memberof proto.BizAccountLinkInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.BizAccountLinkInfo} BizAccountLinkInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        BizAccountLinkInfo.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.BizAccountLinkInfo();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.whatsappBizAcctFbid = reader.uint64();
                    break;
                case 2:
                    message.whatsappAcctNumber = reader.string();
                    break;
                case 3:
                    message.issueTime = reader.uint64();
                    break;
                case 4:
                    message.hostStorage = reader.int32();
                    break;
                case 5:
                    message.accountType = reader.int32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a BizAccountLinkInfo message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.BizAccountLinkInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.BizAccountLinkInfo} BizAccountLinkInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        BizAccountLinkInfo.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a BizAccountLinkInfo message.
         * @function verify
         * @memberof proto.BizAccountLinkInfo
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        BizAccountLinkInfo.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.whatsappBizAcctFbid != null && message.hasOwnProperty("whatsappBizAcctFbid"))
                if (!$util.isInteger(message.whatsappBizAcctFbid) && !(message.whatsappBizAcctFbid && $util.isInteger(message.whatsappBizAcctFbid.low) && $util.isInteger(message.whatsappBizAcctFbid.high)))
                    return "whatsappBizAcctFbid: integer|Long expected";
            if (message.whatsappAcctNumber != null && message.hasOwnProperty("whatsappAcctNumber"))
                if (!$util.isString(message.whatsappAcctNumber))
                    return "whatsappAcctNumber: string expected";
            if (message.issueTime != null && message.hasOwnProperty("issueTime"))
                if (!$util.isInteger(message.issueTime) && !(message.issueTime && $util.isInteger(message.issueTime.low) && $util.isInteger(message.issueTime.high)))
                    return "issueTime: integer|Long expected";
            if (message.hostStorage != null && message.hasOwnProperty("hostStorage"))
                switch (message.hostStorage) {
                default:
                    return "hostStorage: enum value expected";
                case 0:
                case 1:
                    break;
                }
            if (message.accountType != null && message.hasOwnProperty("accountType"))
                switch (message.accountType) {
                default:
                    return "accountType: enum value expected";
                case 0:
                    break;
                }
            return null;
        };

        /**
         * Creates a BizAccountLinkInfo message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.BizAccountLinkInfo
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.BizAccountLinkInfo} BizAccountLinkInfo
         */
        BizAccountLinkInfo.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.BizAccountLinkInfo)
                return object;
            var message = new $root.proto.BizAccountLinkInfo();
            if (object.whatsappBizAcctFbid != null)
                if ($util.Long)
                    (message.whatsappBizAcctFbid = $util.Long.fromValue(object.whatsappBizAcctFbid)).unsigned = true;
                else if (typeof object.whatsappBizAcctFbid === "string")
                    message.whatsappBizAcctFbid = parseInt(object.whatsappBizAcctFbid, 10);
                else if (typeof object.whatsappBizAcctFbid === "number")
                    message.whatsappBizAcctFbid = object.whatsappBizAcctFbid;
                else if (typeof object.whatsappBizAcctFbid === "object")
                    message.whatsappBizAcctFbid = new $util.LongBits(object.whatsappBizAcctFbid.low >>> 0, object.whatsappBizAcctFbid.high >>> 0).toNumber(true);
            if (object.whatsappAcctNumber != null)
                message.whatsappAcctNumber = String(object.whatsappAcctNumber);
            if (object.issueTime != null)
                if ($util.Long)
                    (message.issueTime = $util.Long.fromValue(object.issueTime)).unsigned = true;
                else if (typeof object.issueTime === "string")
                    message.issueTime = parseInt(object.issueTime, 10);
                else if (typeof object.issueTime === "number")
                    message.issueTime = object.issueTime;
                else if (typeof object.issueTime === "object")
                    message.issueTime = new $util.LongBits(object.issueTime.low >>> 0, object.issueTime.high >>> 0).toNumber(true);
            switch (object.hostStorage) {
            case "ON_PREMISE":
            case 0:
                message.hostStorage = 0;
                break;
            case "FACEBOOK":
            case 1:
                message.hostStorage = 1;
                break;
            }
            switch (object.accountType) {
            case "ENTERPRISE":
            case 0:
                message.accountType = 0;
                break;
            }
            return message;
        };

        /**
         * Creates a plain object from a BizAccountLinkInfo message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.BizAccountLinkInfo
         * @static
         * @param {proto.BizAccountLinkInfo} message BizAccountLinkInfo
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        BizAccountLinkInfo.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.whatsappBizAcctFbid = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.whatsappBizAcctFbid = options.longs === String ? "0" : 0;
                object.whatsappAcctNumber = "";
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.issueTime = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.issueTime = options.longs === String ? "0" : 0;
                object.hostStorage = options.enums === String ? "ON_PREMISE" : 0;
                object.accountType = options.enums === String ? "ENTERPRISE" : 0;
            }
            if (message.whatsappBizAcctFbid != null && message.hasOwnProperty("whatsappBizAcctFbid"))
                if (typeof message.whatsappBizAcctFbid === "number")
                    object.whatsappBizAcctFbid = options.longs === String ? String(message.whatsappBizAcctFbid) : message.whatsappBizAcctFbid;
                else
                    object.whatsappBizAcctFbid = options.longs === String ? $util.Long.prototype.toString.call(message.whatsappBizAcctFbid) : options.longs === Number ? new $util.LongBits(message.whatsappBizAcctFbid.low >>> 0, message.whatsappBizAcctFbid.high >>> 0).toNumber(true) : message.whatsappBizAcctFbid;
            if (message.whatsappAcctNumber != null && message.hasOwnProperty("whatsappAcctNumber"))
                object.whatsappAcctNumber = message.whatsappAcctNumber;
            if (message.issueTime != null && message.hasOwnProperty("issueTime"))
                if (typeof message.issueTime === "number")
                    object.issueTime = options.longs === String ? String(message.issueTime) : message.issueTime;
                else
                    object.issueTime = options.longs === String ? $util.Long.prototype.toString.call(message.issueTime) : options.longs === Number ? new $util.LongBits(message.issueTime.low >>> 0, message.issueTime.high >>> 0).toNumber(true) : message.issueTime;
            if (message.hostStorage != null && message.hasOwnProperty("hostStorage"))
                object.hostStorage = options.enums === String ? $root.proto.BizAccountLinkInfo.BizAccountLinkInfoHostStorageType[message.hostStorage] : message.hostStorage;
            if (message.accountType != null && message.hasOwnProperty("accountType"))
                object.accountType = options.enums === String ? $root.proto.BizAccountLinkInfo.BizAccountLinkInfoAccountType[message.accountType] : message.accountType;
            return object;
        };

        /**
         * Converts this BizAccountLinkInfo to JSON.
         * @function toJSON
         * @memberof proto.BizAccountLinkInfo
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        BizAccountLinkInfo.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * BizAccountLinkInfoHostStorageType enum.
         * @name proto.BizAccountLinkInfo.BizAccountLinkInfoHostStorageType
         * @enum {number}
         * @property {number} ON_PREMISE=0 ON_PREMISE value
         * @property {number} FACEBOOK=1 FACEBOOK value
         */
        BizAccountLinkInfo.BizAccountLinkInfoHostStorageType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "ON_PREMISE"] = 0;
            values[valuesById[1] = "FACEBOOK"] = 1;
            return values;
        })();

        /**
         * BizAccountLinkInfoAccountType enum.
         * @name proto.BizAccountLinkInfo.BizAccountLinkInfoAccountType
         * @enum {number}
         * @property {number} ENTERPRISE=0 ENTERPRISE value
         */
        BizAccountLinkInfo.BizAccountLinkInfoAccountType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "ENTERPRISE"] = 0;
            return values;
        })();

        return BizAccountLinkInfo;
    })();

    proto.BizAccountPayload = (function() {

        /**
         * Properties of a BizAccountPayload.
         * @memberof proto
         * @interface IBizAccountPayload
         * @property {proto.IVerifiedNameCertificate|null} [vnameCert] BizAccountPayload vnameCert
         * @property {Uint8Array|null} [bizAcctLinkInfo] BizAccountPayload bizAcctLinkInfo
         */

        /**
         * Constructs a new BizAccountPayload.
         * @memberof proto
         * @classdesc Represents a BizAccountPayload.
         * @implements IBizAccountPayload
         * @constructor
         * @param {proto.IBizAccountPayload=} [properties] Properties to set
         */
        function BizAccountPayload(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * BizAccountPayload vnameCert.
         * @member {proto.IVerifiedNameCertificate|null|undefined} vnameCert
         * @memberof proto.BizAccountPayload
         * @instance
         */
        BizAccountPayload.prototype.vnameCert = null;

        /**
         * BizAccountPayload bizAcctLinkInfo.
         * @member {Uint8Array} bizAcctLinkInfo
         * @memberof proto.BizAccountPayload
         * @instance
         */
        BizAccountPayload.prototype.bizAcctLinkInfo = $util.newBuffer([]);

        /**
         * Creates a new BizAccountPayload instance using the specified properties.
         * @function create
         * @memberof proto.BizAccountPayload
         * @static
         * @param {proto.IBizAccountPayload=} [properties] Properties to set
         * @returns {proto.BizAccountPayload} BizAccountPayload instance
         */
        BizAccountPayload.create = function create(properties) {
            return new BizAccountPayload(properties);
        };

        /**
         * Encodes the specified BizAccountPayload message. Does not implicitly {@link proto.BizAccountPayload.verify|verify} messages.
         * @function encode
         * @memberof proto.BizAccountPayload
         * @static
         * @param {proto.IBizAccountPayload} message BizAccountPayload message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        BizAccountPayload.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.vnameCert != null && Object.hasOwnProperty.call(message, "vnameCert"))
                $root.proto.VerifiedNameCertificate.encode(message.vnameCert, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.bizAcctLinkInfo != null && Object.hasOwnProperty.call(message, "bizAcctLinkInfo"))
                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.bizAcctLinkInfo);
            return writer;
        };

        /**
         * Encodes the specified BizAccountPayload message, length delimited. Does not implicitly {@link proto.BizAccountPayload.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.BizAccountPayload
         * @static
         * @param {proto.IBizAccountPayload} message BizAccountPayload message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        BizAccountPayload.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a BizAccountPayload message from the specified reader or buffer.
         * @function decode
         * @memberof proto.BizAccountPayload
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.BizAccountPayload} BizAccountPayload
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        BizAccountPayload.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.BizAccountPayload();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.vnameCert = $root.proto.VerifiedNameCertificate.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.bizAcctLinkInfo = reader.bytes();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a BizAccountPayload message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.BizAccountPayload
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.BizAccountPayload} BizAccountPayload
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        BizAccountPayload.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a BizAccountPayload message.
         * @function verify
         * @memberof proto.BizAccountPayload
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        BizAccountPayload.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.vnameCert != null && message.hasOwnProperty("vnameCert")) {
                var error = $root.proto.VerifiedNameCertificate.verify(message.vnameCert);
                if (error)
                    return "vnameCert." + error;
            }
            if (message.bizAcctLinkInfo != null && message.hasOwnProperty("bizAcctLinkInfo"))
                if (!(message.bizAcctLinkInfo && typeof message.bizAcctLinkInfo.length === "number" || $util.isString(message.bizAcctLinkInfo)))
                    return "bizAcctLinkInfo: buffer expected";
            return null;
        };

        /**
         * Creates a BizAccountPayload message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.BizAccountPayload
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.BizAccountPayload} BizAccountPayload
         */
        BizAccountPayload.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.BizAccountPayload)
                return object;
            var message = new $root.proto.BizAccountPayload();
            if (object.vnameCert != null) {
                if (typeof object.vnameCert !== "object")
                    throw TypeError(".proto.BizAccountPayload.vnameCert: object expected");
                message.vnameCert = $root.proto.VerifiedNameCertificate.fromObject(object.vnameCert);
            }
            if (object.bizAcctLinkInfo != null)
                if (typeof object.bizAcctLinkInfo === "string")
                    $util.base64.decode(object.bizAcctLinkInfo, message.bizAcctLinkInfo = $util.newBuffer($util.base64.length(object.bizAcctLinkInfo)), 0);
                else if (object.bizAcctLinkInfo.length)
                    message.bizAcctLinkInfo = object.bizAcctLinkInfo;
            return message;
        };

        /**
         * Creates a plain object from a BizAccountPayload message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.BizAccountPayload
         * @static
         * @param {proto.BizAccountPayload} message BizAccountPayload
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        BizAccountPayload.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.vnameCert = null;
                if (options.bytes === String)
                    object.bizAcctLinkInfo = "";
                else {
                    object.bizAcctLinkInfo = [];
                    if (options.bytes !== Array)
                        object.bizAcctLinkInfo = $util.newBuffer(object.bizAcctLinkInfo);
                }
            }
            if (message.vnameCert != null && message.hasOwnProperty("vnameCert"))
                object.vnameCert = $root.proto.VerifiedNameCertificate.toObject(message.vnameCert, options);
            if (message.bizAcctLinkInfo != null && message.hasOwnProperty("bizAcctLinkInfo"))
                object.bizAcctLinkInfo = options.bytes === String ? $util.base64.encode(message.bizAcctLinkInfo, 0, message.bizAcctLinkInfo.length) : options.bytes === Array ? Array.prototype.slice.call(message.bizAcctLinkInfo) : message.bizAcctLinkInfo;
            return object;
        };

        /**
         * Converts this BizAccountPayload to JSON.
         * @function toJSON
         * @memberof proto.BizAccountPayload
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        BizAccountPayload.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return BizAccountPayload;
    })();

    proto.VerifiedNameCertificate = (function() {

        /**
         * Properties of a VerifiedNameCertificate.
         * @memberof proto
         * @interface IVerifiedNameCertificate
         * @property {Uint8Array|null} [details] VerifiedNameCertificate details
         * @property {Uint8Array|null} [signature] VerifiedNameCertificate signature
         * @property {Uint8Array|null} [serverSignature] VerifiedNameCertificate serverSignature
         */

        /**
         * Constructs a new VerifiedNameCertificate.
         * @memberof proto
         * @classdesc Represents a VerifiedNameCertificate.
         * @implements IVerifiedNameCertificate
         * @constructor
         * @param {proto.IVerifiedNameCertificate=} [properties] Properties to set
         */
        function VerifiedNameCertificate(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * VerifiedNameCertificate details.
         * @member {Uint8Array} details
         * @memberof proto.VerifiedNameCertificate
         * @instance
         */
        VerifiedNameCertificate.prototype.details = $util.newBuffer([]);

        /**
         * VerifiedNameCertificate signature.
         * @member {Uint8Array} signature
         * @memberof proto.VerifiedNameCertificate
         * @instance
         */
        VerifiedNameCertificate.prototype.signature = $util.newBuffer([]);

        /**
         * VerifiedNameCertificate serverSignature.
         * @member {Uint8Array} serverSignature
         * @memberof proto.VerifiedNameCertificate
         * @instance
         */
        VerifiedNameCertificate.prototype.serverSignature = $util.newBuffer([]);

        /**
         * Creates a new VerifiedNameCertificate instance using the specified properties.
         * @function create
         * @memberof proto.VerifiedNameCertificate
         * @static
         * @param {proto.IVerifiedNameCertificate=} [properties] Properties to set
         * @returns {proto.VerifiedNameCertificate} VerifiedNameCertificate instance
         */
        VerifiedNameCertificate.create = function create(properties) {
            return new VerifiedNameCertificate(properties);
        };

        /**
         * Encodes the specified VerifiedNameCertificate message. Does not implicitly {@link proto.VerifiedNameCertificate.verify|verify} messages.
         * @function encode
         * @memberof proto.VerifiedNameCertificate
         * @static
         * @param {proto.IVerifiedNameCertificate} message VerifiedNameCertificate message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        VerifiedNameCertificate.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.details != null && Object.hasOwnProperty.call(message, "details"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.details);
            if (message.signature != null && Object.hasOwnProperty.call(message, "signature"))
                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.signature);
            if (message.serverSignature != null && Object.hasOwnProperty.call(message, "serverSignature"))
                writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.serverSignature);
            return writer;
        };

        /**
         * Encodes the specified VerifiedNameCertificate message, length delimited. Does not implicitly {@link proto.VerifiedNameCertificate.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.VerifiedNameCertificate
         * @static
         * @param {proto.IVerifiedNameCertificate} message VerifiedNameCertificate message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        VerifiedNameCertificate.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a VerifiedNameCertificate message from the specified reader or buffer.
         * @function decode
         * @memberof proto.VerifiedNameCertificate
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.VerifiedNameCertificate} VerifiedNameCertificate
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        VerifiedNameCertificate.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.VerifiedNameCertificate();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.details = reader.bytes();
                    break;
                case 2:
                    message.signature = reader.bytes();
                    break;
                case 3:
                    message.serverSignature = reader.bytes();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a VerifiedNameCertificate message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.VerifiedNameCertificate
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.VerifiedNameCertificate} VerifiedNameCertificate
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        VerifiedNameCertificate.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a VerifiedNameCertificate message.
         * @function verify
         * @memberof proto.VerifiedNameCertificate
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        VerifiedNameCertificate.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.details != null && message.hasOwnProperty("details"))
                if (!(message.details && typeof message.details.length === "number" || $util.isString(message.details)))
                    return "details: buffer expected";
            if (message.signature != null && message.hasOwnProperty("signature"))
                if (!(message.signature && typeof message.signature.length === "number" || $util.isString(message.signature)))
                    return "signature: buffer expected";
            if (message.serverSignature != null && message.hasOwnProperty("serverSignature"))
                if (!(message.serverSignature && typeof message.serverSignature.length === "number" || $util.isString(message.serverSignature)))
                    return "serverSignature: buffer expected";
            return null;
        };

        /**
         * Creates a VerifiedNameCertificate message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.VerifiedNameCertificate
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.VerifiedNameCertificate} VerifiedNameCertificate
         */
        VerifiedNameCertificate.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.VerifiedNameCertificate)
                return object;
            var message = new $root.proto.VerifiedNameCertificate();
            if (object.details != null)
                if (typeof object.details === "string")
                    $util.base64.decode(object.details, message.details = $util.newBuffer($util.base64.length(object.details)), 0);
                else if (object.details.length)
                    message.details = object.details;
            if (object.signature != null)
                if (typeof object.signature === "string")
                    $util.base64.decode(object.signature, message.signature = $util.newBuffer($util.base64.length(object.signature)), 0);
                else if (object.signature.length)
                    message.signature = object.signature;
            if (object.serverSignature != null)
                if (typeof object.serverSignature === "string")
                    $util.base64.decode(object.serverSignature, message.serverSignature = $util.newBuffer($util.base64.length(object.serverSignature)), 0);
                else if (object.serverSignature.length)
                    message.serverSignature = object.serverSignature;
            return message;
        };

        /**
         * Creates a plain object from a VerifiedNameCertificate message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.VerifiedNameCertificate
         * @static
         * @param {proto.VerifiedNameCertificate} message VerifiedNameCertificate
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        VerifiedNameCertificate.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object.details = "";
                else {
                    object.details = [];
                    if (options.bytes !== Array)
                        object.details = $util.newBuffer(object.details);
                }
                if (options.bytes === String)
                    object.signature = "";
                else {
                    object.signature = [];
                    if (options.bytes !== Array)
                        object.signature = $util.newBuffer(object.signature);
                }
                if (options.bytes === String)
                    object.serverSignature = "";
                else {
                    object.serverSignature = [];
                    if (options.bytes !== Array)
                        object.serverSignature = $util.newBuffer(object.serverSignature);
                }
            }
            if (message.details != null && message.hasOwnProperty("details"))
                object.details = options.bytes === String ? $util.base64.encode(message.details, 0, message.details.length) : options.bytes === Array ? Array.prototype.slice.call(message.details) : message.details;
            if (message.signature != null && message.hasOwnProperty("signature"))
                object.signature = options.bytes === String ? $util.base64.encode(message.signature, 0, message.signature.length) : options.bytes === Array ? Array.prototype.slice.call(message.signature) : message.signature;
            if (message.serverSignature != null && message.hasOwnProperty("serverSignature"))
                object.serverSignature = options.bytes === String ? $util.base64.encode(message.serverSignature, 0, message.serverSignature.length) : options.bytes === Array ? Array.prototype.slice.call(message.serverSignature) : message.serverSignature;
            return object;
        };

        /**
         * Converts this VerifiedNameCertificate to JSON.
         * @function toJSON
         * @memberof proto.VerifiedNameCertificate
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        VerifiedNameCertificate.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return VerifiedNameCertificate;
    })();

    proto.LocalizedName = (function() {

        /**
         * Properties of a LocalizedName.
         * @memberof proto
         * @interface ILocalizedName
         * @property {string|null} [lg] LocalizedName lg
         * @property {string|null} [lc] LocalizedName lc
         * @property {string|null} [verifiedName] LocalizedName verifiedName
         */

        /**
         * Constructs a new LocalizedName.
         * @memberof proto
         * @classdesc Represents a LocalizedName.
         * @implements ILocalizedName
         * @constructor
         * @param {proto.ILocalizedName=} [properties] Properties to set
         */
        function LocalizedName(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * LocalizedName lg.
         * @member {string} lg
         * @memberof proto.LocalizedName
         * @instance
         */
        LocalizedName.prototype.lg = "";

        /**
         * LocalizedName lc.
         * @member {string} lc
         * @memberof proto.LocalizedName
         * @instance
         */
        LocalizedName.prototype.lc = "";

        /**
         * LocalizedName verifiedName.
         * @member {string} verifiedName
         * @memberof proto.LocalizedName
         * @instance
         */
        LocalizedName.prototype.verifiedName = "";

        /**
         * Creates a new LocalizedName instance using the specified properties.
         * @function create
         * @memberof proto.LocalizedName
         * @static
         * @param {proto.ILocalizedName=} [properties] Properties to set
         * @returns {proto.LocalizedName} LocalizedName instance
         */
        LocalizedName.create = function create(properties) {
            return new LocalizedName(properties);
        };

        /**
         * Encodes the specified LocalizedName message. Does not implicitly {@link proto.LocalizedName.verify|verify} messages.
         * @function encode
         * @memberof proto.LocalizedName
         * @static
         * @param {proto.ILocalizedName} message LocalizedName message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        LocalizedName.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.lg != null && Object.hasOwnProperty.call(message, "lg"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.lg);
            if (message.lc != null && Object.hasOwnProperty.call(message, "lc"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.lc);
            if (message.verifiedName != null && Object.hasOwnProperty.call(message, "verifiedName"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.verifiedName);
            return writer;
        };

        /**
         * Encodes the specified LocalizedName message, length delimited. Does not implicitly {@link proto.LocalizedName.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.LocalizedName
         * @static
         * @param {proto.ILocalizedName} message LocalizedName message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        LocalizedName.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a LocalizedName message from the specified reader or buffer.
         * @function decode
         * @memberof proto.LocalizedName
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.LocalizedName} LocalizedName
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        LocalizedName.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.LocalizedName();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.lg = reader.string();
                    break;
                case 2:
                    message.lc = reader.string();
                    break;
                case 3:
                    message.verifiedName = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a LocalizedName message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.LocalizedName
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.LocalizedName} LocalizedName
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        LocalizedName.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a LocalizedName message.
         * @function verify
         * @memberof proto.LocalizedName
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        LocalizedName.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.lg != null && message.hasOwnProperty("lg"))
                if (!$util.isString(message.lg))
                    return "lg: string expected";
            if (message.lc != null && message.hasOwnProperty("lc"))
                if (!$util.isString(message.lc))
                    return "lc: string expected";
            if (message.verifiedName != null && message.hasOwnProperty("verifiedName"))
                if (!$util.isString(message.verifiedName))
                    return "verifiedName: string expected";
            return null;
        };

        /**
         * Creates a LocalizedName message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.LocalizedName
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.LocalizedName} LocalizedName
         */
        LocalizedName.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.LocalizedName)
                return object;
            var message = new $root.proto.LocalizedName();
            if (object.lg != null)
                message.lg = String(object.lg);
            if (object.lc != null)
                message.lc = String(object.lc);
            if (object.verifiedName != null)
                message.verifiedName = String(object.verifiedName);
            return message;
        };

        /**
         * Creates a plain object from a LocalizedName message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.LocalizedName
         * @static
         * @param {proto.LocalizedName} message LocalizedName
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        LocalizedName.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.lg = "";
                object.lc = "";
                object.verifiedName = "";
            }
            if (message.lg != null && message.hasOwnProperty("lg"))
                object.lg = message.lg;
            if (message.lc != null && message.hasOwnProperty("lc"))
                object.lc = message.lc;
            if (message.verifiedName != null && message.hasOwnProperty("verifiedName"))
                object.verifiedName = message.verifiedName;
            return object;
        };

        /**
         * Converts this LocalizedName to JSON.
         * @function toJSON
         * @memberof proto.LocalizedName
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        LocalizedName.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return LocalizedName;
    })();

    proto.SyncActionData = (function() {

        /**
         * Properties of a SyncActionData.
         * @memberof proto
         * @interface ISyncActionData
         * @property {Uint8Array|null} [index] SyncActionData index
         * @property {proto.ISyncActionValue|null} [value] SyncActionData value
         * @property {Uint8Array|null} [padding] SyncActionData padding
         * @property {number|null} [version] SyncActionData version
         */

        /**
         * Constructs a new SyncActionData.
         * @memberof proto
         * @classdesc Represents a SyncActionData.
         * @implements ISyncActionData
         * @constructor
         * @param {proto.ISyncActionData=} [properties] Properties to set
         */
        function SyncActionData(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * SyncActionData index.
         * @member {Uint8Array} index
         * @memberof proto.SyncActionData
         * @instance
         */
        SyncActionData.prototype.index = $util.newBuffer([]);

        /**
         * SyncActionData value.
         * @member {proto.ISyncActionValue|null|undefined} value
         * @memberof proto.SyncActionData
         * @instance
         */
        SyncActionData.prototype.value = null;

        /**
         * SyncActionData padding.
         * @member {Uint8Array} padding
         * @memberof proto.SyncActionData
         * @instance
         */
        SyncActionData.prototype.padding = $util.newBuffer([]);

        /**
         * SyncActionData version.
         * @member {number} version
         * @memberof proto.SyncActionData
         * @instance
         */
        SyncActionData.prototype.version = 0;

        /**
         * Creates a new SyncActionData instance using the specified properties.
         * @function create
         * @memberof proto.SyncActionData
         * @static
         * @param {proto.ISyncActionData=} [properties] Properties to set
         * @returns {proto.SyncActionData} SyncActionData instance
         */
        SyncActionData.create = function create(properties) {
            return new SyncActionData(properties);
        };

        /**
         * Encodes the specified SyncActionData message. Does not implicitly {@link proto.SyncActionData.verify|verify} messages.
         * @function encode
         * @memberof proto.SyncActionData
         * @static
         * @param {proto.ISyncActionData} message SyncActionData message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SyncActionData.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.index != null && Object.hasOwnProperty.call(message, "index"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.index);
            if (message.value != null && Object.hasOwnProperty.call(message, "value"))
                $root.proto.SyncActionValue.encode(message.value, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.padding != null && Object.hasOwnProperty.call(message, "padding"))
                writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.padding);
            if (message.version != null && Object.hasOwnProperty.call(message, "version"))
                writer.uint32(/* id 4, wireType 0 =*/32).int32(message.version);
            return writer;
        };

        /**
         * Encodes the specified SyncActionData message, length delimited. Does not implicitly {@link proto.SyncActionData.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.SyncActionData
         * @static
         * @param {proto.ISyncActionData} message SyncActionData message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SyncActionData.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a SyncActionData message from the specified reader or buffer.
         * @function decode
         * @memberof proto.SyncActionData
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.SyncActionData} SyncActionData
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SyncActionData.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncActionData();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.index = reader.bytes();
                    break;
                case 2:
                    message.value = $root.proto.SyncActionValue.decode(reader, reader.uint32());
                    break;
                case 3:
                    message.padding = reader.bytes();
                    break;
                case 4:
                    message.version = reader.int32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a SyncActionData message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.SyncActionData
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.SyncActionData} SyncActionData
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SyncActionData.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a SyncActionData message.
         * @function verify
         * @memberof proto.SyncActionData
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        SyncActionData.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.index != null && message.hasOwnProperty("index"))
                if (!(message.index && typeof message.index.length === "number" || $util.isString(message.index)))
                    return "index: buffer expected";
            if (message.value != null && message.hasOwnProperty("value")) {
                var error = $root.proto.SyncActionValue.verify(message.value);
                if (error)
                    return "value." + error;
            }
            if (message.padding != null && message.hasOwnProperty("padding"))
                if (!(message.padding && typeof message.padding.length === "number" || $util.isString(message.padding)))
                    return "padding: buffer expected";
            if (message.version != null && message.hasOwnProperty("version"))
                if (!$util.isInteger(message.version))
                    return "version: integer expected";
            return null;
        };

        /**
         * Creates a SyncActionData message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.SyncActionData
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.SyncActionData} SyncActionData
         */
        SyncActionData.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.SyncActionData)
                return object;
            var message = new $root.proto.SyncActionData();
            if (object.index != null)
                if (typeof object.index === "string")
                    $util.base64.decode(object.index, message.index = $util.newBuffer($util.base64.length(object.index)), 0);
                else if (object.index.length)
                    message.index = object.index;
            if (object.value != null) {
                if (typeof object.value !== "object")
                    throw TypeError(".proto.SyncActionData.value: object expected");
                message.value = $root.proto.SyncActionValue.fromObject(object.value);
            }
            if (object.padding != null)
                if (typeof object.padding === "string")
                    $util.base64.decode(object.padding, message.padding = $util.newBuffer($util.base64.length(object.padding)), 0);
                else if (object.padding.length)
                    message.padding = object.padding;
            if (object.version != null)
                message.version = object.version | 0;
            return message;
        };

        /**
         * Creates a plain object from a SyncActionData message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.SyncActionData
         * @static
         * @param {proto.SyncActionData} message SyncActionData
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        SyncActionData.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object.index = "";
                else {
                    object.index = [];
                    if (options.bytes !== Array)
                        object.index = $util.newBuffer(object.index);
                }
                object.value = null;
                if (options.bytes === String)
                    object.padding = "";
                else {
                    object.padding = [];
                    if (options.bytes !== Array)
                        object.padding = $util.newBuffer(object.padding);
                }
                object.version = 0;
            }
            if (message.index != null && message.hasOwnProperty("index"))
                object.index = options.bytes === String ? $util.base64.encode(message.index, 0, message.index.length) : options.bytes === Array ? Array.prototype.slice.call(message.index) : message.index;
            if (message.value != null && message.hasOwnProperty("value"))
                object.value = $root.proto.SyncActionValue.toObject(message.value, options);
            if (message.padding != null && message.hasOwnProperty("padding"))
                object.padding = options.bytes === String ? $util.base64.encode(message.padding, 0, message.padding.length) : options.bytes === Array ? Array.prototype.slice.call(message.padding) : message.padding;
            if (message.version != null && message.hasOwnProperty("version"))
                object.version = message.version;
            return object;
        };

        /**
         * Converts this SyncActionData to JSON.
         * @function toJSON
         * @memberof proto.SyncActionData
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        SyncActionData.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return SyncActionData;
    })();

    proto.StarAction = (function() {

        /**
         * Properties of a StarAction.
         * @memberof proto
         * @interface IStarAction
         * @property {boolean|null} [starred] StarAction starred
         */

        /**
         * Constructs a new StarAction.
         * @memberof proto
         * @classdesc Represents a StarAction.
         * @implements IStarAction
         * @constructor
         * @param {proto.IStarAction=} [properties] Properties to set
         */
        function StarAction(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * StarAction starred.
         * @member {boolean} starred
         * @memberof proto.StarAction
         * @instance
         */
        StarAction.prototype.starred = false;

        /**
         * Creates a new StarAction instance using the specified properties.
         * @function create
         * @memberof proto.StarAction
         * @static
         * @param {proto.IStarAction=} [properties] Properties to set
         * @returns {proto.StarAction} StarAction instance
         */
        StarAction.create = function create(properties) {
            return new StarAction(properties);
        };

        /**
         * Encodes the specified StarAction message. Does not implicitly {@link proto.StarAction.verify|verify} messages.
         * @function encode
         * @memberof proto.StarAction
         * @static
         * @param {proto.IStarAction} message StarAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        StarAction.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.starred != null && Object.hasOwnProperty.call(message, "starred"))
                writer.uint32(/* id 1, wireType 0 =*/8).bool(message.starred);
            return writer;
        };

        /**
         * Encodes the specified StarAction message, length delimited. Does not implicitly {@link proto.StarAction.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.StarAction
         * @static
         * @param {proto.IStarAction} message StarAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        StarAction.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a StarAction message from the specified reader or buffer.
         * @function decode
         * @memberof proto.StarAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.StarAction} StarAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        StarAction.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.StarAction();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.starred = reader.bool();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a StarAction message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.StarAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.StarAction} StarAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        StarAction.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a StarAction message.
         * @function verify
         * @memberof proto.StarAction
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        StarAction.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.starred != null && message.hasOwnProperty("starred"))
                if (typeof message.starred !== "boolean")
                    return "starred: boolean expected";
            return null;
        };

        /**
         * Creates a StarAction message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.StarAction
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.StarAction} StarAction
         */
        StarAction.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.StarAction)
                return object;
            var message = new $root.proto.StarAction();
            if (object.starred != null)
                message.starred = Boolean(object.starred);
            return message;
        };

        /**
         * Creates a plain object from a StarAction message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.StarAction
         * @static
         * @param {proto.StarAction} message StarAction
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        StarAction.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                object.starred = false;
            if (message.starred != null && message.hasOwnProperty("starred"))
                object.starred = message.starred;
            return object;
        };

        /**
         * Converts this StarAction to JSON.
         * @function toJSON
         * @memberof proto.StarAction
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        StarAction.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return StarAction;
    })();

    proto.ContactAction = (function() {

        /**
         * Properties of a ContactAction.
         * @memberof proto
         * @interface IContactAction
         * @property {string|null} [fullName] ContactAction fullName
         * @property {string|null} [firstName] ContactAction firstName
         */

        /**
         * Constructs a new ContactAction.
         * @memberof proto
         * @classdesc Represents a ContactAction.
         * @implements IContactAction
         * @constructor
         * @param {proto.IContactAction=} [properties] Properties to set
         */
        function ContactAction(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ContactAction fullName.
         * @member {string} fullName
         * @memberof proto.ContactAction
         * @instance
         */
        ContactAction.prototype.fullName = "";

        /**
         * ContactAction firstName.
         * @member {string} firstName
         * @memberof proto.ContactAction
         * @instance
         */
        ContactAction.prototype.firstName = "";

        /**
         * Creates a new ContactAction instance using the specified properties.
         * @function create
         * @memberof proto.ContactAction
         * @static
         * @param {proto.IContactAction=} [properties] Properties to set
         * @returns {proto.ContactAction} ContactAction instance
         */
        ContactAction.create = function create(properties) {
            return new ContactAction(properties);
        };

        /**
         * Encodes the specified ContactAction message. Does not implicitly {@link proto.ContactAction.verify|verify} messages.
         * @function encode
         * @memberof proto.ContactAction
         * @static
         * @param {proto.IContactAction} message ContactAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ContactAction.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.fullName != null && Object.hasOwnProperty.call(message, "fullName"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.fullName);
            if (message.firstName != null && Object.hasOwnProperty.call(message, "firstName"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.firstName);
            return writer;
        };

        /**
         * Encodes the specified ContactAction message, length delimited. Does not implicitly {@link proto.ContactAction.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ContactAction
         * @static
         * @param {proto.IContactAction} message ContactAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ContactAction.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ContactAction message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ContactAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ContactAction} ContactAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ContactAction.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ContactAction();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.fullName = reader.string();
                    break;
                case 2:
                    message.firstName = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ContactAction message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ContactAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ContactAction} ContactAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ContactAction.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ContactAction message.
         * @function verify
         * @memberof proto.ContactAction
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ContactAction.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.fullName != null && message.hasOwnProperty("fullName"))
                if (!$util.isString(message.fullName))
                    return "fullName: string expected";
            if (message.firstName != null && message.hasOwnProperty("firstName"))
                if (!$util.isString(message.firstName))
                    return "firstName: string expected";
            return null;
        };

        /**
         * Creates a ContactAction message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ContactAction
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ContactAction} ContactAction
         */
        ContactAction.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ContactAction)
                return object;
            var message = new $root.proto.ContactAction();
            if (object.fullName != null)
                message.fullName = String(object.fullName);
            if (object.firstName != null)
                message.firstName = String(object.firstName);
            return message;
        };

        /**
         * Creates a plain object from a ContactAction message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ContactAction
         * @static
         * @param {proto.ContactAction} message ContactAction
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ContactAction.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.fullName = "";
                object.firstName = "";
            }
            if (message.fullName != null && message.hasOwnProperty("fullName"))
                object.fullName = message.fullName;
            if (message.firstName != null && message.hasOwnProperty("firstName"))
                object.firstName = message.firstName;
            return object;
        };

        /**
         * Converts this ContactAction to JSON.
         * @function toJSON
         * @memberof proto.ContactAction
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ContactAction.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ContactAction;
    })();

    proto.MuteAction = (function() {

        /**
         * Properties of a MuteAction.
         * @memberof proto
         * @interface IMuteAction
         * @property {boolean|null} [muted] MuteAction muted
         * @property {number|Long|null} [muteEndTimestamp] MuteAction muteEndTimestamp
         */

        /**
         * Constructs a new MuteAction.
         * @memberof proto
         * @classdesc Represents a MuteAction.
         * @implements IMuteAction
         * @constructor
         * @param {proto.IMuteAction=} [properties] Properties to set
         */
        function MuteAction(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * MuteAction muted.
         * @member {boolean} muted
         * @memberof proto.MuteAction
         * @instance
         */
        MuteAction.prototype.muted = false;

        /**
         * MuteAction muteEndTimestamp.
         * @member {number|Long} muteEndTimestamp
         * @memberof proto.MuteAction
         * @instance
         */
        MuteAction.prototype.muteEndTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * Creates a new MuteAction instance using the specified properties.
         * @function create
         * @memberof proto.MuteAction
         * @static
         * @param {proto.IMuteAction=} [properties] Properties to set
         * @returns {proto.MuteAction} MuteAction instance
         */
        MuteAction.create = function create(properties) {
            return new MuteAction(properties);
        };

        /**
         * Encodes the specified MuteAction message. Does not implicitly {@link proto.MuteAction.verify|verify} messages.
         * @function encode
         * @memberof proto.MuteAction
         * @static
         * @param {proto.IMuteAction} message MuteAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        MuteAction.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.muted != null && Object.hasOwnProperty.call(message, "muted"))
                writer.uint32(/* id 1, wireType 0 =*/8).bool(message.muted);
            if (message.muteEndTimestamp != null && Object.hasOwnProperty.call(message, "muteEndTimestamp"))
                writer.uint32(/* id 2, wireType 0 =*/16).int64(message.muteEndTimestamp);
            return writer;
        };

        /**
         * Encodes the specified MuteAction message, length delimited. Does not implicitly {@link proto.MuteAction.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.MuteAction
         * @static
         * @param {proto.IMuteAction} message MuteAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        MuteAction.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a MuteAction message from the specified reader or buffer.
         * @function decode
         * @memberof proto.MuteAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.MuteAction} MuteAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        MuteAction.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MuteAction();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.muted = reader.bool();
                    break;
                case 2:
                    message.muteEndTimestamp = reader.int64();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a MuteAction message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.MuteAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.MuteAction} MuteAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        MuteAction.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a MuteAction message.
         * @function verify
         * @memberof proto.MuteAction
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        MuteAction.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.muted != null && message.hasOwnProperty("muted"))
                if (typeof message.muted !== "boolean")
                    return "muted: boolean expected";
            if (message.muteEndTimestamp != null && message.hasOwnProperty("muteEndTimestamp"))
                if (!$util.isInteger(message.muteEndTimestamp) && !(message.muteEndTimestamp && $util.isInteger(message.muteEndTimestamp.low) && $util.isInteger(message.muteEndTimestamp.high)))
                    return "muteEndTimestamp: integer|Long expected";
            return null;
        };

        /**
         * Creates a MuteAction message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.MuteAction
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.MuteAction} MuteAction
         */
        MuteAction.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.MuteAction)
                return object;
            var message = new $root.proto.MuteAction();
            if (object.muted != null)
                message.muted = Boolean(object.muted);
            if (object.muteEndTimestamp != null)
                if ($util.Long)
                    (message.muteEndTimestamp = $util.Long.fromValue(object.muteEndTimestamp)).unsigned = false;
                else if (typeof object.muteEndTimestamp === "string")
                    message.muteEndTimestamp = parseInt(object.muteEndTimestamp, 10);
                else if (typeof object.muteEndTimestamp === "number")
                    message.muteEndTimestamp = object.muteEndTimestamp;
                else if (typeof object.muteEndTimestamp === "object")
                    message.muteEndTimestamp = new $util.LongBits(object.muteEndTimestamp.low >>> 0, object.muteEndTimestamp.high >>> 0).toNumber();
            return message;
        };

        /**
         * Creates a plain object from a MuteAction message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.MuteAction
         * @static
         * @param {proto.MuteAction} message MuteAction
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        MuteAction.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.muted = false;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.muteEndTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.muteEndTimestamp = options.longs === String ? "0" : 0;
            }
            if (message.muted != null && message.hasOwnProperty("muted"))
                object.muted = message.muted;
            if (message.muteEndTimestamp != null && message.hasOwnProperty("muteEndTimestamp"))
                if (typeof message.muteEndTimestamp === "number")
                    object.muteEndTimestamp = options.longs === String ? String(message.muteEndTimestamp) : message.muteEndTimestamp;
                else
                    object.muteEndTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.muteEndTimestamp) : options.longs === Number ? new $util.LongBits(message.muteEndTimestamp.low >>> 0, message.muteEndTimestamp.high >>> 0).toNumber() : message.muteEndTimestamp;
            return object;
        };

        /**
         * Converts this MuteAction to JSON.
         * @function toJSON
         * @memberof proto.MuteAction
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        MuteAction.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return MuteAction;
    })();

    proto.PinAction = (function() {

        /**
         * Properties of a PinAction.
         * @memberof proto
         * @interface IPinAction
         * @property {boolean|null} [pinned] PinAction pinned
         */

        /**
         * Constructs a new PinAction.
         * @memberof proto
         * @classdesc Represents a PinAction.
         * @implements IPinAction
         * @constructor
         * @param {proto.IPinAction=} [properties] Properties to set
         */
        function PinAction(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * PinAction pinned.
         * @member {boolean} pinned
         * @memberof proto.PinAction
         * @instance
         */
        PinAction.prototype.pinned = false;

        /**
         * Creates a new PinAction instance using the specified properties.
         * @function create
         * @memberof proto.PinAction
         * @static
         * @param {proto.IPinAction=} [properties] Properties to set
         * @returns {proto.PinAction} PinAction instance
         */
        PinAction.create = function create(properties) {
            return new PinAction(properties);
        };

        /**
         * Encodes the specified PinAction message. Does not implicitly {@link proto.PinAction.verify|verify} messages.
         * @function encode
         * @memberof proto.PinAction
         * @static
         * @param {proto.IPinAction} message PinAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PinAction.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.pinned != null && Object.hasOwnProperty.call(message, "pinned"))
                writer.uint32(/* id 1, wireType 0 =*/8).bool(message.pinned);
            return writer;
        };

        /**
         * Encodes the specified PinAction message, length delimited. Does not implicitly {@link proto.PinAction.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.PinAction
         * @static
         * @param {proto.IPinAction} message PinAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PinAction.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a PinAction message from the specified reader or buffer.
         * @function decode
         * @memberof proto.PinAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.PinAction} PinAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PinAction.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.PinAction();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.pinned = reader.bool();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a PinAction message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.PinAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.PinAction} PinAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PinAction.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a PinAction message.
         * @function verify
         * @memberof proto.PinAction
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        PinAction.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.pinned != null && message.hasOwnProperty("pinned"))
                if (typeof message.pinned !== "boolean")
                    return "pinned: boolean expected";
            return null;
        };

        /**
         * Creates a PinAction message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.PinAction
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.PinAction} PinAction
         */
        PinAction.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.PinAction)
                return object;
            var message = new $root.proto.PinAction();
            if (object.pinned != null)
                message.pinned = Boolean(object.pinned);
            return message;
        };

        /**
         * Creates a plain object from a PinAction message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.PinAction
         * @static
         * @param {proto.PinAction} message PinAction
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        PinAction.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                object.pinned = false;
            if (message.pinned != null && message.hasOwnProperty("pinned"))
                object.pinned = message.pinned;
            return object;
        };

        /**
         * Converts this PinAction to JSON.
         * @function toJSON
         * @memberof proto.PinAction
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        PinAction.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return PinAction;
    })();

    proto.SecurityNotificationSetting = (function() {

        /**
         * Properties of a SecurityNotificationSetting.
         * @memberof proto
         * @interface ISecurityNotificationSetting
         * @property {boolean|null} [showNotification] SecurityNotificationSetting showNotification
         */

        /**
         * Constructs a new SecurityNotificationSetting.
         * @memberof proto
         * @classdesc Represents a SecurityNotificationSetting.
         * @implements ISecurityNotificationSetting
         * @constructor
         * @param {proto.ISecurityNotificationSetting=} [properties] Properties to set
         */
        function SecurityNotificationSetting(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * SecurityNotificationSetting showNotification.
         * @member {boolean} showNotification
         * @memberof proto.SecurityNotificationSetting
         * @instance
         */
        SecurityNotificationSetting.prototype.showNotification = false;

        /**
         * Creates a new SecurityNotificationSetting instance using the specified properties.
         * @function create
         * @memberof proto.SecurityNotificationSetting
         * @static
         * @param {proto.ISecurityNotificationSetting=} [properties] Properties to set
         * @returns {proto.SecurityNotificationSetting} SecurityNotificationSetting instance
         */
        SecurityNotificationSetting.create = function create(properties) {
            return new SecurityNotificationSetting(properties);
        };

        /**
         * Encodes the specified SecurityNotificationSetting message. Does not implicitly {@link proto.SecurityNotificationSetting.verify|verify} messages.
         * @function encode
         * @memberof proto.SecurityNotificationSetting
         * @static
         * @param {proto.ISecurityNotificationSetting} message SecurityNotificationSetting message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SecurityNotificationSetting.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.showNotification != null && Object.hasOwnProperty.call(message, "showNotification"))
                writer.uint32(/* id 1, wireType 0 =*/8).bool(message.showNotification);
            return writer;
        };

        /**
         * Encodes the specified SecurityNotificationSetting message, length delimited. Does not implicitly {@link proto.SecurityNotificationSetting.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.SecurityNotificationSetting
         * @static
         * @param {proto.ISecurityNotificationSetting} message SecurityNotificationSetting message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SecurityNotificationSetting.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a SecurityNotificationSetting message from the specified reader or buffer.
         * @function decode
         * @memberof proto.SecurityNotificationSetting
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.SecurityNotificationSetting} SecurityNotificationSetting
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SecurityNotificationSetting.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SecurityNotificationSetting();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.showNotification = reader.bool();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a SecurityNotificationSetting message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.SecurityNotificationSetting
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.SecurityNotificationSetting} SecurityNotificationSetting
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SecurityNotificationSetting.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a SecurityNotificationSetting message.
         * @function verify
         * @memberof proto.SecurityNotificationSetting
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        SecurityNotificationSetting.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.showNotification != null && message.hasOwnProperty("showNotification"))
                if (typeof message.showNotification !== "boolean")
                    return "showNotification: boolean expected";
            return null;
        };

        /**
         * Creates a SecurityNotificationSetting message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.SecurityNotificationSetting
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.SecurityNotificationSetting} SecurityNotificationSetting
         */
        SecurityNotificationSetting.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.SecurityNotificationSetting)
                return object;
            var message = new $root.proto.SecurityNotificationSetting();
            if (object.showNotification != null)
                message.showNotification = Boolean(object.showNotification);
            return message;
        };

        /**
         * Creates a plain object from a SecurityNotificationSetting message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.SecurityNotificationSetting
         * @static
         * @param {proto.SecurityNotificationSetting} message SecurityNotificationSetting
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        SecurityNotificationSetting.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                object.showNotification = false;
            if (message.showNotification != null && message.hasOwnProperty("showNotification"))
                object.showNotification = message.showNotification;
            return object;
        };

        /**
         * Converts this SecurityNotificationSetting to JSON.
         * @function toJSON
         * @memberof proto.SecurityNotificationSetting
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        SecurityNotificationSetting.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return SecurityNotificationSetting;
    })();

    proto.PushNameSetting = (function() {

        /**
         * Properties of a PushNameSetting.
         * @memberof proto
         * @interface IPushNameSetting
         * @property {string|null} [name] PushNameSetting name
         */

        /**
         * Constructs a new PushNameSetting.
         * @memberof proto
         * @classdesc Represents a PushNameSetting.
         * @implements IPushNameSetting
         * @constructor
         * @param {proto.IPushNameSetting=} [properties] Properties to set
         */
        function PushNameSetting(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * PushNameSetting name.
         * @member {string} name
         * @memberof proto.PushNameSetting
         * @instance
         */
        PushNameSetting.prototype.name = "";

        /**
         * Creates a new PushNameSetting instance using the specified properties.
         * @function create
         * @memberof proto.PushNameSetting
         * @static
         * @param {proto.IPushNameSetting=} [properties] Properties to set
         * @returns {proto.PushNameSetting} PushNameSetting instance
         */
        PushNameSetting.create = function create(properties) {
            return new PushNameSetting(properties);
        };

        /**
         * Encodes the specified PushNameSetting message. Does not implicitly {@link proto.PushNameSetting.verify|verify} messages.
         * @function encode
         * @memberof proto.PushNameSetting
         * @static
         * @param {proto.IPushNameSetting} message PushNameSetting message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PushNameSetting.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.name != null && Object.hasOwnProperty.call(message, "name"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.name);
            return writer;
        };

        /**
         * Encodes the specified PushNameSetting message, length delimited. Does not implicitly {@link proto.PushNameSetting.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.PushNameSetting
         * @static
         * @param {proto.IPushNameSetting} message PushNameSetting message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PushNameSetting.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a PushNameSetting message from the specified reader or buffer.
         * @function decode
         * @memberof proto.PushNameSetting
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.PushNameSetting} PushNameSetting
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PushNameSetting.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.PushNameSetting();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.name = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a PushNameSetting message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.PushNameSetting
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.PushNameSetting} PushNameSetting
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PushNameSetting.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a PushNameSetting message.
         * @function verify
         * @memberof proto.PushNameSetting
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        PushNameSetting.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.name != null && message.hasOwnProperty("name"))
                if (!$util.isString(message.name))
                    return "name: string expected";
            return null;
        };

        /**
         * Creates a PushNameSetting message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.PushNameSetting
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.PushNameSetting} PushNameSetting
         */
        PushNameSetting.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.PushNameSetting)
                return object;
            var message = new $root.proto.PushNameSetting();
            if (object.name != null)
                message.name = String(object.name);
            return message;
        };

        /**
         * Creates a plain object from a PushNameSetting message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.PushNameSetting
         * @static
         * @param {proto.PushNameSetting} message PushNameSetting
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        PushNameSetting.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                object.name = "";
            if (message.name != null && message.hasOwnProperty("name"))
                object.name = message.name;
            return object;
        };

        /**
         * Converts this PushNameSetting to JSON.
         * @function toJSON
         * @memberof proto.PushNameSetting
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        PushNameSetting.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return PushNameSetting;
    })();

    proto.LocaleSetting = (function() {

        /**
         * Properties of a LocaleSetting.
         * @memberof proto
         * @interface ILocaleSetting
         * @property {string|null} [locale] LocaleSetting locale
         */

        /**
         * Constructs a new LocaleSetting.
         * @memberof proto
         * @classdesc Represents a LocaleSetting.
         * @implements ILocaleSetting
         * @constructor
         * @param {proto.ILocaleSetting=} [properties] Properties to set
         */
        function LocaleSetting(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * LocaleSetting locale.
         * @member {string} locale
         * @memberof proto.LocaleSetting
         * @instance
         */
        LocaleSetting.prototype.locale = "";

        /**
         * Creates a new LocaleSetting instance using the specified properties.
         * @function create
         * @memberof proto.LocaleSetting
         * @static
         * @param {proto.ILocaleSetting=} [properties] Properties to set
         * @returns {proto.LocaleSetting} LocaleSetting instance
         */
        LocaleSetting.create = function create(properties) {
            return new LocaleSetting(properties);
        };

        /**
         * Encodes the specified LocaleSetting message. Does not implicitly {@link proto.LocaleSetting.verify|verify} messages.
         * @function encode
         * @memberof proto.LocaleSetting
         * @static
         * @param {proto.ILocaleSetting} message LocaleSetting message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        LocaleSetting.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.locale != null && Object.hasOwnProperty.call(message, "locale"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.locale);
            return writer;
        };

        /**
         * Encodes the specified LocaleSetting message, length delimited. Does not implicitly {@link proto.LocaleSetting.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.LocaleSetting
         * @static
         * @param {proto.ILocaleSetting} message LocaleSetting message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        LocaleSetting.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a LocaleSetting message from the specified reader or buffer.
         * @function decode
         * @memberof proto.LocaleSetting
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.LocaleSetting} LocaleSetting
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        LocaleSetting.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.LocaleSetting();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.locale = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a LocaleSetting message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.LocaleSetting
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.LocaleSetting} LocaleSetting
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        LocaleSetting.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a LocaleSetting message.
         * @function verify
         * @memberof proto.LocaleSetting
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        LocaleSetting.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.locale != null && message.hasOwnProperty("locale"))
                if (!$util.isString(message.locale))
                    return "locale: string expected";
            return null;
        };

        /**
         * Creates a LocaleSetting message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.LocaleSetting
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.LocaleSetting} LocaleSetting
         */
        LocaleSetting.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.LocaleSetting)
                return object;
            var message = new $root.proto.LocaleSetting();
            if (object.locale != null)
                message.locale = String(object.locale);
            return message;
        };

        /**
         * Creates a plain object from a LocaleSetting message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.LocaleSetting
         * @static
         * @param {proto.LocaleSetting} message LocaleSetting
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        LocaleSetting.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                object.locale = "";
            if (message.locale != null && message.hasOwnProperty("locale"))
                object.locale = message.locale;
            return object;
        };

        /**
         * Converts this LocaleSetting to JSON.
         * @function toJSON
         * @memberof proto.LocaleSetting
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        LocaleSetting.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return LocaleSetting;
    })();

    proto.QuickReplyAction = (function() {

        /**
         * Properties of a QuickReplyAction.
         * @memberof proto
         * @interface IQuickReplyAction
         * @property {string|null} [shortcut] QuickReplyAction shortcut
         * @property {string|null} [message] QuickReplyAction message
         * @property {Array.<string>|null} [keywords] QuickReplyAction keywords
         * @property {number|null} [count] QuickReplyAction count
         * @property {boolean|null} [deleted] QuickReplyAction deleted
         */

        /**
         * Constructs a new QuickReplyAction.
         * @memberof proto
         * @classdesc Represents a QuickReplyAction.
         * @implements IQuickReplyAction
         * @constructor
         * @param {proto.IQuickReplyAction=} [properties] Properties to set
         */
        function QuickReplyAction(properties) {
            this.keywords = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * QuickReplyAction shortcut.
         * @member {string} shortcut
         * @memberof proto.QuickReplyAction
         * @instance
         */
        QuickReplyAction.prototype.shortcut = "";

        /**
         * QuickReplyAction message.
         * @member {string} message
         * @memberof proto.QuickReplyAction
         * @instance
         */
        QuickReplyAction.prototype.message = "";

        /**
         * QuickReplyAction keywords.
         * @member {Array.<string>} keywords
         * @memberof proto.QuickReplyAction
         * @instance
         */
        QuickReplyAction.prototype.keywords = $util.emptyArray;

        /**
         * QuickReplyAction count.
         * @member {number} count
         * @memberof proto.QuickReplyAction
         * @instance
         */
        QuickReplyAction.prototype.count = 0;

        /**
         * QuickReplyAction deleted.
         * @member {boolean} deleted
         * @memberof proto.QuickReplyAction
         * @instance
         */
        QuickReplyAction.prototype.deleted = false;

        /**
         * Creates a new QuickReplyAction instance using the specified properties.
         * @function create
         * @memberof proto.QuickReplyAction
         * @static
         * @param {proto.IQuickReplyAction=} [properties] Properties to set
         * @returns {proto.QuickReplyAction} QuickReplyAction instance
         */
        QuickReplyAction.create = function create(properties) {
            return new QuickReplyAction(properties);
        };

        /**
         * Encodes the specified QuickReplyAction message. Does not implicitly {@link proto.QuickReplyAction.verify|verify} messages.
         * @function encode
         * @memberof proto.QuickReplyAction
         * @static
         * @param {proto.IQuickReplyAction} message QuickReplyAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        QuickReplyAction.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.shortcut != null && Object.hasOwnProperty.call(message, "shortcut"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.shortcut);
            if (message.message != null && Object.hasOwnProperty.call(message, "message"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.message);
            if (message.keywords != null && message.keywords.length)
                for (var i = 0; i < message.keywords.length; ++i)
                    writer.uint32(/* id 3, wireType 2 =*/26).string(message.keywords[i]);
            if (message.count != null && Object.hasOwnProperty.call(message, "count"))
                writer.uint32(/* id 4, wireType 0 =*/32).int32(message.count);
            if (message.deleted != null && Object.hasOwnProperty.call(message, "deleted"))
                writer.uint32(/* id 5, wireType 0 =*/40).bool(message.deleted);
            return writer;
        };

        /**
         * Encodes the specified QuickReplyAction message, length delimited. Does not implicitly {@link proto.QuickReplyAction.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.QuickReplyAction
         * @static
         * @param {proto.IQuickReplyAction} message QuickReplyAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        QuickReplyAction.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a QuickReplyAction message from the specified reader or buffer.
         * @function decode
         * @memberof proto.QuickReplyAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.QuickReplyAction} QuickReplyAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        QuickReplyAction.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.QuickReplyAction();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.shortcut = reader.string();
                    break;
                case 2:
                    message.message = reader.string();
                    break;
                case 3:
                    if (!(message.keywords && message.keywords.length))
                        message.keywords = [];
                    message.keywords.push(reader.string());
                    break;
                case 4:
                    message.count = reader.int32();
                    break;
                case 5:
                    message.deleted = reader.bool();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a QuickReplyAction message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.QuickReplyAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.QuickReplyAction} QuickReplyAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        QuickReplyAction.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a QuickReplyAction message.
         * @function verify
         * @memberof proto.QuickReplyAction
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        QuickReplyAction.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.shortcut != null && message.hasOwnProperty("shortcut"))
                if (!$util.isString(message.shortcut))
                    return "shortcut: string expected";
            if (message.message != null && message.hasOwnProperty("message"))
                if (!$util.isString(message.message))
                    return "message: string expected";
            if (message.keywords != null && message.hasOwnProperty("keywords")) {
                if (!Array.isArray(message.keywords))
                    return "keywords: array expected";
                for (var i = 0; i < message.keywords.length; ++i)
                    if (!$util.isString(message.keywords[i]))
                        return "keywords: string[] expected";
            }
            if (message.count != null && message.hasOwnProperty("count"))
                if (!$util.isInteger(message.count))
                    return "count: integer expected";
            if (message.deleted != null && message.hasOwnProperty("deleted"))
                if (typeof message.deleted !== "boolean")
                    return "deleted: boolean expected";
            return null;
        };

        /**
         * Creates a QuickReplyAction message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.QuickReplyAction
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.QuickReplyAction} QuickReplyAction
         */
        QuickReplyAction.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.QuickReplyAction)
                return object;
            var message = new $root.proto.QuickReplyAction();
            if (object.shortcut != null)
                message.shortcut = String(object.shortcut);
            if (object.message != null)
                message.message = String(object.message);
            if (object.keywords) {
                if (!Array.isArray(object.keywords))
                    throw TypeError(".proto.QuickReplyAction.keywords: array expected");
                message.keywords = [];
                for (var i = 0; i < object.keywords.length; ++i)
                    message.keywords[i] = String(object.keywords[i]);
            }
            if (object.count != null)
                message.count = object.count | 0;
            if (object.deleted != null)
                message.deleted = Boolean(object.deleted);
            return message;
        };

        /**
         * Creates a plain object from a QuickReplyAction message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.QuickReplyAction
         * @static
         * @param {proto.QuickReplyAction} message QuickReplyAction
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        QuickReplyAction.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.keywords = [];
            if (options.defaults) {
                object.shortcut = "";
                object.message = "";
                object.count = 0;
                object.deleted = false;
            }
            if (message.shortcut != null && message.hasOwnProperty("shortcut"))
                object.shortcut = message.shortcut;
            if (message.message != null && message.hasOwnProperty("message"))
                object.message = message.message;
            if (message.keywords && message.keywords.length) {
                object.keywords = [];
                for (var j = 0; j < message.keywords.length; ++j)
                    object.keywords[j] = message.keywords[j];
            }
            if (message.count != null && message.hasOwnProperty("count"))
                object.count = message.count;
            if (message.deleted != null && message.hasOwnProperty("deleted"))
                object.deleted = message.deleted;
            return object;
        };

        /**
         * Converts this QuickReplyAction to JSON.
         * @function toJSON
         * @memberof proto.QuickReplyAction
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        QuickReplyAction.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return QuickReplyAction;
    })();

    proto.LabelAssociationAction = (function() {

        /**
         * Properties of a LabelAssociationAction.
         * @memberof proto
         * @interface ILabelAssociationAction
         * @property {boolean|null} [labeled] LabelAssociationAction labeled
         */

        /**
         * Constructs a new LabelAssociationAction.
         * @memberof proto
         * @classdesc Represents a LabelAssociationAction.
         * @implements ILabelAssociationAction
         * @constructor
         * @param {proto.ILabelAssociationAction=} [properties] Properties to set
         */
        function LabelAssociationAction(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * LabelAssociationAction labeled.
         * @member {boolean} labeled
         * @memberof proto.LabelAssociationAction
         * @instance
         */
        LabelAssociationAction.prototype.labeled = false;

        /**
         * Creates a new LabelAssociationAction instance using the specified properties.
         * @function create
         * @memberof proto.LabelAssociationAction
         * @static
         * @param {proto.ILabelAssociationAction=} [properties] Properties to set
         * @returns {proto.LabelAssociationAction} LabelAssociationAction instance
         */
        LabelAssociationAction.create = function create(properties) {
            return new LabelAssociationAction(properties);
        };

        /**
         * Encodes the specified LabelAssociationAction message. Does not implicitly {@link proto.LabelAssociationAction.verify|verify} messages.
         * @function encode
         * @memberof proto.LabelAssociationAction
         * @static
         * @param {proto.ILabelAssociationAction} message LabelAssociationAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        LabelAssociationAction.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.labeled != null && Object.hasOwnProperty.call(message, "labeled"))
                writer.uint32(/* id 1, wireType 0 =*/8).bool(message.labeled);
            return writer;
        };

        /**
         * Encodes the specified LabelAssociationAction message, length delimited. Does not implicitly {@link proto.LabelAssociationAction.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.LabelAssociationAction
         * @static
         * @param {proto.ILabelAssociationAction} message LabelAssociationAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        LabelAssociationAction.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a LabelAssociationAction message from the specified reader or buffer.
         * @function decode
         * @memberof proto.LabelAssociationAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.LabelAssociationAction} LabelAssociationAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        LabelAssociationAction.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.LabelAssociationAction();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.labeled = reader.bool();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a LabelAssociationAction message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.LabelAssociationAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.LabelAssociationAction} LabelAssociationAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        LabelAssociationAction.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a LabelAssociationAction message.
         * @function verify
         * @memberof proto.LabelAssociationAction
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        LabelAssociationAction.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.labeled != null && message.hasOwnProperty("labeled"))
                if (typeof message.labeled !== "boolean")
                    return "labeled: boolean expected";
            return null;
        };

        /**
         * Creates a LabelAssociationAction message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.LabelAssociationAction
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.LabelAssociationAction} LabelAssociationAction
         */
        LabelAssociationAction.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.LabelAssociationAction)
                return object;
            var message = new $root.proto.LabelAssociationAction();
            if (object.labeled != null)
                message.labeled = Boolean(object.labeled);
            return message;
        };

        /**
         * Creates a plain object from a LabelAssociationAction message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.LabelAssociationAction
         * @static
         * @param {proto.LabelAssociationAction} message LabelAssociationAction
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        LabelAssociationAction.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                object.labeled = false;
            if (message.labeled != null && message.hasOwnProperty("labeled"))
                object.labeled = message.labeled;
            return object;
        };

        /**
         * Converts this LabelAssociationAction to JSON.
         * @function toJSON
         * @memberof proto.LabelAssociationAction
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        LabelAssociationAction.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return LabelAssociationAction;
    })();

    proto.LabelEditAction = (function() {

        /**
         * Properties of a LabelEditAction.
         * @memberof proto
         * @interface ILabelEditAction
         * @property {string|null} [name] LabelEditAction name
         * @property {number|null} [color] LabelEditAction color
         * @property {number|null} [predefinedId] LabelEditAction predefinedId
         * @property {boolean|null} [deleted] LabelEditAction deleted
         */

        /**
         * Constructs a new LabelEditAction.
         * @memberof proto
         * @classdesc Represents a LabelEditAction.
         * @implements ILabelEditAction
         * @constructor
         * @param {proto.ILabelEditAction=} [properties] Properties to set
         */
        function LabelEditAction(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * LabelEditAction name.
         * @member {string} name
         * @memberof proto.LabelEditAction
         * @instance
         */
        LabelEditAction.prototype.name = "";

        /**
         * LabelEditAction color.
         * @member {number} color
         * @memberof proto.LabelEditAction
         * @instance
         */
        LabelEditAction.prototype.color = 0;

        /**
         * LabelEditAction predefinedId.
         * @member {number} predefinedId
         * @memberof proto.LabelEditAction
         * @instance
         */
        LabelEditAction.prototype.predefinedId = 0;

        /**
         * LabelEditAction deleted.
         * @member {boolean} deleted
         * @memberof proto.LabelEditAction
         * @instance
         */
        LabelEditAction.prototype.deleted = false;

        /**
         * Creates a new LabelEditAction instance using the specified properties.
         * @function create
         * @memberof proto.LabelEditAction
         * @static
         * @param {proto.ILabelEditAction=} [properties] Properties to set
         * @returns {proto.LabelEditAction} LabelEditAction instance
         */
        LabelEditAction.create = function create(properties) {
            return new LabelEditAction(properties);
        };

        /**
         * Encodes the specified LabelEditAction message. Does not implicitly {@link proto.LabelEditAction.verify|verify} messages.
         * @function encode
         * @memberof proto.LabelEditAction
         * @static
         * @param {proto.ILabelEditAction} message LabelEditAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        LabelEditAction.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.name != null && Object.hasOwnProperty.call(message, "name"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.name);
            if (message.color != null && Object.hasOwnProperty.call(message, "color"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.color);
            if (message.predefinedId != null && Object.hasOwnProperty.call(message, "predefinedId"))
                writer.uint32(/* id 3, wireType 0 =*/24).int32(message.predefinedId);
            if (message.deleted != null && Object.hasOwnProperty.call(message, "deleted"))
                writer.uint32(/* id 4, wireType 0 =*/32).bool(message.deleted);
            return writer;
        };

        /**
         * Encodes the specified LabelEditAction message, length delimited. Does not implicitly {@link proto.LabelEditAction.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.LabelEditAction
         * @static
         * @param {proto.ILabelEditAction} message LabelEditAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        LabelEditAction.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a LabelEditAction message from the specified reader or buffer.
         * @function decode
         * @memberof proto.LabelEditAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.LabelEditAction} LabelEditAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        LabelEditAction.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.LabelEditAction();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.name = reader.string();
                    break;
                case 2:
                    message.color = reader.int32();
                    break;
                case 3:
                    message.predefinedId = reader.int32();
                    break;
                case 4:
                    message.deleted = reader.bool();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a LabelEditAction message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.LabelEditAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.LabelEditAction} LabelEditAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        LabelEditAction.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a LabelEditAction message.
         * @function verify
         * @memberof proto.LabelEditAction
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        LabelEditAction.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.name != null && message.hasOwnProperty("name"))
                if (!$util.isString(message.name))
                    return "name: string expected";
            if (message.color != null && message.hasOwnProperty("color"))
                if (!$util.isInteger(message.color))
                    return "color: integer expected";
            if (message.predefinedId != null && message.hasOwnProperty("predefinedId"))
                if (!$util.isInteger(message.predefinedId))
                    return "predefinedId: integer expected";
            if (message.deleted != null && message.hasOwnProperty("deleted"))
                if (typeof message.deleted !== "boolean")
                    return "deleted: boolean expected";
            return null;
        };

        /**
         * Creates a LabelEditAction message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.LabelEditAction
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.LabelEditAction} LabelEditAction
         */
        LabelEditAction.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.LabelEditAction)
                return object;
            var message = new $root.proto.LabelEditAction();
            if (object.name != null)
                message.name = String(object.name);
            if (object.color != null)
                message.color = object.color | 0;
            if (object.predefinedId != null)
                message.predefinedId = object.predefinedId | 0;
            if (object.deleted != null)
                message.deleted = Boolean(object.deleted);
            return message;
        };

        /**
         * Creates a plain object from a LabelEditAction message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.LabelEditAction
         * @static
         * @param {proto.LabelEditAction} message LabelEditAction
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        LabelEditAction.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.name = "";
                object.color = 0;
                object.predefinedId = 0;
                object.deleted = false;
            }
            if (message.name != null && message.hasOwnProperty("name"))
                object.name = message.name;
            if (message.color != null && message.hasOwnProperty("color"))
                object.color = message.color;
            if (message.predefinedId != null && message.hasOwnProperty("predefinedId"))
                object.predefinedId = message.predefinedId;
            if (message.deleted != null && message.hasOwnProperty("deleted"))
                object.deleted = message.deleted;
            return object;
        };

        /**
         * Converts this LabelEditAction to JSON.
         * @function toJSON
         * @memberof proto.LabelEditAction
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        LabelEditAction.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return LabelEditAction;
    })();

    proto.RecentStickerWeightsAction = (function() {

        /**
         * Properties of a RecentStickerWeightsAction.
         * @memberof proto
         * @interface IRecentStickerWeightsAction
         * @property {Array.<proto.IRecentStickerWeight>|null} [weights] RecentStickerWeightsAction weights
         */

        /**
         * Constructs a new RecentStickerWeightsAction.
         * @memberof proto
         * @classdesc Represents a RecentStickerWeightsAction.
         * @implements IRecentStickerWeightsAction
         * @constructor
         * @param {proto.IRecentStickerWeightsAction=} [properties] Properties to set
         */
        function RecentStickerWeightsAction(properties) {
            this.weights = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * RecentStickerWeightsAction weights.
         * @member {Array.<proto.IRecentStickerWeight>} weights
         * @memberof proto.RecentStickerWeightsAction
         * @instance
         */
        RecentStickerWeightsAction.prototype.weights = $util.emptyArray;

        /**
         * Creates a new RecentStickerWeightsAction instance using the specified properties.
         * @function create
         * @memberof proto.RecentStickerWeightsAction
         * @static
         * @param {proto.IRecentStickerWeightsAction=} [properties] Properties to set
         * @returns {proto.RecentStickerWeightsAction} RecentStickerWeightsAction instance
         */
        RecentStickerWeightsAction.create = function create(properties) {
            return new RecentStickerWeightsAction(properties);
        };

        /**
         * Encodes the specified RecentStickerWeightsAction message. Does not implicitly {@link proto.RecentStickerWeightsAction.verify|verify} messages.
         * @function encode
         * @memberof proto.RecentStickerWeightsAction
         * @static
         * @param {proto.IRecentStickerWeightsAction} message RecentStickerWeightsAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RecentStickerWeightsAction.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.weights != null && message.weights.length)
                for (var i = 0; i < message.weights.length; ++i)
                    $root.proto.RecentStickerWeight.encode(message.weights[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified RecentStickerWeightsAction message, length delimited. Does not implicitly {@link proto.RecentStickerWeightsAction.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.RecentStickerWeightsAction
         * @static
         * @param {proto.IRecentStickerWeightsAction} message RecentStickerWeightsAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RecentStickerWeightsAction.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a RecentStickerWeightsAction message from the specified reader or buffer.
         * @function decode
         * @memberof proto.RecentStickerWeightsAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.RecentStickerWeightsAction} RecentStickerWeightsAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RecentStickerWeightsAction.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.RecentStickerWeightsAction();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    if (!(message.weights && message.weights.length))
                        message.weights = [];
                    message.weights.push($root.proto.RecentStickerWeight.decode(reader, reader.uint32()));
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a RecentStickerWeightsAction message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.RecentStickerWeightsAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.RecentStickerWeightsAction} RecentStickerWeightsAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RecentStickerWeightsAction.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a RecentStickerWeightsAction message.
         * @function verify
         * @memberof proto.RecentStickerWeightsAction
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        RecentStickerWeightsAction.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.weights != null && message.hasOwnProperty("weights")) {
                if (!Array.isArray(message.weights))
                    return "weights: array expected";
                for (var i = 0; i < message.weights.length; ++i) {
                    var error = $root.proto.RecentStickerWeight.verify(message.weights[i]);
                    if (error)
                        return "weights." + error;
                }
            }
            return null;
        };

        /**
         * Creates a RecentStickerWeightsAction message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.RecentStickerWeightsAction
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.RecentStickerWeightsAction} RecentStickerWeightsAction
         */
        RecentStickerWeightsAction.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.RecentStickerWeightsAction)
                return object;
            var message = new $root.proto.RecentStickerWeightsAction();
            if (object.weights) {
                if (!Array.isArray(object.weights))
                    throw TypeError(".proto.RecentStickerWeightsAction.weights: array expected");
                message.weights = [];
                for (var i = 0; i < object.weights.length; ++i) {
                    if (typeof object.weights[i] !== "object")
                        throw TypeError(".proto.RecentStickerWeightsAction.weights: object expected");
                    message.weights[i] = $root.proto.RecentStickerWeight.fromObject(object.weights[i]);
                }
            }
            return message;
        };

        /**
         * Creates a plain object from a RecentStickerWeightsAction message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.RecentStickerWeightsAction
         * @static
         * @param {proto.RecentStickerWeightsAction} message RecentStickerWeightsAction
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        RecentStickerWeightsAction.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.weights = [];
            if (message.weights && message.weights.length) {
                object.weights = [];
                for (var j = 0; j < message.weights.length; ++j)
                    object.weights[j] = $root.proto.RecentStickerWeight.toObject(message.weights[j], options);
            }
            return object;
        };

        /**
         * Converts this RecentStickerWeightsAction to JSON.
         * @function toJSON
         * @memberof proto.RecentStickerWeightsAction
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        RecentStickerWeightsAction.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return RecentStickerWeightsAction;
    })();

    proto.RecentStickerMetadata = (function() {

        /**
         * Properties of a RecentStickerMetadata.
         * @memberof proto
         * @interface IRecentStickerMetadata
         * @property {string|null} [directPath] RecentStickerMetadata directPath
         * @property {string|null} [encFilehash] RecentStickerMetadata encFilehash
         * @property {string|null} [mediaKey] RecentStickerMetadata mediaKey
         * @property {string|null} [stanzaId] RecentStickerMetadata stanzaId
         * @property {string|null} [chatJid] RecentStickerMetadata chatJid
         * @property {string|null} [participant] RecentStickerMetadata participant
         * @property {boolean|null} [isSentByMe] RecentStickerMetadata isSentByMe
         */

        /**
         * Constructs a new RecentStickerMetadata.
         * @memberof proto
         * @classdesc Represents a RecentStickerMetadata.
         * @implements IRecentStickerMetadata
         * @constructor
         * @param {proto.IRecentStickerMetadata=} [properties] Properties to set
         */
        function RecentStickerMetadata(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * RecentStickerMetadata directPath.
         * @member {string} directPath
         * @memberof proto.RecentStickerMetadata
         * @instance
         */
        RecentStickerMetadata.prototype.directPath = "";

        /**
         * RecentStickerMetadata encFilehash.
         * @member {string} encFilehash
         * @memberof proto.RecentStickerMetadata
         * @instance
         */
        RecentStickerMetadata.prototype.encFilehash = "";

        /**
         * RecentStickerMetadata mediaKey.
         * @member {string} mediaKey
         * @memberof proto.RecentStickerMetadata
         * @instance
         */
        RecentStickerMetadata.prototype.mediaKey = "";

        /**
         * RecentStickerMetadata stanzaId.
         * @member {string} stanzaId
         * @memberof proto.RecentStickerMetadata
         * @instance
         */
        RecentStickerMetadata.prototype.stanzaId = "";

        /**
         * RecentStickerMetadata chatJid.
         * @member {string} chatJid
         * @memberof proto.RecentStickerMetadata
         * @instance
         */
        RecentStickerMetadata.prototype.chatJid = "";

        /**
         * RecentStickerMetadata participant.
         * @member {string} participant
         * @memberof proto.RecentStickerMetadata
         * @instance
         */
        RecentStickerMetadata.prototype.participant = "";

        /**
         * RecentStickerMetadata isSentByMe.
         * @member {boolean} isSentByMe
         * @memberof proto.RecentStickerMetadata
         * @instance
         */
        RecentStickerMetadata.prototype.isSentByMe = false;

        /**
         * Creates a new RecentStickerMetadata instance using the specified properties.
         * @function create
         * @memberof proto.RecentStickerMetadata
         * @static
         * @param {proto.IRecentStickerMetadata=} [properties] Properties to set
         * @returns {proto.RecentStickerMetadata} RecentStickerMetadata instance
         */
        RecentStickerMetadata.create = function create(properties) {
            return new RecentStickerMetadata(properties);
        };

        /**
         * Encodes the specified RecentStickerMetadata message. Does not implicitly {@link proto.RecentStickerMetadata.verify|verify} messages.
         * @function encode
         * @memberof proto.RecentStickerMetadata
         * @static
         * @param {proto.IRecentStickerMetadata} message RecentStickerMetadata message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RecentStickerMetadata.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.directPath != null && Object.hasOwnProperty.call(message, "directPath"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.directPath);
            if (message.encFilehash != null && Object.hasOwnProperty.call(message, "encFilehash"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.encFilehash);
            if (message.mediaKey != null && Object.hasOwnProperty.call(message, "mediaKey"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.mediaKey);
            if (message.stanzaId != null && Object.hasOwnProperty.call(message, "stanzaId"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.stanzaId);
            if (message.chatJid != null && Object.hasOwnProperty.call(message, "chatJid"))
                writer.uint32(/* id 5, wireType 2 =*/42).string(message.chatJid);
            if (message.participant != null && Object.hasOwnProperty.call(message, "participant"))
                writer.uint32(/* id 6, wireType 2 =*/50).string(message.participant);
            if (message.isSentByMe != null && Object.hasOwnProperty.call(message, "isSentByMe"))
                writer.uint32(/* id 7, wireType 0 =*/56).bool(message.isSentByMe);
            return writer;
        };

        /**
         * Encodes the specified RecentStickerMetadata message, length delimited. Does not implicitly {@link proto.RecentStickerMetadata.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.RecentStickerMetadata
         * @static
         * @param {proto.IRecentStickerMetadata} message RecentStickerMetadata message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RecentStickerMetadata.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a RecentStickerMetadata message from the specified reader or buffer.
         * @function decode
         * @memberof proto.RecentStickerMetadata
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.RecentStickerMetadata} RecentStickerMetadata
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RecentStickerMetadata.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.RecentStickerMetadata();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.directPath = reader.string();
                    break;
                case 2:
                    message.encFilehash = reader.string();
                    break;
                case 3:
                    message.mediaKey = reader.string();
                    break;
                case 4:
                    message.stanzaId = reader.string();
                    break;
                case 5:
                    message.chatJid = reader.string();
                    break;
                case 6:
                    message.participant = reader.string();
                    break;
                case 7:
                    message.isSentByMe = reader.bool();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a RecentStickerMetadata message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.RecentStickerMetadata
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.RecentStickerMetadata} RecentStickerMetadata
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RecentStickerMetadata.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a RecentStickerMetadata message.
         * @function verify
         * @memberof proto.RecentStickerMetadata
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        RecentStickerMetadata.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.directPath != null && message.hasOwnProperty("directPath"))
                if (!$util.isString(message.directPath))
                    return "directPath: string expected";
            if (message.encFilehash != null && message.hasOwnProperty("encFilehash"))
                if (!$util.isString(message.encFilehash))
                    return "encFilehash: string expected";
            if (message.mediaKey != null && message.hasOwnProperty("mediaKey"))
                if (!$util.isString(message.mediaKey))
                    return "mediaKey: string expected";
            if (message.stanzaId != null && message.hasOwnProperty("stanzaId"))
                if (!$util.isString(message.stanzaId))
                    return "stanzaId: string expected";
            if (message.chatJid != null && message.hasOwnProperty("chatJid"))
                if (!$util.isString(message.chatJid))
                    return "chatJid: string expected";
            if (message.participant != null && message.hasOwnProperty("participant"))
                if (!$util.isString(message.participant))
                    return "participant: string expected";
            if (message.isSentByMe != null && message.hasOwnProperty("isSentByMe"))
                if (typeof message.isSentByMe !== "boolean")
                    return "isSentByMe: boolean expected";
            return null;
        };

        /**
         * Creates a RecentStickerMetadata message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.RecentStickerMetadata
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.RecentStickerMetadata} RecentStickerMetadata
         */
        RecentStickerMetadata.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.RecentStickerMetadata)
                return object;
            var message = new $root.proto.RecentStickerMetadata();
            if (object.directPath != null)
                message.directPath = String(object.directPath);
            if (object.encFilehash != null)
                message.encFilehash = String(object.encFilehash);
            if (object.mediaKey != null)
                message.mediaKey = String(object.mediaKey);
            if (object.stanzaId != null)
                message.stanzaId = String(object.stanzaId);
            if (object.chatJid != null)
                message.chatJid = String(object.chatJid);
            if (object.participant != null)
                message.participant = String(object.participant);
            if (object.isSentByMe != null)
                message.isSentByMe = Boolean(object.isSentByMe);
            return message;
        };

        /**
         * Creates a plain object from a RecentStickerMetadata message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.RecentStickerMetadata
         * @static
         * @param {proto.RecentStickerMetadata} message RecentStickerMetadata
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        RecentStickerMetadata.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.directPath = "";
                object.encFilehash = "";
                object.mediaKey = "";
                object.stanzaId = "";
                object.chatJid = "";
                object.participant = "";
                object.isSentByMe = false;
            }
            if (message.directPath != null && message.hasOwnProperty("directPath"))
                object.directPath = message.directPath;
            if (message.encFilehash != null && message.hasOwnProperty("encFilehash"))
                object.encFilehash = message.encFilehash;
            if (message.mediaKey != null && message.hasOwnProperty("mediaKey"))
                object.mediaKey = message.mediaKey;
            if (message.stanzaId != null && message.hasOwnProperty("stanzaId"))
                object.stanzaId = message.stanzaId;
            if (message.chatJid != null && message.hasOwnProperty("chatJid"))
                object.chatJid = message.chatJid;
            if (message.participant != null && message.hasOwnProperty("participant"))
                object.participant = message.participant;
            if (message.isSentByMe != null && message.hasOwnProperty("isSentByMe"))
                object.isSentByMe = message.isSentByMe;
            return object;
        };

        /**
         * Converts this RecentStickerMetadata to JSON.
         * @function toJSON
         * @memberof proto.RecentStickerMetadata
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        RecentStickerMetadata.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return RecentStickerMetadata;
    })();

    proto.RecentEmojiWeightsAction = (function() {

        /**
         * Properties of a RecentEmojiWeightsAction.
         * @memberof proto
         * @interface IRecentEmojiWeightsAction
         * @property {Array.<proto.IRecentEmojiWeight>|null} [weights] RecentEmojiWeightsAction weights
         */

        /**
         * Constructs a new RecentEmojiWeightsAction.
         * @memberof proto
         * @classdesc Represents a RecentEmojiWeightsAction.
         * @implements IRecentEmojiWeightsAction
         * @constructor
         * @param {proto.IRecentEmojiWeightsAction=} [properties] Properties to set
         */
        function RecentEmojiWeightsAction(properties) {
            this.weights = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * RecentEmojiWeightsAction weights.
         * @member {Array.<proto.IRecentEmojiWeight>} weights
         * @memberof proto.RecentEmojiWeightsAction
         * @instance
         */
        RecentEmojiWeightsAction.prototype.weights = $util.emptyArray;

        /**
         * Creates a new RecentEmojiWeightsAction instance using the specified properties.
         * @function create
         * @memberof proto.RecentEmojiWeightsAction
         * @static
         * @param {proto.IRecentEmojiWeightsAction=} [properties] Properties to set
         * @returns {proto.RecentEmojiWeightsAction} RecentEmojiWeightsAction instance
         */
        RecentEmojiWeightsAction.create = function create(properties) {
            return new RecentEmojiWeightsAction(properties);
        };

        /**
         * Encodes the specified RecentEmojiWeightsAction message. Does not implicitly {@link proto.RecentEmojiWeightsAction.verify|verify} messages.
         * @function encode
         * @memberof proto.RecentEmojiWeightsAction
         * @static
         * @param {proto.IRecentEmojiWeightsAction} message RecentEmojiWeightsAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RecentEmojiWeightsAction.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.weights != null && message.weights.length)
                for (var i = 0; i < message.weights.length; ++i)
                    $root.proto.RecentEmojiWeight.encode(message.weights[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified RecentEmojiWeightsAction message, length delimited. Does not implicitly {@link proto.RecentEmojiWeightsAction.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.RecentEmojiWeightsAction
         * @static
         * @param {proto.IRecentEmojiWeightsAction} message RecentEmojiWeightsAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RecentEmojiWeightsAction.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a RecentEmojiWeightsAction message from the specified reader or buffer.
         * @function decode
         * @memberof proto.RecentEmojiWeightsAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.RecentEmojiWeightsAction} RecentEmojiWeightsAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RecentEmojiWeightsAction.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.RecentEmojiWeightsAction();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    if (!(message.weights && message.weights.length))
                        message.weights = [];
                    message.weights.push($root.proto.RecentEmojiWeight.decode(reader, reader.uint32()));
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a RecentEmojiWeightsAction message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.RecentEmojiWeightsAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.RecentEmojiWeightsAction} RecentEmojiWeightsAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RecentEmojiWeightsAction.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a RecentEmojiWeightsAction message.
         * @function verify
         * @memberof proto.RecentEmojiWeightsAction
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        RecentEmojiWeightsAction.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.weights != null && message.hasOwnProperty("weights")) {
                if (!Array.isArray(message.weights))
                    return "weights: array expected";
                for (var i = 0; i < message.weights.length; ++i) {
                    var error = $root.proto.RecentEmojiWeight.verify(message.weights[i]);
                    if (error)
                        return "weights." + error;
                }
            }
            return null;
        };

        /**
         * Creates a RecentEmojiWeightsAction message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.RecentEmojiWeightsAction
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.RecentEmojiWeightsAction} RecentEmojiWeightsAction
         */
        RecentEmojiWeightsAction.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.RecentEmojiWeightsAction)
                return object;
            var message = new $root.proto.RecentEmojiWeightsAction();
            if (object.weights) {
                if (!Array.isArray(object.weights))
                    throw TypeError(".proto.RecentEmojiWeightsAction.weights: array expected");
                message.weights = [];
                for (var i = 0; i < object.weights.length; ++i) {
                    if (typeof object.weights[i] !== "object")
                        throw TypeError(".proto.RecentEmojiWeightsAction.weights: object expected");
                    message.weights[i] = $root.proto.RecentEmojiWeight.fromObject(object.weights[i]);
                }
            }
            return message;
        };

        /**
         * Creates a plain object from a RecentEmojiWeightsAction message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.RecentEmojiWeightsAction
         * @static
         * @param {proto.RecentEmojiWeightsAction} message RecentEmojiWeightsAction
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        RecentEmojiWeightsAction.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.weights = [];
            if (message.weights && message.weights.length) {
                object.weights = [];
                for (var j = 0; j < message.weights.length; ++j)
                    object.weights[j] = $root.proto.RecentEmojiWeight.toObject(message.weights[j], options);
            }
            return object;
        };

        /**
         * Converts this RecentEmojiWeightsAction to JSON.
         * @function toJSON
         * @memberof proto.RecentEmojiWeightsAction
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        RecentEmojiWeightsAction.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return RecentEmojiWeightsAction;
    })();

    proto.FavoriteStickerAction = (function() {

        /**
         * Properties of a FavoriteStickerAction.
         * @memberof proto
         * @interface IFavoriteStickerAction
         * @property {string|null} [directPath] FavoriteStickerAction directPath
         * @property {string|null} [lastUploadTimestamp] FavoriteStickerAction lastUploadTimestamp
         * @property {string|null} [handle] FavoriteStickerAction handle
         * @property {string|null} [encFilehash] FavoriteStickerAction encFilehash
         * @property {string|null} [stickerHashWithoutMeta] FavoriteStickerAction stickerHashWithoutMeta
         * @property {string|null} [mediaKey] FavoriteStickerAction mediaKey
         * @property {number|Long|null} [mediaKeyTimestamp] FavoriteStickerAction mediaKeyTimestamp
         * @property {boolean|null} [isFavorite] FavoriteStickerAction isFavorite
         */

        /**
         * Constructs a new FavoriteStickerAction.
         * @memberof proto
         * @classdesc Represents a FavoriteStickerAction.
         * @implements IFavoriteStickerAction
         * @constructor
         * @param {proto.IFavoriteStickerAction=} [properties] Properties to set
         */
        function FavoriteStickerAction(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * FavoriteStickerAction directPath.
         * @member {string} directPath
         * @memberof proto.FavoriteStickerAction
         * @instance
         */
        FavoriteStickerAction.prototype.directPath = "";

        /**
         * FavoriteStickerAction lastUploadTimestamp.
         * @member {string} lastUploadTimestamp
         * @memberof proto.FavoriteStickerAction
         * @instance
         */
        FavoriteStickerAction.prototype.lastUploadTimestamp = "";

        /**
         * FavoriteStickerAction handle.
         * @member {string} handle
         * @memberof proto.FavoriteStickerAction
         * @instance
         */
        FavoriteStickerAction.prototype.handle = "";

        /**
         * FavoriteStickerAction encFilehash.
         * @member {string} encFilehash
         * @memberof proto.FavoriteStickerAction
         * @instance
         */
        FavoriteStickerAction.prototype.encFilehash = "";

        /**
         * FavoriteStickerAction stickerHashWithoutMeta.
         * @member {string} stickerHashWithoutMeta
         * @memberof proto.FavoriteStickerAction
         * @instance
         */
        FavoriteStickerAction.prototype.stickerHashWithoutMeta = "";

        /**
         * FavoriteStickerAction mediaKey.
         * @member {string} mediaKey
         * @memberof proto.FavoriteStickerAction
         * @instance
         */
        FavoriteStickerAction.prototype.mediaKey = "";

        /**
         * FavoriteStickerAction mediaKeyTimestamp.
         * @member {number|Long} mediaKeyTimestamp
         * @memberof proto.FavoriteStickerAction
         * @instance
         */
        FavoriteStickerAction.prototype.mediaKeyTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * FavoriteStickerAction isFavorite.
         * @member {boolean} isFavorite
         * @memberof proto.FavoriteStickerAction
         * @instance
         */
        FavoriteStickerAction.prototype.isFavorite = false;

        /**
         * Creates a new FavoriteStickerAction instance using the specified properties.
         * @function create
         * @memberof proto.FavoriteStickerAction
         * @static
         * @param {proto.IFavoriteStickerAction=} [properties] Properties to set
         * @returns {proto.FavoriteStickerAction} FavoriteStickerAction instance
         */
        FavoriteStickerAction.create = function create(properties) {
            return new FavoriteStickerAction(properties);
        };

        /**
         * Encodes the specified FavoriteStickerAction message. Does not implicitly {@link proto.FavoriteStickerAction.verify|verify} messages.
         * @function encode
         * @memberof proto.FavoriteStickerAction
         * @static
         * @param {proto.IFavoriteStickerAction} message FavoriteStickerAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FavoriteStickerAction.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.directPath != null && Object.hasOwnProperty.call(message, "directPath"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.directPath);
            if (message.lastUploadTimestamp != null && Object.hasOwnProperty.call(message, "lastUploadTimestamp"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.lastUploadTimestamp);
            if (message.handle != null && Object.hasOwnProperty.call(message, "handle"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.handle);
            if (message.encFilehash != null && Object.hasOwnProperty.call(message, "encFilehash"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.encFilehash);
            if (message.stickerHashWithoutMeta != null && Object.hasOwnProperty.call(message, "stickerHashWithoutMeta"))
                writer.uint32(/* id 5, wireType 2 =*/42).string(message.stickerHashWithoutMeta);
            if (message.mediaKey != null && Object.hasOwnProperty.call(message, "mediaKey"))
                writer.uint32(/* id 6, wireType 2 =*/50).string(message.mediaKey);
            if (message.mediaKeyTimestamp != null && Object.hasOwnProperty.call(message, "mediaKeyTimestamp"))
                writer.uint32(/* id 7, wireType 0 =*/56).int64(message.mediaKeyTimestamp);
            if (message.isFavorite != null && Object.hasOwnProperty.call(message, "isFavorite"))
                writer.uint32(/* id 8, wireType 0 =*/64).bool(message.isFavorite);
            return writer;
        };

        /**
         * Encodes the specified FavoriteStickerAction message, length delimited. Does not implicitly {@link proto.FavoriteStickerAction.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.FavoriteStickerAction
         * @static
         * @param {proto.IFavoriteStickerAction} message FavoriteStickerAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FavoriteStickerAction.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a FavoriteStickerAction message from the specified reader or buffer.
         * @function decode
         * @memberof proto.FavoriteStickerAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.FavoriteStickerAction} FavoriteStickerAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FavoriteStickerAction.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.FavoriteStickerAction();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.directPath = reader.string();
                    break;
                case 2:
                    message.lastUploadTimestamp = reader.string();
                    break;
                case 3:
                    message.handle = reader.string();
                    break;
                case 4:
                    message.encFilehash = reader.string();
                    break;
                case 5:
                    message.stickerHashWithoutMeta = reader.string();
                    break;
                case 6:
                    message.mediaKey = reader.string();
                    break;
                case 7:
                    message.mediaKeyTimestamp = reader.int64();
                    break;
                case 8:
                    message.isFavorite = reader.bool();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a FavoriteStickerAction message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.FavoriteStickerAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.FavoriteStickerAction} FavoriteStickerAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FavoriteStickerAction.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a FavoriteStickerAction message.
         * @function verify
         * @memberof proto.FavoriteStickerAction
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        FavoriteStickerAction.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.directPath != null && message.hasOwnProperty("directPath"))
                if (!$util.isString(message.directPath))
                    return "directPath: string expected";
            if (message.lastUploadTimestamp != null && message.hasOwnProperty("lastUploadTimestamp"))
                if (!$util.isString(message.lastUploadTimestamp))
                    return "lastUploadTimestamp: string expected";
            if (message.handle != null && message.hasOwnProperty("handle"))
                if (!$util.isString(message.handle))
                    return "handle: string expected";
            if (message.encFilehash != null && message.hasOwnProperty("encFilehash"))
                if (!$util.isString(message.encFilehash))
                    return "encFilehash: string expected";
            if (message.stickerHashWithoutMeta != null && message.hasOwnProperty("stickerHashWithoutMeta"))
                if (!$util.isString(message.stickerHashWithoutMeta))
                    return "stickerHashWithoutMeta: string expected";
            if (message.mediaKey != null && message.hasOwnProperty("mediaKey"))
                if (!$util.isString(message.mediaKey))
                    return "mediaKey: string expected";
            if (message.mediaKeyTimestamp != null && message.hasOwnProperty("mediaKeyTimestamp"))
                if (!$util.isInteger(message.mediaKeyTimestamp) && !(message.mediaKeyTimestamp && $util.isInteger(message.mediaKeyTimestamp.low) && $util.isInteger(message.mediaKeyTimestamp.high)))
                    return "mediaKeyTimestamp: integer|Long expected";
            if (message.isFavorite != null && message.hasOwnProperty("isFavorite"))
                if (typeof message.isFavorite !== "boolean")
                    return "isFavorite: boolean expected";
            return null;
        };

        /**
         * Creates a FavoriteStickerAction message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.FavoriteStickerAction
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.FavoriteStickerAction} FavoriteStickerAction
         */
        FavoriteStickerAction.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.FavoriteStickerAction)
                return object;
            var message = new $root.proto.FavoriteStickerAction();
            if (object.directPath != null)
                message.directPath = String(object.directPath);
            if (object.lastUploadTimestamp != null)
                message.lastUploadTimestamp = String(object.lastUploadTimestamp);
            if (object.handle != null)
                message.handle = String(object.handle);
            if (object.encFilehash != null)
                message.encFilehash = String(object.encFilehash);
            if (object.stickerHashWithoutMeta != null)
                message.stickerHashWithoutMeta = String(object.stickerHashWithoutMeta);
            if (object.mediaKey != null)
                message.mediaKey = String(object.mediaKey);
            if (object.mediaKeyTimestamp != null)
                if ($util.Long)
                    (message.mediaKeyTimestamp = $util.Long.fromValue(object.mediaKeyTimestamp)).unsigned = false;
                else if (typeof object.mediaKeyTimestamp === "string")
                    message.mediaKeyTimestamp = parseInt(object.mediaKeyTimestamp, 10);
                else if (typeof object.mediaKeyTimestamp === "number")
                    message.mediaKeyTimestamp = object.mediaKeyTimestamp;
                else if (typeof object.mediaKeyTimestamp === "object")
                    message.mediaKeyTimestamp = new $util.LongBits(object.mediaKeyTimestamp.low >>> 0, object.mediaKeyTimestamp.high >>> 0).toNumber();
            if (object.isFavorite != null)
                message.isFavorite = Boolean(object.isFavorite);
            return message;
        };

        /**
         * Creates a plain object from a FavoriteStickerAction message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.FavoriteStickerAction
         * @static
         * @param {proto.FavoriteStickerAction} message FavoriteStickerAction
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        FavoriteStickerAction.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.directPath = "";
                object.lastUploadTimestamp = "";
                object.handle = "";
                object.encFilehash = "";
                object.stickerHashWithoutMeta = "";
                object.mediaKey = "";
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.mediaKeyTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.mediaKeyTimestamp = options.longs === String ? "0" : 0;
                object.isFavorite = false;
            }
            if (message.directPath != null && message.hasOwnProperty("directPath"))
                object.directPath = message.directPath;
            if (message.lastUploadTimestamp != null && message.hasOwnProperty("lastUploadTimestamp"))
                object.lastUploadTimestamp = message.lastUploadTimestamp;
            if (message.handle != null && message.hasOwnProperty("handle"))
                object.handle = message.handle;
            if (message.encFilehash != null && message.hasOwnProperty("encFilehash"))
                object.encFilehash = message.encFilehash;
            if (message.stickerHashWithoutMeta != null && message.hasOwnProperty("stickerHashWithoutMeta"))
                object.stickerHashWithoutMeta = message.stickerHashWithoutMeta;
            if (message.mediaKey != null && message.hasOwnProperty("mediaKey"))
                object.mediaKey = message.mediaKey;
            if (message.mediaKeyTimestamp != null && message.hasOwnProperty("mediaKeyTimestamp"))
                if (typeof message.mediaKeyTimestamp === "number")
                    object.mediaKeyTimestamp = options.longs === String ? String(message.mediaKeyTimestamp) : message.mediaKeyTimestamp;
                else
                    object.mediaKeyTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.mediaKeyTimestamp) : options.longs === Number ? new $util.LongBits(message.mediaKeyTimestamp.low >>> 0, message.mediaKeyTimestamp.high >>> 0).toNumber() : message.mediaKeyTimestamp;
            if (message.isFavorite != null && message.hasOwnProperty("isFavorite"))
                object.isFavorite = message.isFavorite;
            return object;
        };

        /**
         * Converts this FavoriteStickerAction to JSON.
         * @function toJSON
         * @memberof proto.FavoriteStickerAction
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        FavoriteStickerAction.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return FavoriteStickerAction;
    })();

    proto.ArchiveChatAction = (function() {

        /**
         * Properties of an ArchiveChatAction.
         * @memberof proto
         * @interface IArchiveChatAction
         * @property {boolean|null} [archived] ArchiveChatAction archived
         * @property {proto.ISyncActionMessageRange|null} [messageRange] ArchiveChatAction messageRange
         */

        /**
         * Constructs a new ArchiveChatAction.
         * @memberof proto
         * @classdesc Represents an ArchiveChatAction.
         * @implements IArchiveChatAction
         * @constructor
         * @param {proto.IArchiveChatAction=} [properties] Properties to set
         */
        function ArchiveChatAction(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ArchiveChatAction archived.
         * @member {boolean} archived
         * @memberof proto.ArchiveChatAction
         * @instance
         */
        ArchiveChatAction.prototype.archived = false;

        /**
         * ArchiveChatAction messageRange.
         * @member {proto.ISyncActionMessageRange|null|undefined} messageRange
         * @memberof proto.ArchiveChatAction
         * @instance
         */
        ArchiveChatAction.prototype.messageRange = null;

        /**
         * Creates a new ArchiveChatAction instance using the specified properties.
         * @function create
         * @memberof proto.ArchiveChatAction
         * @static
         * @param {proto.IArchiveChatAction=} [properties] Properties to set
         * @returns {proto.ArchiveChatAction} ArchiveChatAction instance
         */
        ArchiveChatAction.create = function create(properties) {
            return new ArchiveChatAction(properties);
        };

        /**
         * Encodes the specified ArchiveChatAction message. Does not implicitly {@link proto.ArchiveChatAction.verify|verify} messages.
         * @function encode
         * @memberof proto.ArchiveChatAction
         * @static
         * @param {proto.IArchiveChatAction} message ArchiveChatAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ArchiveChatAction.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.archived != null && Object.hasOwnProperty.call(message, "archived"))
                writer.uint32(/* id 1, wireType 0 =*/8).bool(message.archived);
            if (message.messageRange != null && Object.hasOwnProperty.call(message, "messageRange"))
                $root.proto.SyncActionMessageRange.encode(message.messageRange, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified ArchiveChatAction message, length delimited. Does not implicitly {@link proto.ArchiveChatAction.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ArchiveChatAction
         * @static
         * @param {proto.IArchiveChatAction} message ArchiveChatAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ArchiveChatAction.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an ArchiveChatAction message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ArchiveChatAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ArchiveChatAction} ArchiveChatAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ArchiveChatAction.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ArchiveChatAction();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.archived = reader.bool();
                    break;
                case 2:
                    message.messageRange = $root.proto.SyncActionMessageRange.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an ArchiveChatAction message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ArchiveChatAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ArchiveChatAction} ArchiveChatAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ArchiveChatAction.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an ArchiveChatAction message.
         * @function verify
         * @memberof proto.ArchiveChatAction
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ArchiveChatAction.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.archived != null && message.hasOwnProperty("archived"))
                if (typeof message.archived !== "boolean")
                    return "archived: boolean expected";
            if (message.messageRange != null && message.hasOwnProperty("messageRange")) {
                var error = $root.proto.SyncActionMessageRange.verify(message.messageRange);
                if (error)
                    return "messageRange." + error;
            }
            return null;
        };

        /**
         * Creates an ArchiveChatAction message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ArchiveChatAction
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ArchiveChatAction} ArchiveChatAction
         */
        ArchiveChatAction.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ArchiveChatAction)
                return object;
            var message = new $root.proto.ArchiveChatAction();
            if (object.archived != null)
                message.archived = Boolean(object.archived);
            if (object.messageRange != null) {
                if (typeof object.messageRange !== "object")
                    throw TypeError(".proto.ArchiveChatAction.messageRange: object expected");
                message.messageRange = $root.proto.SyncActionMessageRange.fromObject(object.messageRange);
            }
            return message;
        };

        /**
         * Creates a plain object from an ArchiveChatAction message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ArchiveChatAction
         * @static
         * @param {proto.ArchiveChatAction} message ArchiveChatAction
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ArchiveChatAction.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.archived = false;
                object.messageRange = null;
            }
            if (message.archived != null && message.hasOwnProperty("archived"))
                object.archived = message.archived;
            if (message.messageRange != null && message.hasOwnProperty("messageRange"))
                object.messageRange = $root.proto.SyncActionMessageRange.toObject(message.messageRange, options);
            return object;
        };

        /**
         * Converts this ArchiveChatAction to JSON.
         * @function toJSON
         * @memberof proto.ArchiveChatAction
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ArchiveChatAction.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ArchiveChatAction;
    })();

    proto.DeleteMessageForMeAction = (function() {

        /**
         * Properties of a DeleteMessageForMeAction.
         * @memberof proto
         * @interface IDeleteMessageForMeAction
         * @property {boolean|null} [deleteMedia] DeleteMessageForMeAction deleteMedia
         * @property {number|Long|null} [messageTimestamp] DeleteMessageForMeAction messageTimestamp
         */

        /**
         * Constructs a new DeleteMessageForMeAction.
         * @memberof proto
         * @classdesc Represents a DeleteMessageForMeAction.
         * @implements IDeleteMessageForMeAction
         * @constructor
         * @param {proto.IDeleteMessageForMeAction=} [properties] Properties to set
         */
        function DeleteMessageForMeAction(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * DeleteMessageForMeAction deleteMedia.
         * @member {boolean} deleteMedia
         * @memberof proto.DeleteMessageForMeAction
         * @instance
         */
        DeleteMessageForMeAction.prototype.deleteMedia = false;

        /**
         * DeleteMessageForMeAction messageTimestamp.
         * @member {number|Long} messageTimestamp
         * @memberof proto.DeleteMessageForMeAction
         * @instance
         */
        DeleteMessageForMeAction.prototype.messageTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * Creates a new DeleteMessageForMeAction instance using the specified properties.
         * @function create
         * @memberof proto.DeleteMessageForMeAction
         * @static
         * @param {proto.IDeleteMessageForMeAction=} [properties] Properties to set
         * @returns {proto.DeleteMessageForMeAction} DeleteMessageForMeAction instance
         */
        DeleteMessageForMeAction.create = function create(properties) {
            return new DeleteMessageForMeAction(properties);
        };

        /**
         * Encodes the specified DeleteMessageForMeAction message. Does not implicitly {@link proto.DeleteMessageForMeAction.verify|verify} messages.
         * @function encode
         * @memberof proto.DeleteMessageForMeAction
         * @static
         * @param {proto.IDeleteMessageForMeAction} message DeleteMessageForMeAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        DeleteMessageForMeAction.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.deleteMedia != null && Object.hasOwnProperty.call(message, "deleteMedia"))
                writer.uint32(/* id 1, wireType 0 =*/8).bool(message.deleteMedia);
            if (message.messageTimestamp != null && Object.hasOwnProperty.call(message, "messageTimestamp"))
                writer.uint32(/* id 2, wireType 0 =*/16).int64(message.messageTimestamp);
            return writer;
        };

        /**
         * Encodes the specified DeleteMessageForMeAction message, length delimited. Does not implicitly {@link proto.DeleteMessageForMeAction.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.DeleteMessageForMeAction
         * @static
         * @param {proto.IDeleteMessageForMeAction} message DeleteMessageForMeAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        DeleteMessageForMeAction.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a DeleteMessageForMeAction message from the specified reader or buffer.
         * @function decode
         * @memberof proto.DeleteMessageForMeAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.DeleteMessageForMeAction} DeleteMessageForMeAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        DeleteMessageForMeAction.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.DeleteMessageForMeAction();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.deleteMedia = reader.bool();
                    break;
                case 2:
                    message.messageTimestamp = reader.int64();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a DeleteMessageForMeAction message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.DeleteMessageForMeAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.DeleteMessageForMeAction} DeleteMessageForMeAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        DeleteMessageForMeAction.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a DeleteMessageForMeAction message.
         * @function verify
         * @memberof proto.DeleteMessageForMeAction
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        DeleteMessageForMeAction.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.deleteMedia != null && message.hasOwnProperty("deleteMedia"))
                if (typeof message.deleteMedia !== "boolean")
                    return "deleteMedia: boolean expected";
            if (message.messageTimestamp != null && message.hasOwnProperty("messageTimestamp"))
                if (!$util.isInteger(message.messageTimestamp) && !(message.messageTimestamp && $util.isInteger(message.messageTimestamp.low) && $util.isInteger(message.messageTimestamp.high)))
                    return "messageTimestamp: integer|Long expected";
            return null;
        };

        /**
         * Creates a DeleteMessageForMeAction message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.DeleteMessageForMeAction
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.DeleteMessageForMeAction} DeleteMessageForMeAction
         */
        DeleteMessageForMeAction.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.DeleteMessageForMeAction)
                return object;
            var message = new $root.proto.DeleteMessageForMeAction();
            if (object.deleteMedia != null)
                message.deleteMedia = Boolean(object.deleteMedia);
            if (object.messageTimestamp != null)
                if ($util.Long)
                    (message.messageTimestamp = $util.Long.fromValue(object.messageTimestamp)).unsigned = false;
                else if (typeof object.messageTimestamp === "string")
                    message.messageTimestamp = parseInt(object.messageTimestamp, 10);
                else if (typeof object.messageTimestamp === "number")
                    message.messageTimestamp = object.messageTimestamp;
                else if (typeof object.messageTimestamp === "object")
                    message.messageTimestamp = new $util.LongBits(object.messageTimestamp.low >>> 0, object.messageTimestamp.high >>> 0).toNumber();
            return message;
        };

        /**
         * Creates a plain object from a DeleteMessageForMeAction message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.DeleteMessageForMeAction
         * @static
         * @param {proto.DeleteMessageForMeAction} message DeleteMessageForMeAction
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        DeleteMessageForMeAction.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.deleteMedia = false;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.messageTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.messageTimestamp = options.longs === String ? "0" : 0;
            }
            if (message.deleteMedia != null && message.hasOwnProperty("deleteMedia"))
                object.deleteMedia = message.deleteMedia;
            if (message.messageTimestamp != null && message.hasOwnProperty("messageTimestamp"))
                if (typeof message.messageTimestamp === "number")
                    object.messageTimestamp = options.longs === String ? String(message.messageTimestamp) : message.messageTimestamp;
                else
                    object.messageTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.messageTimestamp) : options.longs === Number ? new $util.LongBits(message.messageTimestamp.low >>> 0, message.messageTimestamp.high >>> 0).toNumber() : message.messageTimestamp;
            return object;
        };

        /**
         * Converts this DeleteMessageForMeAction to JSON.
         * @function toJSON
         * @memberof proto.DeleteMessageForMeAction
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        DeleteMessageForMeAction.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return DeleteMessageForMeAction;
    })();

    proto.MarkChatAsReadAction = (function() {

        /**
         * Properties of a MarkChatAsReadAction.
         * @memberof proto
         * @interface IMarkChatAsReadAction
         * @property {boolean|null} [read] MarkChatAsReadAction read
         * @property {proto.ISyncActionMessageRange|null} [messageRange] MarkChatAsReadAction messageRange
         */

        /**
         * Constructs a new MarkChatAsReadAction.
         * @memberof proto
         * @classdesc Represents a MarkChatAsReadAction.
         * @implements IMarkChatAsReadAction
         * @constructor
         * @param {proto.IMarkChatAsReadAction=} [properties] Properties to set
         */
        function MarkChatAsReadAction(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * MarkChatAsReadAction read.
         * @member {boolean} read
         * @memberof proto.MarkChatAsReadAction
         * @instance
         */
        MarkChatAsReadAction.prototype.read = false;

        /**
         * MarkChatAsReadAction messageRange.
         * @member {proto.ISyncActionMessageRange|null|undefined} messageRange
         * @memberof proto.MarkChatAsReadAction
         * @instance
         */
        MarkChatAsReadAction.prototype.messageRange = null;

        /**
         * Creates a new MarkChatAsReadAction instance using the specified properties.
         * @function create
         * @memberof proto.MarkChatAsReadAction
         * @static
         * @param {proto.IMarkChatAsReadAction=} [properties] Properties to set
         * @returns {proto.MarkChatAsReadAction} MarkChatAsReadAction instance
         */
        MarkChatAsReadAction.create = function create(properties) {
            return new MarkChatAsReadAction(properties);
        };

        /**
         * Encodes the specified MarkChatAsReadAction message. Does not implicitly {@link proto.MarkChatAsReadAction.verify|verify} messages.
         * @function encode
         * @memberof proto.MarkChatAsReadAction
         * @static
         * @param {proto.IMarkChatAsReadAction} message MarkChatAsReadAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        MarkChatAsReadAction.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.read != null && Object.hasOwnProperty.call(message, "read"))
                writer.uint32(/* id 1, wireType 0 =*/8).bool(message.read);
            if (message.messageRange != null && Object.hasOwnProperty.call(message, "messageRange"))
                $root.proto.SyncActionMessageRange.encode(message.messageRange, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified MarkChatAsReadAction message, length delimited. Does not implicitly {@link proto.MarkChatAsReadAction.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.MarkChatAsReadAction
         * @static
         * @param {proto.IMarkChatAsReadAction} message MarkChatAsReadAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        MarkChatAsReadAction.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a MarkChatAsReadAction message from the specified reader or buffer.
         * @function decode
         * @memberof proto.MarkChatAsReadAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.MarkChatAsReadAction} MarkChatAsReadAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        MarkChatAsReadAction.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MarkChatAsReadAction();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.read = reader.bool();
                    break;
                case 2:
                    message.messageRange = $root.proto.SyncActionMessageRange.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a MarkChatAsReadAction message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.MarkChatAsReadAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.MarkChatAsReadAction} MarkChatAsReadAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        MarkChatAsReadAction.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a MarkChatAsReadAction message.
         * @function verify
         * @memberof proto.MarkChatAsReadAction
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        MarkChatAsReadAction.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.read != null && message.hasOwnProperty("read"))
                if (typeof message.read !== "boolean")
                    return "read: boolean expected";
            if (message.messageRange != null && message.hasOwnProperty("messageRange")) {
                var error = $root.proto.SyncActionMessageRange.verify(message.messageRange);
                if (error)
                    return "messageRange." + error;
            }
            return null;
        };

        /**
         * Creates a MarkChatAsReadAction message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.MarkChatAsReadAction
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.MarkChatAsReadAction} MarkChatAsReadAction
         */
        MarkChatAsReadAction.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.MarkChatAsReadAction)
                return object;
            var message = new $root.proto.MarkChatAsReadAction();
            if (object.read != null)
                message.read = Boolean(object.read);
            if (object.messageRange != null) {
                if (typeof object.messageRange !== "object")
                    throw TypeError(".proto.MarkChatAsReadAction.messageRange: object expected");
                message.messageRange = $root.proto.SyncActionMessageRange.fromObject(object.messageRange);
            }
            return message;
        };

        /**
         * Creates a plain object from a MarkChatAsReadAction message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.MarkChatAsReadAction
         * @static
         * @param {proto.MarkChatAsReadAction} message MarkChatAsReadAction
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        MarkChatAsReadAction.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.read = false;
                object.messageRange = null;
            }
            if (message.read != null && message.hasOwnProperty("read"))
                object.read = message.read;
            if (message.messageRange != null && message.hasOwnProperty("messageRange"))
                object.messageRange = $root.proto.SyncActionMessageRange.toObject(message.messageRange, options);
            return object;
        };

        /**
         * Converts this MarkChatAsReadAction to JSON.
         * @function toJSON
         * @memberof proto.MarkChatAsReadAction
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        MarkChatAsReadAction.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return MarkChatAsReadAction;
    })();

    proto.ClearChatAction = (function() {

        /**
         * Properties of a ClearChatAction.
         * @memberof proto
         * @interface IClearChatAction
         * @property {proto.ISyncActionMessageRange|null} [messageRange] ClearChatAction messageRange
         */

        /**
         * Constructs a new ClearChatAction.
         * @memberof proto
         * @classdesc Represents a ClearChatAction.
         * @implements IClearChatAction
         * @constructor
         * @param {proto.IClearChatAction=} [properties] Properties to set
         */
        function ClearChatAction(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ClearChatAction messageRange.
         * @member {proto.ISyncActionMessageRange|null|undefined} messageRange
         * @memberof proto.ClearChatAction
         * @instance
         */
        ClearChatAction.prototype.messageRange = null;

        /**
         * Creates a new ClearChatAction instance using the specified properties.
         * @function create
         * @memberof proto.ClearChatAction
         * @static
         * @param {proto.IClearChatAction=} [properties] Properties to set
         * @returns {proto.ClearChatAction} ClearChatAction instance
         */
        ClearChatAction.create = function create(properties) {
            return new ClearChatAction(properties);
        };

        /**
         * Encodes the specified ClearChatAction message. Does not implicitly {@link proto.ClearChatAction.verify|verify} messages.
         * @function encode
         * @memberof proto.ClearChatAction
         * @static
         * @param {proto.IClearChatAction} message ClearChatAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ClearChatAction.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.messageRange != null && Object.hasOwnProperty.call(message, "messageRange"))
                $root.proto.SyncActionMessageRange.encode(message.messageRange, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified ClearChatAction message, length delimited. Does not implicitly {@link proto.ClearChatAction.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ClearChatAction
         * @static
         * @param {proto.IClearChatAction} message ClearChatAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ClearChatAction.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ClearChatAction message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ClearChatAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ClearChatAction} ClearChatAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ClearChatAction.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ClearChatAction();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.messageRange = $root.proto.SyncActionMessageRange.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ClearChatAction message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ClearChatAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ClearChatAction} ClearChatAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ClearChatAction.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ClearChatAction message.
         * @function verify
         * @memberof proto.ClearChatAction
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ClearChatAction.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.messageRange != null && message.hasOwnProperty("messageRange")) {
                var error = $root.proto.SyncActionMessageRange.verify(message.messageRange);
                if (error)
                    return "messageRange." + error;
            }
            return null;
        };

        /**
         * Creates a ClearChatAction message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ClearChatAction
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ClearChatAction} ClearChatAction
         */
        ClearChatAction.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ClearChatAction)
                return object;
            var message = new $root.proto.ClearChatAction();
            if (object.messageRange != null) {
                if (typeof object.messageRange !== "object")
                    throw TypeError(".proto.ClearChatAction.messageRange: object expected");
                message.messageRange = $root.proto.SyncActionMessageRange.fromObject(object.messageRange);
            }
            return message;
        };

        /**
         * Creates a plain object from a ClearChatAction message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ClearChatAction
         * @static
         * @param {proto.ClearChatAction} message ClearChatAction
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ClearChatAction.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                object.messageRange = null;
            if (message.messageRange != null && message.hasOwnProperty("messageRange"))
                object.messageRange = $root.proto.SyncActionMessageRange.toObject(message.messageRange, options);
            return object;
        };

        /**
         * Converts this ClearChatAction to JSON.
         * @function toJSON
         * @memberof proto.ClearChatAction
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ClearChatAction.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ClearChatAction;
    })();

    proto.DeleteChatAction = (function() {

        /**
         * Properties of a DeleteChatAction.
         * @memberof proto
         * @interface IDeleteChatAction
         * @property {proto.ISyncActionMessageRange|null} [messageRange] DeleteChatAction messageRange
         */

        /**
         * Constructs a new DeleteChatAction.
         * @memberof proto
         * @classdesc Represents a DeleteChatAction.
         * @implements IDeleteChatAction
         * @constructor
         * @param {proto.IDeleteChatAction=} [properties] Properties to set
         */
        function DeleteChatAction(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * DeleteChatAction messageRange.
         * @member {proto.ISyncActionMessageRange|null|undefined} messageRange
         * @memberof proto.DeleteChatAction
         * @instance
         */
        DeleteChatAction.prototype.messageRange = null;

        /**
         * Creates a new DeleteChatAction instance using the specified properties.
         * @function create
         * @memberof proto.DeleteChatAction
         * @static
         * @param {proto.IDeleteChatAction=} [properties] Properties to set
         * @returns {proto.DeleteChatAction} DeleteChatAction instance
         */
        DeleteChatAction.create = function create(properties) {
            return new DeleteChatAction(properties);
        };

        /**
         * Encodes the specified DeleteChatAction message. Does not implicitly {@link proto.DeleteChatAction.verify|verify} messages.
         * @function encode
         * @memberof proto.DeleteChatAction
         * @static
         * @param {proto.IDeleteChatAction} message DeleteChatAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        DeleteChatAction.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.messageRange != null && Object.hasOwnProperty.call(message, "messageRange"))
                $root.proto.SyncActionMessageRange.encode(message.messageRange, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified DeleteChatAction message, length delimited. Does not implicitly {@link proto.DeleteChatAction.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.DeleteChatAction
         * @static
         * @param {proto.IDeleteChatAction} message DeleteChatAction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        DeleteChatAction.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a DeleteChatAction message from the specified reader or buffer.
         * @function decode
         * @memberof proto.DeleteChatAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.DeleteChatAction} DeleteChatAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        DeleteChatAction.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.DeleteChatAction();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.messageRange = $root.proto.SyncActionMessageRange.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a DeleteChatAction message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.DeleteChatAction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.DeleteChatAction} DeleteChatAction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        DeleteChatAction.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a DeleteChatAction message.
         * @function verify
         * @memberof proto.DeleteChatAction
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        DeleteChatAction.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.messageRange != null && message.hasOwnProperty("messageRange")) {
                var error = $root.proto.SyncActionMessageRange.verify(message.messageRange);
                if (error)
                    return "messageRange." + error;
            }
            return null;
        };

        /**
         * Creates a DeleteChatAction message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.DeleteChatAction
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.DeleteChatAction} DeleteChatAction
         */
        DeleteChatAction.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.DeleteChatAction)
                return object;
            var message = new $root.proto.DeleteChatAction();
            if (object.messageRange != null) {
                if (typeof object.messageRange !== "object")
                    throw TypeError(".proto.DeleteChatAction.messageRange: object expected");
                message.messageRange = $root.proto.SyncActionMessageRange.fromObject(object.messageRange);
            }
            return message;
        };

        /**
         * Creates a plain object from a DeleteChatAction message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.DeleteChatAction
         * @static
         * @param {proto.DeleteChatAction} message DeleteChatAction
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        DeleteChatAction.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                object.messageRange = null;
            if (message.messageRange != null && message.hasOwnProperty("messageRange"))
                object.messageRange = $root.proto.SyncActionMessageRange.toObject(message.messageRange, options);
            return object;
        };

        /**
         * Converts this DeleteChatAction to JSON.
         * @function toJSON
         * @memberof proto.DeleteChatAction
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        DeleteChatAction.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return DeleteChatAction;
    })();

    proto.UnarchiveChatsSetting = (function() {

        /**
         * Properties of an UnarchiveChatsSetting.
         * @memberof proto
         * @interface IUnarchiveChatsSetting
         * @property {boolean|null} [unarchiveChats] UnarchiveChatsSetting unarchiveChats
         */

        /**
         * Constructs a new UnarchiveChatsSetting.
         * @memberof proto
         * @classdesc Represents an UnarchiveChatsSetting.
         * @implements IUnarchiveChatsSetting
         * @constructor
         * @param {proto.IUnarchiveChatsSetting=} [properties] Properties to set
         */
        function UnarchiveChatsSetting(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * UnarchiveChatsSetting unarchiveChats.
         * @member {boolean} unarchiveChats
         * @memberof proto.UnarchiveChatsSetting
         * @instance
         */
        UnarchiveChatsSetting.prototype.unarchiveChats = false;

        /**
         * Creates a new UnarchiveChatsSetting instance using the specified properties.
         * @function create
         * @memberof proto.UnarchiveChatsSetting
         * @static
         * @param {proto.IUnarchiveChatsSetting=} [properties] Properties to set
         * @returns {proto.UnarchiveChatsSetting} UnarchiveChatsSetting instance
         */
        UnarchiveChatsSetting.create = function create(properties) {
            return new UnarchiveChatsSetting(properties);
        };

        /**
         * Encodes the specified UnarchiveChatsSetting message. Does not implicitly {@link proto.UnarchiveChatsSetting.verify|verify} messages.
         * @function encode
         * @memberof proto.UnarchiveChatsSetting
         * @static
         * @param {proto.IUnarchiveChatsSetting} message UnarchiveChatsSetting message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        UnarchiveChatsSetting.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.unarchiveChats != null && Object.hasOwnProperty.call(message, "unarchiveChats"))
                writer.uint32(/* id 1, wireType 0 =*/8).bool(message.unarchiveChats);
            return writer;
        };

        /**
         * Encodes the specified UnarchiveChatsSetting message, length delimited. Does not implicitly {@link proto.UnarchiveChatsSetting.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.UnarchiveChatsSetting
         * @static
         * @param {proto.IUnarchiveChatsSetting} message UnarchiveChatsSetting message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        UnarchiveChatsSetting.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an UnarchiveChatsSetting message from the specified reader or buffer.
         * @function decode
         * @memberof proto.UnarchiveChatsSetting
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.UnarchiveChatsSetting} UnarchiveChatsSetting
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        UnarchiveChatsSetting.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.UnarchiveChatsSetting();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.unarchiveChats = reader.bool();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an UnarchiveChatsSetting message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.UnarchiveChatsSetting
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.UnarchiveChatsSetting} UnarchiveChatsSetting
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        UnarchiveChatsSetting.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an UnarchiveChatsSetting message.
         * @function verify
         * @memberof proto.UnarchiveChatsSetting
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        UnarchiveChatsSetting.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.unarchiveChats != null && message.hasOwnProperty("unarchiveChats"))
                if (typeof message.unarchiveChats !== "boolean")
                    return "unarchiveChats: boolean expected";
            return null;
        };

        /**
         * Creates an UnarchiveChatsSetting message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.UnarchiveChatsSetting
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.UnarchiveChatsSetting} UnarchiveChatsSetting
         */
        UnarchiveChatsSetting.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.UnarchiveChatsSetting)
                return object;
            var message = new $root.proto.UnarchiveChatsSetting();
            if (object.unarchiveChats != null)
                message.unarchiveChats = Boolean(object.unarchiveChats);
            return message;
        };

        /**
         * Creates a plain object from an UnarchiveChatsSetting message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.UnarchiveChatsSetting
         * @static
         * @param {proto.UnarchiveChatsSetting} message UnarchiveChatsSetting
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        UnarchiveChatsSetting.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                object.unarchiveChats = false;
            if (message.unarchiveChats != null && message.hasOwnProperty("unarchiveChats"))
                object.unarchiveChats = message.unarchiveChats;
            return object;
        };

        /**
         * Converts this UnarchiveChatsSetting to JSON.
         * @function toJSON
         * @memberof proto.UnarchiveChatsSetting
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        UnarchiveChatsSetting.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return UnarchiveChatsSetting;
    })();

    proto.SyncActionMessageRange = (function() {

        /**
         * Properties of a SyncActionMessageRange.
         * @memberof proto
         * @interface ISyncActionMessageRange
         * @property {number|Long|null} [lastMessageTimestamp] SyncActionMessageRange lastMessageTimestamp
         * @property {number|Long|null} [lastSystemMessageTimestamp] SyncActionMessageRange lastSystemMessageTimestamp
         * @property {Array.<proto.ISyncActionMessage>|null} [messages] SyncActionMessageRange messages
         */

        /**
         * Constructs a new SyncActionMessageRange.
         * @memberof proto
         * @classdesc Represents a SyncActionMessageRange.
         * @implements ISyncActionMessageRange
         * @constructor
         * @param {proto.ISyncActionMessageRange=} [properties] Properties to set
         */
        function SyncActionMessageRange(properties) {
            this.messages = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * SyncActionMessageRange lastMessageTimestamp.
         * @member {number|Long} lastMessageTimestamp
         * @memberof proto.SyncActionMessageRange
         * @instance
         */
        SyncActionMessageRange.prototype.lastMessageTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * SyncActionMessageRange lastSystemMessageTimestamp.
         * @member {number|Long} lastSystemMessageTimestamp
         * @memberof proto.SyncActionMessageRange
         * @instance
         */
        SyncActionMessageRange.prototype.lastSystemMessageTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * SyncActionMessageRange messages.
         * @member {Array.<proto.ISyncActionMessage>} messages
         * @memberof proto.SyncActionMessageRange
         * @instance
         */
        SyncActionMessageRange.prototype.messages = $util.emptyArray;

        /**
         * Creates a new SyncActionMessageRange instance using the specified properties.
         * @function create
         * @memberof proto.SyncActionMessageRange
         * @static
         * @param {proto.ISyncActionMessageRange=} [properties] Properties to set
         * @returns {proto.SyncActionMessageRange} SyncActionMessageRange instance
         */
        SyncActionMessageRange.create = function create(properties) {
            return new SyncActionMessageRange(properties);
        };

        /**
         * Encodes the specified SyncActionMessageRange message. Does not implicitly {@link proto.SyncActionMessageRange.verify|verify} messages.
         * @function encode
         * @memberof proto.SyncActionMessageRange
         * @static
         * @param {proto.ISyncActionMessageRange} message SyncActionMessageRange message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SyncActionMessageRange.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.lastMessageTimestamp != null && Object.hasOwnProperty.call(message, "lastMessageTimestamp"))
                writer.uint32(/* id 1, wireType 0 =*/8).int64(message.lastMessageTimestamp);
            if (message.lastSystemMessageTimestamp != null && Object.hasOwnProperty.call(message, "lastSystemMessageTimestamp"))
                writer.uint32(/* id 2, wireType 0 =*/16).int64(message.lastSystemMessageTimestamp);
            if (message.messages != null && message.messages.length)
                for (var i = 0; i < message.messages.length; ++i)
                    $root.proto.SyncActionMessage.encode(message.messages[i], writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified SyncActionMessageRange message, length delimited. Does not implicitly {@link proto.SyncActionMessageRange.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.SyncActionMessageRange
         * @static
         * @param {proto.ISyncActionMessageRange} message SyncActionMessageRange message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SyncActionMessageRange.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a SyncActionMessageRange message from the specified reader or buffer.
         * @function decode
         * @memberof proto.SyncActionMessageRange
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.SyncActionMessageRange} SyncActionMessageRange
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SyncActionMessageRange.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncActionMessageRange();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.lastMessageTimestamp = reader.int64();
                    break;
                case 2:
                    message.lastSystemMessageTimestamp = reader.int64();
                    break;
                case 3:
                    if (!(message.messages && message.messages.length))
                        message.messages = [];
                    message.messages.push($root.proto.SyncActionMessage.decode(reader, reader.uint32()));
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a SyncActionMessageRange message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.SyncActionMessageRange
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.SyncActionMessageRange} SyncActionMessageRange
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SyncActionMessageRange.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a SyncActionMessageRange message.
         * @function verify
         * @memberof proto.SyncActionMessageRange
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        SyncActionMessageRange.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.lastMessageTimestamp != null && message.hasOwnProperty("lastMessageTimestamp"))
                if (!$util.isInteger(message.lastMessageTimestamp) && !(message.lastMessageTimestamp && $util.isInteger(message.lastMessageTimestamp.low) && $util.isInteger(message.lastMessageTimestamp.high)))
                    return "lastMessageTimestamp: integer|Long expected";
            if (message.lastSystemMessageTimestamp != null && message.hasOwnProperty("lastSystemMessageTimestamp"))
                if (!$util.isInteger(message.lastSystemMessageTimestamp) && !(message.lastSystemMessageTimestamp && $util.isInteger(message.lastSystemMessageTimestamp.low) && $util.isInteger(message.lastSystemMessageTimestamp.high)))
                    return "lastSystemMessageTimestamp: integer|Long expected";
            if (message.messages != null && message.hasOwnProperty("messages")) {
                if (!Array.isArray(message.messages))
                    return "messages: array expected";
                for (var i = 0; i < message.messages.length; ++i) {
                    var error = $root.proto.SyncActionMessage.verify(message.messages[i]);
                    if (error)
                        return "messages." + error;
                }
            }
            return null;
        };

        /**
         * Creates a SyncActionMessageRange message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.SyncActionMessageRange
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.SyncActionMessageRange} SyncActionMessageRange
         */
        SyncActionMessageRange.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.SyncActionMessageRange)
                return object;
            var message = new $root.proto.SyncActionMessageRange();
            if (object.lastMessageTimestamp != null)
                if ($util.Long)
                    (message.lastMessageTimestamp = $util.Long.fromValue(object.lastMessageTimestamp)).unsigned = false;
                else if (typeof object.lastMessageTimestamp === "string")
                    message.lastMessageTimestamp = parseInt(object.lastMessageTimestamp, 10);
                else if (typeof object.lastMessageTimestamp === "number")
                    message.lastMessageTimestamp = object.lastMessageTimestamp;
                else if (typeof object.lastMessageTimestamp === "object")
                    message.lastMessageTimestamp = new $util.LongBits(object.lastMessageTimestamp.low >>> 0, object.lastMessageTimestamp.high >>> 0).toNumber();
            if (object.lastSystemMessageTimestamp != null)
                if ($util.Long)
                    (message.lastSystemMessageTimestamp = $util.Long.fromValue(object.lastSystemMessageTimestamp)).unsigned = false;
                else if (typeof object.lastSystemMessageTimestamp === "string")
                    message.lastSystemMessageTimestamp = parseInt(object.lastSystemMessageTimestamp, 10);
                else if (typeof object.lastSystemMessageTimestamp === "number")
                    message.lastSystemMessageTimestamp = object.lastSystemMessageTimestamp;
                else if (typeof object.lastSystemMessageTimestamp === "object")
                    message.lastSystemMessageTimestamp = new $util.LongBits(object.lastSystemMessageTimestamp.low >>> 0, object.lastSystemMessageTimestamp.high >>> 0).toNumber();
            if (object.messages) {
                if (!Array.isArray(object.messages))
                    throw TypeError(".proto.SyncActionMessageRange.messages: array expected");
                message.messages = [];
                for (var i = 0; i < object.messages.length; ++i) {
                    if (typeof object.messages[i] !== "object")
                        throw TypeError(".proto.SyncActionMessageRange.messages: object expected");
                    message.messages[i] = $root.proto.SyncActionMessage.fromObject(object.messages[i]);
                }
            }
            return message;
        };

        /**
         * Creates a plain object from a SyncActionMessageRange message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.SyncActionMessageRange
         * @static
         * @param {proto.SyncActionMessageRange} message SyncActionMessageRange
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        SyncActionMessageRange.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.messages = [];
            if (options.defaults) {
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.lastMessageTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.lastMessageTimestamp = options.longs === String ? "0" : 0;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.lastSystemMessageTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.lastSystemMessageTimestamp = options.longs === String ? "0" : 0;
            }
            if (message.lastMessageTimestamp != null && message.hasOwnProperty("lastMessageTimestamp"))
                if (typeof message.lastMessageTimestamp === "number")
                    object.lastMessageTimestamp = options.longs === String ? String(message.lastMessageTimestamp) : message.lastMessageTimestamp;
                else
                    object.lastMessageTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.lastMessageTimestamp) : options.longs === Number ? new $util.LongBits(message.lastMessageTimestamp.low >>> 0, message.lastMessageTimestamp.high >>> 0).toNumber() : message.lastMessageTimestamp;
            if (message.lastSystemMessageTimestamp != null && message.hasOwnProperty("lastSystemMessageTimestamp"))
                if (typeof message.lastSystemMessageTimestamp === "number")
                    object.lastSystemMessageTimestamp = options.longs === String ? String(message.lastSystemMessageTimestamp) : message.lastSystemMessageTimestamp;
                else
                    object.lastSystemMessageTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.lastSystemMessageTimestamp) : options.longs === Number ? new $util.LongBits(message.lastSystemMessageTimestamp.low >>> 0, message.lastSystemMessageTimestamp.high >>> 0).toNumber() : message.lastSystemMessageTimestamp;
            if (message.messages && message.messages.length) {
                object.messages = [];
                for (var j = 0; j < message.messages.length; ++j)
                    object.messages[j] = $root.proto.SyncActionMessage.toObject(message.messages[j], options);
            }
            return object;
        };

        /**
         * Converts this SyncActionMessageRange to JSON.
         * @function toJSON
         * @memberof proto.SyncActionMessageRange
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        SyncActionMessageRange.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return SyncActionMessageRange;
    })();

    proto.SyncActionMessage = (function() {

        /**
         * Properties of a SyncActionMessage.
         * @memberof proto
         * @interface ISyncActionMessage
         * @property {proto.IMessageKey|null} [key] SyncActionMessage key
         * @property {number|Long|null} [timestamp] SyncActionMessage timestamp
         */

        /**
         * Constructs a new SyncActionMessage.
         * @memberof proto
         * @classdesc Represents a SyncActionMessage.
         * @implements ISyncActionMessage
         * @constructor
         * @param {proto.ISyncActionMessage=} [properties] Properties to set
         */
        function SyncActionMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * SyncActionMessage key.
         * @member {proto.IMessageKey|null|undefined} key
         * @memberof proto.SyncActionMessage
         * @instance
         */
        SyncActionMessage.prototype.key = null;

        /**
         * SyncActionMessage timestamp.
         * @member {number|Long} timestamp
         * @memberof proto.SyncActionMessage
         * @instance
         */
        SyncActionMessage.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * Creates a new SyncActionMessage instance using the specified properties.
         * @function create
         * @memberof proto.SyncActionMessage
         * @static
         * @param {proto.ISyncActionMessage=} [properties] Properties to set
         * @returns {proto.SyncActionMessage} SyncActionMessage instance
         */
        SyncActionMessage.create = function create(properties) {
            return new SyncActionMessage(properties);
        };

        /**
         * Encodes the specified SyncActionMessage message. Does not implicitly {@link proto.SyncActionMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.SyncActionMessage
         * @static
         * @param {proto.ISyncActionMessage} message SyncActionMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SyncActionMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.key != null && Object.hasOwnProperty.call(message, "key"))
                $root.proto.MessageKey.encode(message.key, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp"))
                writer.uint32(/* id 2, wireType 0 =*/16).int64(message.timestamp);
            return writer;
        };

        /**
         * Encodes the specified SyncActionMessage message, length delimited. Does not implicitly {@link proto.SyncActionMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.SyncActionMessage
         * @static
         * @param {proto.ISyncActionMessage} message SyncActionMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SyncActionMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a SyncActionMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.SyncActionMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.SyncActionMessage} SyncActionMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SyncActionMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncActionMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.key = $root.proto.MessageKey.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.timestamp = reader.int64();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a SyncActionMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.SyncActionMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.SyncActionMessage} SyncActionMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SyncActionMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a SyncActionMessage message.
         * @function verify
         * @memberof proto.SyncActionMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        SyncActionMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.key != null && message.hasOwnProperty("key")) {
                var error = $root.proto.MessageKey.verify(message.key);
                if (error)
                    return "key." + error;
            }
            if (message.timestamp != null && message.hasOwnProperty("timestamp"))
                if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high)))
                    return "timestamp: integer|Long expected";
            return null;
        };

        /**
         * Creates a SyncActionMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.SyncActionMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.SyncActionMessage} SyncActionMessage
         */
        SyncActionMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.SyncActionMessage)
                return object;
            var message = new $root.proto.SyncActionMessage();
            if (object.key != null) {
                if (typeof object.key !== "object")
                    throw TypeError(".proto.SyncActionMessage.key: object expected");
                message.key = $root.proto.MessageKey.fromObject(object.key);
            }
            if (object.timestamp != null)
                if ($util.Long)
                    (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = false;
                else if (typeof object.timestamp === "string")
                    message.timestamp = parseInt(object.timestamp, 10);
                else if (typeof object.timestamp === "number")
                    message.timestamp = object.timestamp;
                else if (typeof object.timestamp === "object")
                    message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber();
            return message;
        };

        /**
         * Creates a plain object from a SyncActionMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.SyncActionMessage
         * @static
         * @param {proto.SyncActionMessage} message SyncActionMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        SyncActionMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.key = null;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.timestamp = options.longs === String ? "0" : 0;
            }
            if (message.key != null && message.hasOwnProperty("key"))
                object.key = $root.proto.MessageKey.toObject(message.key, options);
            if (message.timestamp != null && message.hasOwnProperty("timestamp"))
                if (typeof message.timestamp === "number")
                    object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp;
                else
                    object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber() : message.timestamp;
            return object;
        };

        /**
         * Converts this SyncActionMessage to JSON.
         * @function toJSON
         * @memberof proto.SyncActionMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        SyncActionMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return SyncActionMessage;
    })();

    proto.KeyExpiration = (function() {

        /**
         * Properties of a KeyExpiration.
         * @memberof proto
         * @interface IKeyExpiration
         * @property {number|null} [expiredKeyEpoch] KeyExpiration expiredKeyEpoch
         */

        /**
         * Constructs a new KeyExpiration.
         * @memberof proto
         * @classdesc Represents a KeyExpiration.
         * @implements IKeyExpiration
         * @constructor
         * @param {proto.IKeyExpiration=} [properties] Properties to set
         */
        function KeyExpiration(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * KeyExpiration expiredKeyEpoch.
         * @member {number} expiredKeyEpoch
         * @memberof proto.KeyExpiration
         * @instance
         */
        KeyExpiration.prototype.expiredKeyEpoch = 0;

        /**
         * Creates a new KeyExpiration instance using the specified properties.
         * @function create
         * @memberof proto.KeyExpiration
         * @static
         * @param {proto.IKeyExpiration=} [properties] Properties to set
         * @returns {proto.KeyExpiration} KeyExpiration instance
         */
        KeyExpiration.create = function create(properties) {
            return new KeyExpiration(properties);
        };

        /**
         * Encodes the specified KeyExpiration message. Does not implicitly {@link proto.KeyExpiration.verify|verify} messages.
         * @function encode
         * @memberof proto.KeyExpiration
         * @static
         * @param {proto.IKeyExpiration} message KeyExpiration message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        KeyExpiration.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.expiredKeyEpoch != null && Object.hasOwnProperty.call(message, "expiredKeyEpoch"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.expiredKeyEpoch);
            return writer;
        };

        /**
         * Encodes the specified KeyExpiration message, length delimited. Does not implicitly {@link proto.KeyExpiration.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.KeyExpiration
         * @static
         * @param {proto.IKeyExpiration} message KeyExpiration message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        KeyExpiration.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a KeyExpiration message from the specified reader or buffer.
         * @function decode
         * @memberof proto.KeyExpiration
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.KeyExpiration} KeyExpiration
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        KeyExpiration.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.KeyExpiration();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.expiredKeyEpoch = reader.int32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a KeyExpiration message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.KeyExpiration
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.KeyExpiration} KeyExpiration
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        KeyExpiration.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a KeyExpiration message.
         * @function verify
         * @memberof proto.KeyExpiration
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        KeyExpiration.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.expiredKeyEpoch != null && message.hasOwnProperty("expiredKeyEpoch"))
                if (!$util.isInteger(message.expiredKeyEpoch))
                    return "expiredKeyEpoch: integer expected";
            return null;
        };

        /**
         * Creates a KeyExpiration message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.KeyExpiration
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.KeyExpiration} KeyExpiration
         */
        KeyExpiration.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.KeyExpiration)
                return object;
            var message = new $root.proto.KeyExpiration();
            if (object.expiredKeyEpoch != null)
                message.expiredKeyEpoch = object.expiredKeyEpoch | 0;
            return message;
        };

        /**
         * Creates a plain object from a KeyExpiration message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.KeyExpiration
         * @static
         * @param {proto.KeyExpiration} message KeyExpiration
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        KeyExpiration.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                object.expiredKeyEpoch = 0;
            if (message.expiredKeyEpoch != null && message.hasOwnProperty("expiredKeyEpoch"))
                object.expiredKeyEpoch = message.expiredKeyEpoch;
            return object;
        };

        /**
         * Converts this KeyExpiration to JSON.
         * @function toJSON
         * @memberof proto.KeyExpiration
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        KeyExpiration.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return KeyExpiration;
    })();

    proto.PrimaryFeature = (function() {

        /**
         * Properties of a PrimaryFeature.
         * @memberof proto
         * @interface IPrimaryFeature
         * @property {Array.<string>|null} [flags] PrimaryFeature flags
         */

        /**
         * Constructs a new PrimaryFeature.
         * @memberof proto
         * @classdesc Represents a PrimaryFeature.
         * @implements IPrimaryFeature
         * @constructor
         * @param {proto.IPrimaryFeature=} [properties] Properties to set
         */
        function PrimaryFeature(properties) {
            this.flags = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * PrimaryFeature flags.
         * @member {Array.<string>} flags
         * @memberof proto.PrimaryFeature
         * @instance
         */
        PrimaryFeature.prototype.flags = $util.emptyArray;

        /**
         * Creates a new PrimaryFeature instance using the specified properties.
         * @function create
         * @memberof proto.PrimaryFeature
         * @static
         * @param {proto.IPrimaryFeature=} [properties] Properties to set
         * @returns {proto.PrimaryFeature} PrimaryFeature instance
         */
        PrimaryFeature.create = function create(properties) {
            return new PrimaryFeature(properties);
        };

        /**
         * Encodes the specified PrimaryFeature message. Does not implicitly {@link proto.PrimaryFeature.verify|verify} messages.
         * @function encode
         * @memberof proto.PrimaryFeature
         * @static
         * @param {proto.IPrimaryFeature} message PrimaryFeature message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PrimaryFeature.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.flags != null && message.flags.length)
                for (var i = 0; i < message.flags.length; ++i)
                    writer.uint32(/* id 1, wireType 2 =*/10).string(message.flags[i]);
            return writer;
        };

        /**
         * Encodes the specified PrimaryFeature message, length delimited. Does not implicitly {@link proto.PrimaryFeature.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.PrimaryFeature
         * @static
         * @param {proto.IPrimaryFeature} message PrimaryFeature message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PrimaryFeature.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a PrimaryFeature message from the specified reader or buffer.
         * @function decode
         * @memberof proto.PrimaryFeature
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.PrimaryFeature} PrimaryFeature
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PrimaryFeature.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.PrimaryFeature();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    if (!(message.flags && message.flags.length))
                        message.flags = [];
                    message.flags.push(reader.string());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a PrimaryFeature message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.PrimaryFeature
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.PrimaryFeature} PrimaryFeature
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PrimaryFeature.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a PrimaryFeature message.
         * @function verify
         * @memberof proto.PrimaryFeature
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        PrimaryFeature.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.flags != null && message.hasOwnProperty("flags")) {
                if (!Array.isArray(message.flags))
                    return "flags: array expected";
                for (var i = 0; i < message.flags.length; ++i)
                    if (!$util.isString(message.flags[i]))
                        return "flags: string[] expected";
            }
            return null;
        };

        /**
         * Creates a PrimaryFeature message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.PrimaryFeature
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.PrimaryFeature} PrimaryFeature
         */
        PrimaryFeature.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.PrimaryFeature)
                return object;
            var message = new $root.proto.PrimaryFeature();
            if (object.flags) {
                if (!Array.isArray(object.flags))
                    throw TypeError(".proto.PrimaryFeature.flags: array expected");
                message.flags = [];
                for (var i = 0; i < object.flags.length; ++i)
                    message.flags[i] = String(object.flags[i]);
            }
            return message;
        };

        /**
         * Creates a plain object from a PrimaryFeature message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.PrimaryFeature
         * @static
         * @param {proto.PrimaryFeature} message PrimaryFeature
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        PrimaryFeature.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.flags = [];
            if (message.flags && message.flags.length) {
                object.flags = [];
                for (var j = 0; j < message.flags.length; ++j)
                    object.flags[j] = message.flags[j];
            }
            return object;
        };

        /**
         * Converts this PrimaryFeature to JSON.
         * @function toJSON
         * @memberof proto.PrimaryFeature
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        PrimaryFeature.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return PrimaryFeature;
    })();

    proto.AndroidUnsupportedActions = (function() {

        /**
         * Properties of an AndroidUnsupportedActions.
         * @memberof proto
         * @interface IAndroidUnsupportedActions
         * @property {boolean|null} [allowed] AndroidUnsupportedActions allowed
         */

        /**
         * Constructs a new AndroidUnsupportedActions.
         * @memberof proto
         * @classdesc Represents an AndroidUnsupportedActions.
         * @implements IAndroidUnsupportedActions
         * @constructor
         * @param {proto.IAndroidUnsupportedActions=} [properties] Properties to set
         */
        function AndroidUnsupportedActions(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * AndroidUnsupportedActions allowed.
         * @member {boolean} allowed
         * @memberof proto.AndroidUnsupportedActions
         * @instance
         */
        AndroidUnsupportedActions.prototype.allowed = false;

        /**
         * Creates a new AndroidUnsupportedActions instance using the specified properties.
         * @function create
         * @memberof proto.AndroidUnsupportedActions
         * @static
         * @param {proto.IAndroidUnsupportedActions=} [properties] Properties to set
         * @returns {proto.AndroidUnsupportedActions} AndroidUnsupportedActions instance
         */
        AndroidUnsupportedActions.create = function create(properties) {
            return new AndroidUnsupportedActions(properties);
        };

        /**
         * Encodes the specified AndroidUnsupportedActions message. Does not implicitly {@link proto.AndroidUnsupportedActions.verify|verify} messages.
         * @function encode
         * @memberof proto.AndroidUnsupportedActions
         * @static
         * @param {proto.IAndroidUnsupportedActions} message AndroidUnsupportedActions message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AndroidUnsupportedActions.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.allowed != null && Object.hasOwnProperty.call(message, "allowed"))
                writer.uint32(/* id 1, wireType 0 =*/8).bool(message.allowed);
            return writer;
        };

        /**
         * Encodes the specified AndroidUnsupportedActions message, length delimited. Does not implicitly {@link proto.AndroidUnsupportedActions.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.AndroidUnsupportedActions
         * @static
         * @param {proto.IAndroidUnsupportedActions} message AndroidUnsupportedActions message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AndroidUnsupportedActions.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an AndroidUnsupportedActions message from the specified reader or buffer.
         * @function decode
         * @memberof proto.AndroidUnsupportedActions
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.AndroidUnsupportedActions} AndroidUnsupportedActions
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AndroidUnsupportedActions.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.AndroidUnsupportedActions();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.allowed = reader.bool();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an AndroidUnsupportedActions message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.AndroidUnsupportedActions
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.AndroidUnsupportedActions} AndroidUnsupportedActions
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AndroidUnsupportedActions.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an AndroidUnsupportedActions message.
         * @function verify
         * @memberof proto.AndroidUnsupportedActions
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        AndroidUnsupportedActions.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.allowed != null && message.hasOwnProperty("allowed"))
                if (typeof message.allowed !== "boolean")
                    return "allowed: boolean expected";
            return null;
        };

        /**
         * Creates an AndroidUnsupportedActions message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.AndroidUnsupportedActions
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.AndroidUnsupportedActions} AndroidUnsupportedActions
         */
        AndroidUnsupportedActions.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.AndroidUnsupportedActions)
                return object;
            var message = new $root.proto.AndroidUnsupportedActions();
            if (object.allowed != null)
                message.allowed = Boolean(object.allowed);
            return message;
        };

        /**
         * Creates a plain object from an AndroidUnsupportedActions message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.AndroidUnsupportedActions
         * @static
         * @param {proto.AndroidUnsupportedActions} message AndroidUnsupportedActions
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        AndroidUnsupportedActions.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                object.allowed = false;
            if (message.allowed != null && message.hasOwnProperty("allowed"))
                object.allowed = message.allowed;
            return object;
        };

        /**
         * Converts this AndroidUnsupportedActions to JSON.
         * @function toJSON
         * @memberof proto.AndroidUnsupportedActions
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        AndroidUnsupportedActions.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return AndroidUnsupportedActions;
    })();

    proto.SyncActionValue = (function() {

        /**
         * Properties of a SyncActionValue.
         * @memberof proto
         * @interface ISyncActionValue
         * @property {number|Long|null} [timestamp] SyncActionValue timestamp
         * @property {proto.IStarAction|null} [starAction] SyncActionValue starAction
         * @property {proto.IContactAction|null} [contactAction] SyncActionValue contactAction
         * @property {proto.IMuteAction|null} [muteAction] SyncActionValue muteAction
         * @property {proto.IPinAction|null} [pinAction] SyncActionValue pinAction
         * @property {proto.ISecurityNotificationSetting|null} [securityNotificationSetting] SyncActionValue securityNotificationSetting
         * @property {proto.IPushNameSetting|null} [pushNameSetting] SyncActionValue pushNameSetting
         * @property {proto.IQuickReplyAction|null} [quickReplyAction] SyncActionValue quickReplyAction
         * @property {proto.IRecentStickerWeightsAction|null} [recentStickerWeightsAction] SyncActionValue recentStickerWeightsAction
         * @property {proto.IRecentStickerMetadata|null} [recentStickerMetadata] SyncActionValue recentStickerMetadata
         * @property {proto.IRecentEmojiWeightsAction|null} [recentEmojiWeightsAction] SyncActionValue recentEmojiWeightsAction
         * @property {proto.ILabelEditAction|null} [labelEditAction] SyncActionValue labelEditAction
         * @property {proto.ILabelAssociationAction|null} [labelAssociationAction] SyncActionValue labelAssociationAction
         * @property {proto.ILocaleSetting|null} [localeSetting] SyncActionValue localeSetting
         * @property {proto.IArchiveChatAction|null} [archiveChatAction] SyncActionValue archiveChatAction
         * @property {proto.IDeleteMessageForMeAction|null} [deleteMessageForMeAction] SyncActionValue deleteMessageForMeAction
         * @property {proto.IKeyExpiration|null} [keyExpiration] SyncActionValue keyExpiration
         * @property {proto.IMarkChatAsReadAction|null} [markChatAsReadAction] SyncActionValue markChatAsReadAction
         * @property {proto.IClearChatAction|null} [clearChatAction] SyncActionValue clearChatAction
         * @property {proto.IDeleteChatAction|null} [deleteChatAction] SyncActionValue deleteChatAction
         * @property {proto.IUnarchiveChatsSetting|null} [unarchiveChatsSetting] SyncActionValue unarchiveChatsSetting
         * @property {proto.IPrimaryFeature|null} [primaryFeature] SyncActionValue primaryFeature
         * @property {proto.IFavoriteStickerAction|null} [favoriteStickerAction] SyncActionValue favoriteStickerAction
         * @property {proto.IAndroidUnsupportedActions|null} [androidUnsupportedActions] SyncActionValue androidUnsupportedActions
         */

        /**
         * Constructs a new SyncActionValue.
         * @memberof proto
         * @classdesc Represents a SyncActionValue.
         * @implements ISyncActionValue
         * @constructor
         * @param {proto.ISyncActionValue=} [properties] Properties to set
         */
        function SyncActionValue(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * SyncActionValue timestamp.
         * @member {number|Long} timestamp
         * @memberof proto.SyncActionValue
         * @instance
         */
        SyncActionValue.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * SyncActionValue starAction.
         * @member {proto.IStarAction|null|undefined} starAction
         * @memberof proto.SyncActionValue
         * @instance
         */
        SyncActionValue.prototype.starAction = null;

        /**
         * SyncActionValue contactAction.
         * @member {proto.IContactAction|null|undefined} contactAction
         * @memberof proto.SyncActionValue
         * @instance
         */
        SyncActionValue.prototype.contactAction = null;

        /**
         * SyncActionValue muteAction.
         * @member {proto.IMuteAction|null|undefined} muteAction
         * @memberof proto.SyncActionValue
         * @instance
         */
        SyncActionValue.prototype.muteAction = null;

        /**
         * SyncActionValue pinAction.
         * @member {proto.IPinAction|null|undefined} pinAction
         * @memberof proto.SyncActionValue
         * @instance
         */
        SyncActionValue.prototype.pinAction = null;

        /**
         * SyncActionValue securityNotificationSetting.
         * @member {proto.ISecurityNotificationSetting|null|undefined} securityNotificationSetting
         * @memberof proto.SyncActionValue
         * @instance
         */
        SyncActionValue.prototype.securityNotificationSetting = null;

        /**
         * SyncActionValue pushNameSetting.
         * @member {proto.IPushNameSetting|null|undefined} pushNameSetting
         * @memberof proto.SyncActionValue
         * @instance
         */
        SyncActionValue.prototype.pushNameSetting = null;

        /**
         * SyncActionValue quickReplyAction.
         * @member {proto.IQuickReplyAction|null|undefined} quickReplyAction
         * @memberof proto.SyncActionValue
         * @instance
         */
        SyncActionValue.prototype.quickReplyAction = null;

        /**
         * SyncActionValue recentStickerWeightsAction.
         * @member {proto.IRecentStickerWeightsAction|null|undefined} recentStickerWeightsAction
         * @memberof proto.SyncActionValue
         * @instance
         */
        SyncActionValue.prototype.recentStickerWeightsAction = null;

        /**
         * SyncActionValue recentStickerMetadata.
         * @member {proto.IRecentStickerMetadata|null|undefined} recentStickerMetadata
         * @memberof proto.SyncActionValue
         * @instance
         */
        SyncActionValue.prototype.recentStickerMetadata = null;

        /**
         * SyncActionValue recentEmojiWeightsAction.
         * @member {proto.IRecentEmojiWeightsAction|null|undefined} recentEmojiWeightsAction
         * @memberof proto.SyncActionValue
         * @instance
         */
        SyncActionValue.prototype.recentEmojiWeightsAction = null;

        /**
         * SyncActionValue labelEditAction.
         * @member {proto.ILabelEditAction|null|undefined} labelEditAction
         * @memberof proto.SyncActionValue
         * @instance
         */
        SyncActionValue.prototype.labelEditAction = null;

        /**
         * SyncActionValue labelAssociationAction.
         * @member {proto.ILabelAssociationAction|null|undefined} labelAssociationAction
         * @memberof proto.SyncActionValue
         * @instance
         */
        SyncActionValue.prototype.labelAssociationAction = null;

        /**
         * SyncActionValue localeSetting.
         * @member {proto.ILocaleSetting|null|undefined} localeSetting
         * @memberof proto.SyncActionValue
         * @instance
         */
        SyncActionValue.prototype.localeSetting = null;

        /**
         * SyncActionValue archiveChatAction.
         * @member {proto.IArchiveChatAction|null|undefined} archiveChatAction
         * @memberof proto.SyncActionValue
         * @instance
         */
        SyncActionValue.prototype.archiveChatAction = null;

        /**
         * SyncActionValue deleteMessageForMeAction.
         * @member {proto.IDeleteMessageForMeAction|null|undefined} deleteMessageForMeAction
         * @memberof proto.SyncActionValue
         * @instance
         */
        SyncActionValue.prototype.deleteMessageForMeAction = null;

        /**
         * SyncActionValue keyExpiration.
         * @member {proto.IKeyExpiration|null|undefined} keyExpiration
         * @memberof proto.SyncActionValue
         * @instance
         */
        SyncActionValue.prototype.keyExpiration = null;

        /**
         * SyncActionValue markChatAsReadAction.
         * @member {proto.IMarkChatAsReadAction|null|undefined} markChatAsReadAction
         * @memberof proto.SyncActionValue
         * @instance
         */
        SyncActionValue.prototype.markChatAsReadAction = null;

        /**
         * SyncActionValue clearChatAction.
         * @member {proto.IClearChatAction|null|undefined} clearChatAction
         * @memberof proto.SyncActionValue
         * @instance
         */
        SyncActionValue.prototype.clearChatAction = null;

        /**
         * SyncActionValue deleteChatAction.
         * @member {proto.IDeleteChatAction|null|undefined} deleteChatAction
         * @memberof proto.SyncActionValue
         * @instance
         */
        SyncActionValue.prototype.deleteChatAction = null;

        /**
         * SyncActionValue unarchiveChatsSetting.
         * @member {proto.IUnarchiveChatsSetting|null|undefined} unarchiveChatsSetting
         * @memberof proto.SyncActionValue
         * @instance
         */
        SyncActionValue.prototype.unarchiveChatsSetting = null;

        /**
         * SyncActionValue primaryFeature.
         * @member {proto.IPrimaryFeature|null|undefined} primaryFeature
         * @memberof proto.SyncActionValue
         * @instance
         */
        SyncActionValue.prototype.primaryFeature = null;

        /**
         * SyncActionValue favoriteStickerAction.
         * @member {proto.IFavoriteStickerAction|null|undefined} favoriteStickerAction
         * @memberof proto.SyncActionValue
         * @instance
         */
        SyncActionValue.prototype.favoriteStickerAction = null;

        /**
         * SyncActionValue androidUnsupportedActions.
         * @member {proto.IAndroidUnsupportedActions|null|undefined} androidUnsupportedActions
         * @memberof proto.SyncActionValue
         * @instance
         */
        SyncActionValue.prototype.androidUnsupportedActions = null;

        /**
         * Creates a new SyncActionValue instance using the specified properties.
         * @function create
         * @memberof proto.SyncActionValue
         * @static
         * @param {proto.ISyncActionValue=} [properties] Properties to set
         * @returns {proto.SyncActionValue} SyncActionValue instance
         */
        SyncActionValue.create = function create(properties) {
            return new SyncActionValue(properties);
        };

        /**
         * Encodes the specified SyncActionValue message. Does not implicitly {@link proto.SyncActionValue.verify|verify} messages.
         * @function encode
         * @memberof proto.SyncActionValue
         * @static
         * @param {proto.ISyncActionValue} message SyncActionValue message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SyncActionValue.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp"))
                writer.uint32(/* id 1, wireType 0 =*/8).int64(message.timestamp);
            if (message.starAction != null && Object.hasOwnProperty.call(message, "starAction"))
                $root.proto.StarAction.encode(message.starAction, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.contactAction != null && Object.hasOwnProperty.call(message, "contactAction"))
                $root.proto.ContactAction.encode(message.contactAction, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.muteAction != null && Object.hasOwnProperty.call(message, "muteAction"))
                $root.proto.MuteAction.encode(message.muteAction, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
            if (message.pinAction != null && Object.hasOwnProperty.call(message, "pinAction"))
                $root.proto.PinAction.encode(message.pinAction, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim();
            if (message.securityNotificationSetting != null && Object.hasOwnProperty.call(message, "securityNotificationSetting"))
                $root.proto.SecurityNotificationSetting.encode(message.securityNotificationSetting, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim();
            if (message.pushNameSetting != null && Object.hasOwnProperty.call(message, "pushNameSetting"))
                $root.proto.PushNameSetting.encode(message.pushNameSetting, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim();
            if (message.quickReplyAction != null && Object.hasOwnProperty.call(message, "quickReplyAction"))
                $root.proto.QuickReplyAction.encode(message.quickReplyAction, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim();
            if (message.recentStickerWeightsAction != null && Object.hasOwnProperty.call(message, "recentStickerWeightsAction"))
                $root.proto.RecentStickerWeightsAction.encode(message.recentStickerWeightsAction, writer.uint32(/* id 9, wireType 2 =*/74).fork()).ldelim();
            if (message.recentStickerMetadata != null && Object.hasOwnProperty.call(message, "recentStickerMetadata"))
                $root.proto.RecentStickerMetadata.encode(message.recentStickerMetadata, writer.uint32(/* id 10, wireType 2 =*/82).fork()).ldelim();
            if (message.recentEmojiWeightsAction != null && Object.hasOwnProperty.call(message, "recentEmojiWeightsAction"))
                $root.proto.RecentEmojiWeightsAction.encode(message.recentEmojiWeightsAction, writer.uint32(/* id 11, wireType 2 =*/90).fork()).ldelim();
            if (message.labelEditAction != null && Object.hasOwnProperty.call(message, "labelEditAction"))
                $root.proto.LabelEditAction.encode(message.labelEditAction, writer.uint32(/* id 14, wireType 2 =*/114).fork()).ldelim();
            if (message.labelAssociationAction != null && Object.hasOwnProperty.call(message, "labelAssociationAction"))
                $root.proto.LabelAssociationAction.encode(message.labelAssociationAction, writer.uint32(/* id 15, wireType 2 =*/122).fork()).ldelim();
            if (message.localeSetting != null && Object.hasOwnProperty.call(message, "localeSetting"))
                $root.proto.LocaleSetting.encode(message.localeSetting, writer.uint32(/* id 16, wireType 2 =*/130).fork()).ldelim();
            if (message.archiveChatAction != null && Object.hasOwnProperty.call(message, "archiveChatAction"))
                $root.proto.ArchiveChatAction.encode(message.archiveChatAction, writer.uint32(/* id 17, wireType 2 =*/138).fork()).ldelim();
            if (message.deleteMessageForMeAction != null && Object.hasOwnProperty.call(message, "deleteMessageForMeAction"))
                $root.proto.DeleteMessageForMeAction.encode(message.deleteMessageForMeAction, writer.uint32(/* id 18, wireType 2 =*/146).fork()).ldelim();
            if (message.keyExpiration != null && Object.hasOwnProperty.call(message, "keyExpiration"))
                $root.proto.KeyExpiration.encode(message.keyExpiration, writer.uint32(/* id 19, wireType 2 =*/154).fork()).ldelim();
            if (message.markChatAsReadAction != null && Object.hasOwnProperty.call(message, "markChatAsReadAction"))
                $root.proto.MarkChatAsReadAction.encode(message.markChatAsReadAction, writer.uint32(/* id 20, wireType 2 =*/162).fork()).ldelim();
            if (message.clearChatAction != null && Object.hasOwnProperty.call(message, "clearChatAction"))
                $root.proto.ClearChatAction.encode(message.clearChatAction, writer.uint32(/* id 21, wireType 2 =*/170).fork()).ldelim();
            if (message.deleteChatAction != null && Object.hasOwnProperty.call(message, "deleteChatAction"))
                $root.proto.DeleteChatAction.encode(message.deleteChatAction, writer.uint32(/* id 22, wireType 2 =*/178).fork()).ldelim();
            if (message.unarchiveChatsSetting != null && Object.hasOwnProperty.call(message, "unarchiveChatsSetting"))
                $root.proto.UnarchiveChatsSetting.encode(message.unarchiveChatsSetting, writer.uint32(/* id 23, wireType 2 =*/186).fork()).ldelim();
            if (message.primaryFeature != null && Object.hasOwnProperty.call(message, "primaryFeature"))
                $root.proto.PrimaryFeature.encode(message.primaryFeature, writer.uint32(/* id 24, wireType 2 =*/194).fork()).ldelim();
            if (message.favoriteStickerAction != null && Object.hasOwnProperty.call(message, "favoriteStickerAction"))
                $root.proto.FavoriteStickerAction.encode(message.favoriteStickerAction, writer.uint32(/* id 25, wireType 2 =*/202).fork()).ldelim();
            if (message.androidUnsupportedActions != null && Object.hasOwnProperty.call(message, "androidUnsupportedActions"))
                $root.proto.AndroidUnsupportedActions.encode(message.androidUnsupportedActions, writer.uint32(/* id 26, wireType 2 =*/210).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified SyncActionValue message, length delimited. Does not implicitly {@link proto.SyncActionValue.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.SyncActionValue
         * @static
         * @param {proto.ISyncActionValue} message SyncActionValue message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SyncActionValue.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a SyncActionValue message from the specified reader or buffer.
         * @function decode
         * @memberof proto.SyncActionValue
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.SyncActionValue} SyncActionValue
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SyncActionValue.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncActionValue();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.timestamp = reader.int64();
                    break;
                case 2:
                    message.starAction = $root.proto.StarAction.decode(reader, reader.uint32());
                    break;
                case 3:
                    message.contactAction = $root.proto.ContactAction.decode(reader, reader.uint32());
                    break;
                case 4:
                    message.muteAction = $root.proto.MuteAction.decode(reader, reader.uint32());
                    break;
                case 5:
                    message.pinAction = $root.proto.PinAction.decode(reader, reader.uint32());
                    break;
                case 6:
                    message.securityNotificationSetting = $root.proto.SecurityNotificationSetting.decode(reader, reader.uint32());
                    break;
                case 7:
                    message.pushNameSetting = $root.proto.PushNameSetting.decode(reader, reader.uint32());
                    break;
                case 8:
                    message.quickReplyAction = $root.proto.QuickReplyAction.decode(reader, reader.uint32());
                    break;
                case 9:
                    message.recentStickerWeightsAction = $root.proto.RecentStickerWeightsAction.decode(reader, reader.uint32());
                    break;
                case 10:
                    message.recentStickerMetadata = $root.proto.RecentStickerMetadata.decode(reader, reader.uint32());
                    break;
                case 11:
                    message.recentEmojiWeightsAction = $root.proto.RecentEmojiWeightsAction.decode(reader, reader.uint32());
                    break;
                case 14:
                    message.labelEditAction = $root.proto.LabelEditAction.decode(reader, reader.uint32());
                    break;
                case 15:
                    message.labelAssociationAction = $root.proto.LabelAssociationAction.decode(reader, reader.uint32());
                    break;
                case 16:
                    message.localeSetting = $root.proto.LocaleSetting.decode(reader, reader.uint32());
                    break;
                case 17:
                    message.archiveChatAction = $root.proto.ArchiveChatAction.decode(reader, reader.uint32());
                    break;
                case 18:
                    message.deleteMessageForMeAction = $root.proto.DeleteMessageForMeAction.decode(reader, reader.uint32());
                    break;
                case 19:
                    message.keyExpiration = $root.proto.KeyExpiration.decode(reader, reader.uint32());
                    break;
                case 20:
                    message.markChatAsReadAction = $root.proto.MarkChatAsReadAction.decode(reader, reader.uint32());
                    break;
                case 21:
                    message.clearChatAction = $root.proto.ClearChatAction.decode(reader, reader.uint32());
                    break;
                case 22:
                    message.deleteChatAction = $root.proto.DeleteChatAction.decode(reader, reader.uint32());
                    break;
                case 23:
                    message.unarchiveChatsSetting = $root.proto.UnarchiveChatsSetting.decode(reader, reader.uint32());
                    break;
                case 24:
                    message.primaryFeature = $root.proto.PrimaryFeature.decode(reader, reader.uint32());
                    break;
                case 25:
                    message.favoriteStickerAction = $root.proto.FavoriteStickerAction.decode(reader, reader.uint32());
                    break;
                case 26:
                    message.androidUnsupportedActions = $root.proto.AndroidUnsupportedActions.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a SyncActionValue message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.SyncActionValue
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.SyncActionValue} SyncActionValue
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SyncActionValue.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a SyncActionValue message.
         * @function verify
         * @memberof proto.SyncActionValue
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        SyncActionValue.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.timestamp != null && message.hasOwnProperty("timestamp"))
                if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high)))
                    return "timestamp: integer|Long expected";
            if (message.starAction != null && message.hasOwnProperty("starAction")) {
                var error = $root.proto.StarAction.verify(message.starAction);
                if (error)
                    return "starAction." + error;
            }
            if (message.contactAction != null && message.hasOwnProperty("contactAction")) {
                var error = $root.proto.ContactAction.verify(message.contactAction);
                if (error)
                    return "contactAction." + error;
            }
            if (message.muteAction != null && message.hasOwnProperty("muteAction")) {
                var error = $root.proto.MuteAction.verify(message.muteAction);
                if (error)
                    return "muteAction." + error;
            }
            if (message.pinAction != null && message.hasOwnProperty("pinAction")) {
                var error = $root.proto.PinAction.verify(message.pinAction);
                if (error)
                    return "pinAction." + error;
            }
            if (message.securityNotificationSetting != null && message.hasOwnProperty("securityNotificationSetting")) {
                var error = $root.proto.SecurityNotificationSetting.verify(message.securityNotificationSetting);
                if (error)
                    return "securityNotificationSetting." + error;
            }
            if (message.pushNameSetting != null && message.hasOwnProperty("pushNameSetting")) {
                var error = $root.proto.PushNameSetting.verify(message.pushNameSetting);
                if (error)
                    return "pushNameSetting." + error;
            }
            if (message.quickReplyAction != null && message.hasOwnProperty("quickReplyAction")) {
                var error = $root.proto.QuickReplyAction.verify(message.quickReplyAction);
                if (error)
                    return "quickReplyAction." + error;
            }
            if (message.recentStickerWeightsAction != null && message.hasOwnProperty("recentStickerWeightsAction")) {
                var error = $root.proto.RecentStickerWeightsAction.verify(message.recentStickerWeightsAction);
                if (error)
                    return "recentStickerWeightsAction." + error;
            }
            if (message.recentStickerMetadata != null && message.hasOwnProperty("recentStickerMetadata")) {
                var error = $root.proto.RecentStickerMetadata.verify(message.recentStickerMetadata);
                if (error)
                    return "recentStickerMetadata." + error;
            }
            if (message.recentEmojiWeightsAction != null && message.hasOwnProperty("recentEmojiWeightsAction")) {
                var error = $root.proto.RecentEmojiWeightsAction.verify(message.recentEmojiWeightsAction);
                if (error)
                    return "recentEmojiWeightsAction." + error;
            }
            if (message.labelEditAction != null && message.hasOwnProperty("labelEditAction")) {
                var error = $root.proto.LabelEditAction.verify(message.labelEditAction);
                if (error)
                    return "labelEditAction." + error;
            }
            if (message.labelAssociationAction != null && message.hasOwnProperty("labelAssociationAction")) {
                var error = $root.proto.LabelAssociationAction.verify(message.labelAssociationAction);
                if (error)
                    return "labelAssociationAction." + error;
            }
            if (message.localeSetting != null && message.hasOwnProperty("localeSetting")) {
                var error = $root.proto.LocaleSetting.verify(message.localeSetting);
                if (error)
                    return "localeSetting." + error;
            }
            if (message.archiveChatAction != null && message.hasOwnProperty("archiveChatAction")) {
                var error = $root.proto.ArchiveChatAction.verify(message.archiveChatAction);
                if (error)
                    return "archiveChatAction." + error;
            }
            if (message.deleteMessageForMeAction != null && message.hasOwnProperty("deleteMessageForMeAction")) {
                var error = $root.proto.DeleteMessageForMeAction.verify(message.deleteMessageForMeAction);
                if (error)
                    return "deleteMessageForMeAction." + error;
            }
            if (message.keyExpiration != null && message.hasOwnProperty("keyExpiration")) {
                var error = $root.proto.KeyExpiration.verify(message.keyExpiration);
                if (error)
                    return "keyExpiration." + error;
            }
            if (message.markChatAsReadAction != null && message.hasOwnProperty("markChatAsReadAction")) {
                var error = $root.proto.MarkChatAsReadAction.verify(message.markChatAsReadAction);
                if (error)
                    return "markChatAsReadAction." + error;
            }
            if (message.clearChatAction != null && message.hasOwnProperty("clearChatAction")) {
                var error = $root.proto.ClearChatAction.verify(message.clearChatAction);
                if (error)
                    return "clearChatAction." + error;
            }
            if (message.deleteChatAction != null && message.hasOwnProperty("deleteChatAction")) {
                var error = $root.proto.DeleteChatAction.verify(message.deleteChatAction);
                if (error)
                    return "deleteChatAction." + error;
            }
            if (message.unarchiveChatsSetting != null && message.hasOwnProperty("unarchiveChatsSetting")) {
                var error = $root.proto.UnarchiveChatsSetting.verify(message.unarchiveChatsSetting);
                if (error)
                    return "unarchiveChatsSetting." + error;
            }
            if (message.primaryFeature != null && message.hasOwnProperty("primaryFeature")) {
                var error = $root.proto.PrimaryFeature.verify(message.primaryFeature);
                if (error)
                    return "primaryFeature." + error;
            }
            if (message.favoriteStickerAction != null && message.hasOwnProperty("favoriteStickerAction")) {
                var error = $root.proto.FavoriteStickerAction.verify(message.favoriteStickerAction);
                if (error)
                    return "favoriteStickerAction." + error;
            }
            if (message.androidUnsupportedActions != null && message.hasOwnProperty("androidUnsupportedActions")) {
                var error = $root.proto.AndroidUnsupportedActions.verify(message.androidUnsupportedActions);
                if (error)
                    return "androidUnsupportedActions." + error;
            }
            return null;
        };

        /**
         * Creates a SyncActionValue message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.SyncActionValue
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.SyncActionValue} SyncActionValue
         */
        SyncActionValue.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.SyncActionValue)
                return object;
            var message = new $root.proto.SyncActionValue();
            if (object.timestamp != null)
                if ($util.Long)
                    (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = false;
                else if (typeof object.timestamp === "string")
                    message.timestamp = parseInt(object.timestamp, 10);
                else if (typeof object.timestamp === "number")
                    message.timestamp = object.timestamp;
                else if (typeof object.timestamp === "object")
                    message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber();
            if (object.starAction != null) {
                if (typeof object.starAction !== "object")
                    throw TypeError(".proto.SyncActionValue.starAction: object expected");
                message.starAction = $root.proto.StarAction.fromObject(object.starAction);
            }
            if (object.contactAction != null) {
                if (typeof object.contactAction !== "object")
                    throw TypeError(".proto.SyncActionValue.contactAction: object expected");
                message.contactAction = $root.proto.ContactAction.fromObject(object.contactAction);
            }
            if (object.muteAction != null) {
                if (typeof object.muteAction !== "object")
                    throw TypeError(".proto.SyncActionValue.muteAction: object expected");
                message.muteAction = $root.proto.MuteAction.fromObject(object.muteAction);
            }
            if (object.pinAction != null) {
                if (typeof object.pinAction !== "object")
                    throw TypeError(".proto.SyncActionValue.pinAction: object expected");
                message.pinAction = $root.proto.PinAction.fromObject(object.pinAction);
            }
            if (object.securityNotificationSetting != null) {
                if (typeof object.securityNotificationSetting !== "object")
                    throw TypeError(".proto.SyncActionValue.securityNotificationSetting: object expected");
                message.securityNotificationSetting = $root.proto.SecurityNotificationSetting.fromObject(object.securityNotificationSetting);
            }
            if (object.pushNameSetting != null) {
                if (typeof object.pushNameSetting !== "object")
                    throw TypeError(".proto.SyncActionValue.pushNameSetting: object expected");
                message.pushNameSetting = $root.proto.PushNameSetting.fromObject(object.pushNameSetting);
            }
            if (object.quickReplyAction != null) {
                if (typeof object.quickReplyAction !== "object")
                    throw TypeError(".proto.SyncActionValue.quickReplyAction: object expected");
                message.quickReplyAction = $root.proto.QuickReplyAction.fromObject(object.quickReplyAction);
            }
            if (object.recentStickerWeightsAction != null) {
                if (typeof object.recentStickerWeightsAction !== "object")
                    throw TypeError(".proto.SyncActionValue.recentStickerWeightsAction: object expected");
                message.recentStickerWeightsAction = $root.proto.RecentStickerWeightsAction.fromObject(object.recentStickerWeightsAction);
            }
            if (object.recentStickerMetadata != null) {
                if (typeof object.recentStickerMetadata !== "object")
                    throw TypeError(".proto.SyncActionValue.recentStickerMetadata: object expected");
                message.recentStickerMetadata = $root.proto.RecentStickerMetadata.fromObject(object.recentStickerMetadata);
            }
            if (object.recentEmojiWeightsAction != null) {
                if (typeof object.recentEmojiWeightsAction !== "object")
                    throw TypeError(".proto.SyncActionValue.recentEmojiWeightsAction: object expected");
                message.recentEmojiWeightsAction = $root.proto.RecentEmojiWeightsAction.fromObject(object.recentEmojiWeightsAction);
            }
            if (object.labelEditAction != null) {
                if (typeof object.labelEditAction !== "object")
                    throw TypeError(".proto.SyncActionValue.labelEditAction: object expected");
                message.labelEditAction = $root.proto.LabelEditAction.fromObject(object.labelEditAction);
            }
            if (object.labelAssociationAction != null) {
                if (typeof object.labelAssociationAction !== "object")
                    throw TypeError(".proto.SyncActionValue.labelAssociationAction: object expected");
                message.labelAssociationAction = $root.proto.LabelAssociationAction.fromObject(object.labelAssociationAction);
            }
            if (object.localeSetting != null) {
                if (typeof object.localeSetting !== "object")
                    throw TypeError(".proto.SyncActionValue.localeSetting: object expected");
                message.localeSetting = $root.proto.LocaleSetting.fromObject(object.localeSetting);
            }
            if (object.archiveChatAction != null) {
                if (typeof object.archiveChatAction !== "object")
                    throw TypeError(".proto.SyncActionValue.archiveChatAction: object expected");
                message.archiveChatAction = $root.proto.ArchiveChatAction.fromObject(object.archiveChatAction);
            }
            if (object.deleteMessageForMeAction != null) {
                if (typeof object.deleteMessageForMeAction !== "object")
                    throw TypeError(".proto.SyncActionValue.deleteMessageForMeAction: object expected");
                message.deleteMessageForMeAction = $root.proto.DeleteMessageForMeAction.fromObject(object.deleteMessageForMeAction);
            }
            if (object.keyExpiration != null) {
                if (typeof object.keyExpiration !== "object")
                    throw TypeError(".proto.SyncActionValue.keyExpiration: object expected");
                message.keyExpiration = $root.proto.KeyExpiration.fromObject(object.keyExpiration);
            }
            if (object.markChatAsReadAction != null) {
                if (typeof object.markChatAsReadAction !== "object")
                    throw TypeError(".proto.SyncActionValue.markChatAsReadAction: object expected");
                message.markChatAsReadAction = $root.proto.MarkChatAsReadAction.fromObject(object.markChatAsReadAction);
            }
            if (object.clearChatAction != null) {
                if (typeof object.clearChatAction !== "object")
                    throw TypeError(".proto.SyncActionValue.clearChatAction: object expected");
                message.clearChatAction = $root.proto.ClearChatAction.fromObject(object.clearChatAction);
            }
            if (object.deleteChatAction != null) {
                if (typeof object.deleteChatAction !== "object")
                    throw TypeError(".proto.SyncActionValue.deleteChatAction: object expected");
                message.deleteChatAction = $root.proto.DeleteChatAction.fromObject(object.deleteChatAction);
            }
            if (object.unarchiveChatsSetting != null) {
                if (typeof object.unarchiveChatsSetting !== "object")
                    throw TypeError(".proto.SyncActionValue.unarchiveChatsSetting: object expected");
                message.unarchiveChatsSetting = $root.proto.UnarchiveChatsSetting.fromObject(object.unarchiveChatsSetting);
            }
            if (object.primaryFeature != null) {
                if (typeof object.primaryFeature !== "object")
                    throw TypeError(".proto.SyncActionValue.primaryFeature: object expected");
                message.primaryFeature = $root.proto.PrimaryFeature.fromObject(object.primaryFeature);
            }
            if (object.favoriteStickerAction != null) {
                if (typeof object.favoriteStickerAction !== "object")
                    throw TypeError(".proto.SyncActionValue.favoriteStickerAction: object expected");
                message.favoriteStickerAction = $root.proto.FavoriteStickerAction.fromObject(object.favoriteStickerAction);
            }
            if (object.androidUnsupportedActions != null) {
                if (typeof object.androidUnsupportedActions !== "object")
                    throw TypeError(".proto.SyncActionValue.androidUnsupportedActions: object expected");
                message.androidUnsupportedActions = $root.proto.AndroidUnsupportedActions.fromObject(object.androidUnsupportedActions);
            }
            return message;
        };

        /**
         * Creates a plain object from a SyncActionValue message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.SyncActionValue
         * @static
         * @param {proto.SyncActionValue} message SyncActionValue
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        SyncActionValue.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.timestamp = options.longs === String ? "0" : 0;
                object.starAction = null;
                object.contactAction = null;
                object.muteAction = null;
                object.pinAction = null;
                object.securityNotificationSetting = null;
                object.pushNameSetting = null;
                object.quickReplyAction = null;
                object.recentStickerWeightsAction = null;
                object.recentStickerMetadata = null;
                object.recentEmojiWeightsAction = null;
                object.labelEditAction = null;
                object.labelAssociationAction = null;
                object.localeSetting = null;
                object.archiveChatAction = null;
                object.deleteMessageForMeAction = null;
                object.keyExpiration = null;
                object.markChatAsReadAction = null;
                object.clearChatAction = null;
                object.deleteChatAction = null;
                object.unarchiveChatsSetting = null;
                object.primaryFeature = null;
                object.favoriteStickerAction = null;
                object.androidUnsupportedActions = null;
            }
            if (message.timestamp != null && message.hasOwnProperty("timestamp"))
                if (typeof message.timestamp === "number")
                    object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp;
                else
                    object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber() : message.timestamp;
            if (message.starAction != null && message.hasOwnProperty("starAction"))
                object.starAction = $root.proto.StarAction.toObject(message.starAction, options);
            if (message.contactAction != null && message.hasOwnProperty("contactAction"))
                object.contactAction = $root.proto.ContactAction.toObject(message.contactAction, options);
            if (message.muteAction != null && message.hasOwnProperty("muteAction"))
                object.muteAction = $root.proto.MuteAction.toObject(message.muteAction, options);
            if (message.pinAction != null && message.hasOwnProperty("pinAction"))
                object.pinAction = $root.proto.PinAction.toObject(message.pinAction, options);
            if (message.securityNotificationSetting != null && message.hasOwnProperty("securityNotificationSetting"))
                object.securityNotificationSetting = $root.proto.SecurityNotificationSetting.toObject(message.securityNotificationSetting, options);
            if (message.pushNameSetting != null && message.hasOwnProperty("pushNameSetting"))
                object.pushNameSetting = $root.proto.PushNameSetting.toObject(message.pushNameSetting, options);
            if (message.quickReplyAction != null && message.hasOwnProperty("quickReplyAction"))
                object.quickReplyAction = $root.proto.QuickReplyAction.toObject(message.quickReplyAction, options);
            if (message.recentStickerWeightsAction != null && message.hasOwnProperty("recentStickerWeightsAction"))
                object.recentStickerWeightsAction = $root.proto.RecentStickerWeightsAction.toObject(message.recentStickerWeightsAction, options);
            if (message.recentStickerMetadata != null && message.hasOwnProperty("recentStickerMetadata"))
                object.recentStickerMetadata = $root.proto.RecentStickerMetadata.toObject(message.recentStickerMetadata, options);
            if (message.recentEmojiWeightsAction != null && message.hasOwnProperty("recentEmojiWeightsAction"))
                object.recentEmojiWeightsAction = $root.proto.RecentEmojiWeightsAction.toObject(message.recentEmojiWeightsAction, options);
            if (message.labelEditAction != null && message.hasOwnProperty("labelEditAction"))
                object.labelEditAction = $root.proto.LabelEditAction.toObject(message.labelEditAction, options);
            if (message.labelAssociationAction != null && message.hasOwnProperty("labelAssociationAction"))
                object.labelAssociationAction = $root.proto.LabelAssociationAction.toObject(message.labelAssociationAction, options);
            if (message.localeSetting != null && message.hasOwnProperty("localeSetting"))
                object.localeSetting = $root.proto.LocaleSetting.toObject(message.localeSetting, options);
            if (message.archiveChatAction != null && message.hasOwnProperty("archiveChatAction"))
                object.archiveChatAction = $root.proto.ArchiveChatAction.toObject(message.archiveChatAction, options);
            if (message.deleteMessageForMeAction != null && message.hasOwnProperty("deleteMessageForMeAction"))
                object.deleteMessageForMeAction = $root.proto.DeleteMessageForMeAction.toObject(message.deleteMessageForMeAction, options);
            if (message.keyExpiration != null && message.hasOwnProperty("keyExpiration"))
                object.keyExpiration = $root.proto.KeyExpiration.toObject(message.keyExpiration, options);
            if (message.markChatAsReadAction != null && message.hasOwnProperty("markChatAsReadAction"))
                object.markChatAsReadAction = $root.proto.MarkChatAsReadAction.toObject(message.markChatAsReadAction, options);
            if (message.clearChatAction != null && message.hasOwnProperty("clearChatAction"))
                object.clearChatAction = $root.proto.ClearChatAction.toObject(message.clearChatAction, options);
            if (message.deleteChatAction != null && message.hasOwnProperty("deleteChatAction"))
                object.deleteChatAction = $root.proto.DeleteChatAction.toObject(message.deleteChatAction, options);
            if (message.unarchiveChatsSetting != null && message.hasOwnProperty("unarchiveChatsSetting"))
                object.unarchiveChatsSetting = $root.proto.UnarchiveChatsSetting.toObject(message.unarchiveChatsSetting, options);
            if (message.primaryFeature != null && message.hasOwnProperty("primaryFeature"))
                object.primaryFeature = $root.proto.PrimaryFeature.toObject(message.primaryFeature, options);
            if (message.favoriteStickerAction != null && message.hasOwnProperty("favoriteStickerAction"))
                object.favoriteStickerAction = $root.proto.FavoriteStickerAction.toObject(message.favoriteStickerAction, options);
            if (message.androidUnsupportedActions != null && message.hasOwnProperty("androidUnsupportedActions"))
                object.androidUnsupportedActions = $root.proto.AndroidUnsupportedActions.toObject(message.androidUnsupportedActions, options);
            return object;
        };

        /**
         * Converts this SyncActionValue to JSON.
         * @function toJSON
         * @memberof proto.SyncActionValue
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        SyncActionValue.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return SyncActionValue;
    })();

    proto.RecentEmojiWeight = (function() {

        /**
         * Properties of a RecentEmojiWeight.
         * @memberof proto
         * @interface IRecentEmojiWeight
         * @property {string|null} [emoji] RecentEmojiWeight emoji
         * @property {number|null} [weight] RecentEmojiWeight weight
         */

        /**
         * Constructs a new RecentEmojiWeight.
         * @memberof proto
         * @classdesc Represents a RecentEmojiWeight.
         * @implements IRecentEmojiWeight
         * @constructor
         * @param {proto.IRecentEmojiWeight=} [properties] Properties to set
         */
        function RecentEmojiWeight(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * RecentEmojiWeight emoji.
         * @member {string} emoji
         * @memberof proto.RecentEmojiWeight
         * @instance
         */
        RecentEmojiWeight.prototype.emoji = "";

        /**
         * RecentEmojiWeight weight.
         * @member {number} weight
         * @memberof proto.RecentEmojiWeight
         * @instance
         */
        RecentEmojiWeight.prototype.weight = 0;

        /**
         * Creates a new RecentEmojiWeight instance using the specified properties.
         * @function create
         * @memberof proto.RecentEmojiWeight
         * @static
         * @param {proto.IRecentEmojiWeight=} [properties] Properties to set
         * @returns {proto.RecentEmojiWeight} RecentEmojiWeight instance
         */
        RecentEmojiWeight.create = function create(properties) {
            return new RecentEmojiWeight(properties);
        };

        /**
         * Encodes the specified RecentEmojiWeight message. Does not implicitly {@link proto.RecentEmojiWeight.verify|verify} messages.
         * @function encode
         * @memberof proto.RecentEmojiWeight
         * @static
         * @param {proto.IRecentEmojiWeight} message RecentEmojiWeight message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RecentEmojiWeight.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.emoji != null && Object.hasOwnProperty.call(message, "emoji"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.emoji);
            if (message.weight != null && Object.hasOwnProperty.call(message, "weight"))
                writer.uint32(/* id 2, wireType 5 =*/21).float(message.weight);
            return writer;
        };

        /**
         * Encodes the specified RecentEmojiWeight message, length delimited. Does not implicitly {@link proto.RecentEmojiWeight.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.RecentEmojiWeight
         * @static
         * @param {proto.IRecentEmojiWeight} message RecentEmojiWeight message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RecentEmojiWeight.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a RecentEmojiWeight message from the specified reader or buffer.
         * @function decode
         * @memberof proto.RecentEmojiWeight
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.RecentEmojiWeight} RecentEmojiWeight
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RecentEmojiWeight.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.RecentEmojiWeight();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.emoji = reader.string();
                    break;
                case 2:
                    message.weight = reader.float();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a RecentEmojiWeight message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.RecentEmojiWeight
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.RecentEmojiWeight} RecentEmojiWeight
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RecentEmojiWeight.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a RecentEmojiWeight message.
         * @function verify
         * @memberof proto.RecentEmojiWeight
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        RecentEmojiWeight.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.emoji != null && message.hasOwnProperty("emoji"))
                if (!$util.isString(message.emoji))
                    return "emoji: string expected";
            if (message.weight != null && message.hasOwnProperty("weight"))
                if (typeof message.weight !== "number")
                    return "weight: number expected";
            return null;
        };

        /**
         * Creates a RecentEmojiWeight message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.RecentEmojiWeight
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.RecentEmojiWeight} RecentEmojiWeight
         */
        RecentEmojiWeight.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.RecentEmojiWeight)
                return object;
            var message = new $root.proto.RecentEmojiWeight();
            if (object.emoji != null)
                message.emoji = String(object.emoji);
            if (object.weight != null)
                message.weight = Number(object.weight);
            return message;
        };

        /**
         * Creates a plain object from a RecentEmojiWeight message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.RecentEmojiWeight
         * @static
         * @param {proto.RecentEmojiWeight} message RecentEmojiWeight
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        RecentEmojiWeight.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.emoji = "";
                object.weight = 0;
            }
            if (message.emoji != null && message.hasOwnProperty("emoji"))
                object.emoji = message.emoji;
            if (message.weight != null && message.hasOwnProperty("weight"))
                object.weight = options.json && !isFinite(message.weight) ? String(message.weight) : message.weight;
            return object;
        };

        /**
         * Converts this RecentEmojiWeight to JSON.
         * @function toJSON
         * @memberof proto.RecentEmojiWeight
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        RecentEmojiWeight.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return RecentEmojiWeight;
    })();

    proto.RecentStickerWeight = (function() {

        /**
         * Properties of a RecentStickerWeight.
         * @memberof proto
         * @interface IRecentStickerWeight
         * @property {string|null} [filehash] RecentStickerWeight filehash
         * @property {number|null} [weight] RecentStickerWeight weight
         */

        /**
         * Constructs a new RecentStickerWeight.
         * @memberof proto
         * @classdesc Represents a RecentStickerWeight.
         * @implements IRecentStickerWeight
         * @constructor
         * @param {proto.IRecentStickerWeight=} [properties] Properties to set
         */
        function RecentStickerWeight(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * RecentStickerWeight filehash.
         * @member {string} filehash
         * @memberof proto.RecentStickerWeight
         * @instance
         */
        RecentStickerWeight.prototype.filehash = "";

        /**
         * RecentStickerWeight weight.
         * @member {number} weight
         * @memberof proto.RecentStickerWeight
         * @instance
         */
        RecentStickerWeight.prototype.weight = 0;

        /**
         * Creates a new RecentStickerWeight instance using the specified properties.
         * @function create
         * @memberof proto.RecentStickerWeight
         * @static
         * @param {proto.IRecentStickerWeight=} [properties] Properties to set
         * @returns {proto.RecentStickerWeight} RecentStickerWeight instance
         */
        RecentStickerWeight.create = function create(properties) {
            return new RecentStickerWeight(properties);
        };

        /**
         * Encodes the specified RecentStickerWeight message. Does not implicitly {@link proto.RecentStickerWeight.verify|verify} messages.
         * @function encode
         * @memberof proto.RecentStickerWeight
         * @static
         * @param {proto.IRecentStickerWeight} message RecentStickerWeight message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RecentStickerWeight.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.filehash != null && Object.hasOwnProperty.call(message, "filehash"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.filehash);
            if (message.weight != null && Object.hasOwnProperty.call(message, "weight"))
                writer.uint32(/* id 2, wireType 5 =*/21).float(message.weight);
            return writer;
        };

        /**
         * Encodes the specified RecentStickerWeight message, length delimited. Does not implicitly {@link proto.RecentStickerWeight.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.RecentStickerWeight
         * @static
         * @param {proto.IRecentStickerWeight} message RecentStickerWeight message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RecentStickerWeight.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a RecentStickerWeight message from the specified reader or buffer.
         * @function decode
         * @memberof proto.RecentStickerWeight
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.RecentStickerWeight} RecentStickerWeight
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RecentStickerWeight.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.RecentStickerWeight();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.filehash = reader.string();
                    break;
                case 2:
                    message.weight = reader.float();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a RecentStickerWeight message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.RecentStickerWeight
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.RecentStickerWeight} RecentStickerWeight
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RecentStickerWeight.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a RecentStickerWeight message.
         * @function verify
         * @memberof proto.RecentStickerWeight
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        RecentStickerWeight.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.filehash != null && message.hasOwnProperty("filehash"))
                if (!$util.isString(message.filehash))
                    return "filehash: string expected";
            if (message.weight != null && message.hasOwnProperty("weight"))
                if (typeof message.weight !== "number")
                    return "weight: number expected";
            return null;
        };

        /**
         * Creates a RecentStickerWeight message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.RecentStickerWeight
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.RecentStickerWeight} RecentStickerWeight
         */
        RecentStickerWeight.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.RecentStickerWeight)
                return object;
            var message = new $root.proto.RecentStickerWeight();
            if (object.filehash != null)
                message.filehash = String(object.filehash);
            if (object.weight != null)
                message.weight = Number(object.weight);
            return message;
        };

        /**
         * Creates a plain object from a RecentStickerWeight message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.RecentStickerWeight
         * @static
         * @param {proto.RecentStickerWeight} message RecentStickerWeight
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        RecentStickerWeight.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.filehash = "";
                object.weight = 0;
            }
            if (message.filehash != null && message.hasOwnProperty("filehash"))
                object.filehash = message.filehash;
            if (message.weight != null && message.hasOwnProperty("weight"))
                object.weight = options.json && !isFinite(message.weight) ? String(message.weight) : message.weight;
            return object;
        };

        /**
         * Converts this RecentStickerWeight to JSON.
         * @function toJSON
         * @memberof proto.RecentStickerWeight
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        RecentStickerWeight.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return RecentStickerWeight;
    })();

    proto.SyncdPatch = (function() {

        /**
         * Properties of a SyncdPatch.
         * @memberof proto
         * @interface ISyncdPatch
         * @property {proto.ISyncdVersion|null} [version] SyncdPatch version
         * @property {Array.<proto.ISyncdMutation>|null} [mutations] SyncdPatch mutations
         * @property {proto.IExternalBlobReference|null} [externalMutations] SyncdPatch externalMutations
         * @property {Uint8Array|null} [snapshotMac] SyncdPatch snapshotMac
         * @property {Uint8Array|null} [patchMac] SyncdPatch patchMac
         * @property {proto.IKeyId|null} [keyId] SyncdPatch keyId
         * @property {proto.IExitCode|null} [exitCode] SyncdPatch exitCode
         * @property {number|null} [deviceIndex] SyncdPatch deviceIndex
         */

        /**
         * Constructs a new SyncdPatch.
         * @memberof proto
         * @classdesc Represents a SyncdPatch.
         * @implements ISyncdPatch
         * @constructor
         * @param {proto.ISyncdPatch=} [properties] Properties to set
         */
        function SyncdPatch(properties) {
            this.mutations = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * SyncdPatch version.
         * @member {proto.ISyncdVersion|null|undefined} version
         * @memberof proto.SyncdPatch
         * @instance
         */
        SyncdPatch.prototype.version = null;

        /**
         * SyncdPatch mutations.
         * @member {Array.<proto.ISyncdMutation>} mutations
         * @memberof proto.SyncdPatch
         * @instance
         */
        SyncdPatch.prototype.mutations = $util.emptyArray;

        /**
         * SyncdPatch externalMutations.
         * @member {proto.IExternalBlobReference|null|undefined} externalMutations
         * @memberof proto.SyncdPatch
         * @instance
         */
        SyncdPatch.prototype.externalMutations = null;

        /**
         * SyncdPatch snapshotMac.
         * @member {Uint8Array} snapshotMac
         * @memberof proto.SyncdPatch
         * @instance
         */
        SyncdPatch.prototype.snapshotMac = $util.newBuffer([]);

        /**
         * SyncdPatch patchMac.
         * @member {Uint8Array} patchMac
         * @memberof proto.SyncdPatch
         * @instance
         */
        SyncdPatch.prototype.patchMac = $util.newBuffer([]);

        /**
         * SyncdPatch keyId.
         * @member {proto.IKeyId|null|undefined} keyId
         * @memberof proto.SyncdPatch
         * @instance
         */
        SyncdPatch.prototype.keyId = null;

        /**
         * SyncdPatch exitCode.
         * @member {proto.IExitCode|null|undefined} exitCode
         * @memberof proto.SyncdPatch
         * @instance
         */
        SyncdPatch.prototype.exitCode = null;

        /**
         * SyncdPatch deviceIndex.
         * @member {number} deviceIndex
         * @memberof proto.SyncdPatch
         * @instance
         */
        SyncdPatch.prototype.deviceIndex = 0;

        /**
         * Creates a new SyncdPatch instance using the specified properties.
         * @function create
         * @memberof proto.SyncdPatch
         * @static
         * @param {proto.ISyncdPatch=} [properties] Properties to set
         * @returns {proto.SyncdPatch} SyncdPatch instance
         */
        SyncdPatch.create = function create(properties) {
            return new SyncdPatch(properties);
        };

        /**
         * Encodes the specified SyncdPatch message. Does not implicitly {@link proto.SyncdPatch.verify|verify} messages.
         * @function encode
         * @memberof proto.SyncdPatch
         * @static
         * @param {proto.ISyncdPatch} message SyncdPatch message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SyncdPatch.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.version != null && Object.hasOwnProperty.call(message, "version"))
                $root.proto.SyncdVersion.encode(message.version, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.mutations != null && message.mutations.length)
                for (var i = 0; i < message.mutations.length; ++i)
                    $root.proto.SyncdMutation.encode(message.mutations[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.externalMutations != null && Object.hasOwnProperty.call(message, "externalMutations"))
                $root.proto.ExternalBlobReference.encode(message.externalMutations, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.snapshotMac != null && Object.hasOwnProperty.call(message, "snapshotMac"))
                writer.uint32(/* id 4, wireType 2 =*/34).bytes(message.snapshotMac);
            if (message.patchMac != null && Object.hasOwnProperty.call(message, "patchMac"))
                writer.uint32(/* id 5, wireType 2 =*/42).bytes(message.patchMac);
            if (message.keyId != null && Object.hasOwnProperty.call(message, "keyId"))
                $root.proto.KeyId.encode(message.keyId, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim();
            if (message.exitCode != null && Object.hasOwnProperty.call(message, "exitCode"))
                $root.proto.ExitCode.encode(message.exitCode, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim();
            if (message.deviceIndex != null && Object.hasOwnProperty.call(message, "deviceIndex"))
                writer.uint32(/* id 8, wireType 0 =*/64).uint32(message.deviceIndex);
            return writer;
        };

        /**
         * Encodes the specified SyncdPatch message, length delimited. Does not implicitly {@link proto.SyncdPatch.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.SyncdPatch
         * @static
         * @param {proto.ISyncdPatch} message SyncdPatch message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SyncdPatch.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a SyncdPatch message from the specified reader or buffer.
         * @function decode
         * @memberof proto.SyncdPatch
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.SyncdPatch} SyncdPatch
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SyncdPatch.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdPatch();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.version = $root.proto.SyncdVersion.decode(reader, reader.uint32());
                    break;
                case 2:
                    if (!(message.mutations && message.mutations.length))
                        message.mutations = [];
                    message.mutations.push($root.proto.SyncdMutation.decode(reader, reader.uint32()));
                    break;
                case 3:
                    message.externalMutations = $root.proto.ExternalBlobReference.decode(reader, reader.uint32());
                    break;
                case 4:
                    message.snapshotMac = reader.bytes();
                    break;
                case 5:
                    message.patchMac = reader.bytes();
                    break;
                case 6:
                    message.keyId = $root.proto.KeyId.decode(reader, reader.uint32());
                    break;
                case 7:
                    message.exitCode = $root.proto.ExitCode.decode(reader, reader.uint32());
                    break;
                case 8:
                    message.deviceIndex = reader.uint32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a SyncdPatch message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.SyncdPatch
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.SyncdPatch} SyncdPatch
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SyncdPatch.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a SyncdPatch message.
         * @function verify
         * @memberof proto.SyncdPatch
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        SyncdPatch.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.version != null && message.hasOwnProperty("version")) {
                var error = $root.proto.SyncdVersion.verify(message.version);
                if (error)
                    return "version." + error;
            }
            if (message.mutations != null && message.hasOwnProperty("mutations")) {
                if (!Array.isArray(message.mutations))
                    return "mutations: array expected";
                for (var i = 0; i < message.mutations.length; ++i) {
                    var error = $root.proto.SyncdMutation.verify(message.mutations[i]);
                    if (error)
                        return "mutations." + error;
                }
            }
            if (message.externalMutations != null && message.hasOwnProperty("externalMutations")) {
                var error = $root.proto.ExternalBlobReference.verify(message.externalMutations);
                if (error)
                    return "externalMutations." + error;
            }
            if (message.snapshotMac != null && message.hasOwnProperty("snapshotMac"))
                if (!(message.snapshotMac && typeof message.snapshotMac.length === "number" || $util.isString(message.snapshotMac)))
                    return "snapshotMac: buffer expected";
            if (message.patchMac != null && message.hasOwnProperty("patchMac"))
                if (!(message.patchMac && typeof message.patchMac.length === "number" || $util.isString(message.patchMac)))
                    return "patchMac: buffer expected";
            if (message.keyId != null && message.hasOwnProperty("keyId")) {
                var error = $root.proto.KeyId.verify(message.keyId);
                if (error)
                    return "keyId." + error;
            }
            if (message.exitCode != null && message.hasOwnProperty("exitCode")) {
                var error = $root.proto.ExitCode.verify(message.exitCode);
                if (error)
                    return "exitCode." + error;
            }
            if (message.deviceIndex != null && message.hasOwnProperty("deviceIndex"))
                if (!$util.isInteger(message.deviceIndex))
                    return "deviceIndex: integer expected";
            return null;
        };

        /**
         * Creates a SyncdPatch message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.SyncdPatch
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.SyncdPatch} SyncdPatch
         */
        SyncdPatch.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.SyncdPatch)
                return object;
            var message = new $root.proto.SyncdPatch();
            if (object.version != null) {
                if (typeof object.version !== "object")
                    throw TypeError(".proto.SyncdPatch.version: object expected");
                message.version = $root.proto.SyncdVersion.fromObject(object.version);
            }
            if (object.mutations) {
                if (!Array.isArray(object.mutations))
                    throw TypeError(".proto.SyncdPatch.mutations: array expected");
                message.mutations = [];
                for (var i = 0; i < object.mutations.length; ++i) {
                    if (typeof object.mutations[i] !== "object")
                        throw TypeError(".proto.SyncdPatch.mutations: object expected");
                    message.mutations[i] = $root.proto.SyncdMutation.fromObject(object.mutations[i]);
                }
            }
            if (object.externalMutations != null) {
                if (typeof object.externalMutations !== "object")
                    throw TypeError(".proto.SyncdPatch.externalMutations: object expected");
                message.externalMutations = $root.proto.ExternalBlobReference.fromObject(object.externalMutations);
            }
            if (object.snapshotMac != null)
                if (typeof object.snapshotMac === "string")
                    $util.base64.decode(object.snapshotMac, message.snapshotMac = $util.newBuffer($util.base64.length(object.snapshotMac)), 0);
                else if (object.snapshotMac.length)
                    message.snapshotMac = object.snapshotMac;
            if (object.patchMac != null)
                if (typeof object.patchMac === "string")
                    $util.base64.decode(object.patchMac, message.patchMac = $util.newBuffer($util.base64.length(object.patchMac)), 0);
                else if (object.patchMac.length)
                    message.patchMac = object.patchMac;
            if (object.keyId != null) {
                if (typeof object.keyId !== "object")
                    throw TypeError(".proto.SyncdPatch.keyId: object expected");
                message.keyId = $root.proto.KeyId.fromObject(object.keyId);
            }
            if (object.exitCode != null) {
                if (typeof object.exitCode !== "object")
                    throw TypeError(".proto.SyncdPatch.exitCode: object expected");
                message.exitCode = $root.proto.ExitCode.fromObject(object.exitCode);
            }
            if (object.deviceIndex != null)
                message.deviceIndex = object.deviceIndex >>> 0;
            return message;
        };

        /**
         * Creates a plain object from a SyncdPatch message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.SyncdPatch
         * @static
         * @param {proto.SyncdPatch} message SyncdPatch
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        SyncdPatch.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.mutations = [];
            if (options.defaults) {
                object.version = null;
                object.externalMutations = null;
                if (options.bytes === String)
                    object.snapshotMac = "";
                else {
                    object.snapshotMac = [];
                    if (options.bytes !== Array)
                        object.snapshotMac = $util.newBuffer(object.snapshotMac);
                }
                if (options.bytes === String)
                    object.patchMac = "";
                else {
                    object.patchMac = [];
                    if (options.bytes !== Array)
                        object.patchMac = $util.newBuffer(object.patchMac);
                }
                object.keyId = null;
                object.exitCode = null;
                object.deviceIndex = 0;
            }
            if (message.version != null && message.hasOwnProperty("version"))
                object.version = $root.proto.SyncdVersion.toObject(message.version, options);
            if (message.mutations && message.mutations.length) {
                object.mutations = [];
                for (var j = 0; j < message.mutations.length; ++j)
                    object.mutations[j] = $root.proto.SyncdMutation.toObject(message.mutations[j], options);
            }
            if (message.externalMutations != null && message.hasOwnProperty("externalMutations"))
                object.externalMutations = $root.proto.ExternalBlobReference.toObject(message.externalMutations, options);
            if (message.snapshotMac != null && message.hasOwnProperty("snapshotMac"))
                object.snapshotMac = options.bytes === String ? $util.base64.encode(message.snapshotMac, 0, message.snapshotMac.length) : options.bytes === Array ? Array.prototype.slice.call(message.snapshotMac) : message.snapshotMac;
            if (message.patchMac != null && message.hasOwnProperty("patchMac"))
                object.patchMac = options.bytes === String ? $util.base64.encode(message.patchMac, 0, message.patchMac.length) : options.bytes === Array ? Array.prototype.slice.call(message.patchMac) : message.patchMac;
            if (message.keyId != null && message.hasOwnProperty("keyId"))
                object.keyId = $root.proto.KeyId.toObject(message.keyId, options);
            if (message.exitCode != null && message.hasOwnProperty("exitCode"))
                object.exitCode = $root.proto.ExitCode.toObject(message.exitCode, options);
            if (message.deviceIndex != null && message.hasOwnProperty("deviceIndex"))
                object.deviceIndex = message.deviceIndex;
            return object;
        };

        /**
         * Converts this SyncdPatch to JSON.
         * @function toJSON
         * @memberof proto.SyncdPatch
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        SyncdPatch.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return SyncdPatch;
    })();

    proto.SyncdMutation = (function() {

        /**
         * Properties of a SyncdMutation.
         * @memberof proto
         * @interface ISyncdMutation
         * @property {proto.SyncdMutation.SyncdMutationSyncdOperation|null} [operation] SyncdMutation operation
         * @property {proto.ISyncdRecord|null} [record] SyncdMutation record
         */

        /**
         * Constructs a new SyncdMutation.
         * @memberof proto
         * @classdesc Represents a SyncdMutation.
         * @implements ISyncdMutation
         * @constructor
         * @param {proto.ISyncdMutation=} [properties] Properties to set
         */
        function SyncdMutation(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * SyncdMutation operation.
         * @member {proto.SyncdMutation.SyncdMutationSyncdOperation} operation
         * @memberof proto.SyncdMutation
         * @instance
         */
        SyncdMutation.prototype.operation = 0;

        /**
         * SyncdMutation record.
         * @member {proto.ISyncdRecord|null|undefined} record
         * @memberof proto.SyncdMutation
         * @instance
         */
        SyncdMutation.prototype.record = null;

        /**
         * Creates a new SyncdMutation instance using the specified properties.
         * @function create
         * @memberof proto.SyncdMutation
         * @static
         * @param {proto.ISyncdMutation=} [properties] Properties to set
         * @returns {proto.SyncdMutation} SyncdMutation instance
         */
        SyncdMutation.create = function create(properties) {
            return new SyncdMutation(properties);
        };

        /**
         * Encodes the specified SyncdMutation message. Does not implicitly {@link proto.SyncdMutation.verify|verify} messages.
         * @function encode
         * @memberof proto.SyncdMutation
         * @static
         * @param {proto.ISyncdMutation} message SyncdMutation message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SyncdMutation.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.operation != null && Object.hasOwnProperty.call(message, "operation"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.operation);
            if (message.record != null && Object.hasOwnProperty.call(message, "record"))
                $root.proto.SyncdRecord.encode(message.record, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified SyncdMutation message, length delimited. Does not implicitly {@link proto.SyncdMutation.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.SyncdMutation
         * @static
         * @param {proto.ISyncdMutation} message SyncdMutation message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SyncdMutation.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a SyncdMutation message from the specified reader or buffer.
         * @function decode
         * @memberof proto.SyncdMutation
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.SyncdMutation} SyncdMutation
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SyncdMutation.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdMutation();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.operation = reader.int32();
                    break;
                case 2:
                    message.record = $root.proto.SyncdRecord.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a SyncdMutation message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.SyncdMutation
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.SyncdMutation} SyncdMutation
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SyncdMutation.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a SyncdMutation message.
         * @function verify
         * @memberof proto.SyncdMutation
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        SyncdMutation.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.operation != null && message.hasOwnProperty("operation"))
                switch (message.operation) {
                default:
                    return "operation: enum value expected";
                case 0:
                case 1:
                    break;
                }
            if (message.record != null && message.hasOwnProperty("record")) {
                var error = $root.proto.SyncdRecord.verify(message.record);
                if (error)
                    return "record." + error;
            }
            return null;
        };

        /**
         * Creates a SyncdMutation message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.SyncdMutation
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.SyncdMutation} SyncdMutation
         */
        SyncdMutation.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.SyncdMutation)
                return object;
            var message = new $root.proto.SyncdMutation();
            switch (object.operation) {
            case "SET":
            case 0:
                message.operation = 0;
                break;
            case "REMOVE":
            case 1:
                message.operation = 1;
                break;
            }
            if (object.record != null) {
                if (typeof object.record !== "object")
                    throw TypeError(".proto.SyncdMutation.record: object expected");
                message.record = $root.proto.SyncdRecord.fromObject(object.record);
            }
            return message;
        };

        /**
         * Creates a plain object from a SyncdMutation message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.SyncdMutation
         * @static
         * @param {proto.SyncdMutation} message SyncdMutation
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        SyncdMutation.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.operation = options.enums === String ? "SET" : 0;
                object.record = null;
            }
            if (message.operation != null && message.hasOwnProperty("operation"))
                object.operation = options.enums === String ? $root.proto.SyncdMutation.SyncdMutationSyncdOperation[message.operation] : message.operation;
            if (message.record != null && message.hasOwnProperty("record"))
                object.record = $root.proto.SyncdRecord.toObject(message.record, options);
            return object;
        };

        /**
         * Converts this SyncdMutation to JSON.
         * @function toJSON
         * @memberof proto.SyncdMutation
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        SyncdMutation.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * SyncdMutationSyncdOperation enum.
         * @name proto.SyncdMutation.SyncdMutationSyncdOperation
         * @enum {number}
         * @property {number} SET=0 SET value
         * @property {number} REMOVE=1 REMOVE value
         */
        SyncdMutation.SyncdMutationSyncdOperation = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "SET"] = 0;
            values[valuesById[1] = "REMOVE"] = 1;
            return values;
        })();

        return SyncdMutation;
    })();

    proto.SyncdMutations = (function() {

        /**
         * Properties of a SyncdMutations.
         * @memberof proto
         * @interface ISyncdMutations
         * @property {Array.<proto.ISyncdMutation>|null} [mutations] SyncdMutations mutations
         */

        /**
         * Constructs a new SyncdMutations.
         * @memberof proto
         * @classdesc Represents a SyncdMutations.
         * @implements ISyncdMutations
         * @constructor
         * @param {proto.ISyncdMutations=} [properties] Properties to set
         */
        function SyncdMutations(properties) {
            this.mutations = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * SyncdMutations mutations.
         * @member {Array.<proto.ISyncdMutation>} mutations
         * @memberof proto.SyncdMutations
         * @instance
         */
        SyncdMutations.prototype.mutations = $util.emptyArray;

        /**
         * Creates a new SyncdMutations instance using the specified properties.
         * @function create
         * @memberof proto.SyncdMutations
         * @static
         * @param {proto.ISyncdMutations=} [properties] Properties to set
         * @returns {proto.SyncdMutations} SyncdMutations instance
         */
        SyncdMutations.create = function create(properties) {
            return new SyncdMutations(properties);
        };

        /**
         * Encodes the specified SyncdMutations message. Does not implicitly {@link proto.SyncdMutations.verify|verify} messages.
         * @function encode
         * @memberof proto.SyncdMutations
         * @static
         * @param {proto.ISyncdMutations} message SyncdMutations message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SyncdMutations.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.mutations != null && message.mutations.length)
                for (var i = 0; i < message.mutations.length; ++i)
                    $root.proto.SyncdMutation.encode(message.mutations[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified SyncdMutations message, length delimited. Does not implicitly {@link proto.SyncdMutations.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.SyncdMutations
         * @static
         * @param {proto.ISyncdMutations} message SyncdMutations message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SyncdMutations.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a SyncdMutations message from the specified reader or buffer.
         * @function decode
         * @memberof proto.SyncdMutations
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.SyncdMutations} SyncdMutations
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SyncdMutations.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdMutations();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    if (!(message.mutations && message.mutations.length))
                        message.mutations = [];
                    message.mutations.push($root.proto.SyncdMutation.decode(reader, reader.uint32()));
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a SyncdMutations message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.SyncdMutations
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.SyncdMutations} SyncdMutations
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SyncdMutations.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a SyncdMutations message.
         * @function verify
         * @memberof proto.SyncdMutations
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        SyncdMutations.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.mutations != null && message.hasOwnProperty("mutations")) {
                if (!Array.isArray(message.mutations))
                    return "mutations: array expected";
                for (var i = 0; i < message.mutations.length; ++i) {
                    var error = $root.proto.SyncdMutation.verify(message.mutations[i]);
                    if (error)
                        return "mutations." + error;
                }
            }
            return null;
        };

        /**
         * Creates a SyncdMutations message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.SyncdMutations
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.SyncdMutations} SyncdMutations
         */
        SyncdMutations.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.SyncdMutations)
                return object;
            var message = new $root.proto.SyncdMutations();
            if (object.mutations) {
                if (!Array.isArray(object.mutations))
                    throw TypeError(".proto.SyncdMutations.mutations: array expected");
                message.mutations = [];
                for (var i = 0; i < object.mutations.length; ++i) {
                    if (typeof object.mutations[i] !== "object")
                        throw TypeError(".proto.SyncdMutations.mutations: object expected");
                    message.mutations[i] = $root.proto.SyncdMutation.fromObject(object.mutations[i]);
                }
            }
            return message;
        };

        /**
         * Creates a plain object from a SyncdMutations message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.SyncdMutations
         * @static
         * @param {proto.SyncdMutations} message SyncdMutations
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        SyncdMutations.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.mutations = [];
            if (message.mutations && message.mutations.length) {
                object.mutations = [];
                for (var j = 0; j < message.mutations.length; ++j)
                    object.mutations[j] = $root.proto.SyncdMutation.toObject(message.mutations[j], options);
            }
            return object;
        };

        /**
         * Converts this SyncdMutations to JSON.
         * @function toJSON
         * @memberof proto.SyncdMutations
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        SyncdMutations.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return SyncdMutations;
    })();

    proto.SyncdSnapshot = (function() {

        /**
         * Properties of a SyncdSnapshot.
         * @memberof proto
         * @interface ISyncdSnapshot
         * @property {proto.ISyncdVersion|null} [version] SyncdSnapshot version
         * @property {Array.<proto.ISyncdRecord>|null} [records] SyncdSnapshot records
         * @property {Uint8Array|null} [mac] SyncdSnapshot mac
         * @property {proto.IKeyId|null} [keyId] SyncdSnapshot keyId
         */

        /**
         * Constructs a new SyncdSnapshot.
         * @memberof proto
         * @classdesc Represents a SyncdSnapshot.
         * @implements ISyncdSnapshot
         * @constructor
         * @param {proto.ISyncdSnapshot=} [properties] Properties to set
         */
        function SyncdSnapshot(properties) {
            this.records = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * SyncdSnapshot version.
         * @member {proto.ISyncdVersion|null|undefined} version
         * @memberof proto.SyncdSnapshot
         * @instance
         */
        SyncdSnapshot.prototype.version = null;

        /**
         * SyncdSnapshot records.
         * @member {Array.<proto.ISyncdRecord>} records
         * @memberof proto.SyncdSnapshot
         * @instance
         */
        SyncdSnapshot.prototype.records = $util.emptyArray;

        /**
         * SyncdSnapshot mac.
         * @member {Uint8Array} mac
         * @memberof proto.SyncdSnapshot
         * @instance
         */
        SyncdSnapshot.prototype.mac = $util.newBuffer([]);

        /**
         * SyncdSnapshot keyId.
         * @member {proto.IKeyId|null|undefined} keyId
         * @memberof proto.SyncdSnapshot
         * @instance
         */
        SyncdSnapshot.prototype.keyId = null;

        /**
         * Creates a new SyncdSnapshot instance using the specified properties.
         * @function create
         * @memberof proto.SyncdSnapshot
         * @static
         * @param {proto.ISyncdSnapshot=} [properties] Properties to set
         * @returns {proto.SyncdSnapshot} SyncdSnapshot instance
         */
        SyncdSnapshot.create = function create(properties) {
            return new SyncdSnapshot(properties);
        };

        /**
         * Encodes the specified SyncdSnapshot message. Does not implicitly {@link proto.SyncdSnapshot.verify|verify} messages.
         * @function encode
         * @memberof proto.SyncdSnapshot
         * @static
         * @param {proto.ISyncdSnapshot} message SyncdSnapshot message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SyncdSnapshot.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.version != null && Object.hasOwnProperty.call(message, "version"))
                $root.proto.SyncdVersion.encode(message.version, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.records != null && message.records.length)
                for (var i = 0; i < message.records.length; ++i)
                    $root.proto.SyncdRecord.encode(message.records[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.mac != null && Object.hasOwnProperty.call(message, "mac"))
                writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.mac);
            if (message.keyId != null && Object.hasOwnProperty.call(message, "keyId"))
                $root.proto.KeyId.encode(message.keyId, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified SyncdSnapshot message, length delimited. Does not implicitly {@link proto.SyncdSnapshot.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.SyncdSnapshot
         * @static
         * @param {proto.ISyncdSnapshot} message SyncdSnapshot message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SyncdSnapshot.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a SyncdSnapshot message from the specified reader or buffer.
         * @function decode
         * @memberof proto.SyncdSnapshot
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.SyncdSnapshot} SyncdSnapshot
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SyncdSnapshot.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdSnapshot();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.version = $root.proto.SyncdVersion.decode(reader, reader.uint32());
                    break;
                case 2:
                    if (!(message.records && message.records.length))
                        message.records = [];
                    message.records.push($root.proto.SyncdRecord.decode(reader, reader.uint32()));
                    break;
                case 3:
                    message.mac = reader.bytes();
                    break;
                case 4:
                    message.keyId = $root.proto.KeyId.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a SyncdSnapshot message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.SyncdSnapshot
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.SyncdSnapshot} SyncdSnapshot
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SyncdSnapshot.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a SyncdSnapshot message.
         * @function verify
         * @memberof proto.SyncdSnapshot
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        SyncdSnapshot.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.version != null && message.hasOwnProperty("version")) {
                var error = $root.proto.SyncdVersion.verify(message.version);
                if (error)
                    return "version." + error;
            }
            if (message.records != null && message.hasOwnProperty("records")) {
                if (!Array.isArray(message.records))
                    return "records: array expected";
                for (var i = 0; i < message.records.length; ++i) {
                    var error = $root.proto.SyncdRecord.verify(message.records[i]);
                    if (error)
                        return "records." + error;
                }
            }
            if (message.mac != null && message.hasOwnProperty("mac"))
                if (!(message.mac && typeof message.mac.length === "number" || $util.isString(message.mac)))
                    return "mac: buffer expected";
            if (message.keyId != null && message.hasOwnProperty("keyId")) {
                var error = $root.proto.KeyId.verify(message.keyId);
                if (error)
                    return "keyId." + error;
            }
            return null;
        };

        /**
         * Creates a SyncdSnapshot message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.SyncdSnapshot
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.SyncdSnapshot} SyncdSnapshot
         */
        SyncdSnapshot.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.SyncdSnapshot)
                return object;
            var message = new $root.proto.SyncdSnapshot();
            if (object.version != null) {
                if (typeof object.version !== "object")
                    throw TypeError(".proto.SyncdSnapshot.version: object expected");
                message.version = $root.proto.SyncdVersion.fromObject(object.version);
            }
            if (object.records) {
                if (!Array.isArray(object.records))
                    throw TypeError(".proto.SyncdSnapshot.records: array expected");
                message.records = [];
                for (var i = 0; i < object.records.length; ++i) {
                    if (typeof object.records[i] !== "object")
                        throw TypeError(".proto.SyncdSnapshot.records: object expected");
                    message.records[i] = $root.proto.SyncdRecord.fromObject(object.records[i]);
                }
            }
            if (object.mac != null)
                if (typeof object.mac === "string")
                    $util.base64.decode(object.mac, message.mac = $util.newBuffer($util.base64.length(object.mac)), 0);
                else if (object.mac.length)
                    message.mac = object.mac;
            if (object.keyId != null) {
                if (typeof object.keyId !== "object")
                    throw TypeError(".proto.SyncdSnapshot.keyId: object expected");
                message.keyId = $root.proto.KeyId.fromObject(object.keyId);
            }
            return message;
        };

        /**
         * Creates a plain object from a SyncdSnapshot message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.SyncdSnapshot
         * @static
         * @param {proto.SyncdSnapshot} message SyncdSnapshot
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        SyncdSnapshot.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.records = [];
            if (options.defaults) {
                object.version = null;
                if (options.bytes === String)
                    object.mac = "";
                else {
                    object.mac = [];
                    if (options.bytes !== Array)
                        object.mac = $util.newBuffer(object.mac);
                }
                object.keyId = null;
            }
            if (message.version != null && message.hasOwnProperty("version"))
                object.version = $root.proto.SyncdVersion.toObject(message.version, options);
            if (message.records && message.records.length) {
                object.records = [];
                for (var j = 0; j < message.records.length; ++j)
                    object.records[j] = $root.proto.SyncdRecord.toObject(message.records[j], options);
            }
            if (message.mac != null && message.hasOwnProperty("mac"))
                object.mac = options.bytes === String ? $util.base64.encode(message.mac, 0, message.mac.length) : options.bytes === Array ? Array.prototype.slice.call(message.mac) : message.mac;
            if (message.keyId != null && message.hasOwnProperty("keyId"))
                object.keyId = $root.proto.KeyId.toObject(message.keyId, options);
            return object;
        };

        /**
         * Converts this SyncdSnapshot to JSON.
         * @function toJSON
         * @memberof proto.SyncdSnapshot
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        SyncdSnapshot.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return SyncdSnapshot;
    })();

    proto.ExternalBlobReference = (function() {

        /**
         * Properties of an ExternalBlobReference.
         * @memberof proto
         * @interface IExternalBlobReference
         * @property {Uint8Array|null} [mediaKey] ExternalBlobReference mediaKey
         * @property {string|null} [directPath] ExternalBlobReference directPath
         * @property {string|null} [handle] ExternalBlobReference handle
         * @property {number|Long|null} [fileSizeBytes] ExternalBlobReference fileSizeBytes
         * @property {Uint8Array|null} [fileSha256] ExternalBlobReference fileSha256
         * @property {Uint8Array|null} [fileEncSha256] ExternalBlobReference fileEncSha256
         */

        /**
         * Constructs a new ExternalBlobReference.
         * @memberof proto
         * @classdesc Represents an ExternalBlobReference.
         * @implements IExternalBlobReference
         * @constructor
         * @param {proto.IExternalBlobReference=} [properties] Properties to set
         */
        function ExternalBlobReference(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ExternalBlobReference mediaKey.
         * @member {Uint8Array} mediaKey
         * @memberof proto.ExternalBlobReference
         * @instance
         */
        ExternalBlobReference.prototype.mediaKey = $util.newBuffer([]);

        /**
         * ExternalBlobReference directPath.
         * @member {string} directPath
         * @memberof proto.ExternalBlobReference
         * @instance
         */
        ExternalBlobReference.prototype.directPath = "";

        /**
         * ExternalBlobReference handle.
         * @member {string} handle
         * @memberof proto.ExternalBlobReference
         * @instance
         */
        ExternalBlobReference.prototype.handle = "";

        /**
         * ExternalBlobReference fileSizeBytes.
         * @member {number|Long} fileSizeBytes
         * @memberof proto.ExternalBlobReference
         * @instance
         */
        ExternalBlobReference.prototype.fileSizeBytes = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * ExternalBlobReference fileSha256.
         * @member {Uint8Array} fileSha256
         * @memberof proto.ExternalBlobReference
         * @instance
         */
        ExternalBlobReference.prototype.fileSha256 = $util.newBuffer([]);

        /**
         * ExternalBlobReference fileEncSha256.
         * @member {Uint8Array} fileEncSha256
         * @memberof proto.ExternalBlobReference
         * @instance
         */
        ExternalBlobReference.prototype.fileEncSha256 = $util.newBuffer([]);

        /**
         * Creates a new ExternalBlobReference instance using the specified properties.
         * @function create
         * @memberof proto.ExternalBlobReference
         * @static
         * @param {proto.IExternalBlobReference=} [properties] Properties to set
         * @returns {proto.ExternalBlobReference} ExternalBlobReference instance
         */
        ExternalBlobReference.create = function create(properties) {
            return new ExternalBlobReference(properties);
        };

        /**
         * Encodes the specified ExternalBlobReference message. Does not implicitly {@link proto.ExternalBlobReference.verify|verify} messages.
         * @function encode
         * @memberof proto.ExternalBlobReference
         * @static
         * @param {proto.IExternalBlobReference} message ExternalBlobReference message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ExternalBlobReference.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.mediaKey != null && Object.hasOwnProperty.call(message, "mediaKey"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.mediaKey);
            if (message.directPath != null && Object.hasOwnProperty.call(message, "directPath"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.directPath);
            if (message.handle != null && Object.hasOwnProperty.call(message, "handle"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.handle);
            if (message.fileSizeBytes != null && Object.hasOwnProperty.call(message, "fileSizeBytes"))
                writer.uint32(/* id 4, wireType 0 =*/32).uint64(message.fileSizeBytes);
            if (message.fileSha256 != null && Object.hasOwnProperty.call(message, "fileSha256"))
                writer.uint32(/* id 5, wireType 2 =*/42).bytes(message.fileSha256);
            if (message.fileEncSha256 != null && Object.hasOwnProperty.call(message, "fileEncSha256"))
                writer.uint32(/* id 6, wireType 2 =*/50).bytes(message.fileEncSha256);
            return writer;
        };

        /**
         * Encodes the specified ExternalBlobReference message, length delimited. Does not implicitly {@link proto.ExternalBlobReference.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ExternalBlobReference
         * @static
         * @param {proto.IExternalBlobReference} message ExternalBlobReference message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ExternalBlobReference.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an ExternalBlobReference message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ExternalBlobReference
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ExternalBlobReference} ExternalBlobReference
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ExternalBlobReference.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ExternalBlobReference();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.mediaKey = reader.bytes();
                    break;
                case 2:
                    message.directPath = reader.string();
                    break;
                case 3:
                    message.handle = reader.string();
                    break;
                case 4:
                    message.fileSizeBytes = reader.uint64();
                    break;
                case 5:
                    message.fileSha256 = reader.bytes();
                    break;
                case 6:
                    message.fileEncSha256 = reader.bytes();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an ExternalBlobReference message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ExternalBlobReference
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ExternalBlobReference} ExternalBlobReference
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ExternalBlobReference.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an ExternalBlobReference message.
         * @function verify
         * @memberof proto.ExternalBlobReference
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ExternalBlobReference.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.mediaKey != null && message.hasOwnProperty("mediaKey"))
                if (!(message.mediaKey && typeof message.mediaKey.length === "number" || $util.isString(message.mediaKey)))
                    return "mediaKey: buffer expected";
            if (message.directPath != null && message.hasOwnProperty("directPath"))
                if (!$util.isString(message.directPath))
                    return "directPath: string expected";
            if (message.handle != null && message.hasOwnProperty("handle"))
                if (!$util.isString(message.handle))
                    return "handle: string expected";
            if (message.fileSizeBytes != null && message.hasOwnProperty("fileSizeBytes"))
                if (!$util.isInteger(message.fileSizeBytes) && !(message.fileSizeBytes && $util.isInteger(message.fileSizeBytes.low) && $util.isInteger(message.fileSizeBytes.high)))
                    return "fileSizeBytes: integer|Long expected";
            if (message.fileSha256 != null && message.hasOwnProperty("fileSha256"))
                if (!(message.fileSha256 && typeof message.fileSha256.length === "number" || $util.isString(message.fileSha256)))
                    return "fileSha256: buffer expected";
            if (message.fileEncSha256 != null && message.hasOwnProperty("fileEncSha256"))
                if (!(message.fileEncSha256 && typeof message.fileEncSha256.length === "number" || $util.isString(message.fileEncSha256)))
                    return "fileEncSha256: buffer expected";
            return null;
        };

        /**
         * Creates an ExternalBlobReference message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ExternalBlobReference
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ExternalBlobReference} ExternalBlobReference
         */
        ExternalBlobReference.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ExternalBlobReference)
                return object;
            var message = new $root.proto.ExternalBlobReference();
            if (object.mediaKey != null)
                if (typeof object.mediaKey === "string")
                    $util.base64.decode(object.mediaKey, message.mediaKey = $util.newBuffer($util.base64.length(object.mediaKey)), 0);
                else if (object.mediaKey.length)
                    message.mediaKey = object.mediaKey;
            if (object.directPath != null)
                message.directPath = String(object.directPath);
            if (object.handle != null)
                message.handle = String(object.handle);
            if (object.fileSizeBytes != null)
                if ($util.Long)
                    (message.fileSizeBytes = $util.Long.fromValue(object.fileSizeBytes)).unsigned = true;
                else if (typeof object.fileSizeBytes === "string")
                    message.fileSizeBytes = parseInt(object.fileSizeBytes, 10);
                else if (typeof object.fileSizeBytes === "number")
                    message.fileSizeBytes = object.fileSizeBytes;
                else if (typeof object.fileSizeBytes === "object")
                    message.fileSizeBytes = new $util.LongBits(object.fileSizeBytes.low >>> 0, object.fileSizeBytes.high >>> 0).toNumber(true);
            if (object.fileSha256 != null)
                if (typeof object.fileSha256 === "string")
                    $util.base64.decode(object.fileSha256, message.fileSha256 = $util.newBuffer($util.base64.length(object.fileSha256)), 0);
                else if (object.fileSha256.length)
                    message.fileSha256 = object.fileSha256;
            if (object.fileEncSha256 != null)
                if (typeof object.fileEncSha256 === "string")
                    $util.base64.decode(object.fileEncSha256, message.fileEncSha256 = $util.newBuffer($util.base64.length(object.fileEncSha256)), 0);
                else if (object.fileEncSha256.length)
                    message.fileEncSha256 = object.fileEncSha256;
            return message;
        };

        /**
         * Creates a plain object from an ExternalBlobReference message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ExternalBlobReference
         * @static
         * @param {proto.ExternalBlobReference} message ExternalBlobReference
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ExternalBlobReference.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object.mediaKey = "";
                else {
                    object.mediaKey = [];
                    if (options.bytes !== Array)
                        object.mediaKey = $util.newBuffer(object.mediaKey);
                }
                object.directPath = "";
                object.handle = "";
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.fileSizeBytes = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.fileSizeBytes = options.longs === String ? "0" : 0;
                if (options.bytes === String)
                    object.fileSha256 = "";
                else {
                    object.fileSha256 = [];
                    if (options.bytes !== Array)
                        object.fileSha256 = $util.newBuffer(object.fileSha256);
                }
                if (options.bytes === String)
                    object.fileEncSha256 = "";
                else {
                    object.fileEncSha256 = [];
                    if (options.bytes !== Array)
                        object.fileEncSha256 = $util.newBuffer(object.fileEncSha256);
                }
            }
            if (message.mediaKey != null && message.hasOwnProperty("mediaKey"))
                object.mediaKey = options.bytes === String ? $util.base64.encode(message.mediaKey, 0, message.mediaKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.mediaKey) : message.mediaKey;
            if (message.directPath != null && message.hasOwnProperty("directPath"))
                object.directPath = message.directPath;
            if (message.handle != null && message.hasOwnProperty("handle"))
                object.handle = message.handle;
            if (message.fileSizeBytes != null && message.hasOwnProperty("fileSizeBytes"))
                if (typeof message.fileSizeBytes === "number")
                    object.fileSizeBytes = options.longs === String ? String(message.fileSizeBytes) : message.fileSizeBytes;
                else
                    object.fileSizeBytes = options.longs === String ? $util.Long.prototype.toString.call(message.fileSizeBytes) : options.longs === Number ? new $util.LongBits(message.fileSizeBytes.low >>> 0, message.fileSizeBytes.high >>> 0).toNumber(true) : message.fileSizeBytes;
            if (message.fileSha256 != null && message.hasOwnProperty("fileSha256"))
                object.fileSha256 = options.bytes === String ? $util.base64.encode(message.fileSha256, 0, message.fileSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.fileSha256) : message.fileSha256;
            if (message.fileEncSha256 != null && message.hasOwnProperty("fileEncSha256"))
                object.fileEncSha256 = options.bytes === String ? $util.base64.encode(message.fileEncSha256, 0, message.fileEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.fileEncSha256) : message.fileEncSha256;
            return object;
        };

        /**
         * Converts this ExternalBlobReference to JSON.
         * @function toJSON
         * @memberof proto.ExternalBlobReference
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ExternalBlobReference.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ExternalBlobReference;
    })();

    proto.SyncdRecord = (function() {

        /**
         * Properties of a SyncdRecord.
         * @memberof proto
         * @interface ISyncdRecord
         * @property {proto.ISyncdIndex|null} [index] SyncdRecord index
         * @property {proto.ISyncdValue|null} [value] SyncdRecord value
         * @property {proto.IKeyId|null} [keyId] SyncdRecord keyId
         */

        /**
         * Constructs a new SyncdRecord.
         * @memberof proto
         * @classdesc Represents a SyncdRecord.
         * @implements ISyncdRecord
         * @constructor
         * @param {proto.ISyncdRecord=} [properties] Properties to set
         */
        function SyncdRecord(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * SyncdRecord index.
         * @member {proto.ISyncdIndex|null|undefined} index
         * @memberof proto.SyncdRecord
         * @instance
         */
        SyncdRecord.prototype.index = null;

        /**
         * SyncdRecord value.
         * @member {proto.ISyncdValue|null|undefined} value
         * @memberof proto.SyncdRecord
         * @instance
         */
        SyncdRecord.prototype.value = null;

        /**
         * SyncdRecord keyId.
         * @member {proto.IKeyId|null|undefined} keyId
         * @memberof proto.SyncdRecord
         * @instance
         */
        SyncdRecord.prototype.keyId = null;

        /**
         * Creates a new SyncdRecord instance using the specified properties.
         * @function create
         * @memberof proto.SyncdRecord
         * @static
         * @param {proto.ISyncdRecord=} [properties] Properties to set
         * @returns {proto.SyncdRecord} SyncdRecord instance
         */
        SyncdRecord.create = function create(properties) {
            return new SyncdRecord(properties);
        };

        /**
         * Encodes the specified SyncdRecord message. Does not implicitly {@link proto.SyncdRecord.verify|verify} messages.
         * @function encode
         * @memberof proto.SyncdRecord
         * @static
         * @param {proto.ISyncdRecord} message SyncdRecord message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SyncdRecord.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.index != null && Object.hasOwnProperty.call(message, "index"))
                $root.proto.SyncdIndex.encode(message.index, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.value != null && Object.hasOwnProperty.call(message, "value"))
                $root.proto.SyncdValue.encode(message.value, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.keyId != null && Object.hasOwnProperty.call(message, "keyId"))
                $root.proto.KeyId.encode(message.keyId, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified SyncdRecord message, length delimited. Does not implicitly {@link proto.SyncdRecord.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.SyncdRecord
         * @static
         * @param {proto.ISyncdRecord} message SyncdRecord message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SyncdRecord.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a SyncdRecord message from the specified reader or buffer.
         * @function decode
         * @memberof proto.SyncdRecord
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.SyncdRecord} SyncdRecord
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SyncdRecord.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdRecord();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.index = $root.proto.SyncdIndex.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.value = $root.proto.SyncdValue.decode(reader, reader.uint32());
                    break;
                case 3:
                    message.keyId = $root.proto.KeyId.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a SyncdRecord message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.SyncdRecord
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.SyncdRecord} SyncdRecord
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SyncdRecord.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a SyncdRecord message.
         * @function verify
         * @memberof proto.SyncdRecord
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        SyncdRecord.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.index != null && message.hasOwnProperty("index")) {
                var error = $root.proto.SyncdIndex.verify(message.index);
                if (error)
                    return "index." + error;
            }
            if (message.value != null && message.hasOwnProperty("value")) {
                var error = $root.proto.SyncdValue.verify(message.value);
                if (error)
                    return "value." + error;
            }
            if (message.keyId != null && message.hasOwnProperty("keyId")) {
                var error = $root.proto.KeyId.verify(message.keyId);
                if (error)
                    return "keyId." + error;
            }
            return null;
        };

        /**
         * Creates a SyncdRecord message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.SyncdRecord
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.SyncdRecord} SyncdRecord
         */
        SyncdRecord.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.SyncdRecord)
                return object;
            var message = new $root.proto.SyncdRecord();
            if (object.index != null) {
                if (typeof object.index !== "object")
                    throw TypeError(".proto.SyncdRecord.index: object expected");
                message.index = $root.proto.SyncdIndex.fromObject(object.index);
            }
            if (object.value != null) {
                if (typeof object.value !== "object")
                    throw TypeError(".proto.SyncdRecord.value: object expected");
                message.value = $root.proto.SyncdValue.fromObject(object.value);
            }
            if (object.keyId != null) {
                if (typeof object.keyId !== "object")
                    throw TypeError(".proto.SyncdRecord.keyId: object expected");
                message.keyId = $root.proto.KeyId.fromObject(object.keyId);
            }
            return message;
        };

        /**
         * Creates a plain object from a SyncdRecord message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.SyncdRecord
         * @static
         * @param {proto.SyncdRecord} message SyncdRecord
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        SyncdRecord.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.index = null;
                object.value = null;
                object.keyId = null;
            }
            if (message.index != null && message.hasOwnProperty("index"))
                object.index = $root.proto.SyncdIndex.toObject(message.index, options);
            if (message.value != null && message.hasOwnProperty("value"))
                object.value = $root.proto.SyncdValue.toObject(message.value, options);
            if (message.keyId != null && message.hasOwnProperty("keyId"))
                object.keyId = $root.proto.KeyId.toObject(message.keyId, options);
            return object;
        };

        /**
         * Converts this SyncdRecord to JSON.
         * @function toJSON
         * @memberof proto.SyncdRecord
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        SyncdRecord.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return SyncdRecord;
    })();

    proto.KeyId = (function() {

        /**
         * Properties of a KeyId.
         * @memberof proto
         * @interface IKeyId
         * @property {Uint8Array|null} [id] KeyId id
         */

        /**
         * Constructs a new KeyId.
         * @memberof proto
         * @classdesc Represents a KeyId.
         * @implements IKeyId
         * @constructor
         * @param {proto.IKeyId=} [properties] Properties to set
         */
        function KeyId(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * KeyId id.
         * @member {Uint8Array} id
         * @memberof proto.KeyId
         * @instance
         */
        KeyId.prototype.id = $util.newBuffer([]);

        /**
         * Creates a new KeyId instance using the specified properties.
         * @function create
         * @memberof proto.KeyId
         * @static
         * @param {proto.IKeyId=} [properties] Properties to set
         * @returns {proto.KeyId} KeyId instance
         */
        KeyId.create = function create(properties) {
            return new KeyId(properties);
        };

        /**
         * Encodes the specified KeyId message. Does not implicitly {@link proto.KeyId.verify|verify} messages.
         * @function encode
         * @memberof proto.KeyId
         * @static
         * @param {proto.IKeyId} message KeyId message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        KeyId.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.id);
            return writer;
        };

        /**
         * Encodes the specified KeyId message, length delimited. Does not implicitly {@link proto.KeyId.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.KeyId
         * @static
         * @param {proto.IKeyId} message KeyId message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        KeyId.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a KeyId message from the specified reader or buffer.
         * @function decode
         * @memberof proto.KeyId
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.KeyId} KeyId
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        KeyId.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.KeyId();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.id = reader.bytes();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a KeyId message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.KeyId
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.KeyId} KeyId
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        KeyId.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a KeyId message.
         * @function verify
         * @memberof proto.KeyId
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        KeyId.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!(message.id && typeof message.id.length === "number" || $util.isString(message.id)))
                    return "id: buffer expected";
            return null;
        };

        /**
         * Creates a KeyId message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.KeyId
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.KeyId} KeyId
         */
        KeyId.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.KeyId)
                return object;
            var message = new $root.proto.KeyId();
            if (object.id != null)
                if (typeof object.id === "string")
                    $util.base64.decode(object.id, message.id = $util.newBuffer($util.base64.length(object.id)), 0);
                else if (object.id.length)
                    message.id = object.id;
            return message;
        };

        /**
         * Creates a plain object from a KeyId message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.KeyId
         * @static
         * @param {proto.KeyId} message KeyId
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        KeyId.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                if (options.bytes === String)
                    object.id = "";
                else {
                    object.id = [];
                    if (options.bytes !== Array)
                        object.id = $util.newBuffer(object.id);
                }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = options.bytes === String ? $util.base64.encode(message.id, 0, message.id.length) : options.bytes === Array ? Array.prototype.slice.call(message.id) : message.id;
            return object;
        };

        /**
         * Converts this KeyId to JSON.
         * @function toJSON
         * @memberof proto.KeyId
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        KeyId.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return KeyId;
    })();

    proto.SyncdValue = (function() {

        /**
         * Properties of a SyncdValue.
         * @memberof proto
         * @interface ISyncdValue
         * @property {Uint8Array|null} [blob] SyncdValue blob
         */

        /**
         * Constructs a new SyncdValue.
         * @memberof proto
         * @classdesc Represents a SyncdValue.
         * @implements ISyncdValue
         * @constructor
         * @param {proto.ISyncdValue=} [properties] Properties to set
         */
        function SyncdValue(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * SyncdValue blob.
         * @member {Uint8Array} blob
         * @memberof proto.SyncdValue
         * @instance
         */
        SyncdValue.prototype.blob = $util.newBuffer([]);

        /**
         * Creates a new SyncdValue instance using the specified properties.
         * @function create
         * @memberof proto.SyncdValue
         * @static
         * @param {proto.ISyncdValue=} [properties] Properties to set
         * @returns {proto.SyncdValue} SyncdValue instance
         */
        SyncdValue.create = function create(properties) {
            return new SyncdValue(properties);
        };

        /**
         * Encodes the specified SyncdValue message. Does not implicitly {@link proto.SyncdValue.verify|verify} messages.
         * @function encode
         * @memberof proto.SyncdValue
         * @static
         * @param {proto.ISyncdValue} message SyncdValue message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SyncdValue.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.blob != null && Object.hasOwnProperty.call(message, "blob"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.blob);
            return writer;
        };

        /**
         * Encodes the specified SyncdValue message, length delimited. Does not implicitly {@link proto.SyncdValue.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.SyncdValue
         * @static
         * @param {proto.ISyncdValue} message SyncdValue message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SyncdValue.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a SyncdValue message from the specified reader or buffer.
         * @function decode
         * @memberof proto.SyncdValue
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.SyncdValue} SyncdValue
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SyncdValue.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdValue();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.blob = reader.bytes();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a SyncdValue message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.SyncdValue
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.SyncdValue} SyncdValue
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SyncdValue.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a SyncdValue message.
         * @function verify
         * @memberof proto.SyncdValue
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        SyncdValue.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.blob != null && message.hasOwnProperty("blob"))
                if (!(message.blob && typeof message.blob.length === "number" || $util.isString(message.blob)))
                    return "blob: buffer expected";
            return null;
        };

        /**
         * Creates a SyncdValue message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.SyncdValue
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.SyncdValue} SyncdValue
         */
        SyncdValue.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.SyncdValue)
                return object;
            var message = new $root.proto.SyncdValue();
            if (object.blob != null)
                if (typeof object.blob === "string")
                    $util.base64.decode(object.blob, message.blob = $util.newBuffer($util.base64.length(object.blob)), 0);
                else if (object.blob.length)
                    message.blob = object.blob;
            return message;
        };

        /**
         * Creates a plain object from a SyncdValue message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.SyncdValue
         * @static
         * @param {proto.SyncdValue} message SyncdValue
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        SyncdValue.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                if (options.bytes === String)
                    object.blob = "";
                else {
                    object.blob = [];
                    if (options.bytes !== Array)
                        object.blob = $util.newBuffer(object.blob);
                }
            if (message.blob != null && message.hasOwnProperty("blob"))
                object.blob = options.bytes === String ? $util.base64.encode(message.blob, 0, message.blob.length) : options.bytes === Array ? Array.prototype.slice.call(message.blob) : message.blob;
            return object;
        };

        /**
         * Converts this SyncdValue to JSON.
         * @function toJSON
         * @memberof proto.SyncdValue
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        SyncdValue.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return SyncdValue;
    })();

    proto.SyncdIndex = (function() {

        /**
         * Properties of a SyncdIndex.
         * @memberof proto
         * @interface ISyncdIndex
         * @property {Uint8Array|null} [blob] SyncdIndex blob
         */

        /**
         * Constructs a new SyncdIndex.
         * @memberof proto
         * @classdesc Represents a SyncdIndex.
         * @implements ISyncdIndex
         * @constructor
         * @param {proto.ISyncdIndex=} [properties] Properties to set
         */
        function SyncdIndex(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * SyncdIndex blob.
         * @member {Uint8Array} blob
         * @memberof proto.SyncdIndex
         * @instance
         */
        SyncdIndex.prototype.blob = $util.newBuffer([]);

        /**
         * Creates a new SyncdIndex instance using the specified properties.
         * @function create
         * @memberof proto.SyncdIndex
         * @static
         * @param {proto.ISyncdIndex=} [properties] Properties to set
         * @returns {proto.SyncdIndex} SyncdIndex instance
         */
        SyncdIndex.create = function create(properties) {
            return new SyncdIndex(properties);
        };

        /**
         * Encodes the specified SyncdIndex message. Does not implicitly {@link proto.SyncdIndex.verify|verify} messages.
         * @function encode
         * @memberof proto.SyncdIndex
         * @static
         * @param {proto.ISyncdIndex} message SyncdIndex message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SyncdIndex.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.blob != null && Object.hasOwnProperty.call(message, "blob"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.blob);
            return writer;
        };

        /**
         * Encodes the specified SyncdIndex message, length delimited. Does not implicitly {@link proto.SyncdIndex.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.SyncdIndex
         * @static
         * @param {proto.ISyncdIndex} message SyncdIndex message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SyncdIndex.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a SyncdIndex message from the specified reader or buffer.
         * @function decode
         * @memberof proto.SyncdIndex
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.SyncdIndex} SyncdIndex
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SyncdIndex.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdIndex();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.blob = reader.bytes();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a SyncdIndex message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.SyncdIndex
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.SyncdIndex} SyncdIndex
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SyncdIndex.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a SyncdIndex message.
         * @function verify
         * @memberof proto.SyncdIndex
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        SyncdIndex.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.blob != null && message.hasOwnProperty("blob"))
                if (!(message.blob && typeof message.blob.length === "number" || $util.isString(message.blob)))
                    return "blob: buffer expected";
            return null;
        };

        /**
         * Creates a SyncdIndex message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.SyncdIndex
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.SyncdIndex} SyncdIndex
         */
        SyncdIndex.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.SyncdIndex)
                return object;
            var message = new $root.proto.SyncdIndex();
            if (object.blob != null)
                if (typeof object.blob === "string")
                    $util.base64.decode(object.blob, message.blob = $util.newBuffer($util.base64.length(object.blob)), 0);
                else if (object.blob.length)
                    message.blob = object.blob;
            return message;
        };

        /**
         * Creates a plain object from a SyncdIndex message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.SyncdIndex
         * @static
         * @param {proto.SyncdIndex} message SyncdIndex
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        SyncdIndex.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                if (options.bytes === String)
                    object.blob = "";
                else {
                    object.blob = [];
                    if (options.bytes !== Array)
                        object.blob = $util.newBuffer(object.blob);
                }
            if (message.blob != null && message.hasOwnProperty("blob"))
                object.blob = options.bytes === String ? $util.base64.encode(message.blob, 0, message.blob.length) : options.bytes === Array ? Array.prototype.slice.call(message.blob) : message.blob;
            return object;
        };

        /**
         * Converts this SyncdIndex to JSON.
         * @function toJSON
         * @memberof proto.SyncdIndex
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        SyncdIndex.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return SyncdIndex;
    })();

    proto.ExitCode = (function() {

        /**
         * Properties of an ExitCode.
         * @memberof proto
         * @interface IExitCode
         * @property {number|Long|null} [code] ExitCode code
         * @property {string|null} [text] ExitCode text
         */

        /**
         * Constructs a new ExitCode.
         * @memberof proto
         * @classdesc Represents an ExitCode.
         * @implements IExitCode
         * @constructor
         * @param {proto.IExitCode=} [properties] Properties to set
         */
        function ExitCode(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ExitCode code.
         * @member {number|Long} code
         * @memberof proto.ExitCode
         * @instance
         */
        ExitCode.prototype.code = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * ExitCode text.
         * @member {string} text
         * @memberof proto.ExitCode
         * @instance
         */
        ExitCode.prototype.text = "";

        /**
         * Creates a new ExitCode instance using the specified properties.
         * @function create
         * @memberof proto.ExitCode
         * @static
         * @param {proto.IExitCode=} [properties] Properties to set
         * @returns {proto.ExitCode} ExitCode instance
         */
        ExitCode.create = function create(properties) {
            return new ExitCode(properties);
        };

        /**
         * Encodes the specified ExitCode message. Does not implicitly {@link proto.ExitCode.verify|verify} messages.
         * @function encode
         * @memberof proto.ExitCode
         * @static
         * @param {proto.IExitCode} message ExitCode message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ExitCode.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.code != null && Object.hasOwnProperty.call(message, "code"))
                writer.uint32(/* id 1, wireType 0 =*/8).uint64(message.code);
            if (message.text != null && Object.hasOwnProperty.call(message, "text"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.text);
            return writer;
        };

        /**
         * Encodes the specified ExitCode message, length delimited. Does not implicitly {@link proto.ExitCode.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ExitCode
         * @static
         * @param {proto.IExitCode} message ExitCode message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ExitCode.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an ExitCode message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ExitCode
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ExitCode} ExitCode
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ExitCode.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ExitCode();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.code = reader.uint64();
                    break;
                case 2:
                    message.text = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an ExitCode message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ExitCode
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ExitCode} ExitCode
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ExitCode.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an ExitCode message.
         * @function verify
         * @memberof proto.ExitCode
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ExitCode.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.code != null && message.hasOwnProperty("code"))
                if (!$util.isInteger(message.code) && !(message.code && $util.isInteger(message.code.low) && $util.isInteger(message.code.high)))
                    return "code: integer|Long expected";
            if (message.text != null && message.hasOwnProperty("text"))
                if (!$util.isString(message.text))
                    return "text: string expected";
            return null;
        };

        /**
         * Creates an ExitCode message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ExitCode
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ExitCode} ExitCode
         */
        ExitCode.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ExitCode)
                return object;
            var message = new $root.proto.ExitCode();
            if (object.code != null)
                if ($util.Long)
                    (message.code = $util.Long.fromValue(object.code)).unsigned = true;
                else if (typeof object.code === "string")
                    message.code = parseInt(object.code, 10);
                else if (typeof object.code === "number")
                    message.code = object.code;
                else if (typeof object.code === "object")
                    message.code = new $util.LongBits(object.code.low >>> 0, object.code.high >>> 0).toNumber(true);
            if (object.text != null)
                message.text = String(object.text);
            return message;
        };

        /**
         * Creates a plain object from an ExitCode message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ExitCode
         * @static
         * @param {proto.ExitCode} message ExitCode
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ExitCode.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.code = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.code = options.longs === String ? "0" : 0;
                object.text = "";
            }
            if (message.code != null && message.hasOwnProperty("code"))
                if (typeof message.code === "number")
                    object.code = options.longs === String ? String(message.code) : message.code;
                else
                    object.code = options.longs === String ? $util.Long.prototype.toString.call(message.code) : options.longs === Number ? new $util.LongBits(message.code.low >>> 0, message.code.high >>> 0).toNumber(true) : message.code;
            if (message.text != null && message.hasOwnProperty("text"))
                object.text = message.text;
            return object;
        };

        /**
         * Converts this ExitCode to JSON.
         * @function toJSON
         * @memberof proto.ExitCode
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ExitCode.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ExitCode;
    })();

    proto.SyncdVersion = (function() {

        /**
         * Properties of a SyncdVersion.
         * @memberof proto
         * @interface ISyncdVersion
         * @property {number|Long|null} [version] SyncdVersion version
         */

        /**
         * Constructs a new SyncdVersion.
         * @memberof proto
         * @classdesc Represents a SyncdVersion.
         * @implements ISyncdVersion
         * @constructor
         * @param {proto.ISyncdVersion=} [properties] Properties to set
         */
        function SyncdVersion(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * SyncdVersion version.
         * @member {number|Long} version
         * @memberof proto.SyncdVersion
         * @instance
         */
        SyncdVersion.prototype.version = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * Creates a new SyncdVersion instance using the specified properties.
         * @function create
         * @memberof proto.SyncdVersion
         * @static
         * @param {proto.ISyncdVersion=} [properties] Properties to set
         * @returns {proto.SyncdVersion} SyncdVersion instance
         */
        SyncdVersion.create = function create(properties) {
            return new SyncdVersion(properties);
        };

        /**
         * Encodes the specified SyncdVersion message. Does not implicitly {@link proto.SyncdVersion.verify|verify} messages.
         * @function encode
         * @memberof proto.SyncdVersion
         * @static
         * @param {proto.ISyncdVersion} message SyncdVersion message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SyncdVersion.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.version != null && Object.hasOwnProperty.call(message, "version"))
                writer.uint32(/* id 1, wireType 0 =*/8).uint64(message.version);
            return writer;
        };

        /**
         * Encodes the specified SyncdVersion message, length delimited. Does not implicitly {@link proto.SyncdVersion.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.SyncdVersion
         * @static
         * @param {proto.ISyncdVersion} message SyncdVersion message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SyncdVersion.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a SyncdVersion message from the specified reader or buffer.
         * @function decode
         * @memberof proto.SyncdVersion
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.SyncdVersion} SyncdVersion
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SyncdVersion.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SyncdVersion();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.version = reader.uint64();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a SyncdVersion message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.SyncdVersion
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.SyncdVersion} SyncdVersion
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SyncdVersion.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a SyncdVersion message.
         * @function verify
         * @memberof proto.SyncdVersion
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        SyncdVersion.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.version != null && message.hasOwnProperty("version"))
                if (!$util.isInteger(message.version) && !(message.version && $util.isInteger(message.version.low) && $util.isInteger(message.version.high)))
                    return "version: integer|Long expected";
            return null;
        };

        /**
         * Creates a SyncdVersion message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.SyncdVersion
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.SyncdVersion} SyncdVersion
         */
        SyncdVersion.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.SyncdVersion)
                return object;
            var message = new $root.proto.SyncdVersion();
            if (object.version != null)
                if ($util.Long)
                    (message.version = $util.Long.fromValue(object.version)).unsigned = true;
                else if (typeof object.version === "string")
                    message.version = parseInt(object.version, 10);
                else if (typeof object.version === "number")
                    message.version = object.version;
                else if (typeof object.version === "object")
                    message.version = new $util.LongBits(object.version.low >>> 0, object.version.high >>> 0).toNumber(true);
            return message;
        };

        /**
         * Creates a plain object from a SyncdVersion message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.SyncdVersion
         * @static
         * @param {proto.SyncdVersion} message SyncdVersion
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        SyncdVersion.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.version = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.version = options.longs === String ? "0" : 0;
            if (message.version != null && message.hasOwnProperty("version"))
                if (typeof message.version === "number")
                    object.version = options.longs === String ? String(message.version) : message.version;
                else
                    object.version = options.longs === String ? $util.Long.prototype.toString.call(message.version) : options.longs === Number ? new $util.LongBits(message.version.low >>> 0, message.version.high >>> 0).toNumber(true) : message.version;
            return object;
        };

        /**
         * Converts this SyncdVersion to JSON.
         * @function toJSON
         * @memberof proto.SyncdVersion
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        SyncdVersion.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return SyncdVersion;
    })();

    proto.ServerErrorReceipt = (function() {

        /**
         * Properties of a ServerErrorReceipt.
         * @memberof proto
         * @interface IServerErrorReceipt
         * @property {string|null} [stanzaId] ServerErrorReceipt stanzaId
         */

        /**
         * Constructs a new ServerErrorReceipt.
         * @memberof proto
         * @classdesc Represents a ServerErrorReceipt.
         * @implements IServerErrorReceipt
         * @constructor
         * @param {proto.IServerErrorReceipt=} [properties] Properties to set
         */
        function ServerErrorReceipt(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ServerErrorReceipt stanzaId.
         * @member {string} stanzaId
         * @memberof proto.ServerErrorReceipt
         * @instance
         */
        ServerErrorReceipt.prototype.stanzaId = "";

        /**
         * Creates a new ServerErrorReceipt instance using the specified properties.
         * @function create
         * @memberof proto.ServerErrorReceipt
         * @static
         * @param {proto.IServerErrorReceipt=} [properties] Properties to set
         * @returns {proto.ServerErrorReceipt} ServerErrorReceipt instance
         */
        ServerErrorReceipt.create = function create(properties) {
            return new ServerErrorReceipt(properties);
        };

        /**
         * Encodes the specified ServerErrorReceipt message. Does not implicitly {@link proto.ServerErrorReceipt.verify|verify} messages.
         * @function encode
         * @memberof proto.ServerErrorReceipt
         * @static
         * @param {proto.IServerErrorReceipt} message ServerErrorReceipt message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ServerErrorReceipt.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.stanzaId != null && Object.hasOwnProperty.call(message, "stanzaId"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.stanzaId);
            return writer;
        };

        /**
         * Encodes the specified ServerErrorReceipt message, length delimited. Does not implicitly {@link proto.ServerErrorReceipt.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ServerErrorReceipt
         * @static
         * @param {proto.IServerErrorReceipt} message ServerErrorReceipt message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ServerErrorReceipt.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ServerErrorReceipt message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ServerErrorReceipt
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ServerErrorReceipt} ServerErrorReceipt
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ServerErrorReceipt.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ServerErrorReceipt();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.stanzaId = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ServerErrorReceipt message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ServerErrorReceipt
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ServerErrorReceipt} ServerErrorReceipt
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ServerErrorReceipt.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ServerErrorReceipt message.
         * @function verify
         * @memberof proto.ServerErrorReceipt
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ServerErrorReceipt.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.stanzaId != null && message.hasOwnProperty("stanzaId"))
                if (!$util.isString(message.stanzaId))
                    return "stanzaId: string expected";
            return null;
        };

        /**
         * Creates a ServerErrorReceipt message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ServerErrorReceipt
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ServerErrorReceipt} ServerErrorReceipt
         */
        ServerErrorReceipt.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ServerErrorReceipt)
                return object;
            var message = new $root.proto.ServerErrorReceipt();
            if (object.stanzaId != null)
                message.stanzaId = String(object.stanzaId);
            return message;
        };

        /**
         * Creates a plain object from a ServerErrorReceipt message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ServerErrorReceipt
         * @static
         * @param {proto.ServerErrorReceipt} message ServerErrorReceipt
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ServerErrorReceipt.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                object.stanzaId = "";
            if (message.stanzaId != null && message.hasOwnProperty("stanzaId"))
                object.stanzaId = message.stanzaId;
            return object;
        };

        /**
         * Converts this ServerErrorReceipt to JSON.
         * @function toJSON
         * @memberof proto.ServerErrorReceipt
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ServerErrorReceipt.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ServerErrorReceipt;
    })();

    proto.MediaRetryNotification = (function() {

        /**
         * Properties of a MediaRetryNotification.
         * @memberof proto
         * @interface IMediaRetryNotification
         * @property {string|null} [stanzaId] MediaRetryNotification stanzaId
         * @property {string|null} [directPath] MediaRetryNotification directPath
         * @property {proto.MediaRetryNotification.MediaRetryNotificationResultType|null} [result] MediaRetryNotification result
         */

        /**
         * Constructs a new MediaRetryNotification.
         * @memberof proto
         * @classdesc Represents a MediaRetryNotification.
         * @implements IMediaRetryNotification
         * @constructor
         * @param {proto.IMediaRetryNotification=} [properties] Properties to set
         */
        function MediaRetryNotification(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * MediaRetryNotification stanzaId.
         * @member {string} stanzaId
         * @memberof proto.MediaRetryNotification
         * @instance
         */
        MediaRetryNotification.prototype.stanzaId = "";

        /**
         * MediaRetryNotification directPath.
         * @member {string} directPath
         * @memberof proto.MediaRetryNotification
         * @instance
         */
        MediaRetryNotification.prototype.directPath = "";

        /**
         * MediaRetryNotification result.
         * @member {proto.MediaRetryNotification.MediaRetryNotificationResultType} result
         * @memberof proto.MediaRetryNotification
         * @instance
         */
        MediaRetryNotification.prototype.result = 0;

        /**
         * Creates a new MediaRetryNotification instance using the specified properties.
         * @function create
         * @memberof proto.MediaRetryNotification
         * @static
         * @param {proto.IMediaRetryNotification=} [properties] Properties to set
         * @returns {proto.MediaRetryNotification} MediaRetryNotification instance
         */
        MediaRetryNotification.create = function create(properties) {
            return new MediaRetryNotification(properties);
        };

        /**
         * Encodes the specified MediaRetryNotification message. Does not implicitly {@link proto.MediaRetryNotification.verify|verify} messages.
         * @function encode
         * @memberof proto.MediaRetryNotification
         * @static
         * @param {proto.IMediaRetryNotification} message MediaRetryNotification message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        MediaRetryNotification.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.stanzaId != null && Object.hasOwnProperty.call(message, "stanzaId"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.stanzaId);
            if (message.directPath != null && Object.hasOwnProperty.call(message, "directPath"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.directPath);
            if (message.result != null && Object.hasOwnProperty.call(message, "result"))
                writer.uint32(/* id 3, wireType 0 =*/24).int32(message.result);
            return writer;
        };

        /**
         * Encodes the specified MediaRetryNotification message, length delimited. Does not implicitly {@link proto.MediaRetryNotification.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.MediaRetryNotification
         * @static
         * @param {proto.IMediaRetryNotification} message MediaRetryNotification message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        MediaRetryNotification.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a MediaRetryNotification message from the specified reader or buffer.
         * @function decode
         * @memberof proto.MediaRetryNotification
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.MediaRetryNotification} MediaRetryNotification
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        MediaRetryNotification.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MediaRetryNotification();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.stanzaId = reader.string();
                    break;
                case 2:
                    message.directPath = reader.string();
                    break;
                case 3:
                    message.result = reader.int32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a MediaRetryNotification message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.MediaRetryNotification
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.MediaRetryNotification} MediaRetryNotification
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        MediaRetryNotification.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a MediaRetryNotification message.
         * @function verify
         * @memberof proto.MediaRetryNotification
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        MediaRetryNotification.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.stanzaId != null && message.hasOwnProperty("stanzaId"))
                if (!$util.isString(message.stanzaId))
                    return "stanzaId: string expected";
            if (message.directPath != null && message.hasOwnProperty("directPath"))
                if (!$util.isString(message.directPath))
                    return "directPath: string expected";
            if (message.result != null && message.hasOwnProperty("result"))
                switch (message.result) {
                default:
                    return "result: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            return null;
        };

        /**
         * Creates a MediaRetryNotification message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.MediaRetryNotification
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.MediaRetryNotification} MediaRetryNotification
         */
        MediaRetryNotification.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.MediaRetryNotification)
                return object;
            var message = new $root.proto.MediaRetryNotification();
            if (object.stanzaId != null)
                message.stanzaId = String(object.stanzaId);
            if (object.directPath != null)
                message.directPath = String(object.directPath);
            switch (object.result) {
            case "GENERAL_ERROR":
            case 0:
                message.result = 0;
                break;
            case "SUCCESS":
            case 1:
                message.result = 1;
                break;
            case "NOT_FOUND":
            case 2:
                message.result = 2;
                break;
            case "DECRYPTION_ERROR":
            case 3:
                message.result = 3;
                break;
            }
            return message;
        };

        /**
         * Creates a plain object from a MediaRetryNotification message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.MediaRetryNotification
         * @static
         * @param {proto.MediaRetryNotification} message MediaRetryNotification
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        MediaRetryNotification.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.stanzaId = "";
                object.directPath = "";
                object.result = options.enums === String ? "GENERAL_ERROR" : 0;
            }
            if (message.stanzaId != null && message.hasOwnProperty("stanzaId"))
                object.stanzaId = message.stanzaId;
            if (message.directPath != null && message.hasOwnProperty("directPath"))
                object.directPath = message.directPath;
            if (message.result != null && message.hasOwnProperty("result"))
                object.result = options.enums === String ? $root.proto.MediaRetryNotification.MediaRetryNotificationResultType[message.result] : message.result;
            return object;
        };

        /**
         * Converts this MediaRetryNotification to JSON.
         * @function toJSON
         * @memberof proto.MediaRetryNotification
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        MediaRetryNotification.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * MediaRetryNotificationResultType enum.
         * @name proto.MediaRetryNotification.MediaRetryNotificationResultType
         * @enum {number}
         * @property {number} GENERAL_ERROR=0 GENERAL_ERROR value
         * @property {number} SUCCESS=1 SUCCESS value
         * @property {number} NOT_FOUND=2 NOT_FOUND value
         * @property {number} DECRYPTION_ERROR=3 DECRYPTION_ERROR value
         */
        MediaRetryNotification.MediaRetryNotificationResultType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "GENERAL_ERROR"] = 0;
            values[valuesById[1] = "SUCCESS"] = 1;
            values[valuesById[2] = "NOT_FOUND"] = 2;
            values[valuesById[3] = "DECRYPTION_ERROR"] = 3;
            return values;
        })();

        return MediaRetryNotification;
    })();

    proto.MsgOpaqueData = (function() {

        /**
         * Properties of a MsgOpaqueData.
         * @memberof proto
         * @interface IMsgOpaqueData
         * @property {string|null} [body] MsgOpaqueData body
         * @property {string|null} [caption] MsgOpaqueData caption
         * @property {number|null} [lng] MsgOpaqueData lng
         * @property {number|null} [lat] MsgOpaqueData lat
         * @property {number|null} [paymentAmount1000] MsgOpaqueData paymentAmount1000
         * @property {string|null} [paymentNoteMsgBody] MsgOpaqueData paymentNoteMsgBody
         * @property {string|null} [canonicalUrl] MsgOpaqueData canonicalUrl
         * @property {string|null} [matchedText] MsgOpaqueData matchedText
         * @property {string|null} [title] MsgOpaqueData title
         * @property {string|null} [description] MsgOpaqueData description
         * @property {Uint8Array|null} [futureproofBuffer] MsgOpaqueData futureproofBuffer
         * @property {string|null} [clientUrl] MsgOpaqueData clientUrl
         * @property {string|null} [loc] MsgOpaqueData loc
         */

        /**
         * Constructs a new MsgOpaqueData.
         * @memberof proto
         * @classdesc Represents a MsgOpaqueData.
         * @implements IMsgOpaqueData
         * @constructor
         * @param {proto.IMsgOpaqueData=} [properties] Properties to set
         */
        function MsgOpaqueData(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * MsgOpaqueData body.
         * @member {string} body
         * @memberof proto.MsgOpaqueData
         * @instance
         */
        MsgOpaqueData.prototype.body = "";

        /**
         * MsgOpaqueData caption.
         * @member {string} caption
         * @memberof proto.MsgOpaqueData
         * @instance
         */
        MsgOpaqueData.prototype.caption = "";

        /**
         * MsgOpaqueData lng.
         * @member {number} lng
         * @memberof proto.MsgOpaqueData
         * @instance
         */
        MsgOpaqueData.prototype.lng = 0;

        /**
         * MsgOpaqueData lat.
         * @member {number} lat
         * @memberof proto.MsgOpaqueData
         * @instance
         */
        MsgOpaqueData.prototype.lat = 0;

        /**
         * MsgOpaqueData paymentAmount1000.
         * @member {number} paymentAmount1000
         * @memberof proto.MsgOpaqueData
         * @instance
         */
        MsgOpaqueData.prototype.paymentAmount1000 = 0;

        /**
         * MsgOpaqueData paymentNoteMsgBody.
         * @member {string} paymentNoteMsgBody
         * @memberof proto.MsgOpaqueData
         * @instance
         */
        MsgOpaqueData.prototype.paymentNoteMsgBody = "";

        /**
         * MsgOpaqueData canonicalUrl.
         * @member {string} canonicalUrl
         * @memberof proto.MsgOpaqueData
         * @instance
         */
        MsgOpaqueData.prototype.canonicalUrl = "";

        /**
         * MsgOpaqueData matchedText.
         * @member {string} matchedText
         * @memberof proto.MsgOpaqueData
         * @instance
         */
        MsgOpaqueData.prototype.matchedText = "";

        /**
         * MsgOpaqueData title.
         * @member {string} title
         * @memberof proto.MsgOpaqueData
         * @instance
         */
        MsgOpaqueData.prototype.title = "";

        /**
         * MsgOpaqueData description.
         * @member {string} description
         * @memberof proto.MsgOpaqueData
         * @instance
         */
        MsgOpaqueData.prototype.description = "";

        /**
         * MsgOpaqueData futureproofBuffer.
         * @member {Uint8Array} futureproofBuffer
         * @memberof proto.MsgOpaqueData
         * @instance
         */
        MsgOpaqueData.prototype.futureproofBuffer = $util.newBuffer([]);

        /**
         * MsgOpaqueData clientUrl.
         * @member {string} clientUrl
         * @memberof proto.MsgOpaqueData
         * @instance
         */
        MsgOpaqueData.prototype.clientUrl = "";

        /**
         * MsgOpaqueData loc.
         * @member {string} loc
         * @memberof proto.MsgOpaqueData
         * @instance
         */
        MsgOpaqueData.prototype.loc = "";

        /**
         * Creates a new MsgOpaqueData instance using the specified properties.
         * @function create
         * @memberof proto.MsgOpaqueData
         * @static
         * @param {proto.IMsgOpaqueData=} [properties] Properties to set
         * @returns {proto.MsgOpaqueData} MsgOpaqueData instance
         */
        MsgOpaqueData.create = function create(properties) {
            return new MsgOpaqueData(properties);
        };

        /**
         * Encodes the specified MsgOpaqueData message. Does not implicitly {@link proto.MsgOpaqueData.verify|verify} messages.
         * @function encode
         * @memberof proto.MsgOpaqueData
         * @static
         * @param {proto.IMsgOpaqueData} message MsgOpaqueData message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        MsgOpaqueData.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.body != null && Object.hasOwnProperty.call(message, "body"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.body);
            if (message.caption != null && Object.hasOwnProperty.call(message, "caption"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.caption);
            if (message.lng != null && Object.hasOwnProperty.call(message, "lng"))
                writer.uint32(/* id 5, wireType 1 =*/41).double(message.lng);
            if (message.lat != null && Object.hasOwnProperty.call(message, "lat"))
                writer.uint32(/* id 7, wireType 1 =*/57).double(message.lat);
            if (message.paymentAmount1000 != null && Object.hasOwnProperty.call(message, "paymentAmount1000"))
                writer.uint32(/* id 8, wireType 0 =*/64).int32(message.paymentAmount1000);
            if (message.paymentNoteMsgBody != null && Object.hasOwnProperty.call(message, "paymentNoteMsgBody"))
                writer.uint32(/* id 9, wireType 2 =*/74).string(message.paymentNoteMsgBody);
            if (message.canonicalUrl != null && Object.hasOwnProperty.call(message, "canonicalUrl"))
                writer.uint32(/* id 10, wireType 2 =*/82).string(message.canonicalUrl);
            if (message.matchedText != null && Object.hasOwnProperty.call(message, "matchedText"))
                writer.uint32(/* id 11, wireType 2 =*/90).string(message.matchedText);
            if (message.title != null && Object.hasOwnProperty.call(message, "title"))
                writer.uint32(/* id 12, wireType 2 =*/98).string(message.title);
            if (message.description != null && Object.hasOwnProperty.call(message, "description"))
                writer.uint32(/* id 13, wireType 2 =*/106).string(message.description);
            if (message.futureproofBuffer != null && Object.hasOwnProperty.call(message, "futureproofBuffer"))
                writer.uint32(/* id 14, wireType 2 =*/114).bytes(message.futureproofBuffer);
            if (message.clientUrl != null && Object.hasOwnProperty.call(message, "clientUrl"))
                writer.uint32(/* id 15, wireType 2 =*/122).string(message.clientUrl);
            if (message.loc != null && Object.hasOwnProperty.call(message, "loc"))
                writer.uint32(/* id 16, wireType 2 =*/130).string(message.loc);
            return writer;
        };

        /**
         * Encodes the specified MsgOpaqueData message, length delimited. Does not implicitly {@link proto.MsgOpaqueData.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.MsgOpaqueData
         * @static
         * @param {proto.IMsgOpaqueData} message MsgOpaqueData message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        MsgOpaqueData.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a MsgOpaqueData message from the specified reader or buffer.
         * @function decode
         * @memberof proto.MsgOpaqueData
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.MsgOpaqueData} MsgOpaqueData
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        MsgOpaqueData.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MsgOpaqueData();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.body = reader.string();
                    break;
                case 3:
                    message.caption = reader.string();
                    break;
                case 5:
                    message.lng = reader.double();
                    break;
                case 7:
                    message.lat = reader.double();
                    break;
                case 8:
                    message.paymentAmount1000 = reader.int32();
                    break;
                case 9:
                    message.paymentNoteMsgBody = reader.string();
                    break;
                case 10:
                    message.canonicalUrl = reader.string();
                    break;
                case 11:
                    message.matchedText = reader.string();
                    break;
                case 12:
                    message.title = reader.string();
                    break;
                case 13:
                    message.description = reader.string();
                    break;
                case 14:
                    message.futureproofBuffer = reader.bytes();
                    break;
                case 15:
                    message.clientUrl = reader.string();
                    break;
                case 16:
                    message.loc = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a MsgOpaqueData message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.MsgOpaqueData
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.MsgOpaqueData} MsgOpaqueData
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        MsgOpaqueData.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a MsgOpaqueData message.
         * @function verify
         * @memberof proto.MsgOpaqueData
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        MsgOpaqueData.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.body != null && message.hasOwnProperty("body"))
                if (!$util.isString(message.body))
                    return "body: string expected";
            if (message.caption != null && message.hasOwnProperty("caption"))
                if (!$util.isString(message.caption))
                    return "caption: string expected";
            if (message.lng != null && message.hasOwnProperty("lng"))
                if (typeof message.lng !== "number")
                    return "lng: number expected";
            if (message.lat != null && message.hasOwnProperty("lat"))
                if (typeof message.lat !== "number")
                    return "lat: number expected";
            if (message.paymentAmount1000 != null && message.hasOwnProperty("paymentAmount1000"))
                if (!$util.isInteger(message.paymentAmount1000))
                    return "paymentAmount1000: integer expected";
            if (message.paymentNoteMsgBody != null && message.hasOwnProperty("paymentNoteMsgBody"))
                if (!$util.isString(message.paymentNoteMsgBody))
                    return "paymentNoteMsgBody: string expected";
            if (message.canonicalUrl != null && message.hasOwnProperty("canonicalUrl"))
                if (!$util.isString(message.canonicalUrl))
                    return "canonicalUrl: string expected";
            if (message.matchedText != null && message.hasOwnProperty("matchedText"))
                if (!$util.isString(message.matchedText))
                    return "matchedText: string expected";
            if (message.title != null && message.hasOwnProperty("title"))
                if (!$util.isString(message.title))
                    return "title: string expected";
            if (message.description != null && message.hasOwnProperty("description"))
                if (!$util.isString(message.description))
                    return "description: string expected";
            if (message.futureproofBuffer != null && message.hasOwnProperty("futureproofBuffer"))
                if (!(message.futureproofBuffer && typeof message.futureproofBuffer.length === "number" || $util.isString(message.futureproofBuffer)))
                    return "futureproofBuffer: buffer expected";
            if (message.clientUrl != null && message.hasOwnProperty("clientUrl"))
                if (!$util.isString(message.clientUrl))
                    return "clientUrl: string expected";
            if (message.loc != null && message.hasOwnProperty("loc"))
                if (!$util.isString(message.loc))
                    return "loc: string expected";
            return null;
        };

        /**
         * Creates a MsgOpaqueData message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.MsgOpaqueData
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.MsgOpaqueData} MsgOpaqueData
         */
        MsgOpaqueData.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.MsgOpaqueData)
                return object;
            var message = new $root.proto.MsgOpaqueData();
            if (object.body != null)
                message.body = String(object.body);
            if (object.caption != null)
                message.caption = String(object.caption);
            if (object.lng != null)
                message.lng = Number(object.lng);
            if (object.lat != null)
                message.lat = Number(object.lat);
            if (object.paymentAmount1000 != null)
                message.paymentAmount1000 = object.paymentAmount1000 | 0;
            if (object.paymentNoteMsgBody != null)
                message.paymentNoteMsgBody = String(object.paymentNoteMsgBody);
            if (object.canonicalUrl != null)
                message.canonicalUrl = String(object.canonicalUrl);
            if (object.matchedText != null)
                message.matchedText = String(object.matchedText);
            if (object.title != null)
                message.title = String(object.title);
            if (object.description != null)
                message.description = String(object.description);
            if (object.futureproofBuffer != null)
                if (typeof object.futureproofBuffer === "string")
                    $util.base64.decode(object.futureproofBuffer, message.futureproofBuffer = $util.newBuffer($util.base64.length(object.futureproofBuffer)), 0);
                else if (object.futureproofBuffer.length)
                    message.futureproofBuffer = object.futureproofBuffer;
            if (object.clientUrl != null)
                message.clientUrl = String(object.clientUrl);
            if (object.loc != null)
                message.loc = String(object.loc);
            return message;
        };

        /**
         * Creates a plain object from a MsgOpaqueData message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.MsgOpaqueData
         * @static
         * @param {proto.MsgOpaqueData} message MsgOpaqueData
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        MsgOpaqueData.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.body = "";
                object.caption = "";
                object.lng = 0;
                object.lat = 0;
                object.paymentAmount1000 = 0;
                object.paymentNoteMsgBody = "";
                object.canonicalUrl = "";
                object.matchedText = "";
                object.title = "";
                object.description = "";
                if (options.bytes === String)
                    object.futureproofBuffer = "";
                else {
                    object.futureproofBuffer = [];
                    if (options.bytes !== Array)
                        object.futureproofBuffer = $util.newBuffer(object.futureproofBuffer);
                }
                object.clientUrl = "";
                object.loc = "";
            }
            if (message.body != null && message.hasOwnProperty("body"))
                object.body = message.body;
            if (message.caption != null && message.hasOwnProperty("caption"))
                object.caption = message.caption;
            if (message.lng != null && message.hasOwnProperty("lng"))
                object.lng = options.json && !isFinite(message.lng) ? String(message.lng) : message.lng;
            if (message.lat != null && message.hasOwnProperty("lat"))
                object.lat = options.json && !isFinite(message.lat) ? String(message.lat) : message.lat;
            if (message.paymentAmount1000 != null && message.hasOwnProperty("paymentAmount1000"))
                object.paymentAmount1000 = message.paymentAmount1000;
            if (message.paymentNoteMsgBody != null && message.hasOwnProperty("paymentNoteMsgBody"))
                object.paymentNoteMsgBody = message.paymentNoteMsgBody;
            if (message.canonicalUrl != null && message.hasOwnProperty("canonicalUrl"))
                object.canonicalUrl = message.canonicalUrl;
            if (message.matchedText != null && message.hasOwnProperty("matchedText"))
                object.matchedText = message.matchedText;
            if (message.title != null && message.hasOwnProperty("title"))
                object.title = message.title;
            if (message.description != null && message.hasOwnProperty("description"))
                object.description = message.description;
            if (message.futureproofBuffer != null && message.hasOwnProperty("futureproofBuffer"))
                object.futureproofBuffer = options.bytes === String ? $util.base64.encode(message.futureproofBuffer, 0, message.futureproofBuffer.length) : options.bytes === Array ? Array.prototype.slice.call(message.futureproofBuffer) : message.futureproofBuffer;
            if (message.clientUrl != null && message.hasOwnProperty("clientUrl"))
                object.clientUrl = message.clientUrl;
            if (message.loc != null && message.hasOwnProperty("loc"))
                object.loc = message.loc;
            return object;
        };

        /**
         * Converts this MsgOpaqueData to JSON.
         * @function toJSON
         * @memberof proto.MsgOpaqueData
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        MsgOpaqueData.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return MsgOpaqueData;
    })();

    proto.MsgRowOpaqueData = (function() {

        /**
         * Properties of a MsgRowOpaqueData.
         * @memberof proto
         * @interface IMsgRowOpaqueData
         * @property {proto.IMsgOpaqueData|null} [currentMsg] MsgRowOpaqueData currentMsg
         * @property {proto.IMsgOpaqueData|null} [quotedMsg] MsgRowOpaqueData quotedMsg
         */

        /**
         * Constructs a new MsgRowOpaqueData.
         * @memberof proto
         * @classdesc Represents a MsgRowOpaqueData.
         * @implements IMsgRowOpaqueData
         * @constructor
         * @param {proto.IMsgRowOpaqueData=} [properties] Properties to set
         */
        function MsgRowOpaqueData(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * MsgRowOpaqueData currentMsg.
         * @member {proto.IMsgOpaqueData|null|undefined} currentMsg
         * @memberof proto.MsgRowOpaqueData
         * @instance
         */
        MsgRowOpaqueData.prototype.currentMsg = null;

        /**
         * MsgRowOpaqueData quotedMsg.
         * @member {proto.IMsgOpaqueData|null|undefined} quotedMsg
         * @memberof proto.MsgRowOpaqueData
         * @instance
         */
        MsgRowOpaqueData.prototype.quotedMsg = null;

        /**
         * Creates a new MsgRowOpaqueData instance using the specified properties.
         * @function create
         * @memberof proto.MsgRowOpaqueData
         * @static
         * @param {proto.IMsgRowOpaqueData=} [properties] Properties to set
         * @returns {proto.MsgRowOpaqueData} MsgRowOpaqueData instance
         */
        MsgRowOpaqueData.create = function create(properties) {
            return new MsgRowOpaqueData(properties);
        };

        /**
         * Encodes the specified MsgRowOpaqueData message. Does not implicitly {@link proto.MsgRowOpaqueData.verify|verify} messages.
         * @function encode
         * @memberof proto.MsgRowOpaqueData
         * @static
         * @param {proto.IMsgRowOpaqueData} message MsgRowOpaqueData message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        MsgRowOpaqueData.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.currentMsg != null && Object.hasOwnProperty.call(message, "currentMsg"))
                $root.proto.MsgOpaqueData.encode(message.currentMsg, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.quotedMsg != null && Object.hasOwnProperty.call(message, "quotedMsg"))
                $root.proto.MsgOpaqueData.encode(message.quotedMsg, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified MsgRowOpaqueData message, length delimited. Does not implicitly {@link proto.MsgRowOpaqueData.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.MsgRowOpaqueData
         * @static
         * @param {proto.IMsgRowOpaqueData} message MsgRowOpaqueData message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        MsgRowOpaqueData.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a MsgRowOpaqueData message from the specified reader or buffer.
         * @function decode
         * @memberof proto.MsgRowOpaqueData
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.MsgRowOpaqueData} MsgRowOpaqueData
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        MsgRowOpaqueData.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MsgRowOpaqueData();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.currentMsg = $root.proto.MsgOpaqueData.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.quotedMsg = $root.proto.MsgOpaqueData.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a MsgRowOpaqueData message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.MsgRowOpaqueData
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.MsgRowOpaqueData} MsgRowOpaqueData
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        MsgRowOpaqueData.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a MsgRowOpaqueData message.
         * @function verify
         * @memberof proto.MsgRowOpaqueData
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        MsgRowOpaqueData.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.currentMsg != null && message.hasOwnProperty("currentMsg")) {
                var error = $root.proto.MsgOpaqueData.verify(message.currentMsg);
                if (error)
                    return "currentMsg." + error;
            }
            if (message.quotedMsg != null && message.hasOwnProperty("quotedMsg")) {
                var error = $root.proto.MsgOpaqueData.verify(message.quotedMsg);
                if (error)
                    return "quotedMsg." + error;
            }
            return null;
        };

        /**
         * Creates a MsgRowOpaqueData message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.MsgRowOpaqueData
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.MsgRowOpaqueData} MsgRowOpaqueData
         */
        MsgRowOpaqueData.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.MsgRowOpaqueData)
                return object;
            var message = new $root.proto.MsgRowOpaqueData();
            if (object.currentMsg != null) {
                if (typeof object.currentMsg !== "object")
                    throw TypeError(".proto.MsgRowOpaqueData.currentMsg: object expected");
                message.currentMsg = $root.proto.MsgOpaqueData.fromObject(object.currentMsg);
            }
            if (object.quotedMsg != null) {
                if (typeof object.quotedMsg !== "object")
                    throw TypeError(".proto.MsgRowOpaqueData.quotedMsg: object expected");
                message.quotedMsg = $root.proto.MsgOpaqueData.fromObject(object.quotedMsg);
            }
            return message;
        };

        /**
         * Creates a plain object from a MsgRowOpaqueData message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.MsgRowOpaqueData
         * @static
         * @param {proto.MsgRowOpaqueData} message MsgRowOpaqueData
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        MsgRowOpaqueData.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.currentMsg = null;
                object.quotedMsg = null;
            }
            if (message.currentMsg != null && message.hasOwnProperty("currentMsg"))
                object.currentMsg = $root.proto.MsgOpaqueData.toObject(message.currentMsg, options);
            if (message.quotedMsg != null && message.hasOwnProperty("quotedMsg"))
                object.quotedMsg = $root.proto.MsgOpaqueData.toObject(message.quotedMsg, options);
            return object;
        };

        /**
         * Converts this MsgRowOpaqueData to JSON.
         * @function toJSON
         * @memberof proto.MsgRowOpaqueData
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        MsgRowOpaqueData.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return MsgRowOpaqueData;
    })();

    proto.GlobalSettings = (function() {

        /**
         * Properties of a GlobalSettings.
         * @memberof proto
         * @interface IGlobalSettings
         * @property {proto.IWallpaperSettings|null} [lightThemeWallpaper] GlobalSettings lightThemeWallpaper
         * @property {proto.MediaVisibility|null} [mediaVisibility] GlobalSettings mediaVisibility
         * @property {proto.IWallpaperSettings|null} [darkThemeWallpaper] GlobalSettings darkThemeWallpaper
         */

        /**
         * Constructs a new GlobalSettings.
         * @memberof proto
         * @classdesc Represents a GlobalSettings.
         * @implements IGlobalSettings
         * @constructor
         * @param {proto.IGlobalSettings=} [properties] Properties to set
         */
        function GlobalSettings(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * GlobalSettings lightThemeWallpaper.
         * @member {proto.IWallpaperSettings|null|undefined} lightThemeWallpaper
         * @memberof proto.GlobalSettings
         * @instance
         */
        GlobalSettings.prototype.lightThemeWallpaper = null;

        /**
         * GlobalSettings mediaVisibility.
         * @member {proto.MediaVisibility} mediaVisibility
         * @memberof proto.GlobalSettings
         * @instance
         */
        GlobalSettings.prototype.mediaVisibility = 0;

        /**
         * GlobalSettings darkThemeWallpaper.
         * @member {proto.IWallpaperSettings|null|undefined} darkThemeWallpaper
         * @memberof proto.GlobalSettings
         * @instance
         */
        GlobalSettings.prototype.darkThemeWallpaper = null;

        /**
         * Creates a new GlobalSettings instance using the specified properties.
         * @function create
         * @memberof proto.GlobalSettings
         * @static
         * @param {proto.IGlobalSettings=} [properties] Properties to set
         * @returns {proto.GlobalSettings} GlobalSettings instance
         */
        GlobalSettings.create = function create(properties) {
            return new GlobalSettings(properties);
        };

        /**
         * Encodes the specified GlobalSettings message. Does not implicitly {@link proto.GlobalSettings.verify|verify} messages.
         * @function encode
         * @memberof proto.GlobalSettings
         * @static
         * @param {proto.IGlobalSettings} message GlobalSettings message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        GlobalSettings.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.lightThemeWallpaper != null && Object.hasOwnProperty.call(message, "lightThemeWallpaper"))
                $root.proto.WallpaperSettings.encode(message.lightThemeWallpaper, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.mediaVisibility != null && Object.hasOwnProperty.call(message, "mediaVisibility"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.mediaVisibility);
            if (message.darkThemeWallpaper != null && Object.hasOwnProperty.call(message, "darkThemeWallpaper"))
                $root.proto.WallpaperSettings.encode(message.darkThemeWallpaper, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified GlobalSettings message, length delimited. Does not implicitly {@link proto.GlobalSettings.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.GlobalSettings
         * @static
         * @param {proto.IGlobalSettings} message GlobalSettings message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        GlobalSettings.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a GlobalSettings message from the specified reader or buffer.
         * @function decode
         * @memberof proto.GlobalSettings
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.GlobalSettings} GlobalSettings
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        GlobalSettings.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.GlobalSettings();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.lightThemeWallpaper = $root.proto.WallpaperSettings.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.mediaVisibility = reader.int32();
                    break;
                case 3:
                    message.darkThemeWallpaper = $root.proto.WallpaperSettings.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a GlobalSettings message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.GlobalSettings
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.GlobalSettings} GlobalSettings
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        GlobalSettings.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a GlobalSettings message.
         * @function verify
         * @memberof proto.GlobalSettings
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        GlobalSettings.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.lightThemeWallpaper != null && message.hasOwnProperty("lightThemeWallpaper")) {
                var error = $root.proto.WallpaperSettings.verify(message.lightThemeWallpaper);
                if (error)
                    return "lightThemeWallpaper." + error;
            }
            if (message.mediaVisibility != null && message.hasOwnProperty("mediaVisibility"))
                switch (message.mediaVisibility) {
                default:
                    return "mediaVisibility: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            if (message.darkThemeWallpaper != null && message.hasOwnProperty("darkThemeWallpaper")) {
                var error = $root.proto.WallpaperSettings.verify(message.darkThemeWallpaper);
                if (error)
                    return "darkThemeWallpaper." + error;
            }
            return null;
        };

        /**
         * Creates a GlobalSettings message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.GlobalSettings
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.GlobalSettings} GlobalSettings
         */
        GlobalSettings.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.GlobalSettings)
                return object;
            var message = new $root.proto.GlobalSettings();
            if (object.lightThemeWallpaper != null) {
                if (typeof object.lightThemeWallpaper !== "object")
                    throw TypeError(".proto.GlobalSettings.lightThemeWallpaper: object expected");
                message.lightThemeWallpaper = $root.proto.WallpaperSettings.fromObject(object.lightThemeWallpaper);
            }
            switch (object.mediaVisibility) {
            case "DEFAULT":
            case 0:
                message.mediaVisibility = 0;
                break;
            case "OFF":
            case 1:
                message.mediaVisibility = 1;
                break;
            case "ON":
            case 2:
                message.mediaVisibility = 2;
                break;
            }
            if (object.darkThemeWallpaper != null) {
                if (typeof object.darkThemeWallpaper !== "object")
                    throw TypeError(".proto.GlobalSettings.darkThemeWallpaper: object expected");
                message.darkThemeWallpaper = $root.proto.WallpaperSettings.fromObject(object.darkThemeWallpaper);
            }
            return message;
        };

        /**
         * Creates a plain object from a GlobalSettings message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.GlobalSettings
         * @static
         * @param {proto.GlobalSettings} message GlobalSettings
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        GlobalSettings.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.lightThemeWallpaper = null;
                object.mediaVisibility = options.enums === String ? "DEFAULT" : 0;
                object.darkThemeWallpaper = null;
            }
            if (message.lightThemeWallpaper != null && message.hasOwnProperty("lightThemeWallpaper"))
                object.lightThemeWallpaper = $root.proto.WallpaperSettings.toObject(message.lightThemeWallpaper, options);
            if (message.mediaVisibility != null && message.hasOwnProperty("mediaVisibility"))
                object.mediaVisibility = options.enums === String ? $root.proto.MediaVisibility[message.mediaVisibility] : message.mediaVisibility;
            if (message.darkThemeWallpaper != null && message.hasOwnProperty("darkThemeWallpaper"))
                object.darkThemeWallpaper = $root.proto.WallpaperSettings.toObject(message.darkThemeWallpaper, options);
            return object;
        };

        /**
         * Converts this GlobalSettings to JSON.
         * @function toJSON
         * @memberof proto.GlobalSettings
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        GlobalSettings.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return GlobalSettings;
    })();

    proto.WallpaperSettings = (function() {

        /**
         * Properties of a WallpaperSettings.
         * @memberof proto
         * @interface IWallpaperSettings
         * @property {string|null} [filename] WallpaperSettings filename
         * @property {number|null} [opacity] WallpaperSettings opacity
         */

        /**
         * Constructs a new WallpaperSettings.
         * @memberof proto
         * @classdesc Represents a WallpaperSettings.
         * @implements IWallpaperSettings
         * @constructor
         * @param {proto.IWallpaperSettings=} [properties] Properties to set
         */
        function WallpaperSettings(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * WallpaperSettings filename.
         * @member {string} filename
         * @memberof proto.WallpaperSettings
         * @instance
         */
        WallpaperSettings.prototype.filename = "";

        /**
         * WallpaperSettings opacity.
         * @member {number} opacity
         * @memberof proto.WallpaperSettings
         * @instance
         */
        WallpaperSettings.prototype.opacity = 0;

        /**
         * Creates a new WallpaperSettings instance using the specified properties.
         * @function create
         * @memberof proto.WallpaperSettings
         * @static
         * @param {proto.IWallpaperSettings=} [properties] Properties to set
         * @returns {proto.WallpaperSettings} WallpaperSettings instance
         */
        WallpaperSettings.create = function create(properties) {
            return new WallpaperSettings(properties);
        };

        /**
         * Encodes the specified WallpaperSettings message. Does not implicitly {@link proto.WallpaperSettings.verify|verify} messages.
         * @function encode
         * @memberof proto.WallpaperSettings
         * @static
         * @param {proto.IWallpaperSettings} message WallpaperSettings message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        WallpaperSettings.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.filename != null && Object.hasOwnProperty.call(message, "filename"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.filename);
            if (message.opacity != null && Object.hasOwnProperty.call(message, "opacity"))
                writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.opacity);
            return writer;
        };

        /**
         * Encodes the specified WallpaperSettings message, length delimited. Does not implicitly {@link proto.WallpaperSettings.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.WallpaperSettings
         * @static
         * @param {proto.IWallpaperSettings} message WallpaperSettings message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        WallpaperSettings.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a WallpaperSettings message from the specified reader or buffer.
         * @function decode
         * @memberof proto.WallpaperSettings
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.WallpaperSettings} WallpaperSettings
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        WallpaperSettings.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.WallpaperSettings();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.filename = reader.string();
                    break;
                case 2:
                    message.opacity = reader.uint32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a WallpaperSettings message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.WallpaperSettings
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.WallpaperSettings} WallpaperSettings
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        WallpaperSettings.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a WallpaperSettings message.
         * @function verify
         * @memberof proto.WallpaperSettings
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        WallpaperSettings.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.filename != null && message.hasOwnProperty("filename"))
                if (!$util.isString(message.filename))
                    return "filename: string expected";
            if (message.opacity != null && message.hasOwnProperty("opacity"))
                if (!$util.isInteger(message.opacity))
                    return "opacity: integer expected";
            return null;
        };

        /**
         * Creates a WallpaperSettings message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.WallpaperSettings
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.WallpaperSettings} WallpaperSettings
         */
        WallpaperSettings.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.WallpaperSettings)
                return object;
            var message = new $root.proto.WallpaperSettings();
            if (object.filename != null)
                message.filename = String(object.filename);
            if (object.opacity != null)
                message.opacity = object.opacity >>> 0;
            return message;
        };

        /**
         * Creates a plain object from a WallpaperSettings message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.WallpaperSettings
         * @static
         * @param {proto.WallpaperSettings} message WallpaperSettings
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        WallpaperSettings.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.filename = "";
                object.opacity = 0;
            }
            if (message.filename != null && message.hasOwnProperty("filename"))
                object.filename = message.filename;
            if (message.opacity != null && message.hasOwnProperty("opacity"))
                object.opacity = message.opacity;
            return object;
        };

        /**
         * Converts this WallpaperSettings to JSON.
         * @function toJSON
         * @memberof proto.WallpaperSettings
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        WallpaperSettings.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return WallpaperSettings;
    })();

    proto.GroupParticipant = (function() {

        /**
         * Properties of a GroupParticipant.
         * @memberof proto
         * @interface IGroupParticipant
         * @property {string} userJid GroupParticipant userJid
         * @property {proto.GroupParticipant.GroupParticipantRank|null} [rank] GroupParticipant rank
         */

        /**
         * Constructs a new GroupParticipant.
         * @memberof proto
         * @classdesc Represents a GroupParticipant.
         * @implements IGroupParticipant
         * @constructor
         * @param {proto.IGroupParticipant=} [properties] Properties to set
         */
        function GroupParticipant(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * GroupParticipant userJid.
         * @member {string} userJid
         * @memberof proto.GroupParticipant
         * @instance
         */
        GroupParticipant.prototype.userJid = "";

        /**
         * GroupParticipant rank.
         * @member {proto.GroupParticipant.GroupParticipantRank} rank
         * @memberof proto.GroupParticipant
         * @instance
         */
        GroupParticipant.prototype.rank = 0;

        /**
         * Creates a new GroupParticipant instance using the specified properties.
         * @function create
         * @memberof proto.GroupParticipant
         * @static
         * @param {proto.IGroupParticipant=} [properties] Properties to set
         * @returns {proto.GroupParticipant} GroupParticipant instance
         */
        GroupParticipant.create = function create(properties) {
            return new GroupParticipant(properties);
        };

        /**
         * Encodes the specified GroupParticipant message. Does not implicitly {@link proto.GroupParticipant.verify|verify} messages.
         * @function encode
         * @memberof proto.GroupParticipant
         * @static
         * @param {proto.IGroupParticipant} message GroupParticipant message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        GroupParticipant.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            writer.uint32(/* id 1, wireType 2 =*/10).string(message.userJid);
            if (message.rank != null && Object.hasOwnProperty.call(message, "rank"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.rank);
            return writer;
        };

        /**
         * Encodes the specified GroupParticipant message, length delimited. Does not implicitly {@link proto.GroupParticipant.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.GroupParticipant
         * @static
         * @param {proto.IGroupParticipant} message GroupParticipant message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        GroupParticipant.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a GroupParticipant message from the specified reader or buffer.
         * @function decode
         * @memberof proto.GroupParticipant
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.GroupParticipant} GroupParticipant
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        GroupParticipant.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.GroupParticipant();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.userJid = reader.string();
                    break;
                case 2:
                    message.rank = reader.int32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            if (!message.hasOwnProperty("userJid"))
                throw $util.ProtocolError("missing required 'userJid'", { instance: message });
            return message;
        };

        /**
         * Decodes a GroupParticipant message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.GroupParticipant
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.GroupParticipant} GroupParticipant
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        GroupParticipant.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a GroupParticipant message.
         * @function verify
         * @memberof proto.GroupParticipant
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        GroupParticipant.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (!$util.isString(message.userJid))
                return "userJid: string expected";
            if (message.rank != null && message.hasOwnProperty("rank"))
                switch (message.rank) {
                default:
                    return "rank: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            return null;
        };

        /**
         * Creates a GroupParticipant message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.GroupParticipant
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.GroupParticipant} GroupParticipant
         */
        GroupParticipant.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.GroupParticipant)
                return object;
            var message = new $root.proto.GroupParticipant();
            if (object.userJid != null)
                message.userJid = String(object.userJid);
            switch (object.rank) {
            case "REGULAR":
            case 0:
                message.rank = 0;
                break;
            case "ADMIN":
            case 1:
                message.rank = 1;
                break;
            case "SUPERADMIN":
            case 2:
                message.rank = 2;
                break;
            }
            return message;
        };

        /**
         * Creates a plain object from a GroupParticipant message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.GroupParticipant
         * @static
         * @param {proto.GroupParticipant} message GroupParticipant
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        GroupParticipant.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.userJid = "";
                object.rank = options.enums === String ? "REGULAR" : 0;
            }
            if (message.userJid != null && message.hasOwnProperty("userJid"))
                object.userJid = message.userJid;
            if (message.rank != null && message.hasOwnProperty("rank"))
                object.rank = options.enums === String ? $root.proto.GroupParticipant.GroupParticipantRank[message.rank] : message.rank;
            return object;
        };

        /**
         * Converts this GroupParticipant to JSON.
         * @function toJSON
         * @memberof proto.GroupParticipant
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        GroupParticipant.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * GroupParticipantRank enum.
         * @name proto.GroupParticipant.GroupParticipantRank
         * @enum {number}
         * @property {number} REGULAR=0 REGULAR value
         * @property {number} ADMIN=1 ADMIN value
         * @property {number} SUPERADMIN=2 SUPERADMIN value
         */
        GroupParticipant.GroupParticipantRank = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "REGULAR"] = 0;
            values[valuesById[1] = "ADMIN"] = 1;
            values[valuesById[2] = "SUPERADMIN"] = 2;
            return values;
        })();

        return GroupParticipant;
    })();

    proto.Pushname = (function() {

        /**
         * Properties of a Pushname.
         * @memberof proto
         * @interface IPushname
         * @property {string|null} [id] Pushname id
         * @property {string|null} [pushname] Pushname pushname
         */

        /**
         * Constructs a new Pushname.
         * @memberof proto
         * @classdesc Represents a Pushname.
         * @implements IPushname
         * @constructor
         * @param {proto.IPushname=} [properties] Properties to set
         */
        function Pushname(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Pushname id.
         * @member {string} id
         * @memberof proto.Pushname
         * @instance
         */
        Pushname.prototype.id = "";

        /**
         * Pushname pushname.
         * @member {string} pushname
         * @memberof proto.Pushname
         * @instance
         */
        Pushname.prototype.pushname = "";

        /**
         * Creates a new Pushname instance using the specified properties.
         * @function create
         * @memberof proto.Pushname
         * @static
         * @param {proto.IPushname=} [properties] Properties to set
         * @returns {proto.Pushname} Pushname instance
         */
        Pushname.create = function create(properties) {
            return new Pushname(properties);
        };

        /**
         * Encodes the specified Pushname message. Does not implicitly {@link proto.Pushname.verify|verify} messages.
         * @function encode
         * @memberof proto.Pushname
         * @static
         * @param {proto.IPushname} message Pushname message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Pushname.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.id);
            if (message.pushname != null && Object.hasOwnProperty.call(message, "pushname"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.pushname);
            return writer;
        };

        /**
         * Encodes the specified Pushname message, length delimited. Does not implicitly {@link proto.Pushname.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.Pushname
         * @static
         * @param {proto.IPushname} message Pushname message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Pushname.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a Pushname message from the specified reader or buffer.
         * @function decode
         * @memberof proto.Pushname
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.Pushname} Pushname
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Pushname.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Pushname();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.id = reader.string();
                    break;
                case 2:
                    message.pushname = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a Pushname message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.Pushname
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.Pushname} Pushname
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Pushname.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a Pushname message.
         * @function verify
         * @memberof proto.Pushname
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        Pushname.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isString(message.id))
                    return "id: string expected";
            if (message.pushname != null && message.hasOwnProperty("pushname"))
                if (!$util.isString(message.pushname))
                    return "pushname: string expected";
            return null;
        };

        /**
         * Creates a Pushname message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.Pushname
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.Pushname} Pushname
         */
        Pushname.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.Pushname)
                return object;
            var message = new $root.proto.Pushname();
            if (object.id != null)
                message.id = String(object.id);
            if (object.pushname != null)
                message.pushname = String(object.pushname);
            return message;
        };

        /**
         * Creates a plain object from a Pushname message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.Pushname
         * @static
         * @param {proto.Pushname} message Pushname
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        Pushname.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.id = "";
                object.pushname = "";
            }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.pushname != null && message.hasOwnProperty("pushname"))
                object.pushname = message.pushname;
            return object;
        };

        /**
         * Converts this Pushname to JSON.
         * @function toJSON
         * @memberof proto.Pushname
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        Pushname.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return Pushname;
    })();

    proto.HistorySyncMsg = (function() {

        /**
         * Properties of a HistorySyncMsg.
         * @memberof proto
         * @interface IHistorySyncMsg
         * @property {proto.IWebMessageInfo|null} [message] HistorySyncMsg message
         * @property {number|Long|null} [msgOrderId] HistorySyncMsg msgOrderId
         */

        /**
         * Constructs a new HistorySyncMsg.
         * @memberof proto
         * @classdesc Represents a HistorySyncMsg.
         * @implements IHistorySyncMsg
         * @constructor
         * @param {proto.IHistorySyncMsg=} [properties] Properties to set
         */
        function HistorySyncMsg(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * HistorySyncMsg message.
         * @member {proto.IWebMessageInfo|null|undefined} message
         * @memberof proto.HistorySyncMsg
         * @instance
         */
        HistorySyncMsg.prototype.message = null;

        /**
         * HistorySyncMsg msgOrderId.
         * @member {number|Long} msgOrderId
         * @memberof proto.HistorySyncMsg
         * @instance
         */
        HistorySyncMsg.prototype.msgOrderId = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * Creates a new HistorySyncMsg instance using the specified properties.
         * @function create
         * @memberof proto.HistorySyncMsg
         * @static
         * @param {proto.IHistorySyncMsg=} [properties] Properties to set
         * @returns {proto.HistorySyncMsg} HistorySyncMsg instance
         */
        HistorySyncMsg.create = function create(properties) {
            return new HistorySyncMsg(properties);
        };

        /**
         * Encodes the specified HistorySyncMsg message. Does not implicitly {@link proto.HistorySyncMsg.verify|verify} messages.
         * @function encode
         * @memberof proto.HistorySyncMsg
         * @static
         * @param {proto.IHistorySyncMsg} message HistorySyncMsg message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HistorySyncMsg.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.message != null && Object.hasOwnProperty.call(message, "message"))
                $root.proto.WebMessageInfo.encode(message.message, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.msgOrderId != null && Object.hasOwnProperty.call(message, "msgOrderId"))
                writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.msgOrderId);
            return writer;
        };

        /**
         * Encodes the specified HistorySyncMsg message, length delimited. Does not implicitly {@link proto.HistorySyncMsg.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.HistorySyncMsg
         * @static
         * @param {proto.IHistorySyncMsg} message HistorySyncMsg message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HistorySyncMsg.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a HistorySyncMsg message from the specified reader or buffer.
         * @function decode
         * @memberof proto.HistorySyncMsg
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.HistorySyncMsg} HistorySyncMsg
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HistorySyncMsg.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HistorySyncMsg();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.message = $root.proto.WebMessageInfo.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.msgOrderId = reader.uint64();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a HistorySyncMsg message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.HistorySyncMsg
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.HistorySyncMsg} HistorySyncMsg
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HistorySyncMsg.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a HistorySyncMsg message.
         * @function verify
         * @memberof proto.HistorySyncMsg
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        HistorySyncMsg.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.message != null && message.hasOwnProperty("message")) {
                var error = $root.proto.WebMessageInfo.verify(message.message);
                if (error)
                    return "message." + error;
            }
            if (message.msgOrderId != null && message.hasOwnProperty("msgOrderId"))
                if (!$util.isInteger(message.msgOrderId) && !(message.msgOrderId && $util.isInteger(message.msgOrderId.low) && $util.isInteger(message.msgOrderId.high)))
                    return "msgOrderId: integer|Long expected";
            return null;
        };

        /**
         * Creates a HistorySyncMsg message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.HistorySyncMsg
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.HistorySyncMsg} HistorySyncMsg
         */
        HistorySyncMsg.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.HistorySyncMsg)
                return object;
            var message = new $root.proto.HistorySyncMsg();
            if (object.message != null) {
                if (typeof object.message !== "object")
                    throw TypeError(".proto.HistorySyncMsg.message: object expected");
                message.message = $root.proto.WebMessageInfo.fromObject(object.message);
            }
            if (object.msgOrderId != null)
                if ($util.Long)
                    (message.msgOrderId = $util.Long.fromValue(object.msgOrderId)).unsigned = true;
                else if (typeof object.msgOrderId === "string")
                    message.msgOrderId = parseInt(object.msgOrderId, 10);
                else if (typeof object.msgOrderId === "number")
                    message.msgOrderId = object.msgOrderId;
                else if (typeof object.msgOrderId === "object")
                    message.msgOrderId = new $util.LongBits(object.msgOrderId.low >>> 0, object.msgOrderId.high >>> 0).toNumber(true);
            return message;
        };

        /**
         * Creates a plain object from a HistorySyncMsg message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.HistorySyncMsg
         * @static
         * @param {proto.HistorySyncMsg} message HistorySyncMsg
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        HistorySyncMsg.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.message = null;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.msgOrderId = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.msgOrderId = options.longs === String ? "0" : 0;
            }
            if (message.message != null && message.hasOwnProperty("message"))
                object.message = $root.proto.WebMessageInfo.toObject(message.message, options);
            if (message.msgOrderId != null && message.hasOwnProperty("msgOrderId"))
                if (typeof message.msgOrderId === "number")
                    object.msgOrderId = options.longs === String ? String(message.msgOrderId) : message.msgOrderId;
                else
                    object.msgOrderId = options.longs === String ? $util.Long.prototype.toString.call(message.msgOrderId) : options.longs === Number ? new $util.LongBits(message.msgOrderId.low >>> 0, message.msgOrderId.high >>> 0).toNumber(true) : message.msgOrderId;
            return object;
        };

        /**
         * Converts this HistorySyncMsg to JSON.
         * @function toJSON
         * @memberof proto.HistorySyncMsg
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        HistorySyncMsg.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return HistorySyncMsg;
    })();

    proto.Conversation = (function() {

        /**
         * Properties of a Conversation.
         * @memberof proto
         * @interface IConversation
         * @property {string} id Conversation id
         * @property {Array.<proto.IHistorySyncMsg>|null} [messages] Conversation messages
         * @property {string|null} [newJid] Conversation newJid
         * @property {string|null} [oldJid] Conversation oldJid
         * @property {number|Long|null} [lastMsgTimestamp] Conversation lastMsgTimestamp
         * @property {number|null} [unreadCount] Conversation unreadCount
         * @property {boolean|null} [readOnly] Conversation readOnly
         * @property {boolean|null} [endOfHistoryTransfer] Conversation endOfHistoryTransfer
         * @property {number|null} [ephemeralExpiration] Conversation ephemeralExpiration
         * @property {number|Long|null} [ephemeralSettingTimestamp] Conversation ephemeralSettingTimestamp
         * @property {proto.Conversation.ConversationEndOfHistoryTransferType|null} [endOfHistoryTransferType] Conversation endOfHistoryTransferType
         * @property {number|Long|null} [conversationTimestamp] Conversation conversationTimestamp
         * @property {string|null} [name] Conversation name
         * @property {string|null} [pHash] Conversation pHash
         * @property {boolean|null} [notSpam] Conversation notSpam
         * @property {boolean|null} [archived] Conversation archived
         * @property {proto.IDisappearingMode|null} [disappearingMode] Conversation disappearingMode
         * @property {number|null} [unreadMentionCount] Conversation unreadMentionCount
         * @property {boolean|null} [markedAsUnread] Conversation markedAsUnread
         * @property {Array.<proto.IGroupParticipant>|null} [participant] Conversation participant
         * @property {Uint8Array|null} [tcToken] Conversation tcToken
         * @property {number|Long|null} [tcTokenTimestamp] Conversation tcTokenTimestamp
         * @property {Uint8Array|null} [contactPrimaryIdentityKey] Conversation contactPrimaryIdentityKey
         * @property {number|null} [pinned] Conversation pinned
         * @property {number|Long|null} [muteEndTime] Conversation muteEndTime
         * @property {proto.IWallpaperSettings|null} [wallpaper] Conversation wallpaper
         * @property {proto.MediaVisibility|null} [mediaVisibility] Conversation mediaVisibility
         * @property {number|Long|null} [tcTokenSenderTimestamp] Conversation tcTokenSenderTimestamp
         * @property {boolean|null} [suspended] Conversation suspended
         */

        /**
         * Constructs a new Conversation.
         * @memberof proto
         * @classdesc Represents a Conversation.
         * @implements IConversation
         * @constructor
         * @param {proto.IConversation=} [properties] Properties to set
         */
        function Conversation(properties) {
            this.messages = [];
            this.participant = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Conversation id.
         * @member {string} id
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.id = "";

        /**
         * Conversation messages.
         * @member {Array.<proto.IHistorySyncMsg>} messages
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.messages = $util.emptyArray;

        /**
         * Conversation newJid.
         * @member {string} newJid
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.newJid = "";

        /**
         * Conversation oldJid.
         * @member {string} oldJid
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.oldJid = "";

        /**
         * Conversation lastMsgTimestamp.
         * @member {number|Long} lastMsgTimestamp
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.lastMsgTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * Conversation unreadCount.
         * @member {number} unreadCount
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.unreadCount = 0;

        /**
         * Conversation readOnly.
         * @member {boolean} readOnly
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.readOnly = false;

        /**
         * Conversation endOfHistoryTransfer.
         * @member {boolean} endOfHistoryTransfer
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.endOfHistoryTransfer = false;

        /**
         * Conversation ephemeralExpiration.
         * @member {number} ephemeralExpiration
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.ephemeralExpiration = 0;

        /**
         * Conversation ephemeralSettingTimestamp.
         * @member {number|Long} ephemeralSettingTimestamp
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.ephemeralSettingTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * Conversation endOfHistoryTransferType.
         * @member {proto.Conversation.ConversationEndOfHistoryTransferType} endOfHistoryTransferType
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.endOfHistoryTransferType = 0;

        /**
         * Conversation conversationTimestamp.
         * @member {number|Long} conversationTimestamp
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.conversationTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * Conversation name.
         * @member {string} name
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.name = "";

        /**
         * Conversation pHash.
         * @member {string} pHash
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.pHash = "";

        /**
         * Conversation notSpam.
         * @member {boolean} notSpam
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.notSpam = false;

        /**
         * Conversation archived.
         * @member {boolean} archived
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.archived = false;

        /**
         * Conversation disappearingMode.
         * @member {proto.IDisappearingMode|null|undefined} disappearingMode
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.disappearingMode = null;

        /**
         * Conversation unreadMentionCount.
         * @member {number} unreadMentionCount
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.unreadMentionCount = 0;

        /**
         * Conversation markedAsUnread.
         * @member {boolean} markedAsUnread
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.markedAsUnread = false;

        /**
         * Conversation participant.
         * @member {Array.<proto.IGroupParticipant>} participant
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.participant = $util.emptyArray;

        /**
         * Conversation tcToken.
         * @member {Uint8Array} tcToken
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.tcToken = $util.newBuffer([]);

        /**
         * Conversation tcTokenTimestamp.
         * @member {number|Long} tcTokenTimestamp
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.tcTokenTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * Conversation contactPrimaryIdentityKey.
         * @member {Uint8Array} contactPrimaryIdentityKey
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.contactPrimaryIdentityKey = $util.newBuffer([]);

        /**
         * Conversation pinned.
         * @member {number} pinned
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.pinned = 0;

        /**
         * Conversation muteEndTime.
         * @member {number|Long} muteEndTime
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.muteEndTime = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * Conversation wallpaper.
         * @member {proto.IWallpaperSettings|null|undefined} wallpaper
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.wallpaper = null;

        /**
         * Conversation mediaVisibility.
         * @member {proto.MediaVisibility} mediaVisibility
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.mediaVisibility = 0;

        /**
         * Conversation tcTokenSenderTimestamp.
         * @member {number|Long} tcTokenSenderTimestamp
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.tcTokenSenderTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * Conversation suspended.
         * @member {boolean} suspended
         * @memberof proto.Conversation
         * @instance
         */
        Conversation.prototype.suspended = false;

        /**
         * Creates a new Conversation instance using the specified properties.
         * @function create
         * @memberof proto.Conversation
         * @static
         * @param {proto.IConversation=} [properties] Properties to set
         * @returns {proto.Conversation} Conversation instance
         */
        Conversation.create = function create(properties) {
            return new Conversation(properties);
        };

        /**
         * Encodes the specified Conversation message. Does not implicitly {@link proto.Conversation.verify|verify} messages.
         * @function encode
         * @memberof proto.Conversation
         * @static
         * @param {proto.IConversation} message Conversation message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Conversation.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            writer.uint32(/* id 1, wireType 2 =*/10).string(message.id);
            if (message.messages != null && message.messages.length)
                for (var i = 0; i < message.messages.length; ++i)
                    $root.proto.HistorySyncMsg.encode(message.messages[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.newJid != null && Object.hasOwnProperty.call(message, "newJid"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.newJid);
            if (message.oldJid != null && Object.hasOwnProperty.call(message, "oldJid"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.oldJid);
            if (message.lastMsgTimestamp != null && Object.hasOwnProperty.call(message, "lastMsgTimestamp"))
                writer.uint32(/* id 5, wireType 0 =*/40).uint64(message.lastMsgTimestamp);
            if (message.unreadCount != null && Object.hasOwnProperty.call(message, "unreadCount"))
                writer.uint32(/* id 6, wireType 0 =*/48).uint32(message.unreadCount);
            if (message.readOnly != null && Object.hasOwnProperty.call(message, "readOnly"))
                writer.uint32(/* id 7, wireType 0 =*/56).bool(message.readOnly);
            if (message.endOfHistoryTransfer != null && Object.hasOwnProperty.call(message, "endOfHistoryTransfer"))
                writer.uint32(/* id 8, wireType 0 =*/64).bool(message.endOfHistoryTransfer);
            if (message.ephemeralExpiration != null && Object.hasOwnProperty.call(message, "ephemeralExpiration"))
                writer.uint32(/* id 9, wireType 0 =*/72).uint32(message.ephemeralExpiration);
            if (message.ephemeralSettingTimestamp != null && Object.hasOwnProperty.call(message, "ephemeralSettingTimestamp"))
                writer.uint32(/* id 10, wireType 0 =*/80).int64(message.ephemeralSettingTimestamp);
            if (message.endOfHistoryTransferType != null && Object.hasOwnProperty.call(message, "endOfHistoryTransferType"))
                writer.uint32(/* id 11, wireType 0 =*/88).int32(message.endOfHistoryTransferType);
            if (message.conversationTimestamp != null && Object.hasOwnProperty.call(message, "conversationTimestamp"))
                writer.uint32(/* id 12, wireType 0 =*/96).uint64(message.conversationTimestamp);
            if (message.name != null && Object.hasOwnProperty.call(message, "name"))
                writer.uint32(/* id 13, wireType 2 =*/106).string(message.name);
            if (message.pHash != null && Object.hasOwnProperty.call(message, "pHash"))
                writer.uint32(/* id 14, wireType 2 =*/114).string(message.pHash);
            if (message.notSpam != null && Object.hasOwnProperty.call(message, "notSpam"))
                writer.uint32(/* id 15, wireType 0 =*/120).bool(message.notSpam);
            if (message.archived != null && Object.hasOwnProperty.call(message, "archived"))
                writer.uint32(/* id 16, wireType 0 =*/128).bool(message.archived);
            if (message.disappearingMode != null && Object.hasOwnProperty.call(message, "disappearingMode"))
                $root.proto.DisappearingMode.encode(message.disappearingMode, writer.uint32(/* id 17, wireType 2 =*/138).fork()).ldelim();
            if (message.unreadMentionCount != null && Object.hasOwnProperty.call(message, "unreadMentionCount"))
                writer.uint32(/* id 18, wireType 0 =*/144).uint32(message.unreadMentionCount);
            if (message.markedAsUnread != null && Object.hasOwnProperty.call(message, "markedAsUnread"))
                writer.uint32(/* id 19, wireType 0 =*/152).bool(message.markedAsUnread);
            if (message.participant != null && message.participant.length)
                for (var i = 0; i < message.participant.length; ++i)
                    $root.proto.GroupParticipant.encode(message.participant[i], writer.uint32(/* id 20, wireType 2 =*/162).fork()).ldelim();
            if (message.tcToken != null && Object.hasOwnProperty.call(message, "tcToken"))
                writer.uint32(/* id 21, wireType 2 =*/170).bytes(message.tcToken);
            if (message.tcTokenTimestamp != null && Object.hasOwnProperty.call(message, "tcTokenTimestamp"))
                writer.uint32(/* id 22, wireType 0 =*/176).uint64(message.tcTokenTimestamp);
            if (message.contactPrimaryIdentityKey != null && Object.hasOwnProperty.call(message, "contactPrimaryIdentityKey"))
                writer.uint32(/* id 23, wireType 2 =*/186).bytes(message.contactPrimaryIdentityKey);
            if (message.pinned != null && Object.hasOwnProperty.call(message, "pinned"))
                writer.uint32(/* id 24, wireType 0 =*/192).uint32(message.pinned);
            if (message.muteEndTime != null && Object.hasOwnProperty.call(message, "muteEndTime"))
                writer.uint32(/* id 25, wireType 0 =*/200).uint64(message.muteEndTime);
            if (message.wallpaper != null && Object.hasOwnProperty.call(message, "wallpaper"))
                $root.proto.WallpaperSettings.encode(message.wallpaper, writer.uint32(/* id 26, wireType 2 =*/210).fork()).ldelim();
            if (message.mediaVisibility != null && Object.hasOwnProperty.call(message, "mediaVisibility"))
                writer.uint32(/* id 27, wireType 0 =*/216).int32(message.mediaVisibility);
            if (message.tcTokenSenderTimestamp != null && Object.hasOwnProperty.call(message, "tcTokenSenderTimestamp"))
                writer.uint32(/* id 28, wireType 0 =*/224).uint64(message.tcTokenSenderTimestamp);
            if (message.suspended != null && Object.hasOwnProperty.call(message, "suspended"))
                writer.uint32(/* id 29, wireType 0 =*/232).bool(message.suspended);
            return writer;
        };

        /**
         * Encodes the specified Conversation message, length delimited. Does not implicitly {@link proto.Conversation.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.Conversation
         * @static
         * @param {proto.IConversation} message Conversation message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Conversation.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a Conversation message from the specified reader or buffer.
         * @function decode
         * @memberof proto.Conversation
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.Conversation} Conversation
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Conversation.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Conversation();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.id = reader.string();
                    break;
                case 2:
                    if (!(message.messages && message.messages.length))
                        message.messages = [];
                    message.messages.push($root.proto.HistorySyncMsg.decode(reader, reader.uint32()));
                    break;
                case 3:
                    message.newJid = reader.string();
                    break;
                case 4:
                    message.oldJid = reader.string();
                    break;
                case 5:
                    message.lastMsgTimestamp = reader.uint64();
                    break;
                case 6:
                    message.unreadCount = reader.uint32();
                    break;
                case 7:
                    message.readOnly = reader.bool();
                    break;
                case 8:
                    message.endOfHistoryTransfer = reader.bool();
                    break;
                case 9:
                    message.ephemeralExpiration = reader.uint32();
                    break;
                case 10:
                    message.ephemeralSettingTimestamp = reader.int64();
                    break;
                case 11:
                    message.endOfHistoryTransferType = reader.int32();
                    break;
                case 12:
                    message.conversationTimestamp = reader.uint64();
                    break;
                case 13:
                    message.name = reader.string();
                    break;
                case 14:
                    message.pHash = reader.string();
                    break;
                case 15:
                    message.notSpam = reader.bool();
                    break;
                case 16:
                    message.archived = reader.bool();
                    break;
                case 17:
                    message.disappearingMode = $root.proto.DisappearingMode.decode(reader, reader.uint32());
                    break;
                case 18:
                    message.unreadMentionCount = reader.uint32();
                    break;
                case 19:
                    message.markedAsUnread = reader.bool();
                    break;
                case 20:
                    if (!(message.participant && message.participant.length))
                        message.participant = [];
                    message.participant.push($root.proto.GroupParticipant.decode(reader, reader.uint32()));
                    break;
                case 21:
                    message.tcToken = reader.bytes();
                    break;
                case 22:
                    message.tcTokenTimestamp = reader.uint64();
                    break;
                case 23:
                    message.contactPrimaryIdentityKey = reader.bytes();
                    break;
                case 24:
                    message.pinned = reader.uint32();
                    break;
                case 25:
                    message.muteEndTime = reader.uint64();
                    break;
                case 26:
                    message.wallpaper = $root.proto.WallpaperSettings.decode(reader, reader.uint32());
                    break;
                case 27:
                    message.mediaVisibility = reader.int32();
                    break;
                case 28:
                    message.tcTokenSenderTimestamp = reader.uint64();
                    break;
                case 29:
                    message.suspended = reader.bool();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            if (!message.hasOwnProperty("id"))
                throw $util.ProtocolError("missing required 'id'", { instance: message });
            return message;
        };

        /**
         * Decodes a Conversation message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.Conversation
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.Conversation} Conversation
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Conversation.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a Conversation message.
         * @function verify
         * @memberof proto.Conversation
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        Conversation.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (!$util.isString(message.id))
                return "id: string expected";
            if (message.messages != null && message.hasOwnProperty("messages")) {
                if (!Array.isArray(message.messages))
                    return "messages: array expected";
                for (var i = 0; i < message.messages.length; ++i) {
                    var error = $root.proto.HistorySyncMsg.verify(message.messages[i]);
                    if (error)
                        return "messages." + error;
                }
            }
            if (message.newJid != null && message.hasOwnProperty("newJid"))
                if (!$util.isString(message.newJid))
                    return "newJid: string expected";
            if (message.oldJid != null && message.hasOwnProperty("oldJid"))
                if (!$util.isString(message.oldJid))
                    return "oldJid: string expected";
            if (message.lastMsgTimestamp != null && message.hasOwnProperty("lastMsgTimestamp"))
                if (!$util.isInteger(message.lastMsgTimestamp) && !(message.lastMsgTimestamp && $util.isInteger(message.lastMsgTimestamp.low) && $util.isInteger(message.lastMsgTimestamp.high)))
                    return "lastMsgTimestamp: integer|Long expected";
            if (message.unreadCount != null && message.hasOwnProperty("unreadCount"))
                if (!$util.isInteger(message.unreadCount))
                    return "unreadCount: integer expected";
            if (message.readOnly != null && message.hasOwnProperty("readOnly"))
                if (typeof message.readOnly !== "boolean")
                    return "readOnly: boolean expected";
            if (message.endOfHistoryTransfer != null && message.hasOwnProperty("endOfHistoryTransfer"))
                if (typeof message.endOfHistoryTransfer !== "boolean")
                    return "endOfHistoryTransfer: boolean expected";
            if (message.ephemeralExpiration != null && message.hasOwnProperty("ephemeralExpiration"))
                if (!$util.isInteger(message.ephemeralExpiration))
                    return "ephemeralExpiration: integer expected";
            if (message.ephemeralSettingTimestamp != null && message.hasOwnProperty("ephemeralSettingTimestamp"))
                if (!$util.isInteger(message.ephemeralSettingTimestamp) && !(message.ephemeralSettingTimestamp && $util.isInteger(message.ephemeralSettingTimestamp.low) && $util.isInteger(message.ephemeralSettingTimestamp.high)))
                    return "ephemeralSettingTimestamp: integer|Long expected";
            if (message.endOfHistoryTransferType != null && message.hasOwnProperty("endOfHistoryTransferType"))
                switch (message.endOfHistoryTransferType) {
                default:
                    return "endOfHistoryTransferType: enum value expected";
                case 0:
                case 1:
                    break;
                }
            if (message.conversationTimestamp != null && message.hasOwnProperty("conversationTimestamp"))
                if (!$util.isInteger(message.conversationTimestamp) && !(message.conversationTimestamp && $util.isInteger(message.conversationTimestamp.low) && $util.isInteger(message.conversationTimestamp.high)))
                    return "conversationTimestamp: integer|Long expected";
            if (message.name != null && message.hasOwnProperty("name"))
                if (!$util.isString(message.name))
                    return "name: string expected";
            if (message.pHash != null && message.hasOwnProperty("pHash"))
                if (!$util.isString(message.pHash))
                    return "pHash: string expected";
            if (message.notSpam != null && message.hasOwnProperty("notSpam"))
                if (typeof message.notSpam !== "boolean")
                    return "notSpam: boolean expected";
            if (message.archived != null && message.hasOwnProperty("archived"))
                if (typeof message.archived !== "boolean")
                    return "archived: boolean expected";
            if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode")) {
                var error = $root.proto.DisappearingMode.verify(message.disappearingMode);
                if (error)
                    return "disappearingMode." + error;
            }
            if (message.unreadMentionCount != null && message.hasOwnProperty("unreadMentionCount"))
                if (!$util.isInteger(message.unreadMentionCount))
                    return "unreadMentionCount: integer expected";
            if (message.markedAsUnread != null && message.hasOwnProperty("markedAsUnread"))
                if (typeof message.markedAsUnread !== "boolean")
                    return "markedAsUnread: boolean expected";
            if (message.participant != null && message.hasOwnProperty("participant")) {
                if (!Array.isArray(message.participant))
                    return "participant: array expected";
                for (var i = 0; i < message.participant.length; ++i) {
                    var error = $root.proto.GroupParticipant.verify(message.participant[i]);
                    if (error)
                        return "participant." + error;
                }
            }
            if (message.tcToken != null && message.hasOwnProperty("tcToken"))
                if (!(message.tcToken && typeof message.tcToken.length === "number" || $util.isString(message.tcToken)))
                    return "tcToken: buffer expected";
            if (message.tcTokenTimestamp != null && message.hasOwnProperty("tcTokenTimestamp"))
                if (!$util.isInteger(message.tcTokenTimestamp) && !(message.tcTokenTimestamp && $util.isInteger(message.tcTokenTimestamp.low) && $util.isInteger(message.tcTokenTimestamp.high)))
                    return "tcTokenTimestamp: integer|Long expected";
            if (message.contactPrimaryIdentityKey != null && message.hasOwnProperty("contactPrimaryIdentityKey"))
                if (!(message.contactPrimaryIdentityKey && typeof message.contactPrimaryIdentityKey.length === "number" || $util.isString(message.contactPrimaryIdentityKey)))
                    return "contactPrimaryIdentityKey: buffer expected";
            if (message.pinned != null && message.hasOwnProperty("pinned"))
                if (!$util.isInteger(message.pinned))
                    return "pinned: integer expected";
            if (message.muteEndTime != null && message.hasOwnProperty("muteEndTime"))
                if (!$util.isInteger(message.muteEndTime) && !(message.muteEndTime && $util.isInteger(message.muteEndTime.low) && $util.isInteger(message.muteEndTime.high)))
                    return "muteEndTime: integer|Long expected";
            if (message.wallpaper != null && message.hasOwnProperty("wallpaper")) {
                var error = $root.proto.WallpaperSettings.verify(message.wallpaper);
                if (error)
                    return "wallpaper." + error;
            }
            if (message.mediaVisibility != null && message.hasOwnProperty("mediaVisibility"))
                switch (message.mediaVisibility) {
                default:
                    return "mediaVisibility: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            if (message.tcTokenSenderTimestamp != null && message.hasOwnProperty("tcTokenSenderTimestamp"))
                if (!$util.isInteger(message.tcTokenSenderTimestamp) && !(message.tcTokenSenderTimestamp && $util.isInteger(message.tcTokenSenderTimestamp.low) && $util.isInteger(message.tcTokenSenderTimestamp.high)))
                    return "tcTokenSenderTimestamp: integer|Long expected";
            if (message.suspended != null && message.hasOwnProperty("suspended"))
                if (typeof message.suspended !== "boolean")
                    return "suspended: boolean expected";
            return null;
        };

        /**
         * Creates a Conversation message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.Conversation
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.Conversation} Conversation
         */
        Conversation.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.Conversation)
                return object;
            var message = new $root.proto.Conversation();
            if (object.id != null)
                message.id = String(object.id);
            if (object.messages) {
                if (!Array.isArray(object.messages))
                    throw TypeError(".proto.Conversation.messages: array expected");
                message.messages = [];
                for (var i = 0; i < object.messages.length; ++i) {
                    if (typeof object.messages[i] !== "object")
                        throw TypeError(".proto.Conversation.messages: object expected");
                    message.messages[i] = $root.proto.HistorySyncMsg.fromObject(object.messages[i]);
                }
            }
            if (object.newJid != null)
                message.newJid = String(object.newJid);
            if (object.oldJid != null)
                message.oldJid = String(object.oldJid);
            if (object.lastMsgTimestamp != null)
                if ($util.Long)
                    (message.lastMsgTimestamp = $util.Long.fromValue(object.lastMsgTimestamp)).unsigned = true;
                else if (typeof object.lastMsgTimestamp === "string")
                    message.lastMsgTimestamp = parseInt(object.lastMsgTimestamp, 10);
                else if (typeof object.lastMsgTimestamp === "number")
                    message.lastMsgTimestamp = object.lastMsgTimestamp;
                else if (typeof object.lastMsgTimestamp === "object")
                    message.lastMsgTimestamp = new $util.LongBits(object.lastMsgTimestamp.low >>> 0, object.lastMsgTimestamp.high >>> 0).toNumber(true);
            if (object.unreadCount != null)
                message.unreadCount = object.unreadCount >>> 0;
            if (object.readOnly != null)
                message.readOnly = Boolean(object.readOnly);
            if (object.endOfHistoryTransfer != null)
                message.endOfHistoryTransfer = Boolean(object.endOfHistoryTransfer);
            if (object.ephemeralExpiration != null)
                message.ephemeralExpiration = object.ephemeralExpiration >>> 0;
            if (object.ephemeralSettingTimestamp != null)
                if ($util.Long)
                    (message.ephemeralSettingTimestamp = $util.Long.fromValue(object.ephemeralSettingTimestamp)).unsigned = false;
                else if (typeof object.ephemeralSettingTimestamp === "string")
                    message.ephemeralSettingTimestamp = parseInt(object.ephemeralSettingTimestamp, 10);
                else if (typeof object.ephemeralSettingTimestamp === "number")
                    message.ephemeralSettingTimestamp = object.ephemeralSettingTimestamp;
                else if (typeof object.ephemeralSettingTimestamp === "object")
                    message.ephemeralSettingTimestamp = new $util.LongBits(object.ephemeralSettingTimestamp.low >>> 0, object.ephemeralSettingTimestamp.high >>> 0).toNumber();
            switch (object.endOfHistoryTransferType) {
            case "COMPLETE_BUT_MORE_MESSAGES_REMAIN_ON_PRIMARY":
            case 0:
                message.endOfHistoryTransferType = 0;
                break;
            case "COMPLETE_AND_NO_MORE_MESSAGE_REMAIN_ON_PRIMARY":
            case 1:
                message.endOfHistoryTransferType = 1;
                break;
            }
            if (object.conversationTimestamp != null)
                if ($util.Long)
                    (message.conversationTimestamp = $util.Long.fromValue(object.conversationTimestamp)).unsigned = true;
                else if (typeof object.conversationTimestamp === "string")
                    message.conversationTimestamp = parseInt(object.conversationTimestamp, 10);
                else if (typeof object.conversationTimestamp === "number")
                    message.conversationTimestamp = object.conversationTimestamp;
                else if (typeof object.conversationTimestamp === "object")
                    message.conversationTimestamp = new $util.LongBits(object.conversationTimestamp.low >>> 0, object.conversationTimestamp.high >>> 0).toNumber(true);
            if (object.name != null)
                message.name = String(object.name);
            if (object.pHash != null)
                message.pHash = String(object.pHash);
            if (object.notSpam != null)
                message.notSpam = Boolean(object.notSpam);
            if (object.archived != null)
                message.archived = Boolean(object.archived);
            if (object.disappearingMode != null) {
                if (typeof object.disappearingMode !== "object")
                    throw TypeError(".proto.Conversation.disappearingMode: object expected");
                message.disappearingMode = $root.proto.DisappearingMode.fromObject(object.disappearingMode);
            }
            if (object.unreadMentionCount != null)
                message.unreadMentionCount = object.unreadMentionCount >>> 0;
            if (object.markedAsUnread != null)
                message.markedAsUnread = Boolean(object.markedAsUnread);
            if (object.participant) {
                if (!Array.isArray(object.participant))
                    throw TypeError(".proto.Conversation.participant: array expected");
                message.participant = [];
                for (var i = 0; i < object.participant.length; ++i) {
                    if (typeof object.participant[i] !== "object")
                        throw TypeError(".proto.Conversation.participant: object expected");
                    message.participant[i] = $root.proto.GroupParticipant.fromObject(object.participant[i]);
                }
            }
            if (object.tcToken != null)
                if (typeof object.tcToken === "string")
                    $util.base64.decode(object.tcToken, message.tcToken = $util.newBuffer($util.base64.length(object.tcToken)), 0);
                else if (object.tcToken.length)
                    message.tcToken = object.tcToken;
            if (object.tcTokenTimestamp != null)
                if ($util.Long)
                    (message.tcTokenTimestamp = $util.Long.fromValue(object.tcTokenTimestamp)).unsigned = true;
                else if (typeof object.tcTokenTimestamp === "string")
                    message.tcTokenTimestamp = parseInt(object.tcTokenTimestamp, 10);
                else if (typeof object.tcTokenTimestamp === "number")
                    message.tcTokenTimestamp = object.tcTokenTimestamp;
                else if (typeof object.tcTokenTimestamp === "object")
                    message.tcTokenTimestamp = new $util.LongBits(object.tcTokenTimestamp.low >>> 0, object.tcTokenTimestamp.high >>> 0).toNumber(true);
            if (object.contactPrimaryIdentityKey != null)
                if (typeof object.contactPrimaryIdentityKey === "string")
                    $util.base64.decode(object.contactPrimaryIdentityKey, message.contactPrimaryIdentityKey = $util.newBuffer($util.base64.length(object.contactPrimaryIdentityKey)), 0);
                else if (object.contactPrimaryIdentityKey.length)
                    message.contactPrimaryIdentityKey = object.contactPrimaryIdentityKey;
            if (object.pinned != null)
                message.pinned = object.pinned >>> 0;
            if (object.muteEndTime != null)
                if ($util.Long)
                    (message.muteEndTime = $util.Long.fromValue(object.muteEndTime)).unsigned = true;
                else if (typeof object.muteEndTime === "string")
                    message.muteEndTime = parseInt(object.muteEndTime, 10);
                else if (typeof object.muteEndTime === "number")
                    message.muteEndTime = object.muteEndTime;
                else if (typeof object.muteEndTime === "object")
                    message.muteEndTime = new $util.LongBits(object.muteEndTime.low >>> 0, object.muteEndTime.high >>> 0).toNumber(true);
            if (object.wallpaper != null) {
                if (typeof object.wallpaper !== "object")
                    throw TypeError(".proto.Conversation.wallpaper: object expected");
                message.wallpaper = $root.proto.WallpaperSettings.fromObject(object.wallpaper);
            }
            switch (object.mediaVisibility) {
            case "DEFAULT":
            case 0:
                message.mediaVisibility = 0;
                break;
            case "OFF":
            case 1:
                message.mediaVisibility = 1;
                break;
            case "ON":
            case 2:
                message.mediaVisibility = 2;
                break;
            }
            if (object.tcTokenSenderTimestamp != null)
                if ($util.Long)
                    (message.tcTokenSenderTimestamp = $util.Long.fromValue(object.tcTokenSenderTimestamp)).unsigned = true;
                else if (typeof object.tcTokenSenderTimestamp === "string")
                    message.tcTokenSenderTimestamp = parseInt(object.tcTokenSenderTimestamp, 10);
                else if (typeof object.tcTokenSenderTimestamp === "number")
                    message.tcTokenSenderTimestamp = object.tcTokenSenderTimestamp;
                else if (typeof object.tcTokenSenderTimestamp === "object")
                    message.tcTokenSenderTimestamp = new $util.LongBits(object.tcTokenSenderTimestamp.low >>> 0, object.tcTokenSenderTimestamp.high >>> 0).toNumber(true);
            if (object.suspended != null)
                message.suspended = Boolean(object.suspended);
            return message;
        };

        /**
         * Creates a plain object from a Conversation message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.Conversation
         * @static
         * @param {proto.Conversation} message Conversation
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        Conversation.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults) {
                object.messages = [];
                object.participant = [];
            }
            if (options.defaults) {
                object.id = "";
                object.newJid = "";
                object.oldJid = "";
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.lastMsgTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.lastMsgTimestamp = options.longs === String ? "0" : 0;
                object.unreadCount = 0;
                object.readOnly = false;
                object.endOfHistoryTransfer = false;
                object.ephemeralExpiration = 0;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.ephemeralSettingTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.ephemeralSettingTimestamp = options.longs === String ? "0" : 0;
                object.endOfHistoryTransferType = options.enums === String ? "COMPLETE_BUT_MORE_MESSAGES_REMAIN_ON_PRIMARY" : 0;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.conversationTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.conversationTimestamp = options.longs === String ? "0" : 0;
                object.name = "";
                object.pHash = "";
                object.notSpam = false;
                object.archived = false;
                object.disappearingMode = null;
                object.unreadMentionCount = 0;
                object.markedAsUnread = false;
                if (options.bytes === String)
                    object.tcToken = "";
                else {
                    object.tcToken = [];
                    if (options.bytes !== Array)
                        object.tcToken = $util.newBuffer(object.tcToken);
                }
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.tcTokenTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.tcTokenTimestamp = options.longs === String ? "0" : 0;
                if (options.bytes === String)
                    object.contactPrimaryIdentityKey = "";
                else {
                    object.contactPrimaryIdentityKey = [];
                    if (options.bytes !== Array)
                        object.contactPrimaryIdentityKey = $util.newBuffer(object.contactPrimaryIdentityKey);
                }
                object.pinned = 0;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.muteEndTime = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.muteEndTime = options.longs === String ? "0" : 0;
                object.wallpaper = null;
                object.mediaVisibility = options.enums === String ? "DEFAULT" : 0;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.tcTokenSenderTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.tcTokenSenderTimestamp = options.longs === String ? "0" : 0;
                object.suspended = false;
            }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.messages && message.messages.length) {
                object.messages = [];
                for (var j = 0; j < message.messages.length; ++j)
                    object.messages[j] = $root.proto.HistorySyncMsg.toObject(message.messages[j], options);
            }
            if (message.newJid != null && message.hasOwnProperty("newJid"))
                object.newJid = message.newJid;
            if (message.oldJid != null && message.hasOwnProperty("oldJid"))
                object.oldJid = message.oldJid;
            if (message.lastMsgTimestamp != null && message.hasOwnProperty("lastMsgTimestamp"))
                if (typeof message.lastMsgTimestamp === "number")
                    object.lastMsgTimestamp = options.longs === String ? String(message.lastMsgTimestamp) : message.lastMsgTimestamp;
                else
                    object.lastMsgTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.lastMsgTimestamp) : options.longs === Number ? new $util.LongBits(message.lastMsgTimestamp.low >>> 0, message.lastMsgTimestamp.high >>> 0).toNumber(true) : message.lastMsgTimestamp;
            if (message.unreadCount != null && message.hasOwnProperty("unreadCount"))
                object.unreadCount = message.unreadCount;
            if (message.readOnly != null && message.hasOwnProperty("readOnly"))
                object.readOnly = message.readOnly;
            if (message.endOfHistoryTransfer != null && message.hasOwnProperty("endOfHistoryTransfer"))
                object.endOfHistoryTransfer = message.endOfHistoryTransfer;
            if (message.ephemeralExpiration != null && message.hasOwnProperty("ephemeralExpiration"))
                object.ephemeralExpiration = message.ephemeralExpiration;
            if (message.ephemeralSettingTimestamp != null && message.hasOwnProperty("ephemeralSettingTimestamp"))
                if (typeof message.ephemeralSettingTimestamp === "number")
                    object.ephemeralSettingTimestamp = options.longs === String ? String(message.ephemeralSettingTimestamp) : message.ephemeralSettingTimestamp;
                else
                    object.ephemeralSettingTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.ephemeralSettingTimestamp) : options.longs === Number ? new $util.LongBits(message.ephemeralSettingTimestamp.low >>> 0, message.ephemeralSettingTimestamp.high >>> 0).toNumber() : message.ephemeralSettingTimestamp;
            if (message.endOfHistoryTransferType != null && message.hasOwnProperty("endOfHistoryTransferType"))
                object.endOfHistoryTransferType = options.enums === String ? $root.proto.Conversation.ConversationEndOfHistoryTransferType[message.endOfHistoryTransferType] : message.endOfHistoryTransferType;
            if (message.conversationTimestamp != null && message.hasOwnProperty("conversationTimestamp"))
                if (typeof message.conversationTimestamp === "number")
                    object.conversationTimestamp = options.longs === String ? String(message.conversationTimestamp) : message.conversationTimestamp;
                else
                    object.conversationTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.conversationTimestamp) : options.longs === Number ? new $util.LongBits(message.conversationTimestamp.low >>> 0, message.conversationTimestamp.high >>> 0).toNumber(true) : message.conversationTimestamp;
            if (message.name != null && message.hasOwnProperty("name"))
                object.name = message.name;
            if (message.pHash != null && message.hasOwnProperty("pHash"))
                object.pHash = message.pHash;
            if (message.notSpam != null && message.hasOwnProperty("notSpam"))
                object.notSpam = message.notSpam;
            if (message.archived != null && message.hasOwnProperty("archived"))
                object.archived = message.archived;
            if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode"))
                object.disappearingMode = $root.proto.DisappearingMode.toObject(message.disappearingMode, options);
            if (message.unreadMentionCount != null && message.hasOwnProperty("unreadMentionCount"))
                object.unreadMentionCount = message.unreadMentionCount;
            if (message.markedAsUnread != null && message.hasOwnProperty("markedAsUnread"))
                object.markedAsUnread = message.markedAsUnread;
            if (message.participant && message.participant.length) {
                object.participant = [];
                for (var j = 0; j < message.participant.length; ++j)
                    object.participant[j] = $root.proto.GroupParticipant.toObject(message.participant[j], options);
            }
            if (message.tcToken != null && message.hasOwnProperty("tcToken"))
                object.tcToken = options.bytes === String ? $util.base64.encode(message.tcToken, 0, message.tcToken.length) : options.bytes === Array ? Array.prototype.slice.call(message.tcToken) : message.tcToken;
            if (message.tcTokenTimestamp != null && message.hasOwnProperty("tcTokenTimestamp"))
                if (typeof message.tcTokenTimestamp === "number")
                    object.tcTokenTimestamp = options.longs === String ? String(message.tcTokenTimestamp) : message.tcTokenTimestamp;
                else
                    object.tcTokenTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.tcTokenTimestamp) : options.longs === Number ? new $util.LongBits(message.tcTokenTimestamp.low >>> 0, message.tcTokenTimestamp.high >>> 0).toNumber(true) : message.tcTokenTimestamp;
            if (message.contactPrimaryIdentityKey != null && message.hasOwnProperty("contactPrimaryIdentityKey"))
                object.contactPrimaryIdentityKey = options.bytes === String ? $util.base64.encode(message.contactPrimaryIdentityKey, 0, message.contactPrimaryIdentityKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.contactPrimaryIdentityKey) : message.contactPrimaryIdentityKey;
            if (message.pinned != null && message.hasOwnProperty("pinned"))
                object.pinned = message.pinned;
            if (message.muteEndTime != null && message.hasOwnProperty("muteEndTime"))
                if (typeof message.muteEndTime === "number")
                    object.muteEndTime = options.longs === String ? String(message.muteEndTime) : message.muteEndTime;
                else
                    object.muteEndTime = options.longs === String ? $util.Long.prototype.toString.call(message.muteEndTime) : options.longs === Number ? new $util.LongBits(message.muteEndTime.low >>> 0, message.muteEndTime.high >>> 0).toNumber(true) : message.muteEndTime;
            if (message.wallpaper != null && message.hasOwnProperty("wallpaper"))
                object.wallpaper = $root.proto.WallpaperSettings.toObject(message.wallpaper, options);
            if (message.mediaVisibility != null && message.hasOwnProperty("mediaVisibility"))
                object.mediaVisibility = options.enums === String ? $root.proto.MediaVisibility[message.mediaVisibility] : message.mediaVisibility;
            if (message.tcTokenSenderTimestamp != null && message.hasOwnProperty("tcTokenSenderTimestamp"))
                if (typeof message.tcTokenSenderTimestamp === "number")
                    object.tcTokenSenderTimestamp = options.longs === String ? String(message.tcTokenSenderTimestamp) : message.tcTokenSenderTimestamp;
                else
                    object.tcTokenSenderTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.tcTokenSenderTimestamp) : options.longs === Number ? new $util.LongBits(message.tcTokenSenderTimestamp.low >>> 0, message.tcTokenSenderTimestamp.high >>> 0).toNumber(true) : message.tcTokenSenderTimestamp;
            if (message.suspended != null && message.hasOwnProperty("suspended"))
                object.suspended = message.suspended;
            return object;
        };

        /**
         * Converts this Conversation to JSON.
         * @function toJSON
         * @memberof proto.Conversation
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        Conversation.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * ConversationEndOfHistoryTransferType enum.
         * @name proto.Conversation.ConversationEndOfHistoryTransferType
         * @enum {number}
         * @property {number} COMPLETE_BUT_MORE_MESSAGES_REMAIN_ON_PRIMARY=0 COMPLETE_BUT_MORE_MESSAGES_REMAIN_ON_PRIMARY value
         * @property {number} COMPLETE_AND_NO_MORE_MESSAGE_REMAIN_ON_PRIMARY=1 COMPLETE_AND_NO_MORE_MESSAGE_REMAIN_ON_PRIMARY value
         */
        Conversation.ConversationEndOfHistoryTransferType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "COMPLETE_BUT_MORE_MESSAGES_REMAIN_ON_PRIMARY"] = 0;
            values[valuesById[1] = "COMPLETE_AND_NO_MORE_MESSAGE_REMAIN_ON_PRIMARY"] = 1;
            return values;
        })();

        return Conversation;
    })();

    proto.HistorySync = (function() {

        /**
         * Properties of a HistorySync.
         * @memberof proto
         * @interface IHistorySync
         * @property {proto.HistorySync.HistorySyncHistorySyncType} syncType HistorySync syncType
         * @property {Array.<proto.IConversation>|null} [conversations] HistorySync conversations
         * @property {Array.<proto.IWebMessageInfo>|null} [statusV3Messages] HistorySync statusV3Messages
         * @property {number|null} [chunkOrder] HistorySync chunkOrder
         * @property {number|null} [progress] HistorySync progress
         * @property {Array.<proto.IPushname>|null} [pushnames] HistorySync pushnames
         * @property {proto.IGlobalSettings|null} [globalSettings] HistorySync globalSettings
         * @property {Uint8Array|null} [threadIdUserSecret] HistorySync threadIdUserSecret
         * @property {number|null} [threadDsTimeframeOffset] HistorySync threadDsTimeframeOffset
         */

        /**
         * Constructs a new HistorySync.
         * @memberof proto
         * @classdesc Represents a HistorySync.
         * @implements IHistorySync
         * @constructor
         * @param {proto.IHistorySync=} [properties] Properties to set
         */
        function HistorySync(properties) {
            this.conversations = [];
            this.statusV3Messages = [];
            this.pushnames = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * HistorySync syncType.
         * @member {proto.HistorySync.HistorySyncHistorySyncType} syncType
         * @memberof proto.HistorySync
         * @instance
         */
        HistorySync.prototype.syncType = 0;

        /**
         * HistorySync conversations.
         * @member {Array.<proto.IConversation>} conversations
         * @memberof proto.HistorySync
         * @instance
         */
        HistorySync.prototype.conversations = $util.emptyArray;

        /**
         * HistorySync statusV3Messages.
         * @member {Array.<proto.IWebMessageInfo>} statusV3Messages
         * @memberof proto.HistorySync
         * @instance
         */
        HistorySync.prototype.statusV3Messages = $util.emptyArray;

        /**
         * HistorySync chunkOrder.
         * @member {number} chunkOrder
         * @memberof proto.HistorySync
         * @instance
         */
        HistorySync.prototype.chunkOrder = 0;

        /**
         * HistorySync progress.
         * @member {number} progress
         * @memberof proto.HistorySync
         * @instance
         */
        HistorySync.prototype.progress = 0;

        /**
         * HistorySync pushnames.
         * @member {Array.<proto.IPushname>} pushnames
         * @memberof proto.HistorySync
         * @instance
         */
        HistorySync.prototype.pushnames = $util.emptyArray;

        /**
         * HistorySync globalSettings.
         * @member {proto.IGlobalSettings|null|undefined} globalSettings
         * @memberof proto.HistorySync
         * @instance
         */
        HistorySync.prototype.globalSettings = null;

        /**
         * HistorySync threadIdUserSecret.
         * @member {Uint8Array} threadIdUserSecret
         * @memberof proto.HistorySync
         * @instance
         */
        HistorySync.prototype.threadIdUserSecret = $util.newBuffer([]);

        /**
         * HistorySync threadDsTimeframeOffset.
         * @member {number} threadDsTimeframeOffset
         * @memberof proto.HistorySync
         * @instance
         */
        HistorySync.prototype.threadDsTimeframeOffset = 0;

        /**
         * Creates a new HistorySync instance using the specified properties.
         * @function create
         * @memberof proto.HistorySync
         * @static
         * @param {proto.IHistorySync=} [properties] Properties to set
         * @returns {proto.HistorySync} HistorySync instance
         */
        HistorySync.create = function create(properties) {
            return new HistorySync(properties);
        };

        /**
         * Encodes the specified HistorySync message. Does not implicitly {@link proto.HistorySync.verify|verify} messages.
         * @function encode
         * @memberof proto.HistorySync
         * @static
         * @param {proto.IHistorySync} message HistorySync message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HistorySync.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            writer.uint32(/* id 1, wireType 0 =*/8).int32(message.syncType);
            if (message.conversations != null && message.conversations.length)
                for (var i = 0; i < message.conversations.length; ++i)
                    $root.proto.Conversation.encode(message.conversations[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.statusV3Messages != null && message.statusV3Messages.length)
                for (var i = 0; i < message.statusV3Messages.length; ++i)
                    $root.proto.WebMessageInfo.encode(message.statusV3Messages[i], writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.chunkOrder != null && Object.hasOwnProperty.call(message, "chunkOrder"))
                writer.uint32(/* id 5, wireType 0 =*/40).uint32(message.chunkOrder);
            if (message.progress != null && Object.hasOwnProperty.call(message, "progress"))
                writer.uint32(/* id 6, wireType 0 =*/48).uint32(message.progress);
            if (message.pushnames != null && message.pushnames.length)
                for (var i = 0; i < message.pushnames.length; ++i)
                    $root.proto.Pushname.encode(message.pushnames[i], writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim();
            if (message.globalSettings != null && Object.hasOwnProperty.call(message, "globalSettings"))
                $root.proto.GlobalSettings.encode(message.globalSettings, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim();
            if (message.threadIdUserSecret != null && Object.hasOwnProperty.call(message, "threadIdUserSecret"))
                writer.uint32(/* id 9, wireType 2 =*/74).bytes(message.threadIdUserSecret);
            if (message.threadDsTimeframeOffset != null && Object.hasOwnProperty.call(message, "threadDsTimeframeOffset"))
                writer.uint32(/* id 10, wireType 0 =*/80).uint32(message.threadDsTimeframeOffset);
            return writer;
        };

        /**
         * Encodes the specified HistorySync message, length delimited. Does not implicitly {@link proto.HistorySync.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.HistorySync
         * @static
         * @param {proto.IHistorySync} message HistorySync message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HistorySync.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a HistorySync message from the specified reader or buffer.
         * @function decode
         * @memberof proto.HistorySync
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.HistorySync} HistorySync
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HistorySync.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HistorySync();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.syncType = reader.int32();
                    break;
                case 2:
                    if (!(message.conversations && message.conversations.length))
                        message.conversations = [];
                    message.conversations.push($root.proto.Conversation.decode(reader, reader.uint32()));
                    break;
                case 3:
                    if (!(message.statusV3Messages && message.statusV3Messages.length))
                        message.statusV3Messages = [];
                    message.statusV3Messages.push($root.proto.WebMessageInfo.decode(reader, reader.uint32()));
                    break;
                case 5:
                    message.chunkOrder = reader.uint32();
                    break;
                case 6:
                    message.progress = reader.uint32();
                    break;
                case 7:
                    if (!(message.pushnames && message.pushnames.length))
                        message.pushnames = [];
                    message.pushnames.push($root.proto.Pushname.decode(reader, reader.uint32()));
                    break;
                case 8:
                    message.globalSettings = $root.proto.GlobalSettings.decode(reader, reader.uint32());
                    break;
                case 9:
                    message.threadIdUserSecret = reader.bytes();
                    break;
                case 10:
                    message.threadDsTimeframeOffset = reader.uint32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            if (!message.hasOwnProperty("syncType"))
                throw $util.ProtocolError("missing required 'syncType'", { instance: message });
            return message;
        };

        /**
         * Decodes a HistorySync message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.HistorySync
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.HistorySync} HistorySync
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HistorySync.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a HistorySync message.
         * @function verify
         * @memberof proto.HistorySync
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        HistorySync.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            switch (message.syncType) {
            default:
                return "syncType: enum value expected";
            case 0:
            case 1:
            case 2:
            case 3:
            case 4:
                break;
            }
            if (message.conversations != null && message.hasOwnProperty("conversations")) {
                if (!Array.isArray(message.conversations))
                    return "conversations: array expected";
                for (var i = 0; i < message.conversations.length; ++i) {
                    var error = $root.proto.Conversation.verify(message.conversations[i]);
                    if (error)
                        return "conversations." + error;
                }
            }
            if (message.statusV3Messages != null && message.hasOwnProperty("statusV3Messages")) {
                if (!Array.isArray(message.statusV3Messages))
                    return "statusV3Messages: array expected";
                for (var i = 0; i < message.statusV3Messages.length; ++i) {
                    var error = $root.proto.WebMessageInfo.verify(message.statusV3Messages[i]);
                    if (error)
                        return "statusV3Messages." + error;
                }
            }
            if (message.chunkOrder != null && message.hasOwnProperty("chunkOrder"))
                if (!$util.isInteger(message.chunkOrder))
                    return "chunkOrder: integer expected";
            if (message.progress != null && message.hasOwnProperty("progress"))
                if (!$util.isInteger(message.progress))
                    return "progress: integer expected";
            if (message.pushnames != null && message.hasOwnProperty("pushnames")) {
                if (!Array.isArray(message.pushnames))
                    return "pushnames: array expected";
                for (var i = 0; i < message.pushnames.length; ++i) {
                    var error = $root.proto.Pushname.verify(message.pushnames[i]);
                    if (error)
                        return "pushnames." + error;
                }
            }
            if (message.globalSettings != null && message.hasOwnProperty("globalSettings")) {
                var error = $root.proto.GlobalSettings.verify(message.globalSettings);
                if (error)
                    return "globalSettings." + error;
            }
            if (message.threadIdUserSecret != null && message.hasOwnProperty("threadIdUserSecret"))
                if (!(message.threadIdUserSecret && typeof message.threadIdUserSecret.length === "number" || $util.isString(message.threadIdUserSecret)))
                    return "threadIdUserSecret: buffer expected";
            if (message.threadDsTimeframeOffset != null && message.hasOwnProperty("threadDsTimeframeOffset"))
                if (!$util.isInteger(message.threadDsTimeframeOffset))
                    return "threadDsTimeframeOffset: integer expected";
            return null;
        };

        /**
         * Creates a HistorySync message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.HistorySync
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.HistorySync} HistorySync
         */
        HistorySync.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.HistorySync)
                return object;
            var message = new $root.proto.HistorySync();
            switch (object.syncType) {
            case "INITIAL_BOOTSTRAP":
            case 0:
                message.syncType = 0;
                break;
            case "INITIAL_STATUS_V3":
            case 1:
                message.syncType = 1;
                break;
            case "FULL":
            case 2:
                message.syncType = 2;
                break;
            case "RECENT":
            case 3:
                message.syncType = 3;
                break;
            case "PUSH_NAME":
            case 4:
                message.syncType = 4;
                break;
            }
            if (object.conversations) {
                if (!Array.isArray(object.conversations))
                    throw TypeError(".proto.HistorySync.conversations: array expected");
                message.conversations = [];
                for (var i = 0; i < object.conversations.length; ++i) {
                    if (typeof object.conversations[i] !== "object")
                        throw TypeError(".proto.HistorySync.conversations: object expected");
                    message.conversations[i] = $root.proto.Conversation.fromObject(object.conversations[i]);
                }
            }
            if (object.statusV3Messages) {
                if (!Array.isArray(object.statusV3Messages))
                    throw TypeError(".proto.HistorySync.statusV3Messages: array expected");
                message.statusV3Messages = [];
                for (var i = 0; i < object.statusV3Messages.length; ++i) {
                    if (typeof object.statusV3Messages[i] !== "object")
                        throw TypeError(".proto.HistorySync.statusV3Messages: object expected");
                    message.statusV3Messages[i] = $root.proto.WebMessageInfo.fromObject(object.statusV3Messages[i]);
                }
            }
            if (object.chunkOrder != null)
                message.chunkOrder = object.chunkOrder >>> 0;
            if (object.progress != null)
                message.progress = object.progress >>> 0;
            if (object.pushnames) {
                if (!Array.isArray(object.pushnames))
                    throw TypeError(".proto.HistorySync.pushnames: array expected");
                message.pushnames = [];
                for (var i = 0; i < object.pushnames.length; ++i) {
                    if (typeof object.pushnames[i] !== "object")
                        throw TypeError(".proto.HistorySync.pushnames: object expected");
                    message.pushnames[i] = $root.proto.Pushname.fromObject(object.pushnames[i]);
                }
            }
            if (object.globalSettings != null) {
                if (typeof object.globalSettings !== "object")
                    throw TypeError(".proto.HistorySync.globalSettings: object expected");
                message.globalSettings = $root.proto.GlobalSettings.fromObject(object.globalSettings);
            }
            if (object.threadIdUserSecret != null)
                if (typeof object.threadIdUserSecret === "string")
                    $util.base64.decode(object.threadIdUserSecret, message.threadIdUserSecret = $util.newBuffer($util.base64.length(object.threadIdUserSecret)), 0);
                else if (object.threadIdUserSecret.length)
                    message.threadIdUserSecret = object.threadIdUserSecret;
            if (object.threadDsTimeframeOffset != null)
                message.threadDsTimeframeOffset = object.threadDsTimeframeOffset >>> 0;
            return message;
        };

        /**
         * Creates a plain object from a HistorySync message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.HistorySync
         * @static
         * @param {proto.HistorySync} message HistorySync
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        HistorySync.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults) {
                object.conversations = [];
                object.statusV3Messages = [];
                object.pushnames = [];
            }
            if (options.defaults) {
                object.syncType = options.enums === String ? "INITIAL_BOOTSTRAP" : 0;
                object.chunkOrder = 0;
                object.progress = 0;
                object.globalSettings = null;
                if (options.bytes === String)
                    object.threadIdUserSecret = "";
                else {
                    object.threadIdUserSecret = [];
                    if (options.bytes !== Array)
                        object.threadIdUserSecret = $util.newBuffer(object.threadIdUserSecret);
                }
                object.threadDsTimeframeOffset = 0;
            }
            if (message.syncType != null && message.hasOwnProperty("syncType"))
                object.syncType = options.enums === String ? $root.proto.HistorySync.HistorySyncHistorySyncType[message.syncType] : message.syncType;
            if (message.conversations && message.conversations.length) {
                object.conversations = [];
                for (var j = 0; j < message.conversations.length; ++j)
                    object.conversations[j] = $root.proto.Conversation.toObject(message.conversations[j], options);
            }
            if (message.statusV3Messages && message.statusV3Messages.length) {
                object.statusV3Messages = [];
                for (var j = 0; j < message.statusV3Messages.length; ++j)
                    object.statusV3Messages[j] = $root.proto.WebMessageInfo.toObject(message.statusV3Messages[j], options);
            }
            if (message.chunkOrder != null && message.hasOwnProperty("chunkOrder"))
                object.chunkOrder = message.chunkOrder;
            if (message.progress != null && message.hasOwnProperty("progress"))
                object.progress = message.progress;
            if (message.pushnames && message.pushnames.length) {
                object.pushnames = [];
                for (var j = 0; j < message.pushnames.length; ++j)
                    object.pushnames[j] = $root.proto.Pushname.toObject(message.pushnames[j], options);
            }
            if (message.globalSettings != null && message.hasOwnProperty("globalSettings"))
                object.globalSettings = $root.proto.GlobalSettings.toObject(message.globalSettings, options);
            if (message.threadIdUserSecret != null && message.hasOwnProperty("threadIdUserSecret"))
                object.threadIdUserSecret = options.bytes === String ? $util.base64.encode(message.threadIdUserSecret, 0, message.threadIdUserSecret.length) : options.bytes === Array ? Array.prototype.slice.call(message.threadIdUserSecret) : message.threadIdUserSecret;
            if (message.threadDsTimeframeOffset != null && message.hasOwnProperty("threadDsTimeframeOffset"))
                object.threadDsTimeframeOffset = message.threadDsTimeframeOffset;
            return object;
        };

        /**
         * Converts this HistorySync to JSON.
         * @function toJSON
         * @memberof proto.HistorySync
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        HistorySync.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * HistorySyncHistorySyncType enum.
         * @name proto.HistorySync.HistorySyncHistorySyncType
         * @enum {number}
         * @property {number} INITIAL_BOOTSTRAP=0 INITIAL_BOOTSTRAP value
         * @property {number} INITIAL_STATUS_V3=1 INITIAL_STATUS_V3 value
         * @property {number} FULL=2 FULL value
         * @property {number} RECENT=3 RECENT value
         * @property {number} PUSH_NAME=4 PUSH_NAME value
         */
        HistorySync.HistorySyncHistorySyncType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "INITIAL_BOOTSTRAP"] = 0;
            values[valuesById[1] = "INITIAL_STATUS_V3"] = 1;
            values[valuesById[2] = "FULL"] = 2;
            values[valuesById[3] = "RECENT"] = 3;
            values[valuesById[4] = "PUSH_NAME"] = 4;
            return values;
        })();

        return HistorySync;
    })();

    /**
     * MediaVisibility enum.
     * @name proto.MediaVisibility
     * @enum {number}
     * @property {number} DEFAULT=0 DEFAULT value
     * @property {number} OFF=1 OFF value
     * @property {number} ON=2 ON value
     */
    proto.MediaVisibility = (function() {
        var valuesById = {}, values = Object.create(valuesById);
        values[valuesById[0] = "DEFAULT"] = 0;
        values[valuesById[1] = "OFF"] = 1;
        values[valuesById[2] = "ON"] = 2;
        return values;
    })();

    proto.EphemeralSetting = (function() {

        /**
         * Properties of an EphemeralSetting.
         * @memberof proto
         * @interface IEphemeralSetting
         * @property {number|null} [duration] EphemeralSetting duration
         * @property {number|Long|null} [timestamp] EphemeralSetting timestamp
         */

        /**
         * Constructs a new EphemeralSetting.
         * @memberof proto
         * @classdesc Represents an EphemeralSetting.
         * @implements IEphemeralSetting
         * @constructor
         * @param {proto.IEphemeralSetting=} [properties] Properties to set
         */
        function EphemeralSetting(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * EphemeralSetting duration.
         * @member {number} duration
         * @memberof proto.EphemeralSetting
         * @instance
         */
        EphemeralSetting.prototype.duration = 0;

        /**
         * EphemeralSetting timestamp.
         * @member {number|Long} timestamp
         * @memberof proto.EphemeralSetting
         * @instance
         */
        EphemeralSetting.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * Creates a new EphemeralSetting instance using the specified properties.
         * @function create
         * @memberof proto.EphemeralSetting
         * @static
         * @param {proto.IEphemeralSetting=} [properties] Properties to set
         * @returns {proto.EphemeralSetting} EphemeralSetting instance
         */
        EphemeralSetting.create = function create(properties) {
            return new EphemeralSetting(properties);
        };

        /**
         * Encodes the specified EphemeralSetting message. Does not implicitly {@link proto.EphemeralSetting.verify|verify} messages.
         * @function encode
         * @memberof proto.EphemeralSetting
         * @static
         * @param {proto.IEphemeralSetting} message EphemeralSetting message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        EphemeralSetting.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.duration != null && Object.hasOwnProperty.call(message, "duration"))
                writer.uint32(/* id 1, wireType 5 =*/13).sfixed32(message.duration);
            if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp"))
                writer.uint32(/* id 2, wireType 1 =*/17).sfixed64(message.timestamp);
            return writer;
        };

        /**
         * Encodes the specified EphemeralSetting message, length delimited. Does not implicitly {@link proto.EphemeralSetting.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.EphemeralSetting
         * @static
         * @param {proto.IEphemeralSetting} message EphemeralSetting message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        EphemeralSetting.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an EphemeralSetting message from the specified reader or buffer.
         * @function decode
         * @memberof proto.EphemeralSetting
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.EphemeralSetting} EphemeralSetting
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        EphemeralSetting.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.EphemeralSetting();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.duration = reader.sfixed32();
                    break;
                case 2:
                    message.timestamp = reader.sfixed64();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an EphemeralSetting message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.EphemeralSetting
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.EphemeralSetting} EphemeralSetting
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        EphemeralSetting.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an EphemeralSetting message.
         * @function verify
         * @memberof proto.EphemeralSetting
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        EphemeralSetting.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.duration != null && message.hasOwnProperty("duration"))
                if (!$util.isInteger(message.duration))
                    return "duration: integer expected";
            if (message.timestamp != null && message.hasOwnProperty("timestamp"))
                if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high)))
                    return "timestamp: integer|Long expected";
            return null;
        };

        /**
         * Creates an EphemeralSetting message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.EphemeralSetting
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.EphemeralSetting} EphemeralSetting
         */
        EphemeralSetting.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.EphemeralSetting)
                return object;
            var message = new $root.proto.EphemeralSetting();
            if (object.duration != null)
                message.duration = object.duration | 0;
            if (object.timestamp != null)
                if ($util.Long)
                    (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = false;
                else if (typeof object.timestamp === "string")
                    message.timestamp = parseInt(object.timestamp, 10);
                else if (typeof object.timestamp === "number")
                    message.timestamp = object.timestamp;
                else if (typeof object.timestamp === "object")
                    message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber();
            return message;
        };

        /**
         * Creates a plain object from an EphemeralSetting message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.EphemeralSetting
         * @static
         * @param {proto.EphemeralSetting} message EphemeralSetting
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        EphemeralSetting.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.duration = 0;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.timestamp = options.longs === String ? "0" : 0;
            }
            if (message.duration != null && message.hasOwnProperty("duration"))
                object.duration = message.duration;
            if (message.timestamp != null && message.hasOwnProperty("timestamp"))
                if (typeof message.timestamp === "number")
                    object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp;
                else
                    object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber() : message.timestamp;
            return object;
        };

        /**
         * Converts this EphemeralSetting to JSON.
         * @function toJSON
         * @memberof proto.EphemeralSetting
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        EphemeralSetting.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return EphemeralSetting;
    })();

    proto.InteractiveAnnotation = (function() {

        /**
         * Properties of an InteractiveAnnotation.
         * @memberof proto
         * @interface IInteractiveAnnotation
         * @property {Array.<proto.IPoint>|null} [polygonVertices] InteractiveAnnotation polygonVertices
         * @property {proto.ILocation|null} [location] InteractiveAnnotation location
         */

        /**
         * Constructs a new InteractiveAnnotation.
         * @memberof proto
         * @classdesc Represents an InteractiveAnnotation.
         * @implements IInteractiveAnnotation
         * @constructor
         * @param {proto.IInteractiveAnnotation=} [properties] Properties to set
         */
        function InteractiveAnnotation(properties) {
            this.polygonVertices = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * InteractiveAnnotation polygonVertices.
         * @member {Array.<proto.IPoint>} polygonVertices
         * @memberof proto.InteractiveAnnotation
         * @instance
         */
        InteractiveAnnotation.prototype.polygonVertices = $util.emptyArray;

        /**
         * InteractiveAnnotation location.
         * @member {proto.ILocation|null|undefined} location
         * @memberof proto.InteractiveAnnotation
         * @instance
         */
        InteractiveAnnotation.prototype.location = null;

        // OneOf field names bound to virtual getters and setters
        var $oneOfFields;

        /**
         * InteractiveAnnotation action.
         * @member {"location"|undefined} action
         * @memberof proto.InteractiveAnnotation
         * @instance
         */
        Object.defineProperty(InteractiveAnnotation.prototype, "action", {
            get: $util.oneOfGetter($oneOfFields = ["location"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new InteractiveAnnotation instance using the specified properties.
         * @function create
         * @memberof proto.InteractiveAnnotation
         * @static
         * @param {proto.IInteractiveAnnotation=} [properties] Properties to set
         * @returns {proto.InteractiveAnnotation} InteractiveAnnotation instance
         */
        InteractiveAnnotation.create = function create(properties) {
            return new InteractiveAnnotation(properties);
        };

        /**
         * Encodes the specified InteractiveAnnotation message. Does not implicitly {@link proto.InteractiveAnnotation.verify|verify} messages.
         * @function encode
         * @memberof proto.InteractiveAnnotation
         * @static
         * @param {proto.IInteractiveAnnotation} message InteractiveAnnotation message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        InteractiveAnnotation.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.polygonVertices != null && message.polygonVertices.length)
                for (var i = 0; i < message.polygonVertices.length; ++i)
                    $root.proto.Point.encode(message.polygonVertices[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.location != null && Object.hasOwnProperty.call(message, "location"))
                $root.proto.Location.encode(message.location, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified InteractiveAnnotation message, length delimited. Does not implicitly {@link proto.InteractiveAnnotation.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.InteractiveAnnotation
         * @static
         * @param {proto.IInteractiveAnnotation} message InteractiveAnnotation message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        InteractiveAnnotation.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an InteractiveAnnotation message from the specified reader or buffer.
         * @function decode
         * @memberof proto.InteractiveAnnotation
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.InteractiveAnnotation} InteractiveAnnotation
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        InteractiveAnnotation.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.InteractiveAnnotation();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    if (!(message.polygonVertices && message.polygonVertices.length))
                        message.polygonVertices = [];
                    message.polygonVertices.push($root.proto.Point.decode(reader, reader.uint32()));
                    break;
                case 2:
                    message.location = $root.proto.Location.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an InteractiveAnnotation message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.InteractiveAnnotation
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.InteractiveAnnotation} InteractiveAnnotation
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        InteractiveAnnotation.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an InteractiveAnnotation message.
         * @function verify
         * @memberof proto.InteractiveAnnotation
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        InteractiveAnnotation.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            var properties = {};
            if (message.polygonVertices != null && message.hasOwnProperty("polygonVertices")) {
                if (!Array.isArray(message.polygonVertices))
                    return "polygonVertices: array expected";
                for (var i = 0; i < message.polygonVertices.length; ++i) {
                    var error = $root.proto.Point.verify(message.polygonVertices[i]);
                    if (error)
                        return "polygonVertices." + error;
                }
            }
            if (message.location != null && message.hasOwnProperty("location")) {
                properties.action = 1;
                {
                    var error = $root.proto.Location.verify(message.location);
                    if (error)
                        return "location." + error;
                }
            }
            return null;
        };

        /**
         * Creates an InteractiveAnnotation message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.InteractiveAnnotation
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.InteractiveAnnotation} InteractiveAnnotation
         */
        InteractiveAnnotation.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.InteractiveAnnotation)
                return object;
            var message = new $root.proto.InteractiveAnnotation();
            if (object.polygonVertices) {
                if (!Array.isArray(object.polygonVertices))
                    throw TypeError(".proto.InteractiveAnnotation.polygonVertices: array expected");
                message.polygonVertices = [];
                for (var i = 0; i < object.polygonVertices.length; ++i) {
                    if (typeof object.polygonVertices[i] !== "object")
                        throw TypeError(".proto.InteractiveAnnotation.polygonVertices: object expected");
                    message.polygonVertices[i] = $root.proto.Point.fromObject(object.polygonVertices[i]);
                }
            }
            if (object.location != null) {
                if (typeof object.location !== "object")
                    throw TypeError(".proto.InteractiveAnnotation.location: object expected");
                message.location = $root.proto.Location.fromObject(object.location);
            }
            return message;
        };

        /**
         * Creates a plain object from an InteractiveAnnotation message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.InteractiveAnnotation
         * @static
         * @param {proto.InteractiveAnnotation} message InteractiveAnnotation
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        InteractiveAnnotation.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.polygonVertices = [];
            if (message.polygonVertices && message.polygonVertices.length) {
                object.polygonVertices = [];
                for (var j = 0; j < message.polygonVertices.length; ++j)
                    object.polygonVertices[j] = $root.proto.Point.toObject(message.polygonVertices[j], options);
            }
            if (message.location != null && message.hasOwnProperty("location")) {
                object.location = $root.proto.Location.toObject(message.location, options);
                if (options.oneofs)
                    object.action = "location";
            }
            return object;
        };

        /**
         * Converts this InteractiveAnnotation to JSON.
         * @function toJSON
         * @memberof proto.InteractiveAnnotation
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        InteractiveAnnotation.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return InteractiveAnnotation;
    })();

    proto.DeviceListMetadata = (function() {

        /**
         * Properties of a DeviceListMetadata.
         * @memberof proto
         * @interface IDeviceListMetadata
         * @property {Uint8Array|null} [senderKeyHash] DeviceListMetadata senderKeyHash
         * @property {number|Long|null} [senderTimestamp] DeviceListMetadata senderTimestamp
         * @property {Array.<number>|null} [senderKeyIndexes] DeviceListMetadata senderKeyIndexes
         * @property {Uint8Array|null} [recipientKeyHash] DeviceListMetadata recipientKeyHash
         * @property {number|Long|null} [recipientTimestamp] DeviceListMetadata recipientTimestamp
         * @property {Array.<number>|null} [recipientKeyIndexes] DeviceListMetadata recipientKeyIndexes
         */

        /**
         * Constructs a new DeviceListMetadata.
         * @memberof proto
         * @classdesc Represents a DeviceListMetadata.
         * @implements IDeviceListMetadata
         * @constructor
         * @param {proto.IDeviceListMetadata=} [properties] Properties to set
         */
        function DeviceListMetadata(properties) {
            this.senderKeyIndexes = [];
            this.recipientKeyIndexes = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * DeviceListMetadata senderKeyHash.
         * @member {Uint8Array} senderKeyHash
         * @memberof proto.DeviceListMetadata
         * @instance
         */
        DeviceListMetadata.prototype.senderKeyHash = $util.newBuffer([]);

        /**
         * DeviceListMetadata senderTimestamp.
         * @member {number|Long} senderTimestamp
         * @memberof proto.DeviceListMetadata
         * @instance
         */
        DeviceListMetadata.prototype.senderTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * DeviceListMetadata senderKeyIndexes.
         * @member {Array.<number>} senderKeyIndexes
         * @memberof proto.DeviceListMetadata
         * @instance
         */
        DeviceListMetadata.prototype.senderKeyIndexes = $util.emptyArray;

        /**
         * DeviceListMetadata recipientKeyHash.
         * @member {Uint8Array} recipientKeyHash
         * @memberof proto.DeviceListMetadata
         * @instance
         */
        DeviceListMetadata.prototype.recipientKeyHash = $util.newBuffer([]);

        /**
         * DeviceListMetadata recipientTimestamp.
         * @member {number|Long} recipientTimestamp
         * @memberof proto.DeviceListMetadata
         * @instance
         */
        DeviceListMetadata.prototype.recipientTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * DeviceListMetadata recipientKeyIndexes.
         * @member {Array.<number>} recipientKeyIndexes
         * @memberof proto.DeviceListMetadata
         * @instance
         */
        DeviceListMetadata.prototype.recipientKeyIndexes = $util.emptyArray;

        /**
         * Creates a new DeviceListMetadata instance using the specified properties.
         * @function create
         * @memberof proto.DeviceListMetadata
         * @static
         * @param {proto.IDeviceListMetadata=} [properties] Properties to set
         * @returns {proto.DeviceListMetadata} DeviceListMetadata instance
         */
        DeviceListMetadata.create = function create(properties) {
            return new DeviceListMetadata(properties);
        };

        /**
         * Encodes the specified DeviceListMetadata message. Does not implicitly {@link proto.DeviceListMetadata.verify|verify} messages.
         * @function encode
         * @memberof proto.DeviceListMetadata
         * @static
         * @param {proto.IDeviceListMetadata} message DeviceListMetadata message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        DeviceListMetadata.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.senderKeyHash != null && Object.hasOwnProperty.call(message, "senderKeyHash"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.senderKeyHash);
            if (message.senderTimestamp != null && Object.hasOwnProperty.call(message, "senderTimestamp"))
                writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.senderTimestamp);
            if (message.senderKeyIndexes != null && message.senderKeyIndexes.length) {
                writer.uint32(/* id 3, wireType 2 =*/26).fork();
                for (var i = 0; i < message.senderKeyIndexes.length; ++i)
                    writer.uint32(message.senderKeyIndexes[i]);
                writer.ldelim();
            }
            if (message.recipientKeyHash != null && Object.hasOwnProperty.call(message, "recipientKeyHash"))
                writer.uint32(/* id 8, wireType 2 =*/66).bytes(message.recipientKeyHash);
            if (message.recipientTimestamp != null && Object.hasOwnProperty.call(message, "recipientTimestamp"))
                writer.uint32(/* id 9, wireType 0 =*/72).uint64(message.recipientTimestamp);
            if (message.recipientKeyIndexes != null && message.recipientKeyIndexes.length) {
                writer.uint32(/* id 10, wireType 2 =*/82).fork();
                for (var i = 0; i < message.recipientKeyIndexes.length; ++i)
                    writer.uint32(message.recipientKeyIndexes[i]);
                writer.ldelim();
            }
            return writer;
        };

        /**
         * Encodes the specified DeviceListMetadata message, length delimited. Does not implicitly {@link proto.DeviceListMetadata.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.DeviceListMetadata
         * @static
         * @param {proto.IDeviceListMetadata} message DeviceListMetadata message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        DeviceListMetadata.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a DeviceListMetadata message from the specified reader or buffer.
         * @function decode
         * @memberof proto.DeviceListMetadata
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.DeviceListMetadata} DeviceListMetadata
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        DeviceListMetadata.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.DeviceListMetadata();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.senderKeyHash = reader.bytes();
                    break;
                case 2:
                    message.senderTimestamp = reader.uint64();
                    break;
                case 3:
                    if (!(message.senderKeyIndexes && message.senderKeyIndexes.length))
                        message.senderKeyIndexes = [];
                    if ((tag & 7) === 2) {
                        var end2 = reader.uint32() + reader.pos;
                        while (reader.pos < end2)
                            message.senderKeyIndexes.push(reader.uint32());
                    } else
                        message.senderKeyIndexes.push(reader.uint32());
                    break;
                case 8:
                    message.recipientKeyHash = reader.bytes();
                    break;
                case 9:
                    message.recipientTimestamp = reader.uint64();
                    break;
                case 10:
                    if (!(message.recipientKeyIndexes && message.recipientKeyIndexes.length))
                        message.recipientKeyIndexes = [];
                    if ((tag & 7) === 2) {
                        var end2 = reader.uint32() + reader.pos;
                        while (reader.pos < end2)
                            message.recipientKeyIndexes.push(reader.uint32());
                    } else
                        message.recipientKeyIndexes.push(reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a DeviceListMetadata message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.DeviceListMetadata
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.DeviceListMetadata} DeviceListMetadata
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        DeviceListMetadata.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a DeviceListMetadata message.
         * @function verify
         * @memberof proto.DeviceListMetadata
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        DeviceListMetadata.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.senderKeyHash != null && message.hasOwnProperty("senderKeyHash"))
                if (!(message.senderKeyHash && typeof message.senderKeyHash.length === "number" || $util.isString(message.senderKeyHash)))
                    return "senderKeyHash: buffer expected";
            if (message.senderTimestamp != null && message.hasOwnProperty("senderTimestamp"))
                if (!$util.isInteger(message.senderTimestamp) && !(message.senderTimestamp && $util.isInteger(message.senderTimestamp.low) && $util.isInteger(message.senderTimestamp.high)))
                    return "senderTimestamp: integer|Long expected";
            if (message.senderKeyIndexes != null && message.hasOwnProperty("senderKeyIndexes")) {
                if (!Array.isArray(message.senderKeyIndexes))
                    return "senderKeyIndexes: array expected";
                for (var i = 0; i < message.senderKeyIndexes.length; ++i)
                    if (!$util.isInteger(message.senderKeyIndexes[i]))
                        return "senderKeyIndexes: integer[] expected";
            }
            if (message.recipientKeyHash != null && message.hasOwnProperty("recipientKeyHash"))
                if (!(message.recipientKeyHash && typeof message.recipientKeyHash.length === "number" || $util.isString(message.recipientKeyHash)))
                    return "recipientKeyHash: buffer expected";
            if (message.recipientTimestamp != null && message.hasOwnProperty("recipientTimestamp"))
                if (!$util.isInteger(message.recipientTimestamp) && !(message.recipientTimestamp && $util.isInteger(message.recipientTimestamp.low) && $util.isInteger(message.recipientTimestamp.high)))
                    return "recipientTimestamp: integer|Long expected";
            if (message.recipientKeyIndexes != null && message.hasOwnProperty("recipientKeyIndexes")) {
                if (!Array.isArray(message.recipientKeyIndexes))
                    return "recipientKeyIndexes: array expected";
                for (var i = 0; i < message.recipientKeyIndexes.length; ++i)
                    if (!$util.isInteger(message.recipientKeyIndexes[i]))
                        return "recipientKeyIndexes: integer[] expected";
            }
            return null;
        };

        /**
         * Creates a DeviceListMetadata message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.DeviceListMetadata
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.DeviceListMetadata} DeviceListMetadata
         */
        DeviceListMetadata.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.DeviceListMetadata)
                return object;
            var message = new $root.proto.DeviceListMetadata();
            if (object.senderKeyHash != null)
                if (typeof object.senderKeyHash === "string")
                    $util.base64.decode(object.senderKeyHash, message.senderKeyHash = $util.newBuffer($util.base64.length(object.senderKeyHash)), 0);
                else if (object.senderKeyHash.length)
                    message.senderKeyHash = object.senderKeyHash;
            if (object.senderTimestamp != null)
                if ($util.Long)
                    (message.senderTimestamp = $util.Long.fromValue(object.senderTimestamp)).unsigned = true;
                else if (typeof object.senderTimestamp === "string")
                    message.senderTimestamp = parseInt(object.senderTimestamp, 10);
                else if (typeof object.senderTimestamp === "number")
                    message.senderTimestamp = object.senderTimestamp;
                else if (typeof object.senderTimestamp === "object")
                    message.senderTimestamp = new $util.LongBits(object.senderTimestamp.low >>> 0, object.senderTimestamp.high >>> 0).toNumber(true);
            if (object.senderKeyIndexes) {
                if (!Array.isArray(object.senderKeyIndexes))
                    throw TypeError(".proto.DeviceListMetadata.senderKeyIndexes: array expected");
                message.senderKeyIndexes = [];
                for (var i = 0; i < object.senderKeyIndexes.length; ++i)
                    message.senderKeyIndexes[i] = object.senderKeyIndexes[i] >>> 0;
            }
            if (object.recipientKeyHash != null)
                if (typeof object.recipientKeyHash === "string")
                    $util.base64.decode(object.recipientKeyHash, message.recipientKeyHash = $util.newBuffer($util.base64.length(object.recipientKeyHash)), 0);
                else if (object.recipientKeyHash.length)
                    message.recipientKeyHash = object.recipientKeyHash;
            if (object.recipientTimestamp != null)
                if ($util.Long)
                    (message.recipientTimestamp = $util.Long.fromValue(object.recipientTimestamp)).unsigned = true;
                else if (typeof object.recipientTimestamp === "string")
                    message.recipientTimestamp = parseInt(object.recipientTimestamp, 10);
                else if (typeof object.recipientTimestamp === "number")
                    message.recipientTimestamp = object.recipientTimestamp;
                else if (typeof object.recipientTimestamp === "object")
                    message.recipientTimestamp = new $util.LongBits(object.recipientTimestamp.low >>> 0, object.recipientTimestamp.high >>> 0).toNumber(true);
            if (object.recipientKeyIndexes) {
                if (!Array.isArray(object.recipientKeyIndexes))
                    throw TypeError(".proto.DeviceListMetadata.recipientKeyIndexes: array expected");
                message.recipientKeyIndexes = [];
                for (var i = 0; i < object.recipientKeyIndexes.length; ++i)
                    message.recipientKeyIndexes[i] = object.recipientKeyIndexes[i] >>> 0;
            }
            return message;
        };

        /**
         * Creates a plain object from a DeviceListMetadata message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.DeviceListMetadata
         * @static
         * @param {proto.DeviceListMetadata} message DeviceListMetadata
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        DeviceListMetadata.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults) {
                object.senderKeyIndexes = [];
                object.recipientKeyIndexes = [];
            }
            if (options.defaults) {
                if (options.bytes === String)
                    object.senderKeyHash = "";
                else {
                    object.senderKeyHash = [];
                    if (options.bytes !== Array)
                        object.senderKeyHash = $util.newBuffer(object.senderKeyHash);
                }
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.senderTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.senderTimestamp = options.longs === String ? "0" : 0;
                if (options.bytes === String)
                    object.recipientKeyHash = "";
                else {
                    object.recipientKeyHash = [];
                    if (options.bytes !== Array)
                        object.recipientKeyHash = $util.newBuffer(object.recipientKeyHash);
                }
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.recipientTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.recipientTimestamp = options.longs === String ? "0" : 0;
            }
            if (message.senderKeyHash != null && message.hasOwnProperty("senderKeyHash"))
                object.senderKeyHash = options.bytes === String ? $util.base64.encode(message.senderKeyHash, 0, message.senderKeyHash.length) : options.bytes === Array ? Array.prototype.slice.call(message.senderKeyHash) : message.senderKeyHash;
            if (message.senderTimestamp != null && message.hasOwnProperty("senderTimestamp"))
                if (typeof message.senderTimestamp === "number")
                    object.senderTimestamp = options.longs === String ? String(message.senderTimestamp) : message.senderTimestamp;
                else
                    object.senderTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.senderTimestamp) : options.longs === Number ? new $util.LongBits(message.senderTimestamp.low >>> 0, message.senderTimestamp.high >>> 0).toNumber(true) : message.senderTimestamp;
            if (message.senderKeyIndexes && message.senderKeyIndexes.length) {
                object.senderKeyIndexes = [];
                for (var j = 0; j < message.senderKeyIndexes.length; ++j)
                    object.senderKeyIndexes[j] = message.senderKeyIndexes[j];
            }
            if (message.recipientKeyHash != null && message.hasOwnProperty("recipientKeyHash"))
                object.recipientKeyHash = options.bytes === String ? $util.base64.encode(message.recipientKeyHash, 0, message.recipientKeyHash.length) : options.bytes === Array ? Array.prototype.slice.call(message.recipientKeyHash) : message.recipientKeyHash;
            if (message.recipientTimestamp != null && message.hasOwnProperty("recipientTimestamp"))
                if (typeof message.recipientTimestamp === "number")
                    object.recipientTimestamp = options.longs === String ? String(message.recipientTimestamp) : message.recipientTimestamp;
                else
                    object.recipientTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.recipientTimestamp) : options.longs === Number ? new $util.LongBits(message.recipientTimestamp.low >>> 0, message.recipientTimestamp.high >>> 0).toNumber(true) : message.recipientTimestamp;
            if (message.recipientKeyIndexes && message.recipientKeyIndexes.length) {
                object.recipientKeyIndexes = [];
                for (var j = 0; j < message.recipientKeyIndexes.length; ++j)
                    object.recipientKeyIndexes[j] = message.recipientKeyIndexes[j];
            }
            return object;
        };

        /**
         * Converts this DeviceListMetadata to JSON.
         * @function toJSON
         * @memberof proto.DeviceListMetadata
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        DeviceListMetadata.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return DeviceListMetadata;
    })();

    proto.MessageContextInfo = (function() {

        /**
         * Properties of a MessageContextInfo.
         * @memberof proto
         * @interface IMessageContextInfo
         * @property {proto.IDeviceListMetadata|null} [deviceListMetadata] MessageContextInfo deviceListMetadata
         * @property {number|null} [deviceListMetadataVersion] MessageContextInfo deviceListMetadataVersion
         */

        /**
         * Constructs a new MessageContextInfo.
         * @memberof proto
         * @classdesc Represents a MessageContextInfo.
         * @implements IMessageContextInfo
         * @constructor
         * @param {proto.IMessageContextInfo=} [properties] Properties to set
         */
        function MessageContextInfo(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * MessageContextInfo deviceListMetadata.
         * @member {proto.IDeviceListMetadata|null|undefined} deviceListMetadata
         * @memberof proto.MessageContextInfo
         * @instance
         */
        MessageContextInfo.prototype.deviceListMetadata = null;

        /**
         * MessageContextInfo deviceListMetadataVersion.
         * @member {number} deviceListMetadataVersion
         * @memberof proto.MessageContextInfo
         * @instance
         */
        MessageContextInfo.prototype.deviceListMetadataVersion = 0;

        /**
         * Creates a new MessageContextInfo instance using the specified properties.
         * @function create
         * @memberof proto.MessageContextInfo
         * @static
         * @param {proto.IMessageContextInfo=} [properties] Properties to set
         * @returns {proto.MessageContextInfo} MessageContextInfo instance
         */
        MessageContextInfo.create = function create(properties) {
            return new MessageContextInfo(properties);
        };

        /**
         * Encodes the specified MessageContextInfo message. Does not implicitly {@link proto.MessageContextInfo.verify|verify} messages.
         * @function encode
         * @memberof proto.MessageContextInfo
         * @static
         * @param {proto.IMessageContextInfo} message MessageContextInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        MessageContextInfo.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.deviceListMetadata != null && Object.hasOwnProperty.call(message, "deviceListMetadata"))
                $root.proto.DeviceListMetadata.encode(message.deviceListMetadata, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.deviceListMetadataVersion != null && Object.hasOwnProperty.call(message, "deviceListMetadataVersion"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.deviceListMetadataVersion);
            return writer;
        };

        /**
         * Encodes the specified MessageContextInfo message, length delimited. Does not implicitly {@link proto.MessageContextInfo.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.MessageContextInfo
         * @static
         * @param {proto.IMessageContextInfo} message MessageContextInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        MessageContextInfo.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a MessageContextInfo message from the specified reader or buffer.
         * @function decode
         * @memberof proto.MessageContextInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.MessageContextInfo} MessageContextInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        MessageContextInfo.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MessageContextInfo();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.deviceListMetadata = $root.proto.DeviceListMetadata.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.deviceListMetadataVersion = reader.int32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a MessageContextInfo message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.MessageContextInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.MessageContextInfo} MessageContextInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        MessageContextInfo.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a MessageContextInfo message.
         * @function verify
         * @memberof proto.MessageContextInfo
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        MessageContextInfo.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.deviceListMetadata != null && message.hasOwnProperty("deviceListMetadata")) {
                var error = $root.proto.DeviceListMetadata.verify(message.deviceListMetadata);
                if (error)
                    return "deviceListMetadata." + error;
            }
            if (message.deviceListMetadataVersion != null && message.hasOwnProperty("deviceListMetadataVersion"))
                if (!$util.isInteger(message.deviceListMetadataVersion))
                    return "deviceListMetadataVersion: integer expected";
            return null;
        };

        /**
         * Creates a MessageContextInfo message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.MessageContextInfo
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.MessageContextInfo} MessageContextInfo
         */
        MessageContextInfo.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.MessageContextInfo)
                return object;
            var message = new $root.proto.MessageContextInfo();
            if (object.deviceListMetadata != null) {
                if (typeof object.deviceListMetadata !== "object")
                    throw TypeError(".proto.MessageContextInfo.deviceListMetadata: object expected");
                message.deviceListMetadata = $root.proto.DeviceListMetadata.fromObject(object.deviceListMetadata);
            }
            if (object.deviceListMetadataVersion != null)
                message.deviceListMetadataVersion = object.deviceListMetadataVersion | 0;
            return message;
        };

        /**
         * Creates a plain object from a MessageContextInfo message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.MessageContextInfo
         * @static
         * @param {proto.MessageContextInfo} message MessageContextInfo
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        MessageContextInfo.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.deviceListMetadata = null;
                object.deviceListMetadataVersion = 0;
            }
            if (message.deviceListMetadata != null && message.hasOwnProperty("deviceListMetadata"))
                object.deviceListMetadata = $root.proto.DeviceListMetadata.toObject(message.deviceListMetadata, options);
            if (message.deviceListMetadataVersion != null && message.hasOwnProperty("deviceListMetadataVersion"))
                object.deviceListMetadataVersion = message.deviceListMetadataVersion;
            return object;
        };

        /**
         * Converts this MessageContextInfo to JSON.
         * @function toJSON
         * @memberof proto.MessageContextInfo
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        MessageContextInfo.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return MessageContextInfo;
    })();

    proto.AdReplyInfo = (function() {

        /**
         * Properties of an AdReplyInfo.
         * @memberof proto
         * @interface IAdReplyInfo
         * @property {string|null} [advertiserName] AdReplyInfo advertiserName
         * @property {proto.AdReplyInfo.AdReplyInfoMediaType|null} [mediaType] AdReplyInfo mediaType
         * @property {Uint8Array|null} [jpegThumbnail] AdReplyInfo jpegThumbnail
         * @property {string|null} [caption] AdReplyInfo caption
         */

        /**
         * Constructs a new AdReplyInfo.
         * @memberof proto
         * @classdesc Represents an AdReplyInfo.
         * @implements IAdReplyInfo
         * @constructor
         * @param {proto.IAdReplyInfo=} [properties] Properties to set
         */
        function AdReplyInfo(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * AdReplyInfo advertiserName.
         * @member {string} advertiserName
         * @memberof proto.AdReplyInfo
         * @instance
         */
        AdReplyInfo.prototype.advertiserName = "";

        /**
         * AdReplyInfo mediaType.
         * @member {proto.AdReplyInfo.AdReplyInfoMediaType} mediaType
         * @memberof proto.AdReplyInfo
         * @instance
         */
        AdReplyInfo.prototype.mediaType = 0;

        /**
         * AdReplyInfo jpegThumbnail.
         * @member {Uint8Array} jpegThumbnail
         * @memberof proto.AdReplyInfo
         * @instance
         */
        AdReplyInfo.prototype.jpegThumbnail = $util.newBuffer([]);

        /**
         * AdReplyInfo caption.
         * @member {string} caption
         * @memberof proto.AdReplyInfo
         * @instance
         */
        AdReplyInfo.prototype.caption = "";

        /**
         * Creates a new AdReplyInfo instance using the specified properties.
         * @function create
         * @memberof proto.AdReplyInfo
         * @static
         * @param {proto.IAdReplyInfo=} [properties] Properties to set
         * @returns {proto.AdReplyInfo} AdReplyInfo instance
         */
        AdReplyInfo.create = function create(properties) {
            return new AdReplyInfo(properties);
        };

        /**
         * Encodes the specified AdReplyInfo message. Does not implicitly {@link proto.AdReplyInfo.verify|verify} messages.
         * @function encode
         * @memberof proto.AdReplyInfo
         * @static
         * @param {proto.IAdReplyInfo} message AdReplyInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AdReplyInfo.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.advertiserName != null && Object.hasOwnProperty.call(message, "advertiserName"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.advertiserName);
            if (message.mediaType != null && Object.hasOwnProperty.call(message, "mediaType"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.mediaType);
            if (message.jpegThumbnail != null && Object.hasOwnProperty.call(message, "jpegThumbnail"))
                writer.uint32(/* id 16, wireType 2 =*/130).bytes(message.jpegThumbnail);
            if (message.caption != null && Object.hasOwnProperty.call(message, "caption"))
                writer.uint32(/* id 17, wireType 2 =*/138).string(message.caption);
            return writer;
        };

        /**
         * Encodes the specified AdReplyInfo message, length delimited. Does not implicitly {@link proto.AdReplyInfo.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.AdReplyInfo
         * @static
         * @param {proto.IAdReplyInfo} message AdReplyInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AdReplyInfo.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an AdReplyInfo message from the specified reader or buffer.
         * @function decode
         * @memberof proto.AdReplyInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.AdReplyInfo} AdReplyInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AdReplyInfo.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.AdReplyInfo();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.advertiserName = reader.string();
                    break;
                case 2:
                    message.mediaType = reader.int32();
                    break;
                case 16:
                    message.jpegThumbnail = reader.bytes();
                    break;
                case 17:
                    message.caption = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an AdReplyInfo message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.AdReplyInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.AdReplyInfo} AdReplyInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AdReplyInfo.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an AdReplyInfo message.
         * @function verify
         * @memberof proto.AdReplyInfo
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        AdReplyInfo.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.advertiserName != null && message.hasOwnProperty("advertiserName"))
                if (!$util.isString(message.advertiserName))
                    return "advertiserName: string expected";
            if (message.mediaType != null && message.hasOwnProperty("mediaType"))
                switch (message.mediaType) {
                default:
                    return "mediaType: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            if (message.jpegThumbnail != null && message.hasOwnProperty("jpegThumbnail"))
                if (!(message.jpegThumbnail && typeof message.jpegThumbnail.length === "number" || $util.isString(message.jpegThumbnail)))
                    return "jpegThumbnail: buffer expected";
            if (message.caption != null && message.hasOwnProperty("caption"))
                if (!$util.isString(message.caption))
                    return "caption: string expected";
            return null;
        };

        /**
         * Creates an AdReplyInfo message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.AdReplyInfo
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.AdReplyInfo} AdReplyInfo
         */
        AdReplyInfo.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.AdReplyInfo)
                return object;
            var message = new $root.proto.AdReplyInfo();
            if (object.advertiserName != null)
                message.advertiserName = String(object.advertiserName);
            switch (object.mediaType) {
            case "NONE":
            case 0:
                message.mediaType = 0;
                break;
            case "IMAGE":
            case 1:
                message.mediaType = 1;
                break;
            case "VIDEO":
            case 2:
                message.mediaType = 2;
                break;
            }
            if (object.jpegThumbnail != null)
                if (typeof object.jpegThumbnail === "string")
                    $util.base64.decode(object.jpegThumbnail, message.jpegThumbnail = $util.newBuffer($util.base64.length(object.jpegThumbnail)), 0);
                else if (object.jpegThumbnail.length)
                    message.jpegThumbnail = object.jpegThumbnail;
            if (object.caption != null)
                message.caption = String(object.caption);
            return message;
        };

        /**
         * Creates a plain object from an AdReplyInfo message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.AdReplyInfo
         * @static
         * @param {proto.AdReplyInfo} message AdReplyInfo
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        AdReplyInfo.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.advertiserName = "";
                object.mediaType = options.enums === String ? "NONE" : 0;
                if (options.bytes === String)
                    object.jpegThumbnail = "";
                else {
                    object.jpegThumbnail = [];
                    if (options.bytes !== Array)
                        object.jpegThumbnail = $util.newBuffer(object.jpegThumbnail);
                }
                object.caption = "";
            }
            if (message.advertiserName != null && message.hasOwnProperty("advertiserName"))
                object.advertiserName = message.advertiserName;
            if (message.mediaType != null && message.hasOwnProperty("mediaType"))
                object.mediaType = options.enums === String ? $root.proto.AdReplyInfo.AdReplyInfoMediaType[message.mediaType] : message.mediaType;
            if (message.jpegThumbnail != null && message.hasOwnProperty("jpegThumbnail"))
                object.jpegThumbnail = options.bytes === String ? $util.base64.encode(message.jpegThumbnail, 0, message.jpegThumbnail.length) : options.bytes === Array ? Array.prototype.slice.call(message.jpegThumbnail) : message.jpegThumbnail;
            if (message.caption != null && message.hasOwnProperty("caption"))
                object.caption = message.caption;
            return object;
        };

        /**
         * Converts this AdReplyInfo to JSON.
         * @function toJSON
         * @memberof proto.AdReplyInfo
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        AdReplyInfo.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * AdReplyInfoMediaType enum.
         * @name proto.AdReplyInfo.AdReplyInfoMediaType
         * @enum {number}
         * @property {number} NONE=0 NONE value
         * @property {number} IMAGE=1 IMAGE value
         * @property {number} VIDEO=2 VIDEO value
         */
        AdReplyInfo.AdReplyInfoMediaType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "NONE"] = 0;
            values[valuesById[1] = "IMAGE"] = 1;
            values[valuesById[2] = "VIDEO"] = 2;
            return values;
        })();

        return AdReplyInfo;
    })();

    proto.ExternalAdReplyInfo = (function() {

        /**
         * Properties of an ExternalAdReplyInfo.
         * @memberof proto
         * @interface IExternalAdReplyInfo
         * @property {string|null} [title] ExternalAdReplyInfo title
         * @property {string|null} [body] ExternalAdReplyInfo body
         * @property {proto.ExternalAdReplyInfo.ExternalAdReplyInfoMediaType|null} [mediaType] ExternalAdReplyInfo mediaType
         * @property {string|null} [thumbnailUrl] ExternalAdReplyInfo thumbnailUrl
         * @property {string|null} [mediaUrl] ExternalAdReplyInfo mediaUrl
         * @property {Uint8Array|null} [thumbnail] ExternalAdReplyInfo thumbnail
         * @property {string|null} [sourceType] ExternalAdReplyInfo sourceType
         * @property {string|null} [sourceId] ExternalAdReplyInfo sourceId
         * @property {string|null} [sourceUrl] ExternalAdReplyInfo sourceUrl
         */

        /**
         * Constructs a new ExternalAdReplyInfo.
         * @memberof proto
         * @classdesc Represents an ExternalAdReplyInfo.
         * @implements IExternalAdReplyInfo
         * @constructor
         * @param {proto.IExternalAdReplyInfo=} [properties] Properties to set
         */
        function ExternalAdReplyInfo(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ExternalAdReplyInfo title.
         * @member {string} title
         * @memberof proto.ExternalAdReplyInfo
         * @instance
         */
        ExternalAdReplyInfo.prototype.title = "";

        /**
         * ExternalAdReplyInfo body.
         * @member {string} body
         * @memberof proto.ExternalAdReplyInfo
         * @instance
         */
        ExternalAdReplyInfo.prototype.body = "";

        /**
         * ExternalAdReplyInfo mediaType.
         * @member {proto.ExternalAdReplyInfo.ExternalAdReplyInfoMediaType} mediaType
         * @memberof proto.ExternalAdReplyInfo
         * @instance
         */
        ExternalAdReplyInfo.prototype.mediaType = 0;

        /**
         * ExternalAdReplyInfo thumbnailUrl.
         * @member {string} thumbnailUrl
         * @memberof proto.ExternalAdReplyInfo
         * @instance
         */
        ExternalAdReplyInfo.prototype.thumbnailUrl = "";

        /**
         * ExternalAdReplyInfo mediaUrl.
         * @member {string} mediaUrl
         * @memberof proto.ExternalAdReplyInfo
         * @instance
         */
        ExternalAdReplyInfo.prototype.mediaUrl = "";

        /**
         * ExternalAdReplyInfo thumbnail.
         * @member {Uint8Array} thumbnail
         * @memberof proto.ExternalAdReplyInfo
         * @instance
         */
        ExternalAdReplyInfo.prototype.thumbnail = $util.newBuffer([]);

        /**
         * ExternalAdReplyInfo sourceType.
         * @member {string} sourceType
         * @memberof proto.ExternalAdReplyInfo
         * @instance
         */
        ExternalAdReplyInfo.prototype.sourceType = "";

        /**
         * ExternalAdReplyInfo sourceId.
         * @member {string} sourceId
         * @memberof proto.ExternalAdReplyInfo
         * @instance
         */
        ExternalAdReplyInfo.prototype.sourceId = "";

        /**
         * ExternalAdReplyInfo sourceUrl.
         * @member {string} sourceUrl
         * @memberof proto.ExternalAdReplyInfo
         * @instance
         */
        ExternalAdReplyInfo.prototype.sourceUrl = "";

        /**
         * Creates a new ExternalAdReplyInfo instance using the specified properties.
         * @function create
         * @memberof proto.ExternalAdReplyInfo
         * @static
         * @param {proto.IExternalAdReplyInfo=} [properties] Properties to set
         * @returns {proto.ExternalAdReplyInfo} ExternalAdReplyInfo instance
         */
        ExternalAdReplyInfo.create = function create(properties) {
            return new ExternalAdReplyInfo(properties);
        };

        /**
         * Encodes the specified ExternalAdReplyInfo message. Does not implicitly {@link proto.ExternalAdReplyInfo.verify|verify} messages.
         * @function encode
         * @memberof proto.ExternalAdReplyInfo
         * @static
         * @param {proto.IExternalAdReplyInfo} message ExternalAdReplyInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ExternalAdReplyInfo.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.title != null && Object.hasOwnProperty.call(message, "title"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.title);
            if (message.body != null && Object.hasOwnProperty.call(message, "body"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.body);
            if (message.mediaType != null && Object.hasOwnProperty.call(message, "mediaType"))
                writer.uint32(/* id 3, wireType 0 =*/24).int32(message.mediaType);
            if (message.thumbnailUrl != null && Object.hasOwnProperty.call(message, "thumbnailUrl"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.thumbnailUrl);
            if (message.mediaUrl != null && Object.hasOwnProperty.call(message, "mediaUrl"))
                writer.uint32(/* id 5, wireType 2 =*/42).string(message.mediaUrl);
            if (message.thumbnail != null && Object.hasOwnProperty.call(message, "thumbnail"))
                writer.uint32(/* id 6, wireType 2 =*/50).bytes(message.thumbnail);
            if (message.sourceType != null && Object.hasOwnProperty.call(message, "sourceType"))
                writer.uint32(/* id 7, wireType 2 =*/58).string(message.sourceType);
            if (message.sourceId != null && Object.hasOwnProperty.call(message, "sourceId"))
                writer.uint32(/* id 8, wireType 2 =*/66).string(message.sourceId);
            if (message.sourceUrl != null && Object.hasOwnProperty.call(message, "sourceUrl"))
                writer.uint32(/* id 9, wireType 2 =*/74).string(message.sourceUrl);
            return writer;
        };

        /**
         * Encodes the specified ExternalAdReplyInfo message, length delimited. Does not implicitly {@link proto.ExternalAdReplyInfo.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ExternalAdReplyInfo
         * @static
         * @param {proto.IExternalAdReplyInfo} message ExternalAdReplyInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ExternalAdReplyInfo.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an ExternalAdReplyInfo message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ExternalAdReplyInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ExternalAdReplyInfo} ExternalAdReplyInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ExternalAdReplyInfo.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ExternalAdReplyInfo();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.title = reader.string();
                    break;
                case 2:
                    message.body = reader.string();
                    break;
                case 3:
                    message.mediaType = reader.int32();
                    break;
                case 4:
                    message.thumbnailUrl = reader.string();
                    break;
                case 5:
                    message.mediaUrl = reader.string();
                    break;
                case 6:
                    message.thumbnail = reader.bytes();
                    break;
                case 7:
                    message.sourceType = reader.string();
                    break;
                case 8:
                    message.sourceId = reader.string();
                    break;
                case 9:
                    message.sourceUrl = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an ExternalAdReplyInfo message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ExternalAdReplyInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ExternalAdReplyInfo} ExternalAdReplyInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ExternalAdReplyInfo.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an ExternalAdReplyInfo message.
         * @function verify
         * @memberof proto.ExternalAdReplyInfo
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ExternalAdReplyInfo.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.title != null && message.hasOwnProperty("title"))
                if (!$util.isString(message.title))
                    return "title: string expected";
            if (message.body != null && message.hasOwnProperty("body"))
                if (!$util.isString(message.body))
                    return "body: string expected";
            if (message.mediaType != null && message.hasOwnProperty("mediaType"))
                switch (message.mediaType) {
                default:
                    return "mediaType: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            if (message.thumbnailUrl != null && message.hasOwnProperty("thumbnailUrl"))
                if (!$util.isString(message.thumbnailUrl))
                    return "thumbnailUrl: string expected";
            if (message.mediaUrl != null && message.hasOwnProperty("mediaUrl"))
                if (!$util.isString(message.mediaUrl))
                    return "mediaUrl: string expected";
            if (message.thumbnail != null && message.hasOwnProperty("thumbnail"))
                if (!(message.thumbnail && typeof message.thumbnail.length === "number" || $util.isString(message.thumbnail)))
                    return "thumbnail: buffer expected";
            if (message.sourceType != null && message.hasOwnProperty("sourceType"))
                if (!$util.isString(message.sourceType))
                    return "sourceType: string expected";
            if (message.sourceId != null && message.hasOwnProperty("sourceId"))
                if (!$util.isString(message.sourceId))
                    return "sourceId: string expected";
            if (message.sourceUrl != null && message.hasOwnProperty("sourceUrl"))
                if (!$util.isString(message.sourceUrl))
                    return "sourceUrl: string expected";
            return null;
        };

        /**
         * Creates an ExternalAdReplyInfo message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ExternalAdReplyInfo
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ExternalAdReplyInfo} ExternalAdReplyInfo
         */
        ExternalAdReplyInfo.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ExternalAdReplyInfo)
                return object;
            var message = new $root.proto.ExternalAdReplyInfo();
            if (object.title != null)
                message.title = String(object.title);
            if (object.body != null)
                message.body = String(object.body);
            switch (object.mediaType) {
            case "NONE":
            case 0:
                message.mediaType = 0;
                break;
            case "IMAGE":
            case 1:
                message.mediaType = 1;
                break;
            case "VIDEO":
            case 2:
                message.mediaType = 2;
                break;
            }
            if (object.thumbnailUrl != null)
                message.thumbnailUrl = String(object.thumbnailUrl);
            if (object.mediaUrl != null)
                message.mediaUrl = String(object.mediaUrl);
            if (object.thumbnail != null)
                if (typeof object.thumbnail === "string")
                    $util.base64.decode(object.thumbnail, message.thumbnail = $util.newBuffer($util.base64.length(object.thumbnail)), 0);
                else if (object.thumbnail.length)
                    message.thumbnail = object.thumbnail;
            if (object.sourceType != null)
                message.sourceType = String(object.sourceType);
            if (object.sourceId != null)
                message.sourceId = String(object.sourceId);
            if (object.sourceUrl != null)
                message.sourceUrl = String(object.sourceUrl);
            return message;
        };

        /**
         * Creates a plain object from an ExternalAdReplyInfo message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ExternalAdReplyInfo
         * @static
         * @param {proto.ExternalAdReplyInfo} message ExternalAdReplyInfo
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ExternalAdReplyInfo.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.title = "";
                object.body = "";
                object.mediaType = options.enums === String ? "NONE" : 0;
                object.thumbnailUrl = "";
                object.mediaUrl = "";
                if (options.bytes === String)
                    object.thumbnail = "";
                else {
                    object.thumbnail = [];
                    if (options.bytes !== Array)
                        object.thumbnail = $util.newBuffer(object.thumbnail);
                }
                object.sourceType = "";
                object.sourceId = "";
                object.sourceUrl = "";
            }
            if (message.title != null && message.hasOwnProperty("title"))
                object.title = message.title;
            if (message.body != null && message.hasOwnProperty("body"))
                object.body = message.body;
            if (message.mediaType != null && message.hasOwnProperty("mediaType"))
                object.mediaType = options.enums === String ? $root.proto.ExternalAdReplyInfo.ExternalAdReplyInfoMediaType[message.mediaType] : message.mediaType;
            if (message.thumbnailUrl != null && message.hasOwnProperty("thumbnailUrl"))
                object.thumbnailUrl = message.thumbnailUrl;
            if (message.mediaUrl != null && message.hasOwnProperty("mediaUrl"))
                object.mediaUrl = message.mediaUrl;
            if (message.thumbnail != null && message.hasOwnProperty("thumbnail"))
                object.thumbnail = options.bytes === String ? $util.base64.encode(message.thumbnail, 0, message.thumbnail.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnail) : message.thumbnail;
            if (message.sourceType != null && message.hasOwnProperty("sourceType"))
                object.sourceType = message.sourceType;
            if (message.sourceId != null && message.hasOwnProperty("sourceId"))
                object.sourceId = message.sourceId;
            if (message.sourceUrl != null && message.hasOwnProperty("sourceUrl"))
                object.sourceUrl = message.sourceUrl;
            return object;
        };

        /**
         * Converts this ExternalAdReplyInfo to JSON.
         * @function toJSON
         * @memberof proto.ExternalAdReplyInfo
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ExternalAdReplyInfo.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * ExternalAdReplyInfoMediaType enum.
         * @name proto.ExternalAdReplyInfo.ExternalAdReplyInfoMediaType
         * @enum {number}
         * @property {number} NONE=0 NONE value
         * @property {number} IMAGE=1 IMAGE value
         * @property {number} VIDEO=2 VIDEO value
         */
        ExternalAdReplyInfo.ExternalAdReplyInfoMediaType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "NONE"] = 0;
            values[valuesById[1] = "IMAGE"] = 1;
            values[valuesById[2] = "VIDEO"] = 2;
            return values;
        })();

        return ExternalAdReplyInfo;
    })();

    proto.ContextInfo = (function() {

        /**
         * Properties of a ContextInfo.
         * @memberof proto
         * @interface IContextInfo
         * @property {string|null} [stanzaId] ContextInfo stanzaId
         * @property {string|null} [participant] ContextInfo participant
         * @property {proto.IMessage|null} [quotedMessage] ContextInfo quotedMessage
         * @property {string|null} [remoteJid] ContextInfo remoteJid
         * @property {Array.<string>|null} [mentionedJid] ContextInfo mentionedJid
         * @property {string|null} [conversionSource] ContextInfo conversionSource
         * @property {Uint8Array|null} [conversionData] ContextInfo conversionData
         * @property {number|null} [conversionDelaySeconds] ContextInfo conversionDelaySeconds
         * @property {number|null} [forwardingScore] ContextInfo forwardingScore
         * @property {boolean|null} [isForwarded] ContextInfo isForwarded
         * @property {proto.IAdReplyInfo|null} [quotedAd] ContextInfo quotedAd
         * @property {proto.IMessageKey|null} [placeholderKey] ContextInfo placeholderKey
         * @property {number|null} [expiration] ContextInfo expiration
         * @property {number|Long|null} [ephemeralSettingTimestamp] ContextInfo ephemeralSettingTimestamp
         * @property {Uint8Array|null} [ephemeralSharedSecret] ContextInfo ephemeralSharedSecret
         * @property {proto.IExternalAdReplyInfo|null} [externalAdReply] ContextInfo externalAdReply
         * @property {string|null} [entryPointConversionSource] ContextInfo entryPointConversionSource
         * @property {string|null} [entryPointConversionApp] ContextInfo entryPointConversionApp
         * @property {number|null} [entryPointConversionDelaySeconds] ContextInfo entryPointConversionDelaySeconds
         * @property {proto.IDisappearingMode|null} [disappearingMode] ContextInfo disappearingMode
         * @property {proto.IActionLink|null} [actionLink] ContextInfo actionLink
         * @property {string|null} [groupSubject] ContextInfo groupSubject
         * @property {string|null} [parentGroupJid] ContextInfo parentGroupJid
         */

        /**
         * Constructs a new ContextInfo.
         * @memberof proto
         * @classdesc Represents a ContextInfo.
         * @implements IContextInfo
         * @constructor
         * @param {proto.IContextInfo=} [properties] Properties to set
         */
        function ContextInfo(properties) {
            this.mentionedJid = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ContextInfo stanzaId.
         * @member {string} stanzaId
         * @memberof proto.ContextInfo
         * @instance
         */
        ContextInfo.prototype.stanzaId = "";

        /**
         * ContextInfo participant.
         * @member {string} participant
         * @memberof proto.ContextInfo
         * @instance
         */
        ContextInfo.prototype.participant = "";

        /**
         * ContextInfo quotedMessage.
         * @member {proto.IMessage|null|undefined} quotedMessage
         * @memberof proto.ContextInfo
         * @instance
         */
        ContextInfo.prototype.quotedMessage = null;

        /**
         * ContextInfo remoteJid.
         * @member {string} remoteJid
         * @memberof proto.ContextInfo
         * @instance
         */
        ContextInfo.prototype.remoteJid = "";

        /**
         * ContextInfo mentionedJid.
         * @member {Array.<string>} mentionedJid
         * @memberof proto.ContextInfo
         * @instance
         */
        ContextInfo.prototype.mentionedJid = $util.emptyArray;

        /**
         * ContextInfo conversionSource.
         * @member {string} conversionSource
         * @memberof proto.ContextInfo
         * @instance
         */
        ContextInfo.prototype.conversionSource = "";

        /**
         * ContextInfo conversionData.
         * @member {Uint8Array} conversionData
         * @memberof proto.ContextInfo
         * @instance
         */
        ContextInfo.prototype.conversionData = $util.newBuffer([]);

        /**
         * ContextInfo conversionDelaySeconds.
         * @member {number} conversionDelaySeconds
         * @memberof proto.ContextInfo
         * @instance
         */
        ContextInfo.prototype.conversionDelaySeconds = 0;

        /**
         * ContextInfo forwardingScore.
         * @member {number} forwardingScore
         * @memberof proto.ContextInfo
         * @instance
         */
        ContextInfo.prototype.forwardingScore = 0;

        /**
         * ContextInfo isForwarded.
         * @member {boolean} isForwarded
         * @memberof proto.ContextInfo
         * @instance
         */
        ContextInfo.prototype.isForwarded = false;

        /**
         * ContextInfo quotedAd.
         * @member {proto.IAdReplyInfo|null|undefined} quotedAd
         * @memberof proto.ContextInfo
         * @instance
         */
        ContextInfo.prototype.quotedAd = null;

        /**
         * ContextInfo placeholderKey.
         * @member {proto.IMessageKey|null|undefined} placeholderKey
         * @memberof proto.ContextInfo
         * @instance
         */
        ContextInfo.prototype.placeholderKey = null;

        /**
         * ContextInfo expiration.
         * @member {number} expiration
         * @memberof proto.ContextInfo
         * @instance
         */
        ContextInfo.prototype.expiration = 0;

        /**
         * ContextInfo ephemeralSettingTimestamp.
         * @member {number|Long} ephemeralSettingTimestamp
         * @memberof proto.ContextInfo
         * @instance
         */
        ContextInfo.prototype.ephemeralSettingTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * ContextInfo ephemeralSharedSecret.
         * @member {Uint8Array} ephemeralSharedSecret
         * @memberof proto.ContextInfo
         * @instance
         */
        ContextInfo.prototype.ephemeralSharedSecret = $util.newBuffer([]);

        /**
         * ContextInfo externalAdReply.
         * @member {proto.IExternalAdReplyInfo|null|undefined} externalAdReply
         * @memberof proto.ContextInfo
         * @instance
         */
        ContextInfo.prototype.externalAdReply = null;

        /**
         * ContextInfo entryPointConversionSource.
         * @member {string} entryPointConversionSource
         * @memberof proto.ContextInfo
         * @instance
         */
        ContextInfo.prototype.entryPointConversionSource = "";

        /**
         * ContextInfo entryPointConversionApp.
         * @member {string} entryPointConversionApp
         * @memberof proto.ContextInfo
         * @instance
         */
        ContextInfo.prototype.entryPointConversionApp = "";

        /**
         * ContextInfo entryPointConversionDelaySeconds.
         * @member {number} entryPointConversionDelaySeconds
         * @memberof proto.ContextInfo
         * @instance
         */
        ContextInfo.prototype.entryPointConversionDelaySeconds = 0;

        /**
         * ContextInfo disappearingMode.
         * @member {proto.IDisappearingMode|null|undefined} disappearingMode
         * @memberof proto.ContextInfo
         * @instance
         */
        ContextInfo.prototype.disappearingMode = null;

        /**
         * ContextInfo actionLink.
         * @member {proto.IActionLink|null|undefined} actionLink
         * @memberof proto.ContextInfo
         * @instance
         */
        ContextInfo.prototype.actionLink = null;

        /**
         * ContextInfo groupSubject.
         * @member {string} groupSubject
         * @memberof proto.ContextInfo
         * @instance
         */
        ContextInfo.prototype.groupSubject = "";

        /**
         * ContextInfo parentGroupJid.
         * @member {string} parentGroupJid
         * @memberof proto.ContextInfo
         * @instance
         */
        ContextInfo.prototype.parentGroupJid = "";

        /**
         * Creates a new ContextInfo instance using the specified properties.
         * @function create
         * @memberof proto.ContextInfo
         * @static
         * @param {proto.IContextInfo=} [properties] Properties to set
         * @returns {proto.ContextInfo} ContextInfo instance
         */
        ContextInfo.create = function create(properties) {
            return new ContextInfo(properties);
        };

        /**
         * Encodes the specified ContextInfo message. Does not implicitly {@link proto.ContextInfo.verify|verify} messages.
         * @function encode
         * @memberof proto.ContextInfo
         * @static
         * @param {proto.IContextInfo} message ContextInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ContextInfo.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.stanzaId != null && Object.hasOwnProperty.call(message, "stanzaId"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.stanzaId);
            if (message.participant != null && Object.hasOwnProperty.call(message, "participant"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.participant);
            if (message.quotedMessage != null && Object.hasOwnProperty.call(message, "quotedMessage"))
                $root.proto.Message.encode(message.quotedMessage, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.remoteJid != null && Object.hasOwnProperty.call(message, "remoteJid"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.remoteJid);
            if (message.mentionedJid != null && message.mentionedJid.length)
                for (var i = 0; i < message.mentionedJid.length; ++i)
                    writer.uint32(/* id 15, wireType 2 =*/122).string(message.mentionedJid[i]);
            if (message.conversionSource != null && Object.hasOwnProperty.call(message, "conversionSource"))
                writer.uint32(/* id 18, wireType 2 =*/146).string(message.conversionSource);
            if (message.conversionData != null && Object.hasOwnProperty.call(message, "conversionData"))
                writer.uint32(/* id 19, wireType 2 =*/154).bytes(message.conversionData);
            if (message.conversionDelaySeconds != null && Object.hasOwnProperty.call(message, "conversionDelaySeconds"))
                writer.uint32(/* id 20, wireType 0 =*/160).uint32(message.conversionDelaySeconds);
            if (message.forwardingScore != null && Object.hasOwnProperty.call(message, "forwardingScore"))
                writer.uint32(/* id 21, wireType 0 =*/168).uint32(message.forwardingScore);
            if (message.isForwarded != null && Object.hasOwnProperty.call(message, "isForwarded"))
                writer.uint32(/* id 22, wireType 0 =*/176).bool(message.isForwarded);
            if (message.quotedAd != null && Object.hasOwnProperty.call(message, "quotedAd"))
                $root.proto.AdReplyInfo.encode(message.quotedAd, writer.uint32(/* id 23, wireType 2 =*/186).fork()).ldelim();
            if (message.placeholderKey != null && Object.hasOwnProperty.call(message, "placeholderKey"))
                $root.proto.MessageKey.encode(message.placeholderKey, writer.uint32(/* id 24, wireType 2 =*/194).fork()).ldelim();
            if (message.expiration != null && Object.hasOwnProperty.call(message, "expiration"))
                writer.uint32(/* id 25, wireType 0 =*/200).uint32(message.expiration);
            if (message.ephemeralSettingTimestamp != null && Object.hasOwnProperty.call(message, "ephemeralSettingTimestamp"))
                writer.uint32(/* id 26, wireType 0 =*/208).int64(message.ephemeralSettingTimestamp);
            if (message.ephemeralSharedSecret != null && Object.hasOwnProperty.call(message, "ephemeralSharedSecret"))
                writer.uint32(/* id 27, wireType 2 =*/218).bytes(message.ephemeralSharedSecret);
            if (message.externalAdReply != null && Object.hasOwnProperty.call(message, "externalAdReply"))
                $root.proto.ExternalAdReplyInfo.encode(message.externalAdReply, writer.uint32(/* id 28, wireType 2 =*/226).fork()).ldelim();
            if (message.entryPointConversionSource != null && Object.hasOwnProperty.call(message, "entryPointConversionSource"))
                writer.uint32(/* id 29, wireType 2 =*/234).string(message.entryPointConversionSource);
            if (message.entryPointConversionApp != null && Object.hasOwnProperty.call(message, "entryPointConversionApp"))
                writer.uint32(/* id 30, wireType 2 =*/242).string(message.entryPointConversionApp);
            if (message.entryPointConversionDelaySeconds != null && Object.hasOwnProperty.call(message, "entryPointConversionDelaySeconds"))
                writer.uint32(/* id 31, wireType 0 =*/248).uint32(message.entryPointConversionDelaySeconds);
            if (message.disappearingMode != null && Object.hasOwnProperty.call(message, "disappearingMode"))
                $root.proto.DisappearingMode.encode(message.disappearingMode, writer.uint32(/* id 32, wireType 2 =*/258).fork()).ldelim();
            if (message.actionLink != null && Object.hasOwnProperty.call(message, "actionLink"))
                $root.proto.ActionLink.encode(message.actionLink, writer.uint32(/* id 33, wireType 2 =*/266).fork()).ldelim();
            if (message.groupSubject != null && Object.hasOwnProperty.call(message, "groupSubject"))
                writer.uint32(/* id 34, wireType 2 =*/274).string(message.groupSubject);
            if (message.parentGroupJid != null && Object.hasOwnProperty.call(message, "parentGroupJid"))
                writer.uint32(/* id 35, wireType 2 =*/282).string(message.parentGroupJid);
            return writer;
        };

        /**
         * Encodes the specified ContextInfo message, length delimited. Does not implicitly {@link proto.ContextInfo.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ContextInfo
         * @static
         * @param {proto.IContextInfo} message ContextInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ContextInfo.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ContextInfo message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ContextInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ContextInfo} ContextInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ContextInfo.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ContextInfo();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.stanzaId = reader.string();
                    break;
                case 2:
                    message.participant = reader.string();
                    break;
                case 3:
                    message.quotedMessage = $root.proto.Message.decode(reader, reader.uint32());
                    break;
                case 4:
                    message.remoteJid = reader.string();
                    break;
                case 15:
                    if (!(message.mentionedJid && message.mentionedJid.length))
                        message.mentionedJid = [];
                    message.mentionedJid.push(reader.string());
                    break;
                case 18:
                    message.conversionSource = reader.string();
                    break;
                case 19:
                    message.conversionData = reader.bytes();
                    break;
                case 20:
                    message.conversionDelaySeconds = reader.uint32();
                    break;
                case 21:
                    message.forwardingScore = reader.uint32();
                    break;
                case 22:
                    message.isForwarded = reader.bool();
                    break;
                case 23:
                    message.quotedAd = $root.proto.AdReplyInfo.decode(reader, reader.uint32());
                    break;
                case 24:
                    message.placeholderKey = $root.proto.MessageKey.decode(reader, reader.uint32());
                    break;
                case 25:
                    message.expiration = reader.uint32();
                    break;
                case 26:
                    message.ephemeralSettingTimestamp = reader.int64();
                    break;
                case 27:
                    message.ephemeralSharedSecret = reader.bytes();
                    break;
                case 28:
                    message.externalAdReply = $root.proto.ExternalAdReplyInfo.decode(reader, reader.uint32());
                    break;
                case 29:
                    message.entryPointConversionSource = reader.string();
                    break;
                case 30:
                    message.entryPointConversionApp = reader.string();
                    break;
                case 31:
                    message.entryPointConversionDelaySeconds = reader.uint32();
                    break;
                case 32:
                    message.disappearingMode = $root.proto.DisappearingMode.decode(reader, reader.uint32());
                    break;
                case 33:
                    message.actionLink = $root.proto.ActionLink.decode(reader, reader.uint32());
                    break;
                case 34:
                    message.groupSubject = reader.string();
                    break;
                case 35:
                    message.parentGroupJid = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ContextInfo message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ContextInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ContextInfo} ContextInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ContextInfo.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ContextInfo message.
         * @function verify
         * @memberof proto.ContextInfo
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ContextInfo.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.stanzaId != null && message.hasOwnProperty("stanzaId"))
                if (!$util.isString(message.stanzaId))
                    return "stanzaId: string expected";
            if (message.participant != null && message.hasOwnProperty("participant"))
                if (!$util.isString(message.participant))
                    return "participant: string expected";
            if (message.quotedMessage != null && message.hasOwnProperty("quotedMessage")) {
                var error = $root.proto.Message.verify(message.quotedMessage);
                if (error)
                    return "quotedMessage." + error;
            }
            if (message.remoteJid != null && message.hasOwnProperty("remoteJid"))
                if (!$util.isString(message.remoteJid))
                    return "remoteJid: string expected";
            if (message.mentionedJid != null && message.hasOwnProperty("mentionedJid")) {
                if (!Array.isArray(message.mentionedJid))
                    return "mentionedJid: array expected";
                for (var i = 0; i < message.mentionedJid.length; ++i)
                    if (!$util.isString(message.mentionedJid[i]))
                        return "mentionedJid: string[] expected";
            }
            if (message.conversionSource != null && message.hasOwnProperty("conversionSource"))
                if (!$util.isString(message.conversionSource))
                    return "conversionSource: string expected";
            if (message.conversionData != null && message.hasOwnProperty("conversionData"))
                if (!(message.conversionData && typeof message.conversionData.length === "number" || $util.isString(message.conversionData)))
                    return "conversionData: buffer expected";
            if (message.conversionDelaySeconds != null && message.hasOwnProperty("conversionDelaySeconds"))
                if (!$util.isInteger(message.conversionDelaySeconds))
                    return "conversionDelaySeconds: integer expected";
            if (message.forwardingScore != null && message.hasOwnProperty("forwardingScore"))
                if (!$util.isInteger(message.forwardingScore))
                    return "forwardingScore: integer expected";
            if (message.isForwarded != null && message.hasOwnProperty("isForwarded"))
                if (typeof message.isForwarded !== "boolean")
                    return "isForwarded: boolean expected";
            if (message.quotedAd != null && message.hasOwnProperty("quotedAd")) {
                var error = $root.proto.AdReplyInfo.verify(message.quotedAd);
                if (error)
                    return "quotedAd." + error;
            }
            if (message.placeholderKey != null && message.hasOwnProperty("placeholderKey")) {
                var error = $root.proto.MessageKey.verify(message.placeholderKey);
                if (error)
                    return "placeholderKey." + error;
            }
            if (message.expiration != null && message.hasOwnProperty("expiration"))
                if (!$util.isInteger(message.expiration))
                    return "expiration: integer expected";
            if (message.ephemeralSettingTimestamp != null && message.hasOwnProperty("ephemeralSettingTimestamp"))
                if (!$util.isInteger(message.ephemeralSettingTimestamp) && !(message.ephemeralSettingTimestamp && $util.isInteger(message.ephemeralSettingTimestamp.low) && $util.isInteger(message.ephemeralSettingTimestamp.high)))
                    return "ephemeralSettingTimestamp: integer|Long expected";
            if (message.ephemeralSharedSecret != null && message.hasOwnProperty("ephemeralSharedSecret"))
                if (!(message.ephemeralSharedSecret && typeof message.ephemeralSharedSecret.length === "number" || $util.isString(message.ephemeralSharedSecret)))
                    return "ephemeralSharedSecret: buffer expected";
            if (message.externalAdReply != null && message.hasOwnProperty("externalAdReply")) {
                var error = $root.proto.ExternalAdReplyInfo.verify(message.externalAdReply);
                if (error)
                    return "externalAdReply." + error;
            }
            if (message.entryPointConversionSource != null && message.hasOwnProperty("entryPointConversionSource"))
                if (!$util.isString(message.entryPointConversionSource))
                    return "entryPointConversionSource: string expected";
            if (message.entryPointConversionApp != null && message.hasOwnProperty("entryPointConversionApp"))
                if (!$util.isString(message.entryPointConversionApp))
                    return "entryPointConversionApp: string expected";
            if (message.entryPointConversionDelaySeconds != null && message.hasOwnProperty("entryPointConversionDelaySeconds"))
                if (!$util.isInteger(message.entryPointConversionDelaySeconds))
                    return "entryPointConversionDelaySeconds: integer expected";
            if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode")) {
                var error = $root.proto.DisappearingMode.verify(message.disappearingMode);
                if (error)
                    return "disappearingMode." + error;
            }
            if (message.actionLink != null && message.hasOwnProperty("actionLink")) {
                var error = $root.proto.ActionLink.verify(message.actionLink);
                if (error)
                    return "actionLink." + error;
            }
            if (message.groupSubject != null && message.hasOwnProperty("groupSubject"))
                if (!$util.isString(message.groupSubject))
                    return "groupSubject: string expected";
            if (message.parentGroupJid != null && message.hasOwnProperty("parentGroupJid"))
                if (!$util.isString(message.parentGroupJid))
                    return "parentGroupJid: string expected";
            return null;
        };

        /**
         * Creates a ContextInfo message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ContextInfo
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ContextInfo} ContextInfo
         */
        ContextInfo.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ContextInfo)
                return object;
            var message = new $root.proto.ContextInfo();
            if (object.stanzaId != null)
                message.stanzaId = String(object.stanzaId);
            if (object.participant != null)
                message.participant = String(object.participant);
            if (object.quotedMessage != null) {
                if (typeof object.quotedMessage !== "object")
                    throw TypeError(".proto.ContextInfo.quotedMessage: object expected");
                message.quotedMessage = $root.proto.Message.fromObject(object.quotedMessage);
            }
            if (object.remoteJid != null)
                message.remoteJid = String(object.remoteJid);
            if (object.mentionedJid) {
                if (!Array.isArray(object.mentionedJid))
                    throw TypeError(".proto.ContextInfo.mentionedJid: array expected");
                message.mentionedJid = [];
                for (var i = 0; i < object.mentionedJid.length; ++i)
                    message.mentionedJid[i] = String(object.mentionedJid[i]);
            }
            if (object.conversionSource != null)
                message.conversionSource = String(object.conversionSource);
            if (object.conversionData != null)
                if (typeof object.conversionData === "string")
                    $util.base64.decode(object.conversionData, message.conversionData = $util.newBuffer($util.base64.length(object.conversionData)), 0);
                else if (object.conversionData.length)
                    message.conversionData = object.conversionData;
            if (object.conversionDelaySeconds != null)
                message.conversionDelaySeconds = object.conversionDelaySeconds >>> 0;
            if (object.forwardingScore != null)
                message.forwardingScore = object.forwardingScore >>> 0;
            if (object.isForwarded != null)
                message.isForwarded = Boolean(object.isForwarded);
            if (object.quotedAd != null) {
                if (typeof object.quotedAd !== "object")
                    throw TypeError(".proto.ContextInfo.quotedAd: object expected");
                message.quotedAd = $root.proto.AdReplyInfo.fromObject(object.quotedAd);
            }
            if (object.placeholderKey != null) {
                if (typeof object.placeholderKey !== "object")
                    throw TypeError(".proto.ContextInfo.placeholderKey: object expected");
                message.placeholderKey = $root.proto.MessageKey.fromObject(object.placeholderKey);
            }
            if (object.expiration != null)
                message.expiration = object.expiration >>> 0;
            if (object.ephemeralSettingTimestamp != null)
                if ($util.Long)
                    (message.ephemeralSettingTimestamp = $util.Long.fromValue(object.ephemeralSettingTimestamp)).unsigned = false;
                else if (typeof object.ephemeralSettingTimestamp === "string")
                    message.ephemeralSettingTimestamp = parseInt(object.ephemeralSettingTimestamp, 10);
                else if (typeof object.ephemeralSettingTimestamp === "number")
                    message.ephemeralSettingTimestamp = object.ephemeralSettingTimestamp;
                else if (typeof object.ephemeralSettingTimestamp === "object")
                    message.ephemeralSettingTimestamp = new $util.LongBits(object.ephemeralSettingTimestamp.low >>> 0, object.ephemeralSettingTimestamp.high >>> 0).toNumber();
            if (object.ephemeralSharedSecret != null)
                if (typeof object.ephemeralSharedSecret === "string")
                    $util.base64.decode(object.ephemeralSharedSecret, message.ephemeralSharedSecret = $util.newBuffer($util.base64.length(object.ephemeralSharedSecret)), 0);
                else if (object.ephemeralSharedSecret.length)
                    message.ephemeralSharedSecret = object.ephemeralSharedSecret;
            if (object.externalAdReply != null) {
                if (typeof object.externalAdReply !== "object")
                    throw TypeError(".proto.ContextInfo.externalAdReply: object expected");
                message.externalAdReply = $root.proto.ExternalAdReplyInfo.fromObject(object.externalAdReply);
            }
            if (object.entryPointConversionSource != null)
                message.entryPointConversionSource = String(object.entryPointConversionSource);
            if (object.entryPointConversionApp != null)
                message.entryPointConversionApp = String(object.entryPointConversionApp);
            if (object.entryPointConversionDelaySeconds != null)
                message.entryPointConversionDelaySeconds = object.entryPointConversionDelaySeconds >>> 0;
            if (object.disappearingMode != null) {
                if (typeof object.disappearingMode !== "object")
                    throw TypeError(".proto.ContextInfo.disappearingMode: object expected");
                message.disappearingMode = $root.proto.DisappearingMode.fromObject(object.disappearingMode);
            }
            if (object.actionLink != null) {
                if (typeof object.actionLink !== "object")
                    throw TypeError(".proto.ContextInfo.actionLink: object expected");
                message.actionLink = $root.proto.ActionLink.fromObject(object.actionLink);
            }
            if (object.groupSubject != null)
                message.groupSubject = String(object.groupSubject);
            if (object.parentGroupJid != null)
                message.parentGroupJid = String(object.parentGroupJid);
            return message;
        };

        /**
         * Creates a plain object from a ContextInfo message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ContextInfo
         * @static
         * @param {proto.ContextInfo} message ContextInfo
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ContextInfo.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.mentionedJid = [];
            if (options.defaults) {
                object.stanzaId = "";
                object.participant = "";
                object.quotedMessage = null;
                object.remoteJid = "";
                object.conversionSource = "";
                if (options.bytes === String)
                    object.conversionData = "";
                else {
                    object.conversionData = [];
                    if (options.bytes !== Array)
                        object.conversionData = $util.newBuffer(object.conversionData);
                }
                object.conversionDelaySeconds = 0;
                object.forwardingScore = 0;
                object.isForwarded = false;
                object.quotedAd = null;
                object.placeholderKey = null;
                object.expiration = 0;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.ephemeralSettingTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.ephemeralSettingTimestamp = options.longs === String ? "0" : 0;
                if (options.bytes === String)
                    object.ephemeralSharedSecret = "";
                else {
                    object.ephemeralSharedSecret = [];
                    if (options.bytes !== Array)
                        object.ephemeralSharedSecret = $util.newBuffer(object.ephemeralSharedSecret);
                }
                object.externalAdReply = null;
                object.entryPointConversionSource = "";
                object.entryPointConversionApp = "";
                object.entryPointConversionDelaySeconds = 0;
                object.disappearingMode = null;
                object.actionLink = null;
                object.groupSubject = "";
                object.parentGroupJid = "";
            }
            if (message.stanzaId != null && message.hasOwnProperty("stanzaId"))
                object.stanzaId = message.stanzaId;
            if (message.participant != null && message.hasOwnProperty("participant"))
                object.participant = message.participant;
            if (message.quotedMessage != null && message.hasOwnProperty("quotedMessage"))
                object.quotedMessage = $root.proto.Message.toObject(message.quotedMessage, options);
            if (message.remoteJid != null && message.hasOwnProperty("remoteJid"))
                object.remoteJid = message.remoteJid;
            if (message.mentionedJid && message.mentionedJid.length) {
                object.mentionedJid = [];
                for (var j = 0; j < message.mentionedJid.length; ++j)
                    object.mentionedJid[j] = message.mentionedJid[j];
            }
            if (message.conversionSource != null && message.hasOwnProperty("conversionSource"))
                object.conversionSource = message.conversionSource;
            if (message.conversionData != null && message.hasOwnProperty("conversionData"))
                object.conversionData = options.bytes === String ? $util.base64.encode(message.conversionData, 0, message.conversionData.length) : options.bytes === Array ? Array.prototype.slice.call(message.conversionData) : message.conversionData;
            if (message.conversionDelaySeconds != null && message.hasOwnProperty("conversionDelaySeconds"))
                object.conversionDelaySeconds = message.conversionDelaySeconds;
            if (message.forwardingScore != null && message.hasOwnProperty("forwardingScore"))
                object.forwardingScore = message.forwardingScore;
            if (message.isForwarded != null && message.hasOwnProperty("isForwarded"))
                object.isForwarded = message.isForwarded;
            if (message.quotedAd != null && message.hasOwnProperty("quotedAd"))
                object.quotedAd = $root.proto.AdReplyInfo.toObject(message.quotedAd, options);
            if (message.placeholderKey != null && message.hasOwnProperty("placeholderKey"))
                object.placeholderKey = $root.proto.MessageKey.toObject(message.placeholderKey, options);
            if (message.expiration != null && message.hasOwnProperty("expiration"))
                object.expiration = message.expiration;
            if (message.ephemeralSettingTimestamp != null && message.hasOwnProperty("ephemeralSettingTimestamp"))
                if (typeof message.ephemeralSettingTimestamp === "number")
                    object.ephemeralSettingTimestamp = options.longs === String ? String(message.ephemeralSettingTimestamp) : message.ephemeralSettingTimestamp;
                else
                    object.ephemeralSettingTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.ephemeralSettingTimestamp) : options.longs === Number ? new $util.LongBits(message.ephemeralSettingTimestamp.low >>> 0, message.ephemeralSettingTimestamp.high >>> 0).toNumber() : message.ephemeralSettingTimestamp;
            if (message.ephemeralSharedSecret != null && message.hasOwnProperty("ephemeralSharedSecret"))
                object.ephemeralSharedSecret = options.bytes === String ? $util.base64.encode(message.ephemeralSharedSecret, 0, message.ephemeralSharedSecret.length) : options.bytes === Array ? Array.prototype.slice.call(message.ephemeralSharedSecret) : message.ephemeralSharedSecret;
            if (message.externalAdReply != null && message.hasOwnProperty("externalAdReply"))
                object.externalAdReply = $root.proto.ExternalAdReplyInfo.toObject(message.externalAdReply, options);
            if (message.entryPointConversionSource != null && message.hasOwnProperty("entryPointConversionSource"))
                object.entryPointConversionSource = message.entryPointConversionSource;
            if (message.entryPointConversionApp != null && message.hasOwnProperty("entryPointConversionApp"))
                object.entryPointConversionApp = message.entryPointConversionApp;
            if (message.entryPointConversionDelaySeconds != null && message.hasOwnProperty("entryPointConversionDelaySeconds"))
                object.entryPointConversionDelaySeconds = message.entryPointConversionDelaySeconds;
            if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode"))
                object.disappearingMode = $root.proto.DisappearingMode.toObject(message.disappearingMode, options);
            if (message.actionLink != null && message.hasOwnProperty("actionLink"))
                object.actionLink = $root.proto.ActionLink.toObject(message.actionLink, options);
            if (message.groupSubject != null && message.hasOwnProperty("groupSubject"))
                object.groupSubject = message.groupSubject;
            if (message.parentGroupJid != null && message.hasOwnProperty("parentGroupJid"))
                object.parentGroupJid = message.parentGroupJid;
            return object;
        };

        /**
         * Converts this ContextInfo to JSON.
         * @function toJSON
         * @memberof proto.ContextInfo
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ContextInfo.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ContextInfo;
    })();

    proto.SenderKeyDistributionMessage = (function() {

        /**
         * Properties of a SenderKeyDistributionMessage.
         * @memberof proto
         * @interface ISenderKeyDistributionMessage
         * @property {string|null} [groupId] SenderKeyDistributionMessage groupId
         * @property {Uint8Array|null} [axolotlSenderKeyDistributionMessage] SenderKeyDistributionMessage axolotlSenderKeyDistributionMessage
         */

        /**
         * Constructs a new SenderKeyDistributionMessage.
         * @memberof proto
         * @classdesc Represents a SenderKeyDistributionMessage.
         * @implements ISenderKeyDistributionMessage
         * @constructor
         * @param {proto.ISenderKeyDistributionMessage=} [properties] Properties to set
         */
        function SenderKeyDistributionMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * SenderKeyDistributionMessage groupId.
         * @member {string} groupId
         * @memberof proto.SenderKeyDistributionMessage
         * @instance
         */
        SenderKeyDistributionMessage.prototype.groupId = "";

        /**
         * SenderKeyDistributionMessage axolotlSenderKeyDistributionMessage.
         * @member {Uint8Array} axolotlSenderKeyDistributionMessage
         * @memberof proto.SenderKeyDistributionMessage
         * @instance
         */
        SenderKeyDistributionMessage.prototype.axolotlSenderKeyDistributionMessage = $util.newBuffer([]);

        /**
         * Creates a new SenderKeyDistributionMessage instance using the specified properties.
         * @function create
         * @memberof proto.SenderKeyDistributionMessage
         * @static
         * @param {proto.ISenderKeyDistributionMessage=} [properties] Properties to set
         * @returns {proto.SenderKeyDistributionMessage} SenderKeyDistributionMessage instance
         */
        SenderKeyDistributionMessage.create = function create(properties) {
            return new SenderKeyDistributionMessage(properties);
        };

        /**
         * Encodes the specified SenderKeyDistributionMessage message. Does not implicitly {@link proto.SenderKeyDistributionMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.SenderKeyDistributionMessage
         * @static
         * @param {proto.ISenderKeyDistributionMessage} message SenderKeyDistributionMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SenderKeyDistributionMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.groupId != null && Object.hasOwnProperty.call(message, "groupId"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.groupId);
            if (message.axolotlSenderKeyDistributionMessage != null && Object.hasOwnProperty.call(message, "axolotlSenderKeyDistributionMessage"))
                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.axolotlSenderKeyDistributionMessage);
            return writer;
        };

        /**
         * Encodes the specified SenderKeyDistributionMessage message, length delimited. Does not implicitly {@link proto.SenderKeyDistributionMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.SenderKeyDistributionMessage
         * @static
         * @param {proto.ISenderKeyDistributionMessage} message SenderKeyDistributionMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SenderKeyDistributionMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a SenderKeyDistributionMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.SenderKeyDistributionMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.SenderKeyDistributionMessage} SenderKeyDistributionMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SenderKeyDistributionMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SenderKeyDistributionMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.groupId = reader.string();
                    break;
                case 2:
                    message.axolotlSenderKeyDistributionMessage = reader.bytes();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a SenderKeyDistributionMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.SenderKeyDistributionMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.SenderKeyDistributionMessage} SenderKeyDistributionMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SenderKeyDistributionMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a SenderKeyDistributionMessage message.
         * @function verify
         * @memberof proto.SenderKeyDistributionMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        SenderKeyDistributionMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.groupId != null && message.hasOwnProperty("groupId"))
                if (!$util.isString(message.groupId))
                    return "groupId: string expected";
            if (message.axolotlSenderKeyDistributionMessage != null && message.hasOwnProperty("axolotlSenderKeyDistributionMessage"))
                if (!(message.axolotlSenderKeyDistributionMessage && typeof message.axolotlSenderKeyDistributionMessage.length === "number" || $util.isString(message.axolotlSenderKeyDistributionMessage)))
                    return "axolotlSenderKeyDistributionMessage: buffer expected";
            return null;
        };

        /**
         * Creates a SenderKeyDistributionMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.SenderKeyDistributionMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.SenderKeyDistributionMessage} SenderKeyDistributionMessage
         */
        SenderKeyDistributionMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.SenderKeyDistributionMessage)
                return object;
            var message = new $root.proto.SenderKeyDistributionMessage();
            if (object.groupId != null)
                message.groupId = String(object.groupId);
            if (object.axolotlSenderKeyDistributionMessage != null)
                if (typeof object.axolotlSenderKeyDistributionMessage === "string")
                    $util.base64.decode(object.axolotlSenderKeyDistributionMessage, message.axolotlSenderKeyDistributionMessage = $util.newBuffer($util.base64.length(object.axolotlSenderKeyDistributionMessage)), 0);
                else if (object.axolotlSenderKeyDistributionMessage.length)
                    message.axolotlSenderKeyDistributionMessage = object.axolotlSenderKeyDistributionMessage;
            return message;
        };

        /**
         * Creates a plain object from a SenderKeyDistributionMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.SenderKeyDistributionMessage
         * @static
         * @param {proto.SenderKeyDistributionMessage} message SenderKeyDistributionMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        SenderKeyDistributionMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.groupId = "";
                if (options.bytes === String)
                    object.axolotlSenderKeyDistributionMessage = "";
                else {
                    object.axolotlSenderKeyDistributionMessage = [];
                    if (options.bytes !== Array)
                        object.axolotlSenderKeyDistributionMessage = $util.newBuffer(object.axolotlSenderKeyDistributionMessage);
                }
            }
            if (message.groupId != null && message.hasOwnProperty("groupId"))
                object.groupId = message.groupId;
            if (message.axolotlSenderKeyDistributionMessage != null && message.hasOwnProperty("axolotlSenderKeyDistributionMessage"))
                object.axolotlSenderKeyDistributionMessage = options.bytes === String ? $util.base64.encode(message.axolotlSenderKeyDistributionMessage, 0, message.axolotlSenderKeyDistributionMessage.length) : options.bytes === Array ? Array.prototype.slice.call(message.axolotlSenderKeyDistributionMessage) : message.axolotlSenderKeyDistributionMessage;
            return object;
        };

        /**
         * Converts this SenderKeyDistributionMessage to JSON.
         * @function toJSON
         * @memberof proto.SenderKeyDistributionMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        SenderKeyDistributionMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return SenderKeyDistributionMessage;
    })();

    proto.ImageMessage = (function() {

        /**
         * Properties of an ImageMessage.
         * @memberof proto
         * @interface IImageMessage
         * @property {string|null} [url] ImageMessage url
         * @property {string|null} [mimetype] ImageMessage mimetype
         * @property {string|null} [caption] ImageMessage caption
         * @property {Uint8Array|null} [fileSha256] ImageMessage fileSha256
         * @property {number|Long|null} [fileLength] ImageMessage fileLength
         * @property {number|null} [height] ImageMessage height
         * @property {number|null} [width] ImageMessage width
         * @property {Uint8Array|null} [mediaKey] ImageMessage mediaKey
         * @property {Uint8Array|null} [fileEncSha256] ImageMessage fileEncSha256
         * @property {Array.<proto.IInteractiveAnnotation>|null} [interactiveAnnotations] ImageMessage interactiveAnnotations
         * @property {string|null} [directPath] ImageMessage directPath
         * @property {number|Long|null} [mediaKeyTimestamp] ImageMessage mediaKeyTimestamp
         * @property {Uint8Array|null} [jpegThumbnail] ImageMessage jpegThumbnail
         * @property {proto.IContextInfo|null} [contextInfo] ImageMessage contextInfo
         * @property {Uint8Array|null} [firstScanSidecar] ImageMessage firstScanSidecar
         * @property {number|null} [firstScanLength] ImageMessage firstScanLength
         * @property {number|null} [experimentGroupId] ImageMessage experimentGroupId
         * @property {Uint8Array|null} [scansSidecar] ImageMessage scansSidecar
         * @property {Array.<number>|null} [scanLengths] ImageMessage scanLengths
         * @property {Uint8Array|null} [midQualityFileSha256] ImageMessage midQualityFileSha256
         * @property {Uint8Array|null} [midQualityFileEncSha256] ImageMessage midQualityFileEncSha256
         * @property {boolean|null} [viewOnce] ImageMessage viewOnce
         * @property {string|null} [thumbnailDirectPath] ImageMessage thumbnailDirectPath
         * @property {Uint8Array|null} [thumbnailSha256] ImageMessage thumbnailSha256
         * @property {Uint8Array|null} [thumbnailEncSha256] ImageMessage thumbnailEncSha256
         * @property {string|null} [staticUrl] ImageMessage staticUrl
         */

        /**
         * Constructs a new ImageMessage.
         * @memberof proto
         * @classdesc Represents an ImageMessage.
         * @implements IImageMessage
         * @constructor
         * @param {proto.IImageMessage=} [properties] Properties to set
         */
        function ImageMessage(properties) {
            this.interactiveAnnotations = [];
            this.scanLengths = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ImageMessage url.
         * @member {string} url
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.url = "";

        /**
         * ImageMessage mimetype.
         * @member {string} mimetype
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.mimetype = "";

        /**
         * ImageMessage caption.
         * @member {string} caption
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.caption = "";

        /**
         * ImageMessage fileSha256.
         * @member {Uint8Array} fileSha256
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.fileSha256 = $util.newBuffer([]);

        /**
         * ImageMessage fileLength.
         * @member {number|Long} fileLength
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.fileLength = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * ImageMessage height.
         * @member {number} height
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.height = 0;

        /**
         * ImageMessage width.
         * @member {number} width
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.width = 0;

        /**
         * ImageMessage mediaKey.
         * @member {Uint8Array} mediaKey
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.mediaKey = $util.newBuffer([]);

        /**
         * ImageMessage fileEncSha256.
         * @member {Uint8Array} fileEncSha256
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.fileEncSha256 = $util.newBuffer([]);

        /**
         * ImageMessage interactiveAnnotations.
         * @member {Array.<proto.IInteractiveAnnotation>} interactiveAnnotations
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.interactiveAnnotations = $util.emptyArray;

        /**
         * ImageMessage directPath.
         * @member {string} directPath
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.directPath = "";

        /**
         * ImageMessage mediaKeyTimestamp.
         * @member {number|Long} mediaKeyTimestamp
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.mediaKeyTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * ImageMessage jpegThumbnail.
         * @member {Uint8Array} jpegThumbnail
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.jpegThumbnail = $util.newBuffer([]);

        /**
         * ImageMessage contextInfo.
         * @member {proto.IContextInfo|null|undefined} contextInfo
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.contextInfo = null;

        /**
         * ImageMessage firstScanSidecar.
         * @member {Uint8Array} firstScanSidecar
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.firstScanSidecar = $util.newBuffer([]);

        /**
         * ImageMessage firstScanLength.
         * @member {number} firstScanLength
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.firstScanLength = 0;

        /**
         * ImageMessage experimentGroupId.
         * @member {number} experimentGroupId
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.experimentGroupId = 0;

        /**
         * ImageMessage scansSidecar.
         * @member {Uint8Array} scansSidecar
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.scansSidecar = $util.newBuffer([]);

        /**
         * ImageMessage scanLengths.
         * @member {Array.<number>} scanLengths
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.scanLengths = $util.emptyArray;

        /**
         * ImageMessage midQualityFileSha256.
         * @member {Uint8Array} midQualityFileSha256
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.midQualityFileSha256 = $util.newBuffer([]);

        /**
         * ImageMessage midQualityFileEncSha256.
         * @member {Uint8Array} midQualityFileEncSha256
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.midQualityFileEncSha256 = $util.newBuffer([]);

        /**
         * ImageMessage viewOnce.
         * @member {boolean} viewOnce
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.viewOnce = false;

        /**
         * ImageMessage thumbnailDirectPath.
         * @member {string} thumbnailDirectPath
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.thumbnailDirectPath = "";

        /**
         * ImageMessage thumbnailSha256.
         * @member {Uint8Array} thumbnailSha256
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.thumbnailSha256 = $util.newBuffer([]);

        /**
         * ImageMessage thumbnailEncSha256.
         * @member {Uint8Array} thumbnailEncSha256
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.thumbnailEncSha256 = $util.newBuffer([]);

        /**
         * ImageMessage staticUrl.
         * @member {string} staticUrl
         * @memberof proto.ImageMessage
         * @instance
         */
        ImageMessage.prototype.staticUrl = "";

        /**
         * Creates a new ImageMessage instance using the specified properties.
         * @function create
         * @memberof proto.ImageMessage
         * @static
         * @param {proto.IImageMessage=} [properties] Properties to set
         * @returns {proto.ImageMessage} ImageMessage instance
         */
        ImageMessage.create = function create(properties) {
            return new ImageMessage(properties);
        };

        /**
         * Encodes the specified ImageMessage message. Does not implicitly {@link proto.ImageMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.ImageMessage
         * @static
         * @param {proto.IImageMessage} message ImageMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ImageMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.url != null && Object.hasOwnProperty.call(message, "url"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.url);
            if (message.mimetype != null && Object.hasOwnProperty.call(message, "mimetype"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.mimetype);
            if (message.caption != null && Object.hasOwnProperty.call(message, "caption"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.caption);
            if (message.fileSha256 != null && Object.hasOwnProperty.call(message, "fileSha256"))
                writer.uint32(/* id 4, wireType 2 =*/34).bytes(message.fileSha256);
            if (message.fileLength != null && Object.hasOwnProperty.call(message, "fileLength"))
                writer.uint32(/* id 5, wireType 0 =*/40).uint64(message.fileLength);
            if (message.height != null && Object.hasOwnProperty.call(message, "height"))
                writer.uint32(/* id 6, wireType 0 =*/48).uint32(message.height);
            if (message.width != null && Object.hasOwnProperty.call(message, "width"))
                writer.uint32(/* id 7, wireType 0 =*/56).uint32(message.width);
            if (message.mediaKey != null && Object.hasOwnProperty.call(message, "mediaKey"))
                writer.uint32(/* id 8, wireType 2 =*/66).bytes(message.mediaKey);
            if (message.fileEncSha256 != null && Object.hasOwnProperty.call(message, "fileEncSha256"))
                writer.uint32(/* id 9, wireType 2 =*/74).bytes(message.fileEncSha256);
            if (message.interactiveAnnotations != null && message.interactiveAnnotations.length)
                for (var i = 0; i < message.interactiveAnnotations.length; ++i)
                    $root.proto.InteractiveAnnotation.encode(message.interactiveAnnotations[i], writer.uint32(/* id 10, wireType 2 =*/82).fork()).ldelim();
            if (message.directPath != null && Object.hasOwnProperty.call(message, "directPath"))
                writer.uint32(/* id 11, wireType 2 =*/90).string(message.directPath);
            if (message.mediaKeyTimestamp != null && Object.hasOwnProperty.call(message, "mediaKeyTimestamp"))
                writer.uint32(/* id 12, wireType 0 =*/96).int64(message.mediaKeyTimestamp);
            if (message.jpegThumbnail != null && Object.hasOwnProperty.call(message, "jpegThumbnail"))
                writer.uint32(/* id 16, wireType 2 =*/130).bytes(message.jpegThumbnail);
            if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo"))
                $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 17, wireType 2 =*/138).fork()).ldelim();
            if (message.firstScanSidecar != null && Object.hasOwnProperty.call(message, "firstScanSidecar"))
                writer.uint32(/* id 18, wireType 2 =*/146).bytes(message.firstScanSidecar);
            if (message.firstScanLength != null && Object.hasOwnProperty.call(message, "firstScanLength"))
                writer.uint32(/* id 19, wireType 0 =*/152).uint32(message.firstScanLength);
            if (message.experimentGroupId != null && Object.hasOwnProperty.call(message, "experimentGroupId"))
                writer.uint32(/* id 20, wireType 0 =*/160).uint32(message.experimentGroupId);
            if (message.scansSidecar != null && Object.hasOwnProperty.call(message, "scansSidecar"))
                writer.uint32(/* id 21, wireType 2 =*/170).bytes(message.scansSidecar);
            if (message.scanLengths != null && message.scanLengths.length)
                for (var i = 0; i < message.scanLengths.length; ++i)
                    writer.uint32(/* id 22, wireType 0 =*/176).uint32(message.scanLengths[i]);
            if (message.midQualityFileSha256 != null && Object.hasOwnProperty.call(message, "midQualityFileSha256"))
                writer.uint32(/* id 23, wireType 2 =*/186).bytes(message.midQualityFileSha256);
            if (message.midQualityFileEncSha256 != null && Object.hasOwnProperty.call(message, "midQualityFileEncSha256"))
                writer.uint32(/* id 24, wireType 2 =*/194).bytes(message.midQualityFileEncSha256);
            if (message.viewOnce != null && Object.hasOwnProperty.call(message, "viewOnce"))
                writer.uint32(/* id 25, wireType 0 =*/200).bool(message.viewOnce);
            if (message.thumbnailDirectPath != null && Object.hasOwnProperty.call(message, "thumbnailDirectPath"))
                writer.uint32(/* id 26, wireType 2 =*/210).string(message.thumbnailDirectPath);
            if (message.thumbnailSha256 != null && Object.hasOwnProperty.call(message, "thumbnailSha256"))
                writer.uint32(/* id 27, wireType 2 =*/218).bytes(message.thumbnailSha256);
            if (message.thumbnailEncSha256 != null && Object.hasOwnProperty.call(message, "thumbnailEncSha256"))
                writer.uint32(/* id 28, wireType 2 =*/226).bytes(message.thumbnailEncSha256);
            if (message.staticUrl != null && Object.hasOwnProperty.call(message, "staticUrl"))
                writer.uint32(/* id 29, wireType 2 =*/234).string(message.staticUrl);
            return writer;
        };

        /**
         * Encodes the specified ImageMessage message, length delimited. Does not implicitly {@link proto.ImageMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ImageMessage
         * @static
         * @param {proto.IImageMessage} message ImageMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ImageMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an ImageMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ImageMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ImageMessage} ImageMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ImageMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ImageMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.url = reader.string();
                    break;
                case 2:
                    message.mimetype = reader.string();
                    break;
                case 3:
                    message.caption = reader.string();
                    break;
                case 4:
                    message.fileSha256 = reader.bytes();
                    break;
                case 5:
                    message.fileLength = reader.uint64();
                    break;
                case 6:
                    message.height = reader.uint32();
                    break;
                case 7:
                    message.width = reader.uint32();
                    break;
                case 8:
                    message.mediaKey = reader.bytes();
                    break;
                case 9:
                    message.fileEncSha256 = reader.bytes();
                    break;
                case 10:
                    if (!(message.interactiveAnnotations && message.interactiveAnnotations.length))
                        message.interactiveAnnotations = [];
                    message.interactiveAnnotations.push($root.proto.InteractiveAnnotation.decode(reader, reader.uint32()));
                    break;
                case 11:
                    message.directPath = reader.string();
                    break;
                case 12:
                    message.mediaKeyTimestamp = reader.int64();
                    break;
                case 16:
                    message.jpegThumbnail = reader.bytes();
                    break;
                case 17:
                    message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32());
                    break;
                case 18:
                    message.firstScanSidecar = reader.bytes();
                    break;
                case 19:
                    message.firstScanLength = reader.uint32();
                    break;
                case 20:
                    message.experimentGroupId = reader.uint32();
                    break;
                case 21:
                    message.scansSidecar = reader.bytes();
                    break;
                case 22:
                    if (!(message.scanLengths && message.scanLengths.length))
                        message.scanLengths = [];
                    if ((tag & 7) === 2) {
                        var end2 = reader.uint32() + reader.pos;
                        while (reader.pos < end2)
                            message.scanLengths.push(reader.uint32());
                    } else
                        message.scanLengths.push(reader.uint32());
                    break;
                case 23:
                    message.midQualityFileSha256 = reader.bytes();
                    break;
                case 24:
                    message.midQualityFileEncSha256 = reader.bytes();
                    break;
                case 25:
                    message.viewOnce = reader.bool();
                    break;
                case 26:
                    message.thumbnailDirectPath = reader.string();
                    break;
                case 27:
                    message.thumbnailSha256 = reader.bytes();
                    break;
                case 28:
                    message.thumbnailEncSha256 = reader.bytes();
                    break;
                case 29:
                    message.staticUrl = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an ImageMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ImageMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ImageMessage} ImageMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ImageMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an ImageMessage message.
         * @function verify
         * @memberof proto.ImageMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ImageMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.url != null && message.hasOwnProperty("url"))
                if (!$util.isString(message.url))
                    return "url: string expected";
            if (message.mimetype != null && message.hasOwnProperty("mimetype"))
                if (!$util.isString(message.mimetype))
                    return "mimetype: string expected";
            if (message.caption != null && message.hasOwnProperty("caption"))
                if (!$util.isString(message.caption))
                    return "caption: string expected";
            if (message.fileSha256 != null && message.hasOwnProperty("fileSha256"))
                if (!(message.fileSha256 && typeof message.fileSha256.length === "number" || $util.isString(message.fileSha256)))
                    return "fileSha256: buffer expected";
            if (message.fileLength != null && message.hasOwnProperty("fileLength"))
                if (!$util.isInteger(message.fileLength) && !(message.fileLength && $util.isInteger(message.fileLength.low) && $util.isInteger(message.fileLength.high)))
                    return "fileLength: integer|Long expected";
            if (message.height != null && message.hasOwnProperty("height"))
                if (!$util.isInteger(message.height))
                    return "height: integer expected";
            if (message.width != null && message.hasOwnProperty("width"))
                if (!$util.isInteger(message.width))
                    return "width: integer expected";
            if (message.mediaKey != null && message.hasOwnProperty("mediaKey"))
                if (!(message.mediaKey && typeof message.mediaKey.length === "number" || $util.isString(message.mediaKey)))
                    return "mediaKey: buffer expected";
            if (message.fileEncSha256 != null && message.hasOwnProperty("fileEncSha256"))
                if (!(message.fileEncSha256 && typeof message.fileEncSha256.length === "number" || $util.isString(message.fileEncSha256)))
                    return "fileEncSha256: buffer expected";
            if (message.interactiveAnnotations != null && message.hasOwnProperty("interactiveAnnotations")) {
                if (!Array.isArray(message.interactiveAnnotations))
                    return "interactiveAnnotations: array expected";
                for (var i = 0; i < message.interactiveAnnotations.length; ++i) {
                    var error = $root.proto.InteractiveAnnotation.verify(message.interactiveAnnotations[i]);
                    if (error)
                        return "interactiveAnnotations." + error;
                }
            }
            if (message.directPath != null && message.hasOwnProperty("directPath"))
                if (!$util.isString(message.directPath))
                    return "directPath: string expected";
            if (message.mediaKeyTimestamp != null && message.hasOwnProperty("mediaKeyTimestamp"))
                if (!$util.isInteger(message.mediaKeyTimestamp) && !(message.mediaKeyTimestamp && $util.isInteger(message.mediaKeyTimestamp.low) && $util.isInteger(message.mediaKeyTimestamp.high)))
                    return "mediaKeyTimestamp: integer|Long expected";
            if (message.jpegThumbnail != null && message.hasOwnProperty("jpegThumbnail"))
                if (!(message.jpegThumbnail && typeof message.jpegThumbnail.length === "number" || $util.isString(message.jpegThumbnail)))
                    return "jpegThumbnail: buffer expected";
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) {
                var error = $root.proto.ContextInfo.verify(message.contextInfo);
                if (error)
                    return "contextInfo." + error;
            }
            if (message.firstScanSidecar != null && message.hasOwnProperty("firstScanSidecar"))
                if (!(message.firstScanSidecar && typeof message.firstScanSidecar.length === "number" || $util.isString(message.firstScanSidecar)))
                    return "firstScanSidecar: buffer expected";
            if (message.firstScanLength != null && message.hasOwnProperty("firstScanLength"))
                if (!$util.isInteger(message.firstScanLength))
                    return "firstScanLength: integer expected";
            if (message.experimentGroupId != null && message.hasOwnProperty("experimentGroupId"))
                if (!$util.isInteger(message.experimentGroupId))
                    return "experimentGroupId: integer expected";
            if (message.scansSidecar != null && message.hasOwnProperty("scansSidecar"))
                if (!(message.scansSidecar && typeof message.scansSidecar.length === "number" || $util.isString(message.scansSidecar)))
                    return "scansSidecar: buffer expected";
            if (message.scanLengths != null && message.hasOwnProperty("scanLengths")) {
                if (!Array.isArray(message.scanLengths))
                    return "scanLengths: array expected";
                for (var i = 0; i < message.scanLengths.length; ++i)
                    if (!$util.isInteger(message.scanLengths[i]))
                        return "scanLengths: integer[] expected";
            }
            if (message.midQualityFileSha256 != null && message.hasOwnProperty("midQualityFileSha256"))
                if (!(message.midQualityFileSha256 && typeof message.midQualityFileSha256.length === "number" || $util.isString(message.midQualityFileSha256)))
                    return "midQualityFileSha256: buffer expected";
            if (message.midQualityFileEncSha256 != null && message.hasOwnProperty("midQualityFileEncSha256"))
                if (!(message.midQualityFileEncSha256 && typeof message.midQualityFileEncSha256.length === "number" || $util.isString(message.midQualityFileEncSha256)))
                    return "midQualityFileEncSha256: buffer expected";
            if (message.viewOnce != null && message.hasOwnProperty("viewOnce"))
                if (typeof message.viewOnce !== "boolean")
                    return "viewOnce: boolean expected";
            if (message.thumbnailDirectPath != null && message.hasOwnProperty("thumbnailDirectPath"))
                if (!$util.isString(message.thumbnailDirectPath))
                    return "thumbnailDirectPath: string expected";
            if (message.thumbnailSha256 != null && message.hasOwnProperty("thumbnailSha256"))
                if (!(message.thumbnailSha256 && typeof message.thumbnailSha256.length === "number" || $util.isString(message.thumbnailSha256)))
                    return "thumbnailSha256: buffer expected";
            if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256"))
                if (!(message.thumbnailEncSha256 && typeof message.thumbnailEncSha256.length === "number" || $util.isString(message.thumbnailEncSha256)))
                    return "thumbnailEncSha256: buffer expected";
            if (message.staticUrl != null && message.hasOwnProperty("staticUrl"))
                if (!$util.isString(message.staticUrl))
                    return "staticUrl: string expected";
            return null;
        };

        /**
         * Creates an ImageMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ImageMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ImageMessage} ImageMessage
         */
        ImageMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ImageMessage)
                return object;
            var message = new $root.proto.ImageMessage();
            if (object.url != null)
                message.url = String(object.url);
            if (object.mimetype != null)
                message.mimetype = String(object.mimetype);
            if (object.caption != null)
                message.caption = String(object.caption);
            if (object.fileSha256 != null)
                if (typeof object.fileSha256 === "string")
                    $util.base64.decode(object.fileSha256, message.fileSha256 = $util.newBuffer($util.base64.length(object.fileSha256)), 0);
                else if (object.fileSha256.length)
                    message.fileSha256 = object.fileSha256;
            if (object.fileLength != null)
                if ($util.Long)
                    (message.fileLength = $util.Long.fromValue(object.fileLength)).unsigned = true;
                else if (typeof object.fileLength === "string")
                    message.fileLength = parseInt(object.fileLength, 10);
                else if (typeof object.fileLength === "number")
                    message.fileLength = object.fileLength;
                else if (typeof object.fileLength === "object")
                    message.fileLength = new $util.LongBits(object.fileLength.low >>> 0, object.fileLength.high >>> 0).toNumber(true);
            if (object.height != null)
                message.height = object.height >>> 0;
            if (object.width != null)
                message.width = object.width >>> 0;
            if (object.mediaKey != null)
                if (typeof object.mediaKey === "string")
                    $util.base64.decode(object.mediaKey, message.mediaKey = $util.newBuffer($util.base64.length(object.mediaKey)), 0);
                else if (object.mediaKey.length)
                    message.mediaKey = object.mediaKey;
            if (object.fileEncSha256 != null)
                if (typeof object.fileEncSha256 === "string")
                    $util.base64.decode(object.fileEncSha256, message.fileEncSha256 = $util.newBuffer($util.base64.length(object.fileEncSha256)), 0);
                else if (object.fileEncSha256.length)
                    message.fileEncSha256 = object.fileEncSha256;
            if (object.interactiveAnnotations) {
                if (!Array.isArray(object.interactiveAnnotations))
                    throw TypeError(".proto.ImageMessage.interactiveAnnotations: array expected");
                message.interactiveAnnotations = [];
                for (var i = 0; i < object.interactiveAnnotations.length; ++i) {
                    if (typeof object.interactiveAnnotations[i] !== "object")
                        throw TypeError(".proto.ImageMessage.interactiveAnnotations: object expected");
                    message.interactiveAnnotations[i] = $root.proto.InteractiveAnnotation.fromObject(object.interactiveAnnotations[i]);
                }
            }
            if (object.directPath != null)
                message.directPath = String(object.directPath);
            if (object.mediaKeyTimestamp != null)
                if ($util.Long)
                    (message.mediaKeyTimestamp = $util.Long.fromValue(object.mediaKeyTimestamp)).unsigned = false;
                else if (typeof object.mediaKeyTimestamp === "string")
                    message.mediaKeyTimestamp = parseInt(object.mediaKeyTimestamp, 10);
                else if (typeof object.mediaKeyTimestamp === "number")
                    message.mediaKeyTimestamp = object.mediaKeyTimestamp;
                else if (typeof object.mediaKeyTimestamp === "object")
                    message.mediaKeyTimestamp = new $util.LongBits(object.mediaKeyTimestamp.low >>> 0, object.mediaKeyTimestamp.high >>> 0).toNumber();
            if (object.jpegThumbnail != null)
                if (typeof object.jpegThumbnail === "string")
                    $util.base64.decode(object.jpegThumbnail, message.jpegThumbnail = $util.newBuffer($util.base64.length(object.jpegThumbnail)), 0);
                else if (object.jpegThumbnail.length)
                    message.jpegThumbnail = object.jpegThumbnail;
            if (object.contextInfo != null) {
                if (typeof object.contextInfo !== "object")
                    throw TypeError(".proto.ImageMessage.contextInfo: object expected");
                message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo);
            }
            if (object.firstScanSidecar != null)
                if (typeof object.firstScanSidecar === "string")
                    $util.base64.decode(object.firstScanSidecar, message.firstScanSidecar = $util.newBuffer($util.base64.length(object.firstScanSidecar)), 0);
                else if (object.firstScanSidecar.length)
                    message.firstScanSidecar = object.firstScanSidecar;
            if (object.firstScanLength != null)
                message.firstScanLength = object.firstScanLength >>> 0;
            if (object.experimentGroupId != null)
                message.experimentGroupId = object.experimentGroupId >>> 0;
            if (object.scansSidecar != null)
                if (typeof object.scansSidecar === "string")
                    $util.base64.decode(object.scansSidecar, message.scansSidecar = $util.newBuffer($util.base64.length(object.scansSidecar)), 0);
                else if (object.scansSidecar.length)
                    message.scansSidecar = object.scansSidecar;
            if (object.scanLengths) {
                if (!Array.isArray(object.scanLengths))
                    throw TypeError(".proto.ImageMessage.scanLengths: array expected");
                message.scanLengths = [];
                for (var i = 0; i < object.scanLengths.length; ++i)
                    message.scanLengths[i] = object.scanLengths[i] >>> 0;
            }
            if (object.midQualityFileSha256 != null)
                if (typeof object.midQualityFileSha256 === "string")
                    $util.base64.decode(object.midQualityFileSha256, message.midQualityFileSha256 = $util.newBuffer($util.base64.length(object.midQualityFileSha256)), 0);
                else if (object.midQualityFileSha256.length)
                    message.midQualityFileSha256 = object.midQualityFileSha256;
            if (object.midQualityFileEncSha256 != null)
                if (typeof object.midQualityFileEncSha256 === "string")
                    $util.base64.decode(object.midQualityFileEncSha256, message.midQualityFileEncSha256 = $util.newBuffer($util.base64.length(object.midQualityFileEncSha256)), 0);
                else if (object.midQualityFileEncSha256.length)
                    message.midQualityFileEncSha256 = object.midQualityFileEncSha256;
            if (object.viewOnce != null)
                message.viewOnce = Boolean(object.viewOnce);
            if (object.thumbnailDirectPath != null)
                message.thumbnailDirectPath = String(object.thumbnailDirectPath);
            if (object.thumbnailSha256 != null)
                if (typeof object.thumbnailSha256 === "string")
                    $util.base64.decode(object.thumbnailSha256, message.thumbnailSha256 = $util.newBuffer($util.base64.length(object.thumbnailSha256)), 0);
                else if (object.thumbnailSha256.length)
                    message.thumbnailSha256 = object.thumbnailSha256;
            if (object.thumbnailEncSha256 != null)
                if (typeof object.thumbnailEncSha256 === "string")
                    $util.base64.decode(object.thumbnailEncSha256, message.thumbnailEncSha256 = $util.newBuffer($util.base64.length(object.thumbnailEncSha256)), 0);
                else if (object.thumbnailEncSha256.length)
                    message.thumbnailEncSha256 = object.thumbnailEncSha256;
            if (object.staticUrl != null)
                message.staticUrl = String(object.staticUrl);
            return message;
        };

        /**
         * Creates a plain object from an ImageMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ImageMessage
         * @static
         * @param {proto.ImageMessage} message ImageMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ImageMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults) {
                object.interactiveAnnotations = [];
                object.scanLengths = [];
            }
            if (options.defaults) {
                object.url = "";
                object.mimetype = "";
                object.caption = "";
                if (options.bytes === String)
                    object.fileSha256 = "";
                else {
                    object.fileSha256 = [];
                    if (options.bytes !== Array)
                        object.fileSha256 = $util.newBuffer(object.fileSha256);
                }
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.fileLength = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.fileLength = options.longs === String ? "0" : 0;
                object.height = 0;
                object.width = 0;
                if (options.bytes === String)
                    object.mediaKey = "";
                else {
                    object.mediaKey = [];
                    if (options.bytes !== Array)
                        object.mediaKey = $util.newBuffer(object.mediaKey);
                }
                if (options.bytes === String)
                    object.fileEncSha256 = "";
                else {
                    object.fileEncSha256 = [];
                    if (options.bytes !== Array)
                        object.fileEncSha256 = $util.newBuffer(object.fileEncSha256);
                }
                object.directPath = "";
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.mediaKeyTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.mediaKeyTimestamp = options.longs === String ? "0" : 0;
                if (options.bytes === String)
                    object.jpegThumbnail = "";
                else {
                    object.jpegThumbnail = [];
                    if (options.bytes !== Array)
                        object.jpegThumbnail = $util.newBuffer(object.jpegThumbnail);
                }
                object.contextInfo = null;
                if (options.bytes === String)
                    object.firstScanSidecar = "";
                else {
                    object.firstScanSidecar = [];
                    if (options.bytes !== Array)
                        object.firstScanSidecar = $util.newBuffer(object.firstScanSidecar);
                }
                object.firstScanLength = 0;
                object.experimentGroupId = 0;
                if (options.bytes === String)
                    object.scansSidecar = "";
                else {
                    object.scansSidecar = [];
                    if (options.bytes !== Array)
                        object.scansSidecar = $util.newBuffer(object.scansSidecar);
                }
                if (options.bytes === String)
                    object.midQualityFileSha256 = "";
                else {
                    object.midQualityFileSha256 = [];
                    if (options.bytes !== Array)
                        object.midQualityFileSha256 = $util.newBuffer(object.midQualityFileSha256);
                }
                if (options.bytes === String)
                    object.midQualityFileEncSha256 = "";
                else {
                    object.midQualityFileEncSha256 = [];
                    if (options.bytes !== Array)
                        object.midQualityFileEncSha256 = $util.newBuffer(object.midQualityFileEncSha256);
                }
                object.viewOnce = false;
                object.thumbnailDirectPath = "";
                if (options.bytes === String)
                    object.thumbnailSha256 = "";
                else {
                    object.thumbnailSha256 = [];
                    if (options.bytes !== Array)
                        object.thumbnailSha256 = $util.newBuffer(object.thumbnailSha256);
                }
                if (options.bytes === String)
                    object.thumbnailEncSha256 = "";
                else {
                    object.thumbnailEncSha256 = [];
                    if (options.bytes !== Array)
                        object.thumbnailEncSha256 = $util.newBuffer(object.thumbnailEncSha256);
                }
                object.staticUrl = "";
            }
            if (message.url != null && message.hasOwnProperty("url"))
                object.url = message.url;
            if (message.mimetype != null && message.hasOwnProperty("mimetype"))
                object.mimetype = message.mimetype;
            if (message.caption != null && message.hasOwnProperty("caption"))
                object.caption = message.caption;
            if (message.fileSha256 != null && message.hasOwnProperty("fileSha256"))
                object.fileSha256 = options.bytes === String ? $util.base64.encode(message.fileSha256, 0, message.fileSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.fileSha256) : message.fileSha256;
            if (message.fileLength != null && message.hasOwnProperty("fileLength"))
                if (typeof message.fileLength === "number")
                    object.fileLength = options.longs === String ? String(message.fileLength) : message.fileLength;
                else
                    object.fileLength = options.longs === String ? $util.Long.prototype.toString.call(message.fileLength) : options.longs === Number ? new $util.LongBits(message.fileLength.low >>> 0, message.fileLength.high >>> 0).toNumber(true) : message.fileLength;
            if (message.height != null && message.hasOwnProperty("height"))
                object.height = message.height;
            if (message.width != null && message.hasOwnProperty("width"))
                object.width = message.width;
            if (message.mediaKey != null && message.hasOwnProperty("mediaKey"))
                object.mediaKey = options.bytes === String ? $util.base64.encode(message.mediaKey, 0, message.mediaKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.mediaKey) : message.mediaKey;
            if (message.fileEncSha256 != null && message.hasOwnProperty("fileEncSha256"))
                object.fileEncSha256 = options.bytes === String ? $util.base64.encode(message.fileEncSha256, 0, message.fileEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.fileEncSha256) : message.fileEncSha256;
            if (message.interactiveAnnotations && message.interactiveAnnotations.length) {
                object.interactiveAnnotations = [];
                for (var j = 0; j < message.interactiveAnnotations.length; ++j)
                    object.interactiveAnnotations[j] = $root.proto.InteractiveAnnotation.toObject(message.interactiveAnnotations[j], options);
            }
            if (message.directPath != null && message.hasOwnProperty("directPath"))
                object.directPath = message.directPath;
            if (message.mediaKeyTimestamp != null && message.hasOwnProperty("mediaKeyTimestamp"))
                if (typeof message.mediaKeyTimestamp === "number")
                    object.mediaKeyTimestamp = options.longs === String ? String(message.mediaKeyTimestamp) : message.mediaKeyTimestamp;
                else
                    object.mediaKeyTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.mediaKeyTimestamp) : options.longs === Number ? new $util.LongBits(message.mediaKeyTimestamp.low >>> 0, message.mediaKeyTimestamp.high >>> 0).toNumber() : message.mediaKeyTimestamp;
            if (message.jpegThumbnail != null && message.hasOwnProperty("jpegThumbnail"))
                object.jpegThumbnail = options.bytes === String ? $util.base64.encode(message.jpegThumbnail, 0, message.jpegThumbnail.length) : options.bytes === Array ? Array.prototype.slice.call(message.jpegThumbnail) : message.jpegThumbnail;
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo"))
                object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options);
            if (message.firstScanSidecar != null && message.hasOwnProperty("firstScanSidecar"))
                object.firstScanSidecar = options.bytes === String ? $util.base64.encode(message.firstScanSidecar, 0, message.firstScanSidecar.length) : options.bytes === Array ? Array.prototype.slice.call(message.firstScanSidecar) : message.firstScanSidecar;
            if (message.firstScanLength != null && message.hasOwnProperty("firstScanLength"))
                object.firstScanLength = message.firstScanLength;
            if (message.experimentGroupId != null && message.hasOwnProperty("experimentGroupId"))
                object.experimentGroupId = message.experimentGroupId;
            if (message.scansSidecar != null && message.hasOwnProperty("scansSidecar"))
                object.scansSidecar = options.bytes === String ? $util.base64.encode(message.scansSidecar, 0, message.scansSidecar.length) : options.bytes === Array ? Array.prototype.slice.call(message.scansSidecar) : message.scansSidecar;
            if (message.scanLengths && message.scanLengths.length) {
                object.scanLengths = [];
                for (var j = 0; j < message.scanLengths.length; ++j)
                    object.scanLengths[j] = message.scanLengths[j];
            }
            if (message.midQualityFileSha256 != null && message.hasOwnProperty("midQualityFileSha256"))
                object.midQualityFileSha256 = options.bytes === String ? $util.base64.encode(message.midQualityFileSha256, 0, message.midQualityFileSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.midQualityFileSha256) : message.midQualityFileSha256;
            if (message.midQualityFileEncSha256 != null && message.hasOwnProperty("midQualityFileEncSha256"))
                object.midQualityFileEncSha256 = options.bytes === String ? $util.base64.encode(message.midQualityFileEncSha256, 0, message.midQualityFileEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.midQualityFileEncSha256) : message.midQualityFileEncSha256;
            if (message.viewOnce != null && message.hasOwnProperty("viewOnce"))
                object.viewOnce = message.viewOnce;
            if (message.thumbnailDirectPath != null && message.hasOwnProperty("thumbnailDirectPath"))
                object.thumbnailDirectPath = message.thumbnailDirectPath;
            if (message.thumbnailSha256 != null && message.hasOwnProperty("thumbnailSha256"))
                object.thumbnailSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailSha256, 0, message.thumbnailSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailSha256) : message.thumbnailSha256;
            if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256"))
                object.thumbnailEncSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailEncSha256, 0, message.thumbnailEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailEncSha256) : message.thumbnailEncSha256;
            if (message.staticUrl != null && message.hasOwnProperty("staticUrl"))
                object.staticUrl = message.staticUrl;
            return object;
        };

        /**
         * Converts this ImageMessage to JSON.
         * @function toJSON
         * @memberof proto.ImageMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ImageMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ImageMessage;
    })();

    proto.InvoiceMessage = (function() {

        /**
         * Properties of an InvoiceMessage.
         * @memberof proto
         * @interface IInvoiceMessage
         * @property {string|null} [note] InvoiceMessage note
         * @property {string|null} [token] InvoiceMessage token
         * @property {proto.InvoiceMessage.InvoiceMessageAttachmentType|null} [attachmentType] InvoiceMessage attachmentType
         * @property {string|null} [attachmentMimetype] InvoiceMessage attachmentMimetype
         * @property {Uint8Array|null} [attachmentMediaKey] InvoiceMessage attachmentMediaKey
         * @property {number|Long|null} [attachmentMediaKeyTimestamp] InvoiceMessage attachmentMediaKeyTimestamp
         * @property {Uint8Array|null} [attachmentFileSha256] InvoiceMessage attachmentFileSha256
         * @property {Uint8Array|null} [attachmentFileEncSha256] InvoiceMessage attachmentFileEncSha256
         * @property {string|null} [attachmentDirectPath] InvoiceMessage attachmentDirectPath
         * @property {Uint8Array|null} [attachmentJpegThumbnail] InvoiceMessage attachmentJpegThumbnail
         */

        /**
         * Constructs a new InvoiceMessage.
         * @memberof proto
         * @classdesc Represents an InvoiceMessage.
         * @implements IInvoiceMessage
         * @constructor
         * @param {proto.IInvoiceMessage=} [properties] Properties to set
         */
        function InvoiceMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * InvoiceMessage note.
         * @member {string} note
         * @memberof proto.InvoiceMessage
         * @instance
         */
        InvoiceMessage.prototype.note = "";

        /**
         * InvoiceMessage token.
         * @member {string} token
         * @memberof proto.InvoiceMessage
         * @instance
         */
        InvoiceMessage.prototype.token = "";

        /**
         * InvoiceMessage attachmentType.
         * @member {proto.InvoiceMessage.InvoiceMessageAttachmentType} attachmentType
         * @memberof proto.InvoiceMessage
         * @instance
         */
        InvoiceMessage.prototype.attachmentType = 0;

        /**
         * InvoiceMessage attachmentMimetype.
         * @member {string} attachmentMimetype
         * @memberof proto.InvoiceMessage
         * @instance
         */
        InvoiceMessage.prototype.attachmentMimetype = "";

        /**
         * InvoiceMessage attachmentMediaKey.
         * @member {Uint8Array} attachmentMediaKey
         * @memberof proto.InvoiceMessage
         * @instance
         */
        InvoiceMessage.prototype.attachmentMediaKey = $util.newBuffer([]);

        /**
         * InvoiceMessage attachmentMediaKeyTimestamp.
         * @member {number|Long} attachmentMediaKeyTimestamp
         * @memberof proto.InvoiceMessage
         * @instance
         */
        InvoiceMessage.prototype.attachmentMediaKeyTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * InvoiceMessage attachmentFileSha256.
         * @member {Uint8Array} attachmentFileSha256
         * @memberof proto.InvoiceMessage
         * @instance
         */
        InvoiceMessage.prototype.attachmentFileSha256 = $util.newBuffer([]);

        /**
         * InvoiceMessage attachmentFileEncSha256.
         * @member {Uint8Array} attachmentFileEncSha256
         * @memberof proto.InvoiceMessage
         * @instance
         */
        InvoiceMessage.prototype.attachmentFileEncSha256 = $util.newBuffer([]);

        /**
         * InvoiceMessage attachmentDirectPath.
         * @member {string} attachmentDirectPath
         * @memberof proto.InvoiceMessage
         * @instance
         */
        InvoiceMessage.prototype.attachmentDirectPath = "";

        /**
         * InvoiceMessage attachmentJpegThumbnail.
         * @member {Uint8Array} attachmentJpegThumbnail
         * @memberof proto.InvoiceMessage
         * @instance
         */
        InvoiceMessage.prototype.attachmentJpegThumbnail = $util.newBuffer([]);

        /**
         * Creates a new InvoiceMessage instance using the specified properties.
         * @function create
         * @memberof proto.InvoiceMessage
         * @static
         * @param {proto.IInvoiceMessage=} [properties] Properties to set
         * @returns {proto.InvoiceMessage} InvoiceMessage instance
         */
        InvoiceMessage.create = function create(properties) {
            return new InvoiceMessage(properties);
        };

        /**
         * Encodes the specified InvoiceMessage message. Does not implicitly {@link proto.InvoiceMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.InvoiceMessage
         * @static
         * @param {proto.IInvoiceMessage} message InvoiceMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        InvoiceMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.note != null && Object.hasOwnProperty.call(message, "note"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.note);
            if (message.token != null && Object.hasOwnProperty.call(message, "token"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.token);
            if (message.attachmentType != null && Object.hasOwnProperty.call(message, "attachmentType"))
                writer.uint32(/* id 3, wireType 0 =*/24).int32(message.attachmentType);
            if (message.attachmentMimetype != null && Object.hasOwnProperty.call(message, "attachmentMimetype"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.attachmentMimetype);
            if (message.attachmentMediaKey != null && Object.hasOwnProperty.call(message, "attachmentMediaKey"))
                writer.uint32(/* id 5, wireType 2 =*/42).bytes(message.attachmentMediaKey);
            if (message.attachmentMediaKeyTimestamp != null && Object.hasOwnProperty.call(message, "attachmentMediaKeyTimestamp"))
                writer.uint32(/* id 6, wireType 0 =*/48).int64(message.attachmentMediaKeyTimestamp);
            if (message.attachmentFileSha256 != null && Object.hasOwnProperty.call(message, "attachmentFileSha256"))
                writer.uint32(/* id 7, wireType 2 =*/58).bytes(message.attachmentFileSha256);
            if (message.attachmentFileEncSha256 != null && Object.hasOwnProperty.call(message, "attachmentFileEncSha256"))
                writer.uint32(/* id 8, wireType 2 =*/66).bytes(message.attachmentFileEncSha256);
            if (message.attachmentDirectPath != null && Object.hasOwnProperty.call(message, "attachmentDirectPath"))
                writer.uint32(/* id 9, wireType 2 =*/74).string(message.attachmentDirectPath);
            if (message.attachmentJpegThumbnail != null && Object.hasOwnProperty.call(message, "attachmentJpegThumbnail"))
                writer.uint32(/* id 10, wireType 2 =*/82).bytes(message.attachmentJpegThumbnail);
            return writer;
        };

        /**
         * Encodes the specified InvoiceMessage message, length delimited. Does not implicitly {@link proto.InvoiceMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.InvoiceMessage
         * @static
         * @param {proto.IInvoiceMessage} message InvoiceMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        InvoiceMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an InvoiceMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.InvoiceMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.InvoiceMessage} InvoiceMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        InvoiceMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.InvoiceMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.note = reader.string();
                    break;
                case 2:
                    message.token = reader.string();
                    break;
                case 3:
                    message.attachmentType = reader.int32();
                    break;
                case 4:
                    message.attachmentMimetype = reader.string();
                    break;
                case 5:
                    message.attachmentMediaKey = reader.bytes();
                    break;
                case 6:
                    message.attachmentMediaKeyTimestamp = reader.int64();
                    break;
                case 7:
                    message.attachmentFileSha256 = reader.bytes();
                    break;
                case 8:
                    message.attachmentFileEncSha256 = reader.bytes();
                    break;
                case 9:
                    message.attachmentDirectPath = reader.string();
                    break;
                case 10:
                    message.attachmentJpegThumbnail = reader.bytes();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an InvoiceMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.InvoiceMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.InvoiceMessage} InvoiceMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        InvoiceMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an InvoiceMessage message.
         * @function verify
         * @memberof proto.InvoiceMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        InvoiceMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.note != null && message.hasOwnProperty("note"))
                if (!$util.isString(message.note))
                    return "note: string expected";
            if (message.token != null && message.hasOwnProperty("token"))
                if (!$util.isString(message.token))
                    return "token: string expected";
            if (message.attachmentType != null && message.hasOwnProperty("attachmentType"))
                switch (message.attachmentType) {
                default:
                    return "attachmentType: enum value expected";
                case 0:
                case 1:
                    break;
                }
            if (message.attachmentMimetype != null && message.hasOwnProperty("attachmentMimetype"))
                if (!$util.isString(message.attachmentMimetype))
                    return "attachmentMimetype: string expected";
            if (message.attachmentMediaKey != null && message.hasOwnProperty("attachmentMediaKey"))
                if (!(message.attachmentMediaKey && typeof message.attachmentMediaKey.length === "number" || $util.isString(message.attachmentMediaKey)))
                    return "attachmentMediaKey: buffer expected";
            if (message.attachmentMediaKeyTimestamp != null && message.hasOwnProperty("attachmentMediaKeyTimestamp"))
                if (!$util.isInteger(message.attachmentMediaKeyTimestamp) && !(message.attachmentMediaKeyTimestamp && $util.isInteger(message.attachmentMediaKeyTimestamp.low) && $util.isInteger(message.attachmentMediaKeyTimestamp.high)))
                    return "attachmentMediaKeyTimestamp: integer|Long expected";
            if (message.attachmentFileSha256 != null && message.hasOwnProperty("attachmentFileSha256"))
                if (!(message.attachmentFileSha256 && typeof message.attachmentFileSha256.length === "number" || $util.isString(message.attachmentFileSha256)))
                    return "attachmentFileSha256: buffer expected";
            if (message.attachmentFileEncSha256 != null && message.hasOwnProperty("attachmentFileEncSha256"))
                if (!(message.attachmentFileEncSha256 && typeof message.attachmentFileEncSha256.length === "number" || $util.isString(message.attachmentFileEncSha256)))
                    return "attachmentFileEncSha256: buffer expected";
            if (message.attachmentDirectPath != null && message.hasOwnProperty("attachmentDirectPath"))
                if (!$util.isString(message.attachmentDirectPath))
                    return "attachmentDirectPath: string expected";
            if (message.attachmentJpegThumbnail != null && message.hasOwnProperty("attachmentJpegThumbnail"))
                if (!(message.attachmentJpegThumbnail && typeof message.attachmentJpegThumbnail.length === "number" || $util.isString(message.attachmentJpegThumbnail)))
                    return "attachmentJpegThumbnail: buffer expected";
            return null;
        };

        /**
         * Creates an InvoiceMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.InvoiceMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.InvoiceMessage} InvoiceMessage
         */
        InvoiceMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.InvoiceMessage)
                return object;
            var message = new $root.proto.InvoiceMessage();
            if (object.note != null)
                message.note = String(object.note);
            if (object.token != null)
                message.token = String(object.token);
            switch (object.attachmentType) {
            case "IMAGE":
            case 0:
                message.attachmentType = 0;
                break;
            case "PDF":
            case 1:
                message.attachmentType = 1;
                break;
            }
            if (object.attachmentMimetype != null)
                message.attachmentMimetype = String(object.attachmentMimetype);
            if (object.attachmentMediaKey != null)
                if (typeof object.attachmentMediaKey === "string")
                    $util.base64.decode(object.attachmentMediaKey, message.attachmentMediaKey = $util.newBuffer($util.base64.length(object.attachmentMediaKey)), 0);
                else if (object.attachmentMediaKey.length)
                    message.attachmentMediaKey = object.attachmentMediaKey;
            if (object.attachmentMediaKeyTimestamp != null)
                if ($util.Long)
                    (message.attachmentMediaKeyTimestamp = $util.Long.fromValue(object.attachmentMediaKeyTimestamp)).unsigned = false;
                else if (typeof object.attachmentMediaKeyTimestamp === "string")
                    message.attachmentMediaKeyTimestamp = parseInt(object.attachmentMediaKeyTimestamp, 10);
                else if (typeof object.attachmentMediaKeyTimestamp === "number")
                    message.attachmentMediaKeyTimestamp = object.attachmentMediaKeyTimestamp;
                else if (typeof object.attachmentMediaKeyTimestamp === "object")
                    message.attachmentMediaKeyTimestamp = new $util.LongBits(object.attachmentMediaKeyTimestamp.low >>> 0, object.attachmentMediaKeyTimestamp.high >>> 0).toNumber();
            if (object.attachmentFileSha256 != null)
                if (typeof object.attachmentFileSha256 === "string")
                    $util.base64.decode(object.attachmentFileSha256, message.attachmentFileSha256 = $util.newBuffer($util.base64.length(object.attachmentFileSha256)), 0);
                else if (object.attachmentFileSha256.length)
                    message.attachmentFileSha256 = object.attachmentFileSha256;
            if (object.attachmentFileEncSha256 != null)
                if (typeof object.attachmentFileEncSha256 === "string")
                    $util.base64.decode(object.attachmentFileEncSha256, message.attachmentFileEncSha256 = $util.newBuffer($util.base64.length(object.attachmentFileEncSha256)), 0);
                else if (object.attachmentFileEncSha256.length)
                    message.attachmentFileEncSha256 = object.attachmentFileEncSha256;
            if (object.attachmentDirectPath != null)
                message.attachmentDirectPath = String(object.attachmentDirectPath);
            if (object.attachmentJpegThumbnail != null)
                if (typeof object.attachmentJpegThumbnail === "string")
                    $util.base64.decode(object.attachmentJpegThumbnail, message.attachmentJpegThumbnail = $util.newBuffer($util.base64.length(object.attachmentJpegThumbnail)), 0);
                else if (object.attachmentJpegThumbnail.length)
                    message.attachmentJpegThumbnail = object.attachmentJpegThumbnail;
            return message;
        };

        /**
         * Creates a plain object from an InvoiceMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.InvoiceMessage
         * @static
         * @param {proto.InvoiceMessage} message InvoiceMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        InvoiceMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.note = "";
                object.token = "";
                object.attachmentType = options.enums === String ? "IMAGE" : 0;
                object.attachmentMimetype = "";
                if (options.bytes === String)
                    object.attachmentMediaKey = "";
                else {
                    object.attachmentMediaKey = [];
                    if (options.bytes !== Array)
                        object.attachmentMediaKey = $util.newBuffer(object.attachmentMediaKey);
                }
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.attachmentMediaKeyTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.attachmentMediaKeyTimestamp = options.longs === String ? "0" : 0;
                if (options.bytes === String)
                    object.attachmentFileSha256 = "";
                else {
                    object.attachmentFileSha256 = [];
                    if (options.bytes !== Array)
                        object.attachmentFileSha256 = $util.newBuffer(object.attachmentFileSha256);
                }
                if (options.bytes === String)
                    object.attachmentFileEncSha256 = "";
                else {
                    object.attachmentFileEncSha256 = [];
                    if (options.bytes !== Array)
                        object.attachmentFileEncSha256 = $util.newBuffer(object.attachmentFileEncSha256);
                }
                object.attachmentDirectPath = "";
                if (options.bytes === String)
                    object.attachmentJpegThumbnail = "";
                else {
                    object.attachmentJpegThumbnail = [];
                    if (options.bytes !== Array)
                        object.attachmentJpegThumbnail = $util.newBuffer(object.attachmentJpegThumbnail);
                }
            }
            if (message.note != null && message.hasOwnProperty("note"))
                object.note = message.note;
            if (message.token != null && message.hasOwnProperty("token"))
                object.token = message.token;
            if (message.attachmentType != null && message.hasOwnProperty("attachmentType"))
                object.attachmentType = options.enums === String ? $root.proto.InvoiceMessage.InvoiceMessageAttachmentType[message.attachmentType] : message.attachmentType;
            if (message.attachmentMimetype != null && message.hasOwnProperty("attachmentMimetype"))
                object.attachmentMimetype = message.attachmentMimetype;
            if (message.attachmentMediaKey != null && message.hasOwnProperty("attachmentMediaKey"))
                object.attachmentMediaKey = options.bytes === String ? $util.base64.encode(message.attachmentMediaKey, 0, message.attachmentMediaKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.attachmentMediaKey) : message.attachmentMediaKey;
            if (message.attachmentMediaKeyTimestamp != null && message.hasOwnProperty("attachmentMediaKeyTimestamp"))
                if (typeof message.attachmentMediaKeyTimestamp === "number")
                    object.attachmentMediaKeyTimestamp = options.longs === String ? String(message.attachmentMediaKeyTimestamp) : message.attachmentMediaKeyTimestamp;
                else
                    object.attachmentMediaKeyTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.attachmentMediaKeyTimestamp) : options.longs === Number ? new $util.LongBits(message.attachmentMediaKeyTimestamp.low >>> 0, message.attachmentMediaKeyTimestamp.high >>> 0).toNumber() : message.attachmentMediaKeyTimestamp;
            if (message.attachmentFileSha256 != null && message.hasOwnProperty("attachmentFileSha256"))
                object.attachmentFileSha256 = options.bytes === String ? $util.base64.encode(message.attachmentFileSha256, 0, message.attachmentFileSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.attachmentFileSha256) : message.attachmentFileSha256;
            if (message.attachmentFileEncSha256 != null && message.hasOwnProperty("attachmentFileEncSha256"))
                object.attachmentFileEncSha256 = options.bytes === String ? $util.base64.encode(message.attachmentFileEncSha256, 0, message.attachmentFileEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.attachmentFileEncSha256) : message.attachmentFileEncSha256;
            if (message.attachmentDirectPath != null && message.hasOwnProperty("attachmentDirectPath"))
                object.attachmentDirectPath = message.attachmentDirectPath;
            if (message.attachmentJpegThumbnail != null && message.hasOwnProperty("attachmentJpegThumbnail"))
                object.attachmentJpegThumbnail = options.bytes === String ? $util.base64.encode(message.attachmentJpegThumbnail, 0, message.attachmentJpegThumbnail.length) : options.bytes === Array ? Array.prototype.slice.call(message.attachmentJpegThumbnail) : message.attachmentJpegThumbnail;
            return object;
        };

        /**
         * Converts this InvoiceMessage to JSON.
         * @function toJSON
         * @memberof proto.InvoiceMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        InvoiceMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * InvoiceMessageAttachmentType enum.
         * @name proto.InvoiceMessage.InvoiceMessageAttachmentType
         * @enum {number}
         * @property {number} IMAGE=0 IMAGE value
         * @property {number} PDF=1 PDF value
         */
        InvoiceMessage.InvoiceMessageAttachmentType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "IMAGE"] = 0;
            values[valuesById[1] = "PDF"] = 1;
            return values;
        })();

        return InvoiceMessage;
    })();

    proto.ContactMessage = (function() {

        /**
         * Properties of a ContactMessage.
         * @memberof proto
         * @interface IContactMessage
         * @property {string|null} [displayName] ContactMessage displayName
         * @property {string|null} [vcard] ContactMessage vcard
         * @property {proto.IContextInfo|null} [contextInfo] ContactMessage contextInfo
         */

        /**
         * Constructs a new ContactMessage.
         * @memberof proto
         * @classdesc Represents a ContactMessage.
         * @implements IContactMessage
         * @constructor
         * @param {proto.IContactMessage=} [properties] Properties to set
         */
        function ContactMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ContactMessage displayName.
         * @member {string} displayName
         * @memberof proto.ContactMessage
         * @instance
         */
        ContactMessage.prototype.displayName = "";

        /**
         * ContactMessage vcard.
         * @member {string} vcard
         * @memberof proto.ContactMessage
         * @instance
         */
        ContactMessage.prototype.vcard = "";

        /**
         * ContactMessage contextInfo.
         * @member {proto.IContextInfo|null|undefined} contextInfo
         * @memberof proto.ContactMessage
         * @instance
         */
        ContactMessage.prototype.contextInfo = null;

        /**
         * Creates a new ContactMessage instance using the specified properties.
         * @function create
         * @memberof proto.ContactMessage
         * @static
         * @param {proto.IContactMessage=} [properties] Properties to set
         * @returns {proto.ContactMessage} ContactMessage instance
         */
        ContactMessage.create = function create(properties) {
            return new ContactMessage(properties);
        };

        /**
         * Encodes the specified ContactMessage message. Does not implicitly {@link proto.ContactMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.ContactMessage
         * @static
         * @param {proto.IContactMessage} message ContactMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ContactMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.displayName != null && Object.hasOwnProperty.call(message, "displayName"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayName);
            if (message.vcard != null && Object.hasOwnProperty.call(message, "vcard"))
                writer.uint32(/* id 16, wireType 2 =*/130).string(message.vcard);
            if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo"))
                $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 17, wireType 2 =*/138).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified ContactMessage message, length delimited. Does not implicitly {@link proto.ContactMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ContactMessage
         * @static
         * @param {proto.IContactMessage} message ContactMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ContactMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ContactMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ContactMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ContactMessage} ContactMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ContactMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ContactMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.displayName = reader.string();
                    break;
                case 16:
                    message.vcard = reader.string();
                    break;
                case 17:
                    message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ContactMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ContactMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ContactMessage} ContactMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ContactMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ContactMessage message.
         * @function verify
         * @memberof proto.ContactMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ContactMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.displayName != null && message.hasOwnProperty("displayName"))
                if (!$util.isString(message.displayName))
                    return "displayName: string expected";
            if (message.vcard != null && message.hasOwnProperty("vcard"))
                if (!$util.isString(message.vcard))
                    return "vcard: string expected";
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) {
                var error = $root.proto.ContextInfo.verify(message.contextInfo);
                if (error)
                    return "contextInfo." + error;
            }
            return null;
        };

        /**
         * Creates a ContactMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ContactMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ContactMessage} ContactMessage
         */
        ContactMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ContactMessage)
                return object;
            var message = new $root.proto.ContactMessage();
            if (object.displayName != null)
                message.displayName = String(object.displayName);
            if (object.vcard != null)
                message.vcard = String(object.vcard);
            if (object.contextInfo != null) {
                if (typeof object.contextInfo !== "object")
                    throw TypeError(".proto.ContactMessage.contextInfo: object expected");
                message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo);
            }
            return message;
        };

        /**
         * Creates a plain object from a ContactMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ContactMessage
         * @static
         * @param {proto.ContactMessage} message ContactMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ContactMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.displayName = "";
                object.vcard = "";
                object.contextInfo = null;
            }
            if (message.displayName != null && message.hasOwnProperty("displayName"))
                object.displayName = message.displayName;
            if (message.vcard != null && message.hasOwnProperty("vcard"))
                object.vcard = message.vcard;
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo"))
                object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options);
            return object;
        };

        /**
         * Converts this ContactMessage to JSON.
         * @function toJSON
         * @memberof proto.ContactMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ContactMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ContactMessage;
    })();

    proto.LocationMessage = (function() {

        /**
         * Properties of a LocationMessage.
         * @memberof proto
         * @interface ILocationMessage
         * @property {number|null} [degreesLatitude] LocationMessage degreesLatitude
         * @property {number|null} [degreesLongitude] LocationMessage degreesLongitude
         * @property {string|null} [name] LocationMessage name
         * @property {string|null} [address] LocationMessage address
         * @property {string|null} [url] LocationMessage url
         * @property {boolean|null} [isLive] LocationMessage isLive
         * @property {number|null} [accuracyInMeters] LocationMessage accuracyInMeters
         * @property {number|null} [speedInMps] LocationMessage speedInMps
         * @property {number|null} [degreesClockwiseFromMagneticNorth] LocationMessage degreesClockwiseFromMagneticNorth
         * @property {string|null} [comment] LocationMessage comment
         * @property {Uint8Array|null} [jpegThumbnail] LocationMessage jpegThumbnail
         * @property {proto.IContextInfo|null} [contextInfo] LocationMessage contextInfo
         */

        /**
         * Constructs a new LocationMessage.
         * @memberof proto
         * @classdesc Represents a LocationMessage.
         * @implements ILocationMessage
         * @constructor
         * @param {proto.ILocationMessage=} [properties] Properties to set
         */
        function LocationMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * LocationMessage degreesLatitude.
         * @member {number} degreesLatitude
         * @memberof proto.LocationMessage
         * @instance
         */
        LocationMessage.prototype.degreesLatitude = 0;

        /**
         * LocationMessage degreesLongitude.
         * @member {number} degreesLongitude
         * @memberof proto.LocationMessage
         * @instance
         */
        LocationMessage.prototype.degreesLongitude = 0;

        /**
         * LocationMessage name.
         * @member {string} name
         * @memberof proto.LocationMessage
         * @instance
         */
        LocationMessage.prototype.name = "";

        /**
         * LocationMessage address.
         * @member {string} address
         * @memberof proto.LocationMessage
         * @instance
         */
        LocationMessage.prototype.address = "";

        /**
         * LocationMessage url.
         * @member {string} url
         * @memberof proto.LocationMessage
         * @instance
         */
        LocationMessage.prototype.url = "";

        /**
         * LocationMessage isLive.
         * @member {boolean} isLive
         * @memberof proto.LocationMessage
         * @instance
         */
        LocationMessage.prototype.isLive = false;

        /**
         * LocationMessage accuracyInMeters.
         * @member {number} accuracyInMeters
         * @memberof proto.LocationMessage
         * @instance
         */
        LocationMessage.prototype.accuracyInMeters = 0;

        /**
         * LocationMessage speedInMps.
         * @member {number} speedInMps
         * @memberof proto.LocationMessage
         * @instance
         */
        LocationMessage.prototype.speedInMps = 0;

        /**
         * LocationMessage degreesClockwiseFromMagneticNorth.
         * @member {number} degreesClockwiseFromMagneticNorth
         * @memberof proto.LocationMessage
         * @instance
         */
        LocationMessage.prototype.degreesClockwiseFromMagneticNorth = 0;

        /**
         * LocationMessage comment.
         * @member {string} comment
         * @memberof proto.LocationMessage
         * @instance
         */
        LocationMessage.prototype.comment = "";

        /**
         * LocationMessage jpegThumbnail.
         * @member {Uint8Array} jpegThumbnail
         * @memberof proto.LocationMessage
         * @instance
         */
        LocationMessage.prototype.jpegThumbnail = $util.newBuffer([]);

        /**
         * LocationMessage contextInfo.
         * @member {proto.IContextInfo|null|undefined} contextInfo
         * @memberof proto.LocationMessage
         * @instance
         */
        LocationMessage.prototype.contextInfo = null;

        /**
         * Creates a new LocationMessage instance using the specified properties.
         * @function create
         * @memberof proto.LocationMessage
         * @static
         * @param {proto.ILocationMessage=} [properties] Properties to set
         * @returns {proto.LocationMessage} LocationMessage instance
         */
        LocationMessage.create = function create(properties) {
            return new LocationMessage(properties);
        };

        /**
         * Encodes the specified LocationMessage message. Does not implicitly {@link proto.LocationMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.LocationMessage
         * @static
         * @param {proto.ILocationMessage} message LocationMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        LocationMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.degreesLatitude != null && Object.hasOwnProperty.call(message, "degreesLatitude"))
                writer.uint32(/* id 1, wireType 1 =*/9).double(message.degreesLatitude);
            if (message.degreesLongitude != null && Object.hasOwnProperty.call(message, "degreesLongitude"))
                writer.uint32(/* id 2, wireType 1 =*/17).double(message.degreesLongitude);
            if (message.name != null && Object.hasOwnProperty.call(message, "name"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.name);
            if (message.address != null && Object.hasOwnProperty.call(message, "address"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.address);
            if (message.url != null && Object.hasOwnProperty.call(message, "url"))
                writer.uint32(/* id 5, wireType 2 =*/42).string(message.url);
            if (message.isLive != null && Object.hasOwnProperty.call(message, "isLive"))
                writer.uint32(/* id 6, wireType 0 =*/48).bool(message.isLive);
            if (message.accuracyInMeters != null && Object.hasOwnProperty.call(message, "accuracyInMeters"))
                writer.uint32(/* id 7, wireType 0 =*/56).uint32(message.accuracyInMeters);
            if (message.speedInMps != null && Object.hasOwnProperty.call(message, "speedInMps"))
                writer.uint32(/* id 8, wireType 5 =*/69).float(message.speedInMps);
            if (message.degreesClockwiseFromMagneticNorth != null && Object.hasOwnProperty.call(message, "degreesClockwiseFromMagneticNorth"))
                writer.uint32(/* id 9, wireType 0 =*/72).uint32(message.degreesClockwiseFromMagneticNorth);
            if (message.comment != null && Object.hasOwnProperty.call(message, "comment"))
                writer.uint32(/* id 11, wireType 2 =*/90).string(message.comment);
            if (message.jpegThumbnail != null && Object.hasOwnProperty.call(message, "jpegThumbnail"))
                writer.uint32(/* id 16, wireType 2 =*/130).bytes(message.jpegThumbnail);
            if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo"))
                $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 17, wireType 2 =*/138).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified LocationMessage message, length delimited. Does not implicitly {@link proto.LocationMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.LocationMessage
         * @static
         * @param {proto.ILocationMessage} message LocationMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        LocationMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a LocationMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.LocationMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.LocationMessage} LocationMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        LocationMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.LocationMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.degreesLatitude = reader.double();
                    break;
                case 2:
                    message.degreesLongitude = reader.double();
                    break;
                case 3:
                    message.name = reader.string();
                    break;
                case 4:
                    message.address = reader.string();
                    break;
                case 5:
                    message.url = reader.string();
                    break;
                case 6:
                    message.isLive = reader.bool();
                    break;
                case 7:
                    message.accuracyInMeters = reader.uint32();
                    break;
                case 8:
                    message.speedInMps = reader.float();
                    break;
                case 9:
                    message.degreesClockwiseFromMagneticNorth = reader.uint32();
                    break;
                case 11:
                    message.comment = reader.string();
                    break;
                case 16:
                    message.jpegThumbnail = reader.bytes();
                    break;
                case 17:
                    message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a LocationMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.LocationMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.LocationMessage} LocationMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        LocationMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a LocationMessage message.
         * @function verify
         * @memberof proto.LocationMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        LocationMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.degreesLatitude != null && message.hasOwnProperty("degreesLatitude"))
                if (typeof message.degreesLatitude !== "number")
                    return "degreesLatitude: number expected";
            if (message.degreesLongitude != null && message.hasOwnProperty("degreesLongitude"))
                if (typeof message.degreesLongitude !== "number")
                    return "degreesLongitude: number expected";
            if (message.name != null && message.hasOwnProperty("name"))
                if (!$util.isString(message.name))
                    return "name: string expected";
            if (message.address != null && message.hasOwnProperty("address"))
                if (!$util.isString(message.address))
                    return "address: string expected";
            if (message.url != null && message.hasOwnProperty("url"))
                if (!$util.isString(message.url))
                    return "url: string expected";
            if (message.isLive != null && message.hasOwnProperty("isLive"))
                if (typeof message.isLive !== "boolean")
                    return "isLive: boolean expected";
            if (message.accuracyInMeters != null && message.hasOwnProperty("accuracyInMeters"))
                if (!$util.isInteger(message.accuracyInMeters))
                    return "accuracyInMeters: integer expected";
            if (message.speedInMps != null && message.hasOwnProperty("speedInMps"))
                if (typeof message.speedInMps !== "number")
                    return "speedInMps: number expected";
            if (message.degreesClockwiseFromMagneticNorth != null && message.hasOwnProperty("degreesClockwiseFromMagneticNorth"))
                if (!$util.isInteger(message.degreesClockwiseFromMagneticNorth))
                    return "degreesClockwiseFromMagneticNorth: integer expected";
            if (message.comment != null && message.hasOwnProperty("comment"))
                if (!$util.isString(message.comment))
                    return "comment: string expected";
            if (message.jpegThumbnail != null && message.hasOwnProperty("jpegThumbnail"))
                if (!(message.jpegThumbnail && typeof message.jpegThumbnail.length === "number" || $util.isString(message.jpegThumbnail)))
                    return "jpegThumbnail: buffer expected";
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) {
                var error = $root.proto.ContextInfo.verify(message.contextInfo);
                if (error)
                    return "contextInfo." + error;
            }
            return null;
        };

        /**
         * Creates a LocationMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.LocationMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.LocationMessage} LocationMessage
         */
        LocationMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.LocationMessage)
                return object;
            var message = new $root.proto.LocationMessage();
            if (object.degreesLatitude != null)
                message.degreesLatitude = Number(object.degreesLatitude);
            if (object.degreesLongitude != null)
                message.degreesLongitude = Number(object.degreesLongitude);
            if (object.name != null)
                message.name = String(object.name);
            if (object.address != null)
                message.address = String(object.address);
            if (object.url != null)
                message.url = String(object.url);
            if (object.isLive != null)
                message.isLive = Boolean(object.isLive);
            if (object.accuracyInMeters != null)
                message.accuracyInMeters = object.accuracyInMeters >>> 0;
            if (object.speedInMps != null)
                message.speedInMps = Number(object.speedInMps);
            if (object.degreesClockwiseFromMagneticNorth != null)
                message.degreesClockwiseFromMagneticNorth = object.degreesClockwiseFromMagneticNorth >>> 0;
            if (object.comment != null)
                message.comment = String(object.comment);
            if (object.jpegThumbnail != null)
                if (typeof object.jpegThumbnail === "string")
                    $util.base64.decode(object.jpegThumbnail, message.jpegThumbnail = $util.newBuffer($util.base64.length(object.jpegThumbnail)), 0);
                else if (object.jpegThumbnail.length)
                    message.jpegThumbnail = object.jpegThumbnail;
            if (object.contextInfo != null) {
                if (typeof object.contextInfo !== "object")
                    throw TypeError(".proto.LocationMessage.contextInfo: object expected");
                message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo);
            }
            return message;
        };

        /**
         * Creates a plain object from a LocationMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.LocationMessage
         * @static
         * @param {proto.LocationMessage} message LocationMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        LocationMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.degreesLatitude = 0;
                object.degreesLongitude = 0;
                object.name = "";
                object.address = "";
                object.url = "";
                object.isLive = false;
                object.accuracyInMeters = 0;
                object.speedInMps = 0;
                object.degreesClockwiseFromMagneticNorth = 0;
                object.comment = "";
                if (options.bytes === String)
                    object.jpegThumbnail = "";
                else {
                    object.jpegThumbnail = [];
                    if (options.bytes !== Array)
                        object.jpegThumbnail = $util.newBuffer(object.jpegThumbnail);
                }
                object.contextInfo = null;
            }
            if (message.degreesLatitude != null && message.hasOwnProperty("degreesLatitude"))
                object.degreesLatitude = options.json && !isFinite(message.degreesLatitude) ? String(message.degreesLatitude) : message.degreesLatitude;
            if (message.degreesLongitude != null && message.hasOwnProperty("degreesLongitude"))
                object.degreesLongitude = options.json && !isFinite(message.degreesLongitude) ? String(message.degreesLongitude) : message.degreesLongitude;
            if (message.name != null && message.hasOwnProperty("name"))
                object.name = message.name;
            if (message.address != null && message.hasOwnProperty("address"))
                object.address = message.address;
            if (message.url != null && message.hasOwnProperty("url"))
                object.url = message.url;
            if (message.isLive != null && message.hasOwnProperty("isLive"))
                object.isLive = message.isLive;
            if (message.accuracyInMeters != null && message.hasOwnProperty("accuracyInMeters"))
                object.accuracyInMeters = message.accuracyInMeters;
            if (message.speedInMps != null && message.hasOwnProperty("speedInMps"))
                object.speedInMps = options.json && !isFinite(message.speedInMps) ? String(message.speedInMps) : message.speedInMps;
            if (message.degreesClockwiseFromMagneticNorth != null && message.hasOwnProperty("degreesClockwiseFromMagneticNorth"))
                object.degreesClockwiseFromMagneticNorth = message.degreesClockwiseFromMagneticNorth;
            if (message.comment != null && message.hasOwnProperty("comment"))
                object.comment = message.comment;
            if (message.jpegThumbnail != null && message.hasOwnProperty("jpegThumbnail"))
                object.jpegThumbnail = options.bytes === String ? $util.base64.encode(message.jpegThumbnail, 0, message.jpegThumbnail.length) : options.bytes === Array ? Array.prototype.slice.call(message.jpegThumbnail) : message.jpegThumbnail;
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo"))
                object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options);
            return object;
        };

        /**
         * Converts this LocationMessage to JSON.
         * @function toJSON
         * @memberof proto.LocationMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        LocationMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return LocationMessage;
    })();

    proto.ExtendedTextMessage = (function() {

        /**
         * Properties of an ExtendedTextMessage.
         * @memberof proto
         * @interface IExtendedTextMessage
         * @property {string|null} [text] ExtendedTextMessage text
         * @property {string|null} [matchedText] ExtendedTextMessage matchedText
         * @property {string|null} [canonicalUrl] ExtendedTextMessage canonicalUrl
         * @property {string|null} [description] ExtendedTextMessage description
         * @property {string|null} [title] ExtendedTextMessage title
         * @property {number|null} [textArgb] ExtendedTextMessage textArgb
         * @property {number|null} [backgroundArgb] ExtendedTextMessage backgroundArgb
         * @property {proto.ExtendedTextMessage.ExtendedTextMessageFontType|null} [font] ExtendedTextMessage font
         * @property {proto.ExtendedTextMessage.ExtendedTextMessagePreviewType|null} [previewType] ExtendedTextMessage previewType
         * @property {Uint8Array|null} [jpegThumbnail] ExtendedTextMessage jpegThumbnail
         * @property {proto.IContextInfo|null} [contextInfo] ExtendedTextMessage contextInfo
         * @property {boolean|null} [doNotPlayInline] ExtendedTextMessage doNotPlayInline
         * @property {string|null} [thumbnailDirectPath] ExtendedTextMessage thumbnailDirectPath
         * @property {Uint8Array|null} [thumbnailSha256] ExtendedTextMessage thumbnailSha256
         * @property {Uint8Array|null} [thumbnailEncSha256] ExtendedTextMessage thumbnailEncSha256
         * @property {Uint8Array|null} [mediaKey] ExtendedTextMessage mediaKey
         * @property {number|Long|null} [mediaKeyTimestamp] ExtendedTextMessage mediaKeyTimestamp
         * @property {number|null} [thumbnailHeight] ExtendedTextMessage thumbnailHeight
         * @property {number|null} [thumbnailWidth] ExtendedTextMessage thumbnailWidth
         * @property {proto.ExtendedTextMessage.ExtendedTextMessageInviteLinkGroupType|null} [inviteLinkGroupType] ExtendedTextMessage inviteLinkGroupType
         */

        /**
         * Constructs a new ExtendedTextMessage.
         * @memberof proto
         * @classdesc Represents an ExtendedTextMessage.
         * @implements IExtendedTextMessage
         * @constructor
         * @param {proto.IExtendedTextMessage=} [properties] Properties to set
         */
        function ExtendedTextMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ExtendedTextMessage text.
         * @member {string} text
         * @memberof proto.ExtendedTextMessage
         * @instance
         */
        ExtendedTextMessage.prototype.text = "";

        /**
         * ExtendedTextMessage matchedText.
         * @member {string} matchedText
         * @memberof proto.ExtendedTextMessage
         * @instance
         */
        ExtendedTextMessage.prototype.matchedText = "";

        /**
         * ExtendedTextMessage canonicalUrl.
         * @member {string} canonicalUrl
         * @memberof proto.ExtendedTextMessage
         * @instance
         */
        ExtendedTextMessage.prototype.canonicalUrl = "";

        /**
         * ExtendedTextMessage description.
         * @member {string} description
         * @memberof proto.ExtendedTextMessage
         * @instance
         */
        ExtendedTextMessage.prototype.description = "";

        /**
         * ExtendedTextMessage title.
         * @member {string} title
         * @memberof proto.ExtendedTextMessage
         * @instance
         */
        ExtendedTextMessage.prototype.title = "";

        /**
         * ExtendedTextMessage textArgb.
         * @member {number} textArgb
         * @memberof proto.ExtendedTextMessage
         * @instance
         */
        ExtendedTextMessage.prototype.textArgb = 0;

        /**
         * ExtendedTextMessage backgroundArgb.
         * @member {number} backgroundArgb
         * @memberof proto.ExtendedTextMessage
         * @instance
         */
        ExtendedTextMessage.prototype.backgroundArgb = 0;

        /**
         * ExtendedTextMessage font.
         * @member {proto.ExtendedTextMessage.ExtendedTextMessageFontType} font
         * @memberof proto.ExtendedTextMessage
         * @instance
         */
        ExtendedTextMessage.prototype.font = 0;

        /**
         * ExtendedTextMessage previewType.
         * @member {proto.ExtendedTextMessage.ExtendedTextMessagePreviewType} previewType
         * @memberof proto.ExtendedTextMessage
         * @instance
         */
        ExtendedTextMessage.prototype.previewType = 0;

        /**
         * ExtendedTextMessage jpegThumbnail.
         * @member {Uint8Array} jpegThumbnail
         * @memberof proto.ExtendedTextMessage
         * @instance
         */
        ExtendedTextMessage.prototype.jpegThumbnail = $util.newBuffer([]);

        /**
         * ExtendedTextMessage contextInfo.
         * @member {proto.IContextInfo|null|undefined} contextInfo
         * @memberof proto.ExtendedTextMessage
         * @instance
         */
        ExtendedTextMessage.prototype.contextInfo = null;

        /**
         * ExtendedTextMessage doNotPlayInline.
         * @member {boolean} doNotPlayInline
         * @memberof proto.ExtendedTextMessage
         * @instance
         */
        ExtendedTextMessage.prototype.doNotPlayInline = false;

        /**
         * ExtendedTextMessage thumbnailDirectPath.
         * @member {string} thumbnailDirectPath
         * @memberof proto.ExtendedTextMessage
         * @instance
         */
        ExtendedTextMessage.prototype.thumbnailDirectPath = "";

        /**
         * ExtendedTextMessage thumbnailSha256.
         * @member {Uint8Array} thumbnailSha256
         * @memberof proto.ExtendedTextMessage
         * @instance
         */
        ExtendedTextMessage.prototype.thumbnailSha256 = $util.newBuffer([]);

        /**
         * ExtendedTextMessage thumbnailEncSha256.
         * @member {Uint8Array} thumbnailEncSha256
         * @memberof proto.ExtendedTextMessage
         * @instance
         */
        ExtendedTextMessage.prototype.thumbnailEncSha256 = $util.newBuffer([]);

        /**
         * ExtendedTextMessage mediaKey.
         * @member {Uint8Array} mediaKey
         * @memberof proto.ExtendedTextMessage
         * @instance
         */
        ExtendedTextMessage.prototype.mediaKey = $util.newBuffer([]);

        /**
         * ExtendedTextMessage mediaKeyTimestamp.
         * @member {number|Long} mediaKeyTimestamp
         * @memberof proto.ExtendedTextMessage
         * @instance
         */
        ExtendedTextMessage.prototype.mediaKeyTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * ExtendedTextMessage thumbnailHeight.
         * @member {number} thumbnailHeight
         * @memberof proto.ExtendedTextMessage
         * @instance
         */
        ExtendedTextMessage.prototype.thumbnailHeight = 0;

        /**
         * ExtendedTextMessage thumbnailWidth.
         * @member {number} thumbnailWidth
         * @memberof proto.ExtendedTextMessage
         * @instance
         */
        ExtendedTextMessage.prototype.thumbnailWidth = 0;

        /**
         * ExtendedTextMessage inviteLinkGroupType.
         * @member {proto.ExtendedTextMessage.ExtendedTextMessageInviteLinkGroupType} inviteLinkGroupType
         * @memberof proto.ExtendedTextMessage
         * @instance
         */
        ExtendedTextMessage.prototype.inviteLinkGroupType = 0;

        /**
         * Creates a new ExtendedTextMessage instance using the specified properties.
         * @function create
         * @memberof proto.ExtendedTextMessage
         * @static
         * @param {proto.IExtendedTextMessage=} [properties] Properties to set
         * @returns {proto.ExtendedTextMessage} ExtendedTextMessage instance
         */
        ExtendedTextMessage.create = function create(properties) {
            return new ExtendedTextMessage(properties);
        };

        /**
         * Encodes the specified ExtendedTextMessage message. Does not implicitly {@link proto.ExtendedTextMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.ExtendedTextMessage
         * @static
         * @param {proto.IExtendedTextMessage} message ExtendedTextMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ExtendedTextMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.text != null && Object.hasOwnProperty.call(message, "text"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.text);
            if (message.matchedText != null && Object.hasOwnProperty.call(message, "matchedText"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.matchedText);
            if (message.canonicalUrl != null && Object.hasOwnProperty.call(message, "canonicalUrl"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.canonicalUrl);
            if (message.description != null && Object.hasOwnProperty.call(message, "description"))
                writer.uint32(/* id 5, wireType 2 =*/42).string(message.description);
            if (message.title != null && Object.hasOwnProperty.call(message, "title"))
                writer.uint32(/* id 6, wireType 2 =*/50).string(message.title);
            if (message.textArgb != null && Object.hasOwnProperty.call(message, "textArgb"))
                writer.uint32(/* id 7, wireType 5 =*/61).fixed32(message.textArgb);
            if (message.backgroundArgb != null && Object.hasOwnProperty.call(message, "backgroundArgb"))
                writer.uint32(/* id 8, wireType 5 =*/69).fixed32(message.backgroundArgb);
            if (message.font != null && Object.hasOwnProperty.call(message, "font"))
                writer.uint32(/* id 9, wireType 0 =*/72).int32(message.font);
            if (message.previewType != null && Object.hasOwnProperty.call(message, "previewType"))
                writer.uint32(/* id 10, wireType 0 =*/80).int32(message.previewType);
            if (message.jpegThumbnail != null && Object.hasOwnProperty.call(message, "jpegThumbnail"))
                writer.uint32(/* id 16, wireType 2 =*/130).bytes(message.jpegThumbnail);
            if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo"))
                $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 17, wireType 2 =*/138).fork()).ldelim();
            if (message.doNotPlayInline != null && Object.hasOwnProperty.call(message, "doNotPlayInline"))
                writer.uint32(/* id 18, wireType 0 =*/144).bool(message.doNotPlayInline);
            if (message.thumbnailDirectPath != null && Object.hasOwnProperty.call(message, "thumbnailDirectPath"))
                writer.uint32(/* id 19, wireType 2 =*/154).string(message.thumbnailDirectPath);
            if (message.thumbnailSha256 != null && Object.hasOwnProperty.call(message, "thumbnailSha256"))
                writer.uint32(/* id 20, wireType 2 =*/162).bytes(message.thumbnailSha256);
            if (message.thumbnailEncSha256 != null && Object.hasOwnProperty.call(message, "thumbnailEncSha256"))
                writer.uint32(/* id 21, wireType 2 =*/170).bytes(message.thumbnailEncSha256);
            if (message.mediaKey != null && Object.hasOwnProperty.call(message, "mediaKey"))
                writer.uint32(/* id 22, wireType 2 =*/178).bytes(message.mediaKey);
            if (message.mediaKeyTimestamp != null && Object.hasOwnProperty.call(message, "mediaKeyTimestamp"))
                writer.uint32(/* id 23, wireType 0 =*/184).int64(message.mediaKeyTimestamp);
            if (message.thumbnailHeight != null && Object.hasOwnProperty.call(message, "thumbnailHeight"))
                writer.uint32(/* id 24, wireType 0 =*/192).uint32(message.thumbnailHeight);
            if (message.thumbnailWidth != null && Object.hasOwnProperty.call(message, "thumbnailWidth"))
                writer.uint32(/* id 25, wireType 0 =*/200).uint32(message.thumbnailWidth);
            if (message.inviteLinkGroupType != null && Object.hasOwnProperty.call(message, "inviteLinkGroupType"))
                writer.uint32(/* id 26, wireType 0 =*/208).int32(message.inviteLinkGroupType);
            return writer;
        };

        /**
         * Encodes the specified ExtendedTextMessage message, length delimited. Does not implicitly {@link proto.ExtendedTextMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ExtendedTextMessage
         * @static
         * @param {proto.IExtendedTextMessage} message ExtendedTextMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ExtendedTextMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an ExtendedTextMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ExtendedTextMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ExtendedTextMessage} ExtendedTextMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ExtendedTextMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ExtendedTextMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.text = reader.string();
                    break;
                case 2:
                    message.matchedText = reader.string();
                    break;
                case 4:
                    message.canonicalUrl = reader.string();
                    break;
                case 5:
                    message.description = reader.string();
                    break;
                case 6:
                    message.title = reader.string();
                    break;
                case 7:
                    message.textArgb = reader.fixed32();
                    break;
                case 8:
                    message.backgroundArgb = reader.fixed32();
                    break;
                case 9:
                    message.font = reader.int32();
                    break;
                case 10:
                    message.previewType = reader.int32();
                    break;
                case 16:
                    message.jpegThumbnail = reader.bytes();
                    break;
                case 17:
                    message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32());
                    break;
                case 18:
                    message.doNotPlayInline = reader.bool();
                    break;
                case 19:
                    message.thumbnailDirectPath = reader.string();
                    break;
                case 20:
                    message.thumbnailSha256 = reader.bytes();
                    break;
                case 21:
                    message.thumbnailEncSha256 = reader.bytes();
                    break;
                case 22:
                    message.mediaKey = reader.bytes();
                    break;
                case 23:
                    message.mediaKeyTimestamp = reader.int64();
                    break;
                case 24:
                    message.thumbnailHeight = reader.uint32();
                    break;
                case 25:
                    message.thumbnailWidth = reader.uint32();
                    break;
                case 26:
                    message.inviteLinkGroupType = reader.int32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an ExtendedTextMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ExtendedTextMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ExtendedTextMessage} ExtendedTextMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ExtendedTextMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an ExtendedTextMessage message.
         * @function verify
         * @memberof proto.ExtendedTextMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ExtendedTextMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.text != null && message.hasOwnProperty("text"))
                if (!$util.isString(message.text))
                    return "text: string expected";
            if (message.matchedText != null && message.hasOwnProperty("matchedText"))
                if (!$util.isString(message.matchedText))
                    return "matchedText: string expected";
            if (message.canonicalUrl != null && message.hasOwnProperty("canonicalUrl"))
                if (!$util.isString(message.canonicalUrl))
                    return "canonicalUrl: string expected";
            if (message.description != null && message.hasOwnProperty("description"))
                if (!$util.isString(message.description))
                    return "description: string expected";
            if (message.title != null && message.hasOwnProperty("title"))
                if (!$util.isString(message.title))
                    return "title: string expected";
            if (message.textArgb != null && message.hasOwnProperty("textArgb"))
                if (!$util.isInteger(message.textArgb))
                    return "textArgb: integer expected";
            if (message.backgroundArgb != null && message.hasOwnProperty("backgroundArgb"))
                if (!$util.isInteger(message.backgroundArgb))
                    return "backgroundArgb: integer expected";
            if (message.font != null && message.hasOwnProperty("font"))
                switch (message.font) {
                default:
                    return "font: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                    break;
                }
            if (message.previewType != null && message.hasOwnProperty("previewType"))
                switch (message.previewType) {
                default:
                    return "previewType: enum value expected";
                case 0:
                case 1:
                    break;
                }
            if (message.jpegThumbnail != null && message.hasOwnProperty("jpegThumbnail"))
                if (!(message.jpegThumbnail && typeof message.jpegThumbnail.length === "number" || $util.isString(message.jpegThumbnail)))
                    return "jpegThumbnail: buffer expected";
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) {
                var error = $root.proto.ContextInfo.verify(message.contextInfo);
                if (error)
                    return "contextInfo." + error;
            }
            if (message.doNotPlayInline != null && message.hasOwnProperty("doNotPlayInline"))
                if (typeof message.doNotPlayInline !== "boolean")
                    return "doNotPlayInline: boolean expected";
            if (message.thumbnailDirectPath != null && message.hasOwnProperty("thumbnailDirectPath"))
                if (!$util.isString(message.thumbnailDirectPath))
                    return "thumbnailDirectPath: string expected";
            if (message.thumbnailSha256 != null && message.hasOwnProperty("thumbnailSha256"))
                if (!(message.thumbnailSha256 && typeof message.thumbnailSha256.length === "number" || $util.isString(message.thumbnailSha256)))
                    return "thumbnailSha256: buffer expected";
            if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256"))
                if (!(message.thumbnailEncSha256 && typeof message.thumbnailEncSha256.length === "number" || $util.isString(message.thumbnailEncSha256)))
                    return "thumbnailEncSha256: buffer expected";
            if (message.mediaKey != null && message.hasOwnProperty("mediaKey"))
                if (!(message.mediaKey && typeof message.mediaKey.length === "number" || $util.isString(message.mediaKey)))
                    return "mediaKey: buffer expected";
            if (message.mediaKeyTimestamp != null && message.hasOwnProperty("mediaKeyTimestamp"))
                if (!$util.isInteger(message.mediaKeyTimestamp) && !(message.mediaKeyTimestamp && $util.isInteger(message.mediaKeyTimestamp.low) && $util.isInteger(message.mediaKeyTimestamp.high)))
                    return "mediaKeyTimestamp: integer|Long expected";
            if (message.thumbnailHeight != null && message.hasOwnProperty("thumbnailHeight"))
                if (!$util.isInteger(message.thumbnailHeight))
                    return "thumbnailHeight: integer expected";
            if (message.thumbnailWidth != null && message.hasOwnProperty("thumbnailWidth"))
                if (!$util.isInteger(message.thumbnailWidth))
                    return "thumbnailWidth: integer expected";
            if (message.inviteLinkGroupType != null && message.hasOwnProperty("inviteLinkGroupType"))
                switch (message.inviteLinkGroupType) {
                default:
                    return "inviteLinkGroupType: enum value expected";
                case 0:
                case 1:
                    break;
                }
            return null;
        };

        /**
         * Creates an ExtendedTextMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ExtendedTextMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ExtendedTextMessage} ExtendedTextMessage
         */
        ExtendedTextMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ExtendedTextMessage)
                return object;
            var message = new $root.proto.ExtendedTextMessage();
            if (object.text != null)
                message.text = String(object.text);
            if (object.matchedText != null)
                message.matchedText = String(object.matchedText);
            if (object.canonicalUrl != null)
                message.canonicalUrl = String(object.canonicalUrl);
            if (object.description != null)
                message.description = String(object.description);
            if (object.title != null)
                message.title = String(object.title);
            if (object.textArgb != null)
                message.textArgb = object.textArgb >>> 0;
            if (object.backgroundArgb != null)
                message.backgroundArgb = object.backgroundArgb >>> 0;
            switch (object.font) {
            case "SANS_SERIF":
            case 0:
                message.font = 0;
                break;
            case "SERIF":
            case 1:
                message.font = 1;
                break;
            case "NORICAN_REGULAR":
            case 2:
                message.font = 2;
                break;
            case "BRYNDAN_WRITE":
            case 3:
                message.font = 3;
                break;
            case "BEBASNEUE_REGULAR":
            case 4:
                message.font = 4;
                break;
            case "OSWALD_HEAVY":
            case 5:
                message.font = 5;
                break;
            }
            switch (object.previewType) {
            case "NONE":
            case 0:
                message.previewType = 0;
                break;
            case "VIDEO":
            case 1:
                message.previewType = 1;
                break;
            }
            if (object.jpegThumbnail != null)
                if (typeof object.jpegThumbnail === "string")
                    $util.base64.decode(object.jpegThumbnail, message.jpegThumbnail = $util.newBuffer($util.base64.length(object.jpegThumbnail)), 0);
                else if (object.jpegThumbnail.length)
                    message.jpegThumbnail = object.jpegThumbnail;
            if (object.contextInfo != null) {
                if (typeof object.contextInfo !== "object")
                    throw TypeError(".proto.ExtendedTextMessage.contextInfo: object expected");
                message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo);
            }
            if (object.doNotPlayInline != null)
                message.doNotPlayInline = Boolean(object.doNotPlayInline);
            if (object.thumbnailDirectPath != null)
                message.thumbnailDirectPath = String(object.thumbnailDirectPath);
            if (object.thumbnailSha256 != null)
                if (typeof object.thumbnailSha256 === "string")
                    $util.base64.decode(object.thumbnailSha256, message.thumbnailSha256 = $util.newBuffer($util.base64.length(object.thumbnailSha256)), 0);
                else if (object.thumbnailSha256.length)
                    message.thumbnailSha256 = object.thumbnailSha256;
            if (object.thumbnailEncSha256 != null)
                if (typeof object.thumbnailEncSha256 === "string")
                    $util.base64.decode(object.thumbnailEncSha256, message.thumbnailEncSha256 = $util.newBuffer($util.base64.length(object.thumbnailEncSha256)), 0);
                else if (object.thumbnailEncSha256.length)
                    message.thumbnailEncSha256 = object.thumbnailEncSha256;
            if (object.mediaKey != null)
                if (typeof object.mediaKey === "string")
                    $util.base64.decode(object.mediaKey, message.mediaKey = $util.newBuffer($util.base64.length(object.mediaKey)), 0);
                else if (object.mediaKey.length)
                    message.mediaKey = object.mediaKey;
            if (object.mediaKeyTimestamp != null)
                if ($util.Long)
                    (message.mediaKeyTimestamp = $util.Long.fromValue(object.mediaKeyTimestamp)).unsigned = false;
                else if (typeof object.mediaKeyTimestamp === "string")
                    message.mediaKeyTimestamp = parseInt(object.mediaKeyTimestamp, 10);
                else if (typeof object.mediaKeyTimestamp === "number")
                    message.mediaKeyTimestamp = object.mediaKeyTimestamp;
                else if (typeof object.mediaKeyTimestamp === "object")
                    message.mediaKeyTimestamp = new $util.LongBits(object.mediaKeyTimestamp.low >>> 0, object.mediaKeyTimestamp.high >>> 0).toNumber();
            if (object.thumbnailHeight != null)
                message.thumbnailHeight = object.thumbnailHeight >>> 0;
            if (object.thumbnailWidth != null)
                message.thumbnailWidth = object.thumbnailWidth >>> 0;
            switch (object.inviteLinkGroupType) {
            case "DEFAULT":
            case 0:
                message.inviteLinkGroupType = 0;
                break;
            case "PARENT":
            case 1:
                message.inviteLinkGroupType = 1;
                break;
            }
            return message;
        };

        /**
         * Creates a plain object from an ExtendedTextMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ExtendedTextMessage
         * @static
         * @param {proto.ExtendedTextMessage} message ExtendedTextMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ExtendedTextMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.text = "";
                object.matchedText = "";
                object.canonicalUrl = "";
                object.description = "";
                object.title = "";
                object.textArgb = 0;
                object.backgroundArgb = 0;
                object.font = options.enums === String ? "SANS_SERIF" : 0;
                object.previewType = options.enums === String ? "NONE" : 0;
                if (options.bytes === String)
                    object.jpegThumbnail = "";
                else {
                    object.jpegThumbnail = [];
                    if (options.bytes !== Array)
                        object.jpegThumbnail = $util.newBuffer(object.jpegThumbnail);
                }
                object.contextInfo = null;
                object.doNotPlayInline = false;
                object.thumbnailDirectPath = "";
                if (options.bytes === String)
                    object.thumbnailSha256 = "";
                else {
                    object.thumbnailSha256 = [];
                    if (options.bytes !== Array)
                        object.thumbnailSha256 = $util.newBuffer(object.thumbnailSha256);
                }
                if (options.bytes === String)
                    object.thumbnailEncSha256 = "";
                else {
                    object.thumbnailEncSha256 = [];
                    if (options.bytes !== Array)
                        object.thumbnailEncSha256 = $util.newBuffer(object.thumbnailEncSha256);
                }
                if (options.bytes === String)
                    object.mediaKey = "";
                else {
                    object.mediaKey = [];
                    if (options.bytes !== Array)
                        object.mediaKey = $util.newBuffer(object.mediaKey);
                }
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.mediaKeyTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.mediaKeyTimestamp = options.longs === String ? "0" : 0;
                object.thumbnailHeight = 0;
                object.thumbnailWidth = 0;
                object.inviteLinkGroupType = options.enums === String ? "DEFAULT" : 0;
            }
            if (message.text != null && message.hasOwnProperty("text"))
                object.text = message.text;
            if (message.matchedText != null && message.hasOwnProperty("matchedText"))
                object.matchedText = message.matchedText;
            if (message.canonicalUrl != null && message.hasOwnProperty("canonicalUrl"))
                object.canonicalUrl = message.canonicalUrl;
            if (message.description != null && message.hasOwnProperty("description"))
                object.description = message.description;
            if (message.title != null && message.hasOwnProperty("title"))
                object.title = message.title;
            if (message.textArgb != null && message.hasOwnProperty("textArgb"))
                object.textArgb = message.textArgb;
            if (message.backgroundArgb != null && message.hasOwnProperty("backgroundArgb"))
                object.backgroundArgb = message.backgroundArgb;
            if (message.font != null && message.hasOwnProperty("font"))
                object.font = options.enums === String ? $root.proto.ExtendedTextMessage.ExtendedTextMessageFontType[message.font] : message.font;
            if (message.previewType != null && message.hasOwnProperty("previewType"))
                object.previewType = options.enums === String ? $root.proto.ExtendedTextMessage.ExtendedTextMessagePreviewType[message.previewType] : message.previewType;
            if (message.jpegThumbnail != null && message.hasOwnProperty("jpegThumbnail"))
                object.jpegThumbnail = options.bytes === String ? $util.base64.encode(message.jpegThumbnail, 0, message.jpegThumbnail.length) : options.bytes === Array ? Array.prototype.slice.call(message.jpegThumbnail) : message.jpegThumbnail;
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo"))
                object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options);
            if (message.doNotPlayInline != null && message.hasOwnProperty("doNotPlayInline"))
                object.doNotPlayInline = message.doNotPlayInline;
            if (message.thumbnailDirectPath != null && message.hasOwnProperty("thumbnailDirectPath"))
                object.thumbnailDirectPath = message.thumbnailDirectPath;
            if (message.thumbnailSha256 != null && message.hasOwnProperty("thumbnailSha256"))
                object.thumbnailSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailSha256, 0, message.thumbnailSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailSha256) : message.thumbnailSha256;
            if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256"))
                object.thumbnailEncSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailEncSha256, 0, message.thumbnailEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailEncSha256) : message.thumbnailEncSha256;
            if (message.mediaKey != null && message.hasOwnProperty("mediaKey"))
                object.mediaKey = options.bytes === String ? $util.base64.encode(message.mediaKey, 0, message.mediaKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.mediaKey) : message.mediaKey;
            if (message.mediaKeyTimestamp != null && message.hasOwnProperty("mediaKeyTimestamp"))
                if (typeof message.mediaKeyTimestamp === "number")
                    object.mediaKeyTimestamp = options.longs === String ? String(message.mediaKeyTimestamp) : message.mediaKeyTimestamp;
                else
                    object.mediaKeyTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.mediaKeyTimestamp) : options.longs === Number ? new $util.LongBits(message.mediaKeyTimestamp.low >>> 0, message.mediaKeyTimestamp.high >>> 0).toNumber() : message.mediaKeyTimestamp;
            if (message.thumbnailHeight != null && message.hasOwnProperty("thumbnailHeight"))
                object.thumbnailHeight = message.thumbnailHeight;
            if (message.thumbnailWidth != null && message.hasOwnProperty("thumbnailWidth"))
                object.thumbnailWidth = message.thumbnailWidth;
            if (message.inviteLinkGroupType != null && message.hasOwnProperty("inviteLinkGroupType"))
                object.inviteLinkGroupType = options.enums === String ? $root.proto.ExtendedTextMessage.ExtendedTextMessageInviteLinkGroupType[message.inviteLinkGroupType] : message.inviteLinkGroupType;
            return object;
        };

        /**
         * Converts this ExtendedTextMessage to JSON.
         * @function toJSON
         * @memberof proto.ExtendedTextMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ExtendedTextMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * ExtendedTextMessageFontType enum.
         * @name proto.ExtendedTextMessage.ExtendedTextMessageFontType
         * @enum {number}
         * @property {number} SANS_SERIF=0 SANS_SERIF value
         * @property {number} SERIF=1 SERIF value
         * @property {number} NORICAN_REGULAR=2 NORICAN_REGULAR value
         * @property {number} BRYNDAN_WRITE=3 BRYNDAN_WRITE value
         * @property {number} BEBASNEUE_REGULAR=4 BEBASNEUE_REGULAR value
         * @property {number} OSWALD_HEAVY=5 OSWALD_HEAVY value
         */
        ExtendedTextMessage.ExtendedTextMessageFontType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "SANS_SERIF"] = 0;
            values[valuesById[1] = "SERIF"] = 1;
            values[valuesById[2] = "NORICAN_REGULAR"] = 2;
            values[valuesById[3] = "BRYNDAN_WRITE"] = 3;
            values[valuesById[4] = "BEBASNEUE_REGULAR"] = 4;
            values[valuesById[5] = "OSWALD_HEAVY"] = 5;
            return values;
        })();

        /**
         * ExtendedTextMessagePreviewType enum.
         * @name proto.ExtendedTextMessage.ExtendedTextMessagePreviewType
         * @enum {number}
         * @property {number} NONE=0 NONE value
         * @property {number} VIDEO=1 VIDEO value
         */
        ExtendedTextMessage.ExtendedTextMessagePreviewType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "NONE"] = 0;
            values[valuesById[1] = "VIDEO"] = 1;
            return values;
        })();

        /**
         * ExtendedTextMessageInviteLinkGroupType enum.
         * @name proto.ExtendedTextMessage.ExtendedTextMessageInviteLinkGroupType
         * @enum {number}
         * @property {number} DEFAULT=0 DEFAULT value
         * @property {number} PARENT=1 PARENT value
         */
        ExtendedTextMessage.ExtendedTextMessageInviteLinkGroupType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "DEFAULT"] = 0;
            values[valuesById[1] = "PARENT"] = 1;
            return values;
        })();

        return ExtendedTextMessage;
    })();

    proto.DocumentMessage = (function() {

        /**
         * Properties of a DocumentMessage.
         * @memberof proto
         * @interface IDocumentMessage
         * @property {string|null} [url] DocumentMessage url
         * @property {string|null} [mimetype] DocumentMessage mimetype
         * @property {string|null} [title] DocumentMessage title
         * @property {Uint8Array|null} [fileSha256] DocumentMessage fileSha256
         * @property {number|Long|null} [fileLength] DocumentMessage fileLength
         * @property {number|null} [pageCount] DocumentMessage pageCount
         * @property {Uint8Array|null} [mediaKey] DocumentMessage mediaKey
         * @property {string|null} [fileName] DocumentMessage fileName
         * @property {Uint8Array|null} [fileEncSha256] DocumentMessage fileEncSha256
         * @property {string|null} [directPath] DocumentMessage directPath
         * @property {number|Long|null} [mediaKeyTimestamp] DocumentMessage mediaKeyTimestamp
         * @property {boolean|null} [contactVcard] DocumentMessage contactVcard
         * @property {string|null} [thumbnailDirectPath] DocumentMessage thumbnailDirectPath
         * @property {Uint8Array|null} [thumbnailSha256] DocumentMessage thumbnailSha256
         * @property {Uint8Array|null} [thumbnailEncSha256] DocumentMessage thumbnailEncSha256
         * @property {Uint8Array|null} [jpegThumbnail] DocumentMessage jpegThumbnail
         * @property {proto.IContextInfo|null} [contextInfo] DocumentMessage contextInfo
         * @property {number|null} [thumbnailHeight] DocumentMessage thumbnailHeight
         * @property {number|null} [thumbnailWidth] DocumentMessage thumbnailWidth
         */

        /**
         * Constructs a new DocumentMessage.
         * @memberof proto
         * @classdesc Represents a DocumentMessage.
         * @implements IDocumentMessage
         * @constructor
         * @param {proto.IDocumentMessage=} [properties] Properties to set
         */
        function DocumentMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * DocumentMessage url.
         * @member {string} url
         * @memberof proto.DocumentMessage
         * @instance
         */
        DocumentMessage.prototype.url = "";

        /**
         * DocumentMessage mimetype.
         * @member {string} mimetype
         * @memberof proto.DocumentMessage
         * @instance
         */
        DocumentMessage.prototype.mimetype = "";

        /**
         * DocumentMessage title.
         * @member {string} title
         * @memberof proto.DocumentMessage
         * @instance
         */
        DocumentMessage.prototype.title = "";

        /**
         * DocumentMessage fileSha256.
         * @member {Uint8Array} fileSha256
         * @memberof proto.DocumentMessage
         * @instance
         */
        DocumentMessage.prototype.fileSha256 = $util.newBuffer([]);

        /**
         * DocumentMessage fileLength.
         * @member {number|Long} fileLength
         * @memberof proto.DocumentMessage
         * @instance
         */
        DocumentMessage.prototype.fileLength = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * DocumentMessage pageCount.
         * @member {number} pageCount
         * @memberof proto.DocumentMessage
         * @instance
         */
        DocumentMessage.prototype.pageCount = 0;

        /**
         * DocumentMessage mediaKey.
         * @member {Uint8Array} mediaKey
         * @memberof proto.DocumentMessage
         * @instance
         */
        DocumentMessage.prototype.mediaKey = $util.newBuffer([]);

        /**
         * DocumentMessage fileName.
         * @member {string} fileName
         * @memberof proto.DocumentMessage
         * @instance
         */
        DocumentMessage.prototype.fileName = "";

        /**
         * DocumentMessage fileEncSha256.
         * @member {Uint8Array} fileEncSha256
         * @memberof proto.DocumentMessage
         * @instance
         */
        DocumentMessage.prototype.fileEncSha256 = $util.newBuffer([]);

        /**
         * DocumentMessage directPath.
         * @member {string} directPath
         * @memberof proto.DocumentMessage
         * @instance
         */
        DocumentMessage.prototype.directPath = "";

        /**
         * DocumentMessage mediaKeyTimestamp.
         * @member {number|Long} mediaKeyTimestamp
         * @memberof proto.DocumentMessage
         * @instance
         */
        DocumentMessage.prototype.mediaKeyTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * DocumentMessage contactVcard.
         * @member {boolean} contactVcard
         * @memberof proto.DocumentMessage
         * @instance
         */
        DocumentMessage.prototype.contactVcard = false;

        /**
         * DocumentMessage thumbnailDirectPath.
         * @member {string} thumbnailDirectPath
         * @memberof proto.DocumentMessage
         * @instance
         */
        DocumentMessage.prototype.thumbnailDirectPath = "";

        /**
         * DocumentMessage thumbnailSha256.
         * @member {Uint8Array} thumbnailSha256
         * @memberof proto.DocumentMessage
         * @instance
         */
        DocumentMessage.prototype.thumbnailSha256 = $util.newBuffer([]);

        /**
         * DocumentMessage thumbnailEncSha256.
         * @member {Uint8Array} thumbnailEncSha256
         * @memberof proto.DocumentMessage
         * @instance
         */
        DocumentMessage.prototype.thumbnailEncSha256 = $util.newBuffer([]);

        /**
         * DocumentMessage jpegThumbnail.
         * @member {Uint8Array} jpegThumbnail
         * @memberof proto.DocumentMessage
         * @instance
         */
        DocumentMessage.prototype.jpegThumbnail = $util.newBuffer([]);

        /**
         * DocumentMessage contextInfo.
         * @member {proto.IContextInfo|null|undefined} contextInfo
         * @memberof proto.DocumentMessage
         * @instance
         */
        DocumentMessage.prototype.contextInfo = null;

        /**
         * DocumentMessage thumbnailHeight.
         * @member {number} thumbnailHeight
         * @memberof proto.DocumentMessage
         * @instance
         */
        DocumentMessage.prototype.thumbnailHeight = 0;

        /**
         * DocumentMessage thumbnailWidth.
         * @member {number} thumbnailWidth
         * @memberof proto.DocumentMessage
         * @instance
         */
        DocumentMessage.prototype.thumbnailWidth = 0;

        /**
         * Creates a new DocumentMessage instance using the specified properties.
         * @function create
         * @memberof proto.DocumentMessage
         * @static
         * @param {proto.IDocumentMessage=} [properties] Properties to set
         * @returns {proto.DocumentMessage} DocumentMessage instance
         */
        DocumentMessage.create = function create(properties) {
            return new DocumentMessage(properties);
        };

        /**
         * Encodes the specified DocumentMessage message. Does not implicitly {@link proto.DocumentMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.DocumentMessage
         * @static
         * @param {proto.IDocumentMessage} message DocumentMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        DocumentMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.url != null && Object.hasOwnProperty.call(message, "url"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.url);
            if (message.mimetype != null && Object.hasOwnProperty.call(message, "mimetype"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.mimetype);
            if (message.title != null && Object.hasOwnProperty.call(message, "title"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.title);
            if (message.fileSha256 != null && Object.hasOwnProperty.call(message, "fileSha256"))
                writer.uint32(/* id 4, wireType 2 =*/34).bytes(message.fileSha256);
            if (message.fileLength != null && Object.hasOwnProperty.call(message, "fileLength"))
                writer.uint32(/* id 5, wireType 0 =*/40).uint64(message.fileLength);
            if (message.pageCount != null && Object.hasOwnProperty.call(message, "pageCount"))
                writer.uint32(/* id 6, wireType 0 =*/48).uint32(message.pageCount);
            if (message.mediaKey != null && Object.hasOwnProperty.call(message, "mediaKey"))
                writer.uint32(/* id 7, wireType 2 =*/58).bytes(message.mediaKey);
            if (message.fileName != null && Object.hasOwnProperty.call(message, "fileName"))
                writer.uint32(/* id 8, wireType 2 =*/66).string(message.fileName);
            if (message.fileEncSha256 != null && Object.hasOwnProperty.call(message, "fileEncSha256"))
                writer.uint32(/* id 9, wireType 2 =*/74).bytes(message.fileEncSha256);
            if (message.directPath != null && Object.hasOwnProperty.call(message, "directPath"))
                writer.uint32(/* id 10, wireType 2 =*/82).string(message.directPath);
            if (message.mediaKeyTimestamp != null && Object.hasOwnProperty.call(message, "mediaKeyTimestamp"))
                writer.uint32(/* id 11, wireType 0 =*/88).int64(message.mediaKeyTimestamp);
            if (message.contactVcard != null && Object.hasOwnProperty.call(message, "contactVcard"))
                writer.uint32(/* id 12, wireType 0 =*/96).bool(message.contactVcard);
            if (message.thumbnailDirectPath != null && Object.hasOwnProperty.call(message, "thumbnailDirectPath"))
                writer.uint32(/* id 13, wireType 2 =*/106).string(message.thumbnailDirectPath);
            if (message.thumbnailSha256 != null && Object.hasOwnProperty.call(message, "thumbnailSha256"))
                writer.uint32(/* id 14, wireType 2 =*/114).bytes(message.thumbnailSha256);
            if (message.thumbnailEncSha256 != null && Object.hasOwnProperty.call(message, "thumbnailEncSha256"))
                writer.uint32(/* id 15, wireType 2 =*/122).bytes(message.thumbnailEncSha256);
            if (message.jpegThumbnail != null && Object.hasOwnProperty.call(message, "jpegThumbnail"))
                writer.uint32(/* id 16, wireType 2 =*/130).bytes(message.jpegThumbnail);
            if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo"))
                $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 17, wireType 2 =*/138).fork()).ldelim();
            if (message.thumbnailHeight != null && Object.hasOwnProperty.call(message, "thumbnailHeight"))
                writer.uint32(/* id 18, wireType 0 =*/144).uint32(message.thumbnailHeight);
            if (message.thumbnailWidth != null && Object.hasOwnProperty.call(message, "thumbnailWidth"))
                writer.uint32(/* id 19, wireType 0 =*/152).uint32(message.thumbnailWidth);
            return writer;
        };

        /**
         * Encodes the specified DocumentMessage message, length delimited. Does not implicitly {@link proto.DocumentMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.DocumentMessage
         * @static
         * @param {proto.IDocumentMessage} message DocumentMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        DocumentMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a DocumentMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.DocumentMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.DocumentMessage} DocumentMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        DocumentMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.DocumentMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.url = reader.string();
                    break;
                case 2:
                    message.mimetype = reader.string();
                    break;
                case 3:
                    message.title = reader.string();
                    break;
                case 4:
                    message.fileSha256 = reader.bytes();
                    break;
                case 5:
                    message.fileLength = reader.uint64();
                    break;
                case 6:
                    message.pageCount = reader.uint32();
                    break;
                case 7:
                    message.mediaKey = reader.bytes();
                    break;
                case 8:
                    message.fileName = reader.string();
                    break;
                case 9:
                    message.fileEncSha256 = reader.bytes();
                    break;
                case 10:
                    message.directPath = reader.string();
                    break;
                case 11:
                    message.mediaKeyTimestamp = reader.int64();
                    break;
                case 12:
                    message.contactVcard = reader.bool();
                    break;
                case 13:
                    message.thumbnailDirectPath = reader.string();
                    break;
                case 14:
                    message.thumbnailSha256 = reader.bytes();
                    break;
                case 15:
                    message.thumbnailEncSha256 = reader.bytes();
                    break;
                case 16:
                    message.jpegThumbnail = reader.bytes();
                    break;
                case 17:
                    message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32());
                    break;
                case 18:
                    message.thumbnailHeight = reader.uint32();
                    break;
                case 19:
                    message.thumbnailWidth = reader.uint32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a DocumentMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.DocumentMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.DocumentMessage} DocumentMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        DocumentMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a DocumentMessage message.
         * @function verify
         * @memberof proto.DocumentMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        DocumentMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.url != null && message.hasOwnProperty("url"))
                if (!$util.isString(message.url))
                    return "url: string expected";
            if (message.mimetype != null && message.hasOwnProperty("mimetype"))
                if (!$util.isString(message.mimetype))
                    return "mimetype: string expected";
            if (message.title != null && message.hasOwnProperty("title"))
                if (!$util.isString(message.title))
                    return "title: string expected";
            if (message.fileSha256 != null && message.hasOwnProperty("fileSha256"))
                if (!(message.fileSha256 && typeof message.fileSha256.length === "number" || $util.isString(message.fileSha256)))
                    return "fileSha256: buffer expected";
            if (message.fileLength != null && message.hasOwnProperty("fileLength"))
                if (!$util.isInteger(message.fileLength) && !(message.fileLength && $util.isInteger(message.fileLength.low) && $util.isInteger(message.fileLength.high)))
                    return "fileLength: integer|Long expected";
            if (message.pageCount != null && message.hasOwnProperty("pageCount"))
                if (!$util.isInteger(message.pageCount))
                    return "pageCount: integer expected";
            if (message.mediaKey != null && message.hasOwnProperty("mediaKey"))
                if (!(message.mediaKey && typeof message.mediaKey.length === "number" || $util.isString(message.mediaKey)))
                    return "mediaKey: buffer expected";
            if (message.fileName != null && message.hasOwnProperty("fileName"))
                if (!$util.isString(message.fileName))
                    return "fileName: string expected";
            if (message.fileEncSha256 != null && message.hasOwnProperty("fileEncSha256"))
                if (!(message.fileEncSha256 && typeof message.fileEncSha256.length === "number" || $util.isString(message.fileEncSha256)))
                    return "fileEncSha256: buffer expected";
            if (message.directPath != null && message.hasOwnProperty("directPath"))
                if (!$util.isString(message.directPath))
                    return "directPath: string expected";
            if (message.mediaKeyTimestamp != null && message.hasOwnProperty("mediaKeyTimestamp"))
                if (!$util.isInteger(message.mediaKeyTimestamp) && !(message.mediaKeyTimestamp && $util.isInteger(message.mediaKeyTimestamp.low) && $util.isInteger(message.mediaKeyTimestamp.high)))
                    return "mediaKeyTimestamp: integer|Long expected";
            if (message.contactVcard != null && message.hasOwnProperty("contactVcard"))
                if (typeof message.contactVcard !== "boolean")
                    return "contactVcard: boolean expected";
            if (message.thumbnailDirectPath != null && message.hasOwnProperty("thumbnailDirectPath"))
                if (!$util.isString(message.thumbnailDirectPath))
                    return "thumbnailDirectPath: string expected";
            if (message.thumbnailSha256 != null && message.hasOwnProperty("thumbnailSha256"))
                if (!(message.thumbnailSha256 && typeof message.thumbnailSha256.length === "number" || $util.isString(message.thumbnailSha256)))
                    return "thumbnailSha256: buffer expected";
            if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256"))
                if (!(message.thumbnailEncSha256 && typeof message.thumbnailEncSha256.length === "number" || $util.isString(message.thumbnailEncSha256)))
                    return "thumbnailEncSha256: buffer expected";
            if (message.jpegThumbnail != null && message.hasOwnProperty("jpegThumbnail"))
                if (!(message.jpegThumbnail && typeof message.jpegThumbnail.length === "number" || $util.isString(message.jpegThumbnail)))
                    return "jpegThumbnail: buffer expected";
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) {
                var error = $root.proto.ContextInfo.verify(message.contextInfo);
                if (error)
                    return "contextInfo." + error;
            }
            if (message.thumbnailHeight != null && message.hasOwnProperty("thumbnailHeight"))
                if (!$util.isInteger(message.thumbnailHeight))
                    return "thumbnailHeight: integer expected";
            if (message.thumbnailWidth != null && message.hasOwnProperty("thumbnailWidth"))
                if (!$util.isInteger(message.thumbnailWidth))
                    return "thumbnailWidth: integer expected";
            return null;
        };

        /**
         * Creates a DocumentMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.DocumentMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.DocumentMessage} DocumentMessage
         */
        DocumentMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.DocumentMessage)
                return object;
            var message = new $root.proto.DocumentMessage();
            if (object.url != null)
                message.url = String(object.url);
            if (object.mimetype != null)
                message.mimetype = String(object.mimetype);
            if (object.title != null)
                message.title = String(object.title);
            if (object.fileSha256 != null)
                if (typeof object.fileSha256 === "string")
                    $util.base64.decode(object.fileSha256, message.fileSha256 = $util.newBuffer($util.base64.length(object.fileSha256)), 0);
                else if (object.fileSha256.length)
                    message.fileSha256 = object.fileSha256;
            if (object.fileLength != null)
                if ($util.Long)
                    (message.fileLength = $util.Long.fromValue(object.fileLength)).unsigned = true;
                else if (typeof object.fileLength === "string")
                    message.fileLength = parseInt(object.fileLength, 10);
                else if (typeof object.fileLength === "number")
                    message.fileLength = object.fileLength;
                else if (typeof object.fileLength === "object")
                    message.fileLength = new $util.LongBits(object.fileLength.low >>> 0, object.fileLength.high >>> 0).toNumber(true);
            if (object.pageCount != null)
                message.pageCount = object.pageCount >>> 0;
            if (object.mediaKey != null)
                if (typeof object.mediaKey === "string")
                    $util.base64.decode(object.mediaKey, message.mediaKey = $util.newBuffer($util.base64.length(object.mediaKey)), 0);
                else if (object.mediaKey.length)
                    message.mediaKey = object.mediaKey;
            if (object.fileName != null)
                message.fileName = String(object.fileName);
            if (object.fileEncSha256 != null)
                if (typeof object.fileEncSha256 === "string")
                    $util.base64.decode(object.fileEncSha256, message.fileEncSha256 = $util.newBuffer($util.base64.length(object.fileEncSha256)), 0);
                else if (object.fileEncSha256.length)
                    message.fileEncSha256 = object.fileEncSha256;
            if (object.directPath != null)
                message.directPath = String(object.directPath);
            if (object.mediaKeyTimestamp != null)
                if ($util.Long)
                    (message.mediaKeyTimestamp = $util.Long.fromValue(object.mediaKeyTimestamp)).unsigned = false;
                else if (typeof object.mediaKeyTimestamp === "string")
                    message.mediaKeyTimestamp = parseInt(object.mediaKeyTimestamp, 10);
                else if (typeof object.mediaKeyTimestamp === "number")
                    message.mediaKeyTimestamp = object.mediaKeyTimestamp;
                else if (typeof object.mediaKeyTimestamp === "object")
                    message.mediaKeyTimestamp = new $util.LongBits(object.mediaKeyTimestamp.low >>> 0, object.mediaKeyTimestamp.high >>> 0).toNumber();
            if (object.contactVcard != null)
                message.contactVcard = Boolean(object.contactVcard);
            if (object.thumbnailDirectPath != null)
                message.thumbnailDirectPath = String(object.thumbnailDirectPath);
            if (object.thumbnailSha256 != null)
                if (typeof object.thumbnailSha256 === "string")
                    $util.base64.decode(object.thumbnailSha256, message.thumbnailSha256 = $util.newBuffer($util.base64.length(object.thumbnailSha256)), 0);
                else if (object.thumbnailSha256.length)
                    message.thumbnailSha256 = object.thumbnailSha256;
            if (object.thumbnailEncSha256 != null)
                if (typeof object.thumbnailEncSha256 === "string")
                    $util.base64.decode(object.thumbnailEncSha256, message.thumbnailEncSha256 = $util.newBuffer($util.base64.length(object.thumbnailEncSha256)), 0);
                else if (object.thumbnailEncSha256.length)
                    message.thumbnailEncSha256 = object.thumbnailEncSha256;
            if (object.jpegThumbnail != null)
                if (typeof object.jpegThumbnail === "string")
                    $util.base64.decode(object.jpegThumbnail, message.jpegThumbnail = $util.newBuffer($util.base64.length(object.jpegThumbnail)), 0);
                else if (object.jpegThumbnail.length)
                    message.jpegThumbnail = object.jpegThumbnail;
            if (object.contextInfo != null) {
                if (typeof object.contextInfo !== "object")
                    throw TypeError(".proto.DocumentMessage.contextInfo: object expected");
                message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo);
            }
            if (object.thumbnailHeight != null)
                message.thumbnailHeight = object.thumbnailHeight >>> 0;
            if (object.thumbnailWidth != null)
                message.thumbnailWidth = object.thumbnailWidth >>> 0;
            return message;
        };

        /**
         * Creates a plain object from a DocumentMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.DocumentMessage
         * @static
         * @param {proto.DocumentMessage} message DocumentMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        DocumentMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.url = "";
                object.mimetype = "";
                object.title = "";
                if (options.bytes === String)
                    object.fileSha256 = "";
                else {
                    object.fileSha256 = [];
                    if (options.bytes !== Array)
                        object.fileSha256 = $util.newBuffer(object.fileSha256);
                }
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.fileLength = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.fileLength = options.longs === String ? "0" : 0;
                object.pageCount = 0;
                if (options.bytes === String)
                    object.mediaKey = "";
                else {
                    object.mediaKey = [];
                    if (options.bytes !== Array)
                        object.mediaKey = $util.newBuffer(object.mediaKey);
                }
                object.fileName = "";
                if (options.bytes === String)
                    object.fileEncSha256 = "";
                else {
                    object.fileEncSha256 = [];
                    if (options.bytes !== Array)
                        object.fileEncSha256 = $util.newBuffer(object.fileEncSha256);
                }
                object.directPath = "";
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.mediaKeyTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.mediaKeyTimestamp = options.longs === String ? "0" : 0;
                object.contactVcard = false;
                object.thumbnailDirectPath = "";
                if (options.bytes === String)
                    object.thumbnailSha256 = "";
                else {
                    object.thumbnailSha256 = [];
                    if (options.bytes !== Array)
                        object.thumbnailSha256 = $util.newBuffer(object.thumbnailSha256);
                }
                if (options.bytes === String)
                    object.thumbnailEncSha256 = "";
                else {
                    object.thumbnailEncSha256 = [];
                    if (options.bytes !== Array)
                        object.thumbnailEncSha256 = $util.newBuffer(object.thumbnailEncSha256);
                }
                if (options.bytes === String)
                    object.jpegThumbnail = "";
                else {
                    object.jpegThumbnail = [];
                    if (options.bytes !== Array)
                        object.jpegThumbnail = $util.newBuffer(object.jpegThumbnail);
                }
                object.contextInfo = null;
                object.thumbnailHeight = 0;
                object.thumbnailWidth = 0;
            }
            if (message.url != null && message.hasOwnProperty("url"))
                object.url = message.url;
            if (message.mimetype != null && message.hasOwnProperty("mimetype"))
                object.mimetype = message.mimetype;
            if (message.title != null && message.hasOwnProperty("title"))
                object.title = message.title;
            if (message.fileSha256 != null && message.hasOwnProperty("fileSha256"))
                object.fileSha256 = options.bytes === String ? $util.base64.encode(message.fileSha256, 0, message.fileSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.fileSha256) : message.fileSha256;
            if (message.fileLength != null && message.hasOwnProperty("fileLength"))
                if (typeof message.fileLength === "number")
                    object.fileLength = options.longs === String ? String(message.fileLength) : message.fileLength;
                else
                    object.fileLength = options.longs === String ? $util.Long.prototype.toString.call(message.fileLength) : options.longs === Number ? new $util.LongBits(message.fileLength.low >>> 0, message.fileLength.high >>> 0).toNumber(true) : message.fileLength;
            if (message.pageCount != null && message.hasOwnProperty("pageCount"))
                object.pageCount = message.pageCount;
            if (message.mediaKey != null && message.hasOwnProperty("mediaKey"))
                object.mediaKey = options.bytes === String ? $util.base64.encode(message.mediaKey, 0, message.mediaKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.mediaKey) : message.mediaKey;
            if (message.fileName != null && message.hasOwnProperty("fileName"))
                object.fileName = message.fileName;
            if (message.fileEncSha256 != null && message.hasOwnProperty("fileEncSha256"))
                object.fileEncSha256 = options.bytes === String ? $util.base64.encode(message.fileEncSha256, 0, message.fileEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.fileEncSha256) : message.fileEncSha256;
            if (message.directPath != null && message.hasOwnProperty("directPath"))
                object.directPath = message.directPath;
            if (message.mediaKeyTimestamp != null && message.hasOwnProperty("mediaKeyTimestamp"))
                if (typeof message.mediaKeyTimestamp === "number")
                    object.mediaKeyTimestamp = options.longs === String ? String(message.mediaKeyTimestamp) : message.mediaKeyTimestamp;
                else
                    object.mediaKeyTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.mediaKeyTimestamp) : options.longs === Number ? new $util.LongBits(message.mediaKeyTimestamp.low >>> 0, message.mediaKeyTimestamp.high >>> 0).toNumber() : message.mediaKeyTimestamp;
            if (message.contactVcard != null && message.hasOwnProperty("contactVcard"))
                object.contactVcard = message.contactVcard;
            if (message.thumbnailDirectPath != null && message.hasOwnProperty("thumbnailDirectPath"))
                object.thumbnailDirectPath = message.thumbnailDirectPath;
            if (message.thumbnailSha256 != null && message.hasOwnProperty("thumbnailSha256"))
                object.thumbnailSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailSha256, 0, message.thumbnailSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailSha256) : message.thumbnailSha256;
            if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256"))
                object.thumbnailEncSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailEncSha256, 0, message.thumbnailEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailEncSha256) : message.thumbnailEncSha256;
            if (message.jpegThumbnail != null && message.hasOwnProperty("jpegThumbnail"))
                object.jpegThumbnail = options.bytes === String ? $util.base64.encode(message.jpegThumbnail, 0, message.jpegThumbnail.length) : options.bytes === Array ? Array.prototype.slice.call(message.jpegThumbnail) : message.jpegThumbnail;
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo"))
                object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options);
            if (message.thumbnailHeight != null && message.hasOwnProperty("thumbnailHeight"))
                object.thumbnailHeight = message.thumbnailHeight;
            if (message.thumbnailWidth != null && message.hasOwnProperty("thumbnailWidth"))
                object.thumbnailWidth = message.thumbnailWidth;
            return object;
        };

        /**
         * Converts this DocumentMessage to JSON.
         * @function toJSON
         * @memberof proto.DocumentMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        DocumentMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return DocumentMessage;
    })();

    proto.AudioMessage = (function() {

        /**
         * Properties of an AudioMessage.
         * @memberof proto
         * @interface IAudioMessage
         * @property {string|null} [url] AudioMessage url
         * @property {string|null} [mimetype] AudioMessage mimetype
         * @property {Uint8Array|null} [fileSha256] AudioMessage fileSha256
         * @property {number|Long|null} [fileLength] AudioMessage fileLength
         * @property {number|null} [seconds] AudioMessage seconds
         * @property {boolean|null} [ptt] AudioMessage ptt
         * @property {Uint8Array|null} [mediaKey] AudioMessage mediaKey
         * @property {Uint8Array|null} [fileEncSha256] AudioMessage fileEncSha256
         * @property {string|null} [directPath] AudioMessage directPath
         * @property {number|Long|null} [mediaKeyTimestamp] AudioMessage mediaKeyTimestamp
         * @property {proto.IContextInfo|null} [contextInfo] AudioMessage contextInfo
         * @property {Uint8Array|null} [streamingSidecar] AudioMessage streamingSidecar
         * @property {Uint8Array|null} [waveform] AudioMessage waveform
         */

        /**
         * Constructs a new AudioMessage.
         * @memberof proto
         * @classdesc Represents an AudioMessage.
         * @implements IAudioMessage
         * @constructor
         * @param {proto.IAudioMessage=} [properties] Properties to set
         */
        function AudioMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * AudioMessage url.
         * @member {string} url
         * @memberof proto.AudioMessage
         * @instance
         */
        AudioMessage.prototype.url = "";

        /**
         * AudioMessage mimetype.
         * @member {string} mimetype
         * @memberof proto.AudioMessage
         * @instance
         */
        AudioMessage.prototype.mimetype = "";

        /**
         * AudioMessage fileSha256.
         * @member {Uint8Array} fileSha256
         * @memberof proto.AudioMessage
         * @instance
         */
        AudioMessage.prototype.fileSha256 = $util.newBuffer([]);

        /**
         * AudioMessage fileLength.
         * @member {number|Long} fileLength
         * @memberof proto.AudioMessage
         * @instance
         */
        AudioMessage.prototype.fileLength = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * AudioMessage seconds.
         * @member {number} seconds
         * @memberof proto.AudioMessage
         * @instance
         */
        AudioMessage.prototype.seconds = 0;

        /**
         * AudioMessage ptt.
         * @member {boolean} ptt
         * @memberof proto.AudioMessage
         * @instance
         */
        AudioMessage.prototype.ptt = false;

        /**
         * AudioMessage mediaKey.
         * @member {Uint8Array} mediaKey
         * @memberof proto.AudioMessage
         * @instance
         */
        AudioMessage.prototype.mediaKey = $util.newBuffer([]);

        /**
         * AudioMessage fileEncSha256.
         * @member {Uint8Array} fileEncSha256
         * @memberof proto.AudioMessage
         * @instance
         */
        AudioMessage.prototype.fileEncSha256 = $util.newBuffer([]);

        /**
         * AudioMessage directPath.
         * @member {string} directPath
         * @memberof proto.AudioMessage
         * @instance
         */
        AudioMessage.prototype.directPath = "";

        /**
         * AudioMessage mediaKeyTimestamp.
         * @member {number|Long} mediaKeyTimestamp
         * @memberof proto.AudioMessage
         * @instance
         */
        AudioMessage.prototype.mediaKeyTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * AudioMessage contextInfo.
         * @member {proto.IContextInfo|null|undefined} contextInfo
         * @memberof proto.AudioMessage
         * @instance
         */
        AudioMessage.prototype.contextInfo = null;

        /**
         * AudioMessage streamingSidecar.
         * @member {Uint8Array} streamingSidecar
         * @memberof proto.AudioMessage
         * @instance
         */
        AudioMessage.prototype.streamingSidecar = $util.newBuffer([]);

        /**
         * AudioMessage waveform.
         * @member {Uint8Array} waveform
         * @memberof proto.AudioMessage
         * @instance
         */
        AudioMessage.prototype.waveform = $util.newBuffer([]);

        /**
         * Creates a new AudioMessage instance using the specified properties.
         * @function create
         * @memberof proto.AudioMessage
         * @static
         * @param {proto.IAudioMessage=} [properties] Properties to set
         * @returns {proto.AudioMessage} AudioMessage instance
         */
        AudioMessage.create = function create(properties) {
            return new AudioMessage(properties);
        };

        /**
         * Encodes the specified AudioMessage message. Does not implicitly {@link proto.AudioMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.AudioMessage
         * @static
         * @param {proto.IAudioMessage} message AudioMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AudioMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.url != null && Object.hasOwnProperty.call(message, "url"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.url);
            if (message.mimetype != null && Object.hasOwnProperty.call(message, "mimetype"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.mimetype);
            if (message.fileSha256 != null && Object.hasOwnProperty.call(message, "fileSha256"))
                writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.fileSha256);
            if (message.fileLength != null && Object.hasOwnProperty.call(message, "fileLength"))
                writer.uint32(/* id 4, wireType 0 =*/32).uint64(message.fileLength);
            if (message.seconds != null && Object.hasOwnProperty.call(message, "seconds"))
                writer.uint32(/* id 5, wireType 0 =*/40).uint32(message.seconds);
            if (message.ptt != null && Object.hasOwnProperty.call(message, "ptt"))
                writer.uint32(/* id 6, wireType 0 =*/48).bool(message.ptt);
            if (message.mediaKey != null && Object.hasOwnProperty.call(message, "mediaKey"))
                writer.uint32(/* id 7, wireType 2 =*/58).bytes(message.mediaKey);
            if (message.fileEncSha256 != null && Object.hasOwnProperty.call(message, "fileEncSha256"))
                writer.uint32(/* id 8, wireType 2 =*/66).bytes(message.fileEncSha256);
            if (message.directPath != null && Object.hasOwnProperty.call(message, "directPath"))
                writer.uint32(/* id 9, wireType 2 =*/74).string(message.directPath);
            if (message.mediaKeyTimestamp != null && Object.hasOwnProperty.call(message, "mediaKeyTimestamp"))
                writer.uint32(/* id 10, wireType 0 =*/80).int64(message.mediaKeyTimestamp);
            if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo"))
                $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 17, wireType 2 =*/138).fork()).ldelim();
            if (message.streamingSidecar != null && Object.hasOwnProperty.call(message, "streamingSidecar"))
                writer.uint32(/* id 18, wireType 2 =*/146).bytes(message.streamingSidecar);
            if (message.waveform != null && Object.hasOwnProperty.call(message, "waveform"))
                writer.uint32(/* id 19, wireType 2 =*/154).bytes(message.waveform);
            return writer;
        };

        /**
         * Encodes the specified AudioMessage message, length delimited. Does not implicitly {@link proto.AudioMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.AudioMessage
         * @static
         * @param {proto.IAudioMessage} message AudioMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AudioMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an AudioMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.AudioMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.AudioMessage} AudioMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AudioMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.AudioMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.url = reader.string();
                    break;
                case 2:
                    message.mimetype = reader.string();
                    break;
                case 3:
                    message.fileSha256 = reader.bytes();
                    break;
                case 4:
                    message.fileLength = reader.uint64();
                    break;
                case 5:
                    message.seconds = reader.uint32();
                    break;
                case 6:
                    message.ptt = reader.bool();
                    break;
                case 7:
                    message.mediaKey = reader.bytes();
                    break;
                case 8:
                    message.fileEncSha256 = reader.bytes();
                    break;
                case 9:
                    message.directPath = reader.string();
                    break;
                case 10:
                    message.mediaKeyTimestamp = reader.int64();
                    break;
                case 17:
                    message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32());
                    break;
                case 18:
                    message.streamingSidecar = reader.bytes();
                    break;
                case 19:
                    message.waveform = reader.bytes();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an AudioMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.AudioMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.AudioMessage} AudioMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AudioMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an AudioMessage message.
         * @function verify
         * @memberof proto.AudioMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        AudioMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.url != null && message.hasOwnProperty("url"))
                if (!$util.isString(message.url))
                    return "url: string expected";
            if (message.mimetype != null && message.hasOwnProperty("mimetype"))
                if (!$util.isString(message.mimetype))
                    return "mimetype: string expected";
            if (message.fileSha256 != null && message.hasOwnProperty("fileSha256"))
                if (!(message.fileSha256 && typeof message.fileSha256.length === "number" || $util.isString(message.fileSha256)))
                    return "fileSha256: buffer expected";
            if (message.fileLength != null && message.hasOwnProperty("fileLength"))
                if (!$util.isInteger(message.fileLength) && !(message.fileLength && $util.isInteger(message.fileLength.low) && $util.isInteger(message.fileLength.high)))
                    return "fileLength: integer|Long expected";
            if (message.seconds != null && message.hasOwnProperty("seconds"))
                if (!$util.isInteger(message.seconds))
                    return "seconds: integer expected";
            if (message.ptt != null && message.hasOwnProperty("ptt"))
                if (typeof message.ptt !== "boolean")
                    return "ptt: boolean expected";
            if (message.mediaKey != null && message.hasOwnProperty("mediaKey"))
                if (!(message.mediaKey && typeof message.mediaKey.length === "number" || $util.isString(message.mediaKey)))
                    return "mediaKey: buffer expected";
            if (message.fileEncSha256 != null && message.hasOwnProperty("fileEncSha256"))
                if (!(message.fileEncSha256 && typeof message.fileEncSha256.length === "number" || $util.isString(message.fileEncSha256)))
                    return "fileEncSha256: buffer expected";
            if (message.directPath != null && message.hasOwnProperty("directPath"))
                if (!$util.isString(message.directPath))
                    return "directPath: string expected";
            if (message.mediaKeyTimestamp != null && message.hasOwnProperty("mediaKeyTimestamp"))
                if (!$util.isInteger(message.mediaKeyTimestamp) && !(message.mediaKeyTimestamp && $util.isInteger(message.mediaKeyTimestamp.low) && $util.isInteger(message.mediaKeyTimestamp.high)))
                    return "mediaKeyTimestamp: integer|Long expected";
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) {
                var error = $root.proto.ContextInfo.verify(message.contextInfo);
                if (error)
                    return "contextInfo." + error;
            }
            if (message.streamingSidecar != null && message.hasOwnProperty("streamingSidecar"))
                if (!(message.streamingSidecar && typeof message.streamingSidecar.length === "number" || $util.isString(message.streamingSidecar)))
                    return "streamingSidecar: buffer expected";
            if (message.waveform != null && message.hasOwnProperty("waveform"))
                if (!(message.waveform && typeof message.waveform.length === "number" || $util.isString(message.waveform)))
                    return "waveform: buffer expected";
            return null;
        };

        /**
         * Creates an AudioMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.AudioMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.AudioMessage} AudioMessage
         */
        AudioMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.AudioMessage)
                return object;
            var message = new $root.proto.AudioMessage();
            if (object.url != null)
                message.url = String(object.url);
            if (object.mimetype != null)
                message.mimetype = String(object.mimetype);
            if (object.fileSha256 != null)
                if (typeof object.fileSha256 === "string")
                    $util.base64.decode(object.fileSha256, message.fileSha256 = $util.newBuffer($util.base64.length(object.fileSha256)), 0);
                else if (object.fileSha256.length)
                    message.fileSha256 = object.fileSha256;
            if (object.fileLength != null)
                if ($util.Long)
                    (message.fileLength = $util.Long.fromValue(object.fileLength)).unsigned = true;
                else if (typeof object.fileLength === "string")
                    message.fileLength = parseInt(object.fileLength, 10);
                else if (typeof object.fileLength === "number")
                    message.fileLength = object.fileLength;
                else if (typeof object.fileLength === "object")
                    message.fileLength = new $util.LongBits(object.fileLength.low >>> 0, object.fileLength.high >>> 0).toNumber(true);
            if (object.seconds != null)
                message.seconds = object.seconds >>> 0;
            if (object.ptt != null)
                message.ptt = Boolean(object.ptt);
            if (object.mediaKey != null)
                if (typeof object.mediaKey === "string")
                    $util.base64.decode(object.mediaKey, message.mediaKey = $util.newBuffer($util.base64.length(object.mediaKey)), 0);
                else if (object.mediaKey.length)
                    message.mediaKey = object.mediaKey;
            if (object.fileEncSha256 != null)
                if (typeof object.fileEncSha256 === "string")
                    $util.base64.decode(object.fileEncSha256, message.fileEncSha256 = $util.newBuffer($util.base64.length(object.fileEncSha256)), 0);
                else if (object.fileEncSha256.length)
                    message.fileEncSha256 = object.fileEncSha256;
            if (object.directPath != null)
                message.directPath = String(object.directPath);
            if (object.mediaKeyTimestamp != null)
                if ($util.Long)
                    (message.mediaKeyTimestamp = $util.Long.fromValue(object.mediaKeyTimestamp)).unsigned = false;
                else if (typeof object.mediaKeyTimestamp === "string")
                    message.mediaKeyTimestamp = parseInt(object.mediaKeyTimestamp, 10);
                else if (typeof object.mediaKeyTimestamp === "number")
                    message.mediaKeyTimestamp = object.mediaKeyTimestamp;
                else if (typeof object.mediaKeyTimestamp === "object")
                    message.mediaKeyTimestamp = new $util.LongBits(object.mediaKeyTimestamp.low >>> 0, object.mediaKeyTimestamp.high >>> 0).toNumber();
            if (object.contextInfo != null) {
                if (typeof object.contextInfo !== "object")
                    throw TypeError(".proto.AudioMessage.contextInfo: object expected");
                message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo);
            }
            if (object.streamingSidecar != null)
                if (typeof object.streamingSidecar === "string")
                    $util.base64.decode(object.streamingSidecar, message.streamingSidecar = $util.newBuffer($util.base64.length(object.streamingSidecar)), 0);
                else if (object.streamingSidecar.length)
                    message.streamingSidecar = object.streamingSidecar;
            if (object.waveform != null)
                if (typeof object.waveform === "string")
                    $util.base64.decode(object.waveform, message.waveform = $util.newBuffer($util.base64.length(object.waveform)), 0);
                else if (object.waveform.length)
                    message.waveform = object.waveform;
            return message;
        };

        /**
         * Creates a plain object from an AudioMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.AudioMessage
         * @static
         * @param {proto.AudioMessage} message AudioMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        AudioMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.url = "";
                object.mimetype = "";
                if (options.bytes === String)
                    object.fileSha256 = "";
                else {
                    object.fileSha256 = [];
                    if (options.bytes !== Array)
                        object.fileSha256 = $util.newBuffer(object.fileSha256);
                }
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.fileLength = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.fileLength = options.longs === String ? "0" : 0;
                object.seconds = 0;
                object.ptt = false;
                if (options.bytes === String)
                    object.mediaKey = "";
                else {
                    object.mediaKey = [];
                    if (options.bytes !== Array)
                        object.mediaKey = $util.newBuffer(object.mediaKey);
                }
                if (options.bytes === String)
                    object.fileEncSha256 = "";
                else {
                    object.fileEncSha256 = [];
                    if (options.bytes !== Array)
                        object.fileEncSha256 = $util.newBuffer(object.fileEncSha256);
                }
                object.directPath = "";
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.mediaKeyTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.mediaKeyTimestamp = options.longs === String ? "0" : 0;
                object.contextInfo = null;
                if (options.bytes === String)
                    object.streamingSidecar = "";
                else {
                    object.streamingSidecar = [];
                    if (options.bytes !== Array)
                        object.streamingSidecar = $util.newBuffer(object.streamingSidecar);
                }
                if (options.bytes === String)
                    object.waveform = "";
                else {
                    object.waveform = [];
                    if (options.bytes !== Array)
                        object.waveform = $util.newBuffer(object.waveform);
                }
            }
            if (message.url != null && message.hasOwnProperty("url"))
                object.url = message.url;
            if (message.mimetype != null && message.hasOwnProperty("mimetype"))
                object.mimetype = message.mimetype;
            if (message.fileSha256 != null && message.hasOwnProperty("fileSha256"))
                object.fileSha256 = options.bytes === String ? $util.base64.encode(message.fileSha256, 0, message.fileSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.fileSha256) : message.fileSha256;
            if (message.fileLength != null && message.hasOwnProperty("fileLength"))
                if (typeof message.fileLength === "number")
                    object.fileLength = options.longs === String ? String(message.fileLength) : message.fileLength;
                else
                    object.fileLength = options.longs === String ? $util.Long.prototype.toString.call(message.fileLength) : options.longs === Number ? new $util.LongBits(message.fileLength.low >>> 0, message.fileLength.high >>> 0).toNumber(true) : message.fileLength;
            if (message.seconds != null && message.hasOwnProperty("seconds"))
                object.seconds = message.seconds;
            if (message.ptt != null && message.hasOwnProperty("ptt"))
                object.ptt = message.ptt;
            if (message.mediaKey != null && message.hasOwnProperty("mediaKey"))
                object.mediaKey = options.bytes === String ? $util.base64.encode(message.mediaKey, 0, message.mediaKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.mediaKey) : message.mediaKey;
            if (message.fileEncSha256 != null && message.hasOwnProperty("fileEncSha256"))
                object.fileEncSha256 = options.bytes === String ? $util.base64.encode(message.fileEncSha256, 0, message.fileEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.fileEncSha256) : message.fileEncSha256;
            if (message.directPath != null && message.hasOwnProperty("directPath"))
                object.directPath = message.directPath;
            if (message.mediaKeyTimestamp != null && message.hasOwnProperty("mediaKeyTimestamp"))
                if (typeof message.mediaKeyTimestamp === "number")
                    object.mediaKeyTimestamp = options.longs === String ? String(message.mediaKeyTimestamp) : message.mediaKeyTimestamp;
                else
                    object.mediaKeyTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.mediaKeyTimestamp) : options.longs === Number ? new $util.LongBits(message.mediaKeyTimestamp.low >>> 0, message.mediaKeyTimestamp.high >>> 0).toNumber() : message.mediaKeyTimestamp;
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo"))
                object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options);
            if (message.streamingSidecar != null && message.hasOwnProperty("streamingSidecar"))
                object.streamingSidecar = options.bytes === String ? $util.base64.encode(message.streamingSidecar, 0, message.streamingSidecar.length) : options.bytes === Array ? Array.prototype.slice.call(message.streamingSidecar) : message.streamingSidecar;
            if (message.waveform != null && message.hasOwnProperty("waveform"))
                object.waveform = options.bytes === String ? $util.base64.encode(message.waveform, 0, message.waveform.length) : options.bytes === Array ? Array.prototype.slice.call(message.waveform) : message.waveform;
            return object;
        };

        /**
         * Converts this AudioMessage to JSON.
         * @function toJSON
         * @memberof proto.AudioMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        AudioMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return AudioMessage;
    })();

    proto.VideoMessage = (function() {

        /**
         * Properties of a VideoMessage.
         * @memberof proto
         * @interface IVideoMessage
         * @property {string|null} [url] VideoMessage url
         * @property {string|null} [mimetype] VideoMessage mimetype
         * @property {Uint8Array|null} [fileSha256] VideoMessage fileSha256
         * @property {number|Long|null} [fileLength] VideoMessage fileLength
         * @property {number|null} [seconds] VideoMessage seconds
         * @property {Uint8Array|null} [mediaKey] VideoMessage mediaKey
         * @property {string|null} [caption] VideoMessage caption
         * @property {boolean|null} [gifPlayback] VideoMessage gifPlayback
         * @property {number|null} [height] VideoMessage height
         * @property {number|null} [width] VideoMessage width
         * @property {Uint8Array|null} [fileEncSha256] VideoMessage fileEncSha256
         * @property {Array.<proto.IInteractiveAnnotation>|null} [interactiveAnnotations] VideoMessage interactiveAnnotations
         * @property {string|null} [directPath] VideoMessage directPath
         * @property {number|Long|null} [mediaKeyTimestamp] VideoMessage mediaKeyTimestamp
         * @property {Uint8Array|null} [jpegThumbnail] VideoMessage jpegThumbnail
         * @property {proto.IContextInfo|null} [contextInfo] VideoMessage contextInfo
         * @property {Uint8Array|null} [streamingSidecar] VideoMessage streamingSidecar
         * @property {proto.VideoMessage.VideoMessageAttribution|null} [gifAttribution] VideoMessage gifAttribution
         * @property {boolean|null} [viewOnce] VideoMessage viewOnce
         * @property {string|null} [thumbnailDirectPath] VideoMessage thumbnailDirectPath
         * @property {Uint8Array|null} [thumbnailSha256] VideoMessage thumbnailSha256
         * @property {Uint8Array|null} [thumbnailEncSha256] VideoMessage thumbnailEncSha256
         * @property {string|null} [staticUrl] VideoMessage staticUrl
         */

        /**
         * Constructs a new VideoMessage.
         * @memberof proto
         * @classdesc Represents a VideoMessage.
         * @implements IVideoMessage
         * @constructor
         * @param {proto.IVideoMessage=} [properties] Properties to set
         */
        function VideoMessage(properties) {
            this.interactiveAnnotations = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * VideoMessage url.
         * @member {string} url
         * @memberof proto.VideoMessage
         * @instance
         */
        VideoMessage.prototype.url = "";

        /**
         * VideoMessage mimetype.
         * @member {string} mimetype
         * @memberof proto.VideoMessage
         * @instance
         */
        VideoMessage.prototype.mimetype = "";

        /**
         * VideoMessage fileSha256.
         * @member {Uint8Array} fileSha256
         * @memberof proto.VideoMessage
         * @instance
         */
        VideoMessage.prototype.fileSha256 = $util.newBuffer([]);

        /**
         * VideoMessage fileLength.
         * @member {number|Long} fileLength
         * @memberof proto.VideoMessage
         * @instance
         */
        VideoMessage.prototype.fileLength = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * VideoMessage seconds.
         * @member {number} seconds
         * @memberof proto.VideoMessage
         * @instance
         */
        VideoMessage.prototype.seconds = 0;

        /**
         * VideoMessage mediaKey.
         * @member {Uint8Array} mediaKey
         * @memberof proto.VideoMessage
         * @instance
         */
        VideoMessage.prototype.mediaKey = $util.newBuffer([]);

        /**
         * VideoMessage caption.
         * @member {string} caption
         * @memberof proto.VideoMessage
         * @instance
         */
        VideoMessage.prototype.caption = "";

        /**
         * VideoMessage gifPlayback.
         * @member {boolean} gifPlayback
         * @memberof proto.VideoMessage
         * @instance
         */
        VideoMessage.prototype.gifPlayback = false;

        /**
         * VideoMessage height.
         * @member {number} height
         * @memberof proto.VideoMessage
         * @instance
         */
        VideoMessage.prototype.height = 0;

        /**
         * VideoMessage width.
         * @member {number} width
         * @memberof proto.VideoMessage
         * @instance
         */
        VideoMessage.prototype.width = 0;

        /**
         * VideoMessage fileEncSha256.
         * @member {Uint8Array} fileEncSha256
         * @memberof proto.VideoMessage
         * @instance
         */
        VideoMessage.prototype.fileEncSha256 = $util.newBuffer([]);

        /**
         * VideoMessage interactiveAnnotations.
         * @member {Array.<proto.IInteractiveAnnotation>} interactiveAnnotations
         * @memberof proto.VideoMessage
         * @instance
         */
        VideoMessage.prototype.interactiveAnnotations = $util.emptyArray;

        /**
         * VideoMessage directPath.
         * @member {string} directPath
         * @memberof proto.VideoMessage
         * @instance
         */
        VideoMessage.prototype.directPath = "";

        /**
         * VideoMessage mediaKeyTimestamp.
         * @member {number|Long} mediaKeyTimestamp
         * @memberof proto.VideoMessage
         * @instance
         */
        VideoMessage.prototype.mediaKeyTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * VideoMessage jpegThumbnail.
         * @member {Uint8Array} jpegThumbnail
         * @memberof proto.VideoMessage
         * @instance
         */
        VideoMessage.prototype.jpegThumbnail = $util.newBuffer([]);

        /**
         * VideoMessage contextInfo.
         * @member {proto.IContextInfo|null|undefined} contextInfo
         * @memberof proto.VideoMessage
         * @instance
         */
        VideoMessage.prototype.contextInfo = null;

        /**
         * VideoMessage streamingSidecar.
         * @member {Uint8Array} streamingSidecar
         * @memberof proto.VideoMessage
         * @instance
         */
        VideoMessage.prototype.streamingSidecar = $util.newBuffer([]);

        /**
         * VideoMessage gifAttribution.
         * @member {proto.VideoMessage.VideoMessageAttribution} gifAttribution
         * @memberof proto.VideoMessage
         * @instance
         */
        VideoMessage.prototype.gifAttribution = 0;

        /**
         * VideoMessage viewOnce.
         * @member {boolean} viewOnce
         * @memberof proto.VideoMessage
         * @instance
         */
        VideoMessage.prototype.viewOnce = false;

        /**
         * VideoMessage thumbnailDirectPath.
         * @member {string} thumbnailDirectPath
         * @memberof proto.VideoMessage
         * @instance
         */
        VideoMessage.prototype.thumbnailDirectPath = "";

        /**
         * VideoMessage thumbnailSha256.
         * @member {Uint8Array} thumbnailSha256
         * @memberof proto.VideoMessage
         * @instance
         */
        VideoMessage.prototype.thumbnailSha256 = $util.newBuffer([]);

        /**
         * VideoMessage thumbnailEncSha256.
         * @member {Uint8Array} thumbnailEncSha256
         * @memberof proto.VideoMessage
         * @instance
         */
        VideoMessage.prototype.thumbnailEncSha256 = $util.newBuffer([]);

        /**
         * VideoMessage staticUrl.
         * @member {string} staticUrl
         * @memberof proto.VideoMessage
         * @instance
         */
        VideoMessage.prototype.staticUrl = "";

        /**
         * Creates a new VideoMessage instance using the specified properties.
         * @function create
         * @memberof proto.VideoMessage
         * @static
         * @param {proto.IVideoMessage=} [properties] Properties to set
         * @returns {proto.VideoMessage} VideoMessage instance
         */
        VideoMessage.create = function create(properties) {
            return new VideoMessage(properties);
        };

        /**
         * Encodes the specified VideoMessage message. Does not implicitly {@link proto.VideoMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.VideoMessage
         * @static
         * @param {proto.IVideoMessage} message VideoMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        VideoMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.url != null && Object.hasOwnProperty.call(message, "url"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.url);
            if (message.mimetype != null && Object.hasOwnProperty.call(message, "mimetype"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.mimetype);
            if (message.fileSha256 != null && Object.hasOwnProperty.call(message, "fileSha256"))
                writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.fileSha256);
            if (message.fileLength != null && Object.hasOwnProperty.call(message, "fileLength"))
                writer.uint32(/* id 4, wireType 0 =*/32).uint64(message.fileLength);
            if (message.seconds != null && Object.hasOwnProperty.call(message, "seconds"))
                writer.uint32(/* id 5, wireType 0 =*/40).uint32(message.seconds);
            if (message.mediaKey != null && Object.hasOwnProperty.call(message, "mediaKey"))
                writer.uint32(/* id 6, wireType 2 =*/50).bytes(message.mediaKey);
            if (message.caption != null && Object.hasOwnProperty.call(message, "caption"))
                writer.uint32(/* id 7, wireType 2 =*/58).string(message.caption);
            if (message.gifPlayback != null && Object.hasOwnProperty.call(message, "gifPlayback"))
                writer.uint32(/* id 8, wireType 0 =*/64).bool(message.gifPlayback);
            if (message.height != null && Object.hasOwnProperty.call(message, "height"))
                writer.uint32(/* id 9, wireType 0 =*/72).uint32(message.height);
            if (message.width != null && Object.hasOwnProperty.call(message, "width"))
                writer.uint32(/* id 10, wireType 0 =*/80).uint32(message.width);
            if (message.fileEncSha256 != null && Object.hasOwnProperty.call(message, "fileEncSha256"))
                writer.uint32(/* id 11, wireType 2 =*/90).bytes(message.fileEncSha256);
            if (message.interactiveAnnotations != null && message.interactiveAnnotations.length)
                for (var i = 0; i < message.interactiveAnnotations.length; ++i)
                    $root.proto.InteractiveAnnotation.encode(message.interactiveAnnotations[i], writer.uint32(/* id 12, wireType 2 =*/98).fork()).ldelim();
            if (message.directPath != null && Object.hasOwnProperty.call(message, "directPath"))
                writer.uint32(/* id 13, wireType 2 =*/106).string(message.directPath);
            if (message.mediaKeyTimestamp != null && Object.hasOwnProperty.call(message, "mediaKeyTimestamp"))
                writer.uint32(/* id 14, wireType 0 =*/112).int64(message.mediaKeyTimestamp);
            if (message.jpegThumbnail != null && Object.hasOwnProperty.call(message, "jpegThumbnail"))
                writer.uint32(/* id 16, wireType 2 =*/130).bytes(message.jpegThumbnail);
            if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo"))
                $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 17, wireType 2 =*/138).fork()).ldelim();
            if (message.streamingSidecar != null && Object.hasOwnProperty.call(message, "streamingSidecar"))
                writer.uint32(/* id 18, wireType 2 =*/146).bytes(message.streamingSidecar);
            if (message.gifAttribution != null && Object.hasOwnProperty.call(message, "gifAttribution"))
                writer.uint32(/* id 19, wireType 0 =*/152).int32(message.gifAttribution);
            if (message.viewOnce != null && Object.hasOwnProperty.call(message, "viewOnce"))
                writer.uint32(/* id 20, wireType 0 =*/160).bool(message.viewOnce);
            if (message.thumbnailDirectPath != null && Object.hasOwnProperty.call(message, "thumbnailDirectPath"))
                writer.uint32(/* id 21, wireType 2 =*/170).string(message.thumbnailDirectPath);
            if (message.thumbnailSha256 != null && Object.hasOwnProperty.call(message, "thumbnailSha256"))
                writer.uint32(/* id 22, wireType 2 =*/178).bytes(message.thumbnailSha256);
            if (message.thumbnailEncSha256 != null && Object.hasOwnProperty.call(message, "thumbnailEncSha256"))
                writer.uint32(/* id 23, wireType 2 =*/186).bytes(message.thumbnailEncSha256);
            if (message.staticUrl != null && Object.hasOwnProperty.call(message, "staticUrl"))
                writer.uint32(/* id 24, wireType 2 =*/194).string(message.staticUrl);
            return writer;
        };

        /**
         * Encodes the specified VideoMessage message, length delimited. Does not implicitly {@link proto.VideoMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.VideoMessage
         * @static
         * @param {proto.IVideoMessage} message VideoMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        VideoMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a VideoMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.VideoMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.VideoMessage} VideoMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        VideoMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.VideoMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.url = reader.string();
                    break;
                case 2:
                    message.mimetype = reader.string();
                    break;
                case 3:
                    message.fileSha256 = reader.bytes();
                    break;
                case 4:
                    message.fileLength = reader.uint64();
                    break;
                case 5:
                    message.seconds = reader.uint32();
                    break;
                case 6:
                    message.mediaKey = reader.bytes();
                    break;
                case 7:
                    message.caption = reader.string();
                    break;
                case 8:
                    message.gifPlayback = reader.bool();
                    break;
                case 9:
                    message.height = reader.uint32();
                    break;
                case 10:
                    message.width = reader.uint32();
                    break;
                case 11:
                    message.fileEncSha256 = reader.bytes();
                    break;
                case 12:
                    if (!(message.interactiveAnnotations && message.interactiveAnnotations.length))
                        message.interactiveAnnotations = [];
                    message.interactiveAnnotations.push($root.proto.InteractiveAnnotation.decode(reader, reader.uint32()));
                    break;
                case 13:
                    message.directPath = reader.string();
                    break;
                case 14:
                    message.mediaKeyTimestamp = reader.int64();
                    break;
                case 16:
                    message.jpegThumbnail = reader.bytes();
                    break;
                case 17:
                    message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32());
                    break;
                case 18:
                    message.streamingSidecar = reader.bytes();
                    break;
                case 19:
                    message.gifAttribution = reader.int32();
                    break;
                case 20:
                    message.viewOnce = reader.bool();
                    break;
                case 21:
                    message.thumbnailDirectPath = reader.string();
                    break;
                case 22:
                    message.thumbnailSha256 = reader.bytes();
                    break;
                case 23:
                    message.thumbnailEncSha256 = reader.bytes();
                    break;
                case 24:
                    message.staticUrl = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a VideoMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.VideoMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.VideoMessage} VideoMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        VideoMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a VideoMessage message.
         * @function verify
         * @memberof proto.VideoMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        VideoMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.url != null && message.hasOwnProperty("url"))
                if (!$util.isString(message.url))
                    return "url: string expected";
            if (message.mimetype != null && message.hasOwnProperty("mimetype"))
                if (!$util.isString(message.mimetype))
                    return "mimetype: string expected";
            if (message.fileSha256 != null && message.hasOwnProperty("fileSha256"))
                if (!(message.fileSha256 && typeof message.fileSha256.length === "number" || $util.isString(message.fileSha256)))
                    return "fileSha256: buffer expected";
            if (message.fileLength != null && message.hasOwnProperty("fileLength"))
                if (!$util.isInteger(message.fileLength) && !(message.fileLength && $util.isInteger(message.fileLength.low) && $util.isInteger(message.fileLength.high)))
                    return "fileLength: integer|Long expected";
            if (message.seconds != null && message.hasOwnProperty("seconds"))
                if (!$util.isInteger(message.seconds))
                    return "seconds: integer expected";
            if (message.mediaKey != null && message.hasOwnProperty("mediaKey"))
                if (!(message.mediaKey && typeof message.mediaKey.length === "number" || $util.isString(message.mediaKey)))
                    return "mediaKey: buffer expected";
            if (message.caption != null && message.hasOwnProperty("caption"))
                if (!$util.isString(message.caption))
                    return "caption: string expected";
            if (message.gifPlayback != null && message.hasOwnProperty("gifPlayback"))
                if (typeof message.gifPlayback !== "boolean")
                    return "gifPlayback: boolean expected";
            if (message.height != null && message.hasOwnProperty("height"))
                if (!$util.isInteger(message.height))
                    return "height: integer expected";
            if (message.width != null && message.hasOwnProperty("width"))
                if (!$util.isInteger(message.width))
                    return "width: integer expected";
            if (message.fileEncSha256 != null && message.hasOwnProperty("fileEncSha256"))
                if (!(message.fileEncSha256 && typeof message.fileEncSha256.length === "number" || $util.isString(message.fileEncSha256)))
                    return "fileEncSha256: buffer expected";
            if (message.interactiveAnnotations != null && message.hasOwnProperty("interactiveAnnotations")) {
                if (!Array.isArray(message.interactiveAnnotations))
                    return "interactiveAnnotations: array expected";
                for (var i = 0; i < message.interactiveAnnotations.length; ++i) {
                    var error = $root.proto.InteractiveAnnotation.verify(message.interactiveAnnotations[i]);
                    if (error)
                        return "interactiveAnnotations." + error;
                }
            }
            if (message.directPath != null && message.hasOwnProperty("directPath"))
                if (!$util.isString(message.directPath))
                    return "directPath: string expected";
            if (message.mediaKeyTimestamp != null && message.hasOwnProperty("mediaKeyTimestamp"))
                if (!$util.isInteger(message.mediaKeyTimestamp) && !(message.mediaKeyTimestamp && $util.isInteger(message.mediaKeyTimestamp.low) && $util.isInteger(message.mediaKeyTimestamp.high)))
                    return "mediaKeyTimestamp: integer|Long expected";
            if (message.jpegThumbnail != null && message.hasOwnProperty("jpegThumbnail"))
                if (!(message.jpegThumbnail && typeof message.jpegThumbnail.length === "number" || $util.isString(message.jpegThumbnail)))
                    return "jpegThumbnail: buffer expected";
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) {
                var error = $root.proto.ContextInfo.verify(message.contextInfo);
                if (error)
                    return "contextInfo." + error;
            }
            if (message.streamingSidecar != null && message.hasOwnProperty("streamingSidecar"))
                if (!(message.streamingSidecar && typeof message.streamingSidecar.length === "number" || $util.isString(message.streamingSidecar)))
                    return "streamingSidecar: buffer expected";
            if (message.gifAttribution != null && message.hasOwnProperty("gifAttribution"))
                switch (message.gifAttribution) {
                default:
                    return "gifAttribution: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            if (message.viewOnce != null && message.hasOwnProperty("viewOnce"))
                if (typeof message.viewOnce !== "boolean")
                    return "viewOnce: boolean expected";
            if (message.thumbnailDirectPath != null && message.hasOwnProperty("thumbnailDirectPath"))
                if (!$util.isString(message.thumbnailDirectPath))
                    return "thumbnailDirectPath: string expected";
            if (message.thumbnailSha256 != null && message.hasOwnProperty("thumbnailSha256"))
                if (!(message.thumbnailSha256 && typeof message.thumbnailSha256.length === "number" || $util.isString(message.thumbnailSha256)))
                    return "thumbnailSha256: buffer expected";
            if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256"))
                if (!(message.thumbnailEncSha256 && typeof message.thumbnailEncSha256.length === "number" || $util.isString(message.thumbnailEncSha256)))
                    return "thumbnailEncSha256: buffer expected";
            if (message.staticUrl != null && message.hasOwnProperty("staticUrl"))
                if (!$util.isString(message.staticUrl))
                    return "staticUrl: string expected";
            return null;
        };

        /**
         * Creates a VideoMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.VideoMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.VideoMessage} VideoMessage
         */
        VideoMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.VideoMessage)
                return object;
            var message = new $root.proto.VideoMessage();
            if (object.url != null)
                message.url = String(object.url);
            if (object.mimetype != null)
                message.mimetype = String(object.mimetype);
            if (object.fileSha256 != null)
                if (typeof object.fileSha256 === "string")
                    $util.base64.decode(object.fileSha256, message.fileSha256 = $util.newBuffer($util.base64.length(object.fileSha256)), 0);
                else if (object.fileSha256.length)
                    message.fileSha256 = object.fileSha256;
            if (object.fileLength != null)
                if ($util.Long)
                    (message.fileLength = $util.Long.fromValue(object.fileLength)).unsigned = true;
                else if (typeof object.fileLength === "string")
                    message.fileLength = parseInt(object.fileLength, 10);
                else if (typeof object.fileLength === "number")
                    message.fileLength = object.fileLength;
                else if (typeof object.fileLength === "object")
                    message.fileLength = new $util.LongBits(object.fileLength.low >>> 0, object.fileLength.high >>> 0).toNumber(true);
            if (object.seconds != null)
                message.seconds = object.seconds >>> 0;
            if (object.mediaKey != null)
                if (typeof object.mediaKey === "string")
                    $util.base64.decode(object.mediaKey, message.mediaKey = $util.newBuffer($util.base64.length(object.mediaKey)), 0);
                else if (object.mediaKey.length)
                    message.mediaKey = object.mediaKey;
            if (object.caption != null)
                message.caption = String(object.caption);
            if (object.gifPlayback != null)
                message.gifPlayback = Boolean(object.gifPlayback);
            if (object.height != null)
                message.height = object.height >>> 0;
            if (object.width != null)
                message.width = object.width >>> 0;
            if (object.fileEncSha256 != null)
                if (typeof object.fileEncSha256 === "string")
                    $util.base64.decode(object.fileEncSha256, message.fileEncSha256 = $util.newBuffer($util.base64.length(object.fileEncSha256)), 0);
                else if (object.fileEncSha256.length)
                    message.fileEncSha256 = object.fileEncSha256;
            if (object.interactiveAnnotations) {
                if (!Array.isArray(object.interactiveAnnotations))
                    throw TypeError(".proto.VideoMessage.interactiveAnnotations: array expected");
                message.interactiveAnnotations = [];
                for (var i = 0; i < object.interactiveAnnotations.length; ++i) {
                    if (typeof object.interactiveAnnotations[i] !== "object")
                        throw TypeError(".proto.VideoMessage.interactiveAnnotations: object expected");
                    message.interactiveAnnotations[i] = $root.proto.InteractiveAnnotation.fromObject(object.interactiveAnnotations[i]);
                }
            }
            if (object.directPath != null)
                message.directPath = String(object.directPath);
            if (object.mediaKeyTimestamp != null)
                if ($util.Long)
                    (message.mediaKeyTimestamp = $util.Long.fromValue(object.mediaKeyTimestamp)).unsigned = false;
                else if (typeof object.mediaKeyTimestamp === "string")
                    message.mediaKeyTimestamp = parseInt(object.mediaKeyTimestamp, 10);
                else if (typeof object.mediaKeyTimestamp === "number")
                    message.mediaKeyTimestamp = object.mediaKeyTimestamp;
                else if (typeof object.mediaKeyTimestamp === "object")
                    message.mediaKeyTimestamp = new $util.LongBits(object.mediaKeyTimestamp.low >>> 0, object.mediaKeyTimestamp.high >>> 0).toNumber();
            if (object.jpegThumbnail != null)
                if (typeof object.jpegThumbnail === "string")
                    $util.base64.decode(object.jpegThumbnail, message.jpegThumbnail = $util.newBuffer($util.base64.length(object.jpegThumbnail)), 0);
                else if (object.jpegThumbnail.length)
                    message.jpegThumbnail = object.jpegThumbnail;
            if (object.contextInfo != null) {
                if (typeof object.contextInfo !== "object")
                    throw TypeError(".proto.VideoMessage.contextInfo: object expected");
                message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo);
            }
            if (object.streamingSidecar != null)
                if (typeof object.streamingSidecar === "string")
                    $util.base64.decode(object.streamingSidecar, message.streamingSidecar = $util.newBuffer($util.base64.length(object.streamingSidecar)), 0);
                else if (object.streamingSidecar.length)
                    message.streamingSidecar = object.streamingSidecar;
            switch (object.gifAttribution) {
            case "NONE":
            case 0:
                message.gifAttribution = 0;
                break;
            case "GIPHY":
            case 1:
                message.gifAttribution = 1;
                break;
            case "TENOR":
            case 2:
                message.gifAttribution = 2;
                break;
            }
            if (object.viewOnce != null)
                message.viewOnce = Boolean(object.viewOnce);
            if (object.thumbnailDirectPath != null)
                message.thumbnailDirectPath = String(object.thumbnailDirectPath);
            if (object.thumbnailSha256 != null)
                if (typeof object.thumbnailSha256 === "string")
                    $util.base64.decode(object.thumbnailSha256, message.thumbnailSha256 = $util.newBuffer($util.base64.length(object.thumbnailSha256)), 0);
                else if (object.thumbnailSha256.length)
                    message.thumbnailSha256 = object.thumbnailSha256;
            if (object.thumbnailEncSha256 != null)
                if (typeof object.thumbnailEncSha256 === "string")
                    $util.base64.decode(object.thumbnailEncSha256, message.thumbnailEncSha256 = $util.newBuffer($util.base64.length(object.thumbnailEncSha256)), 0);
                else if (object.thumbnailEncSha256.length)
                    message.thumbnailEncSha256 = object.thumbnailEncSha256;
            if (object.staticUrl != null)
                message.staticUrl = String(object.staticUrl);
            return message;
        };

        /**
         * Creates a plain object from a VideoMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.VideoMessage
         * @static
         * @param {proto.VideoMessage} message VideoMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        VideoMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.interactiveAnnotations = [];
            if (options.defaults) {
                object.url = "";
                object.mimetype = "";
                if (options.bytes === String)
                    object.fileSha256 = "";
                else {
                    object.fileSha256 = [];
                    if (options.bytes !== Array)
                        object.fileSha256 = $util.newBuffer(object.fileSha256);
                }
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.fileLength = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.fileLength = options.longs === String ? "0" : 0;
                object.seconds = 0;
                if (options.bytes === String)
                    object.mediaKey = "";
                else {
                    object.mediaKey = [];
                    if (options.bytes !== Array)
                        object.mediaKey = $util.newBuffer(object.mediaKey);
                }
                object.caption = "";
                object.gifPlayback = false;
                object.height = 0;
                object.width = 0;
                if (options.bytes === String)
                    object.fileEncSha256 = "";
                else {
                    object.fileEncSha256 = [];
                    if (options.bytes !== Array)
                        object.fileEncSha256 = $util.newBuffer(object.fileEncSha256);
                }
                object.directPath = "";
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.mediaKeyTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.mediaKeyTimestamp = options.longs === String ? "0" : 0;
                if (options.bytes === String)
                    object.jpegThumbnail = "";
                else {
                    object.jpegThumbnail = [];
                    if (options.bytes !== Array)
                        object.jpegThumbnail = $util.newBuffer(object.jpegThumbnail);
                }
                object.contextInfo = null;
                if (options.bytes === String)
                    object.streamingSidecar = "";
                else {
                    object.streamingSidecar = [];
                    if (options.bytes !== Array)
                        object.streamingSidecar = $util.newBuffer(object.streamingSidecar);
                }
                object.gifAttribution = options.enums === String ? "NONE" : 0;
                object.viewOnce = false;
                object.thumbnailDirectPath = "";
                if (options.bytes === String)
                    object.thumbnailSha256 = "";
                else {
                    object.thumbnailSha256 = [];
                    if (options.bytes !== Array)
                        object.thumbnailSha256 = $util.newBuffer(object.thumbnailSha256);
                }
                if (options.bytes === String)
                    object.thumbnailEncSha256 = "";
                else {
                    object.thumbnailEncSha256 = [];
                    if (options.bytes !== Array)
                        object.thumbnailEncSha256 = $util.newBuffer(object.thumbnailEncSha256);
                }
                object.staticUrl = "";
            }
            if (message.url != null && message.hasOwnProperty("url"))
                object.url = message.url;
            if (message.mimetype != null && message.hasOwnProperty("mimetype"))
                object.mimetype = message.mimetype;
            if (message.fileSha256 != null && message.hasOwnProperty("fileSha256"))
                object.fileSha256 = options.bytes === String ? $util.base64.encode(message.fileSha256, 0, message.fileSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.fileSha256) : message.fileSha256;
            if (message.fileLength != null && message.hasOwnProperty("fileLength"))
                if (typeof message.fileLength === "number")
                    object.fileLength = options.longs === String ? String(message.fileLength) : message.fileLength;
                else
                    object.fileLength = options.longs === String ? $util.Long.prototype.toString.call(message.fileLength) : options.longs === Number ? new $util.LongBits(message.fileLength.low >>> 0, message.fileLength.high >>> 0).toNumber(true) : message.fileLength;
            if (message.seconds != null && message.hasOwnProperty("seconds"))
                object.seconds = message.seconds;
            if (message.mediaKey != null && message.hasOwnProperty("mediaKey"))
                object.mediaKey = options.bytes === String ? $util.base64.encode(message.mediaKey, 0, message.mediaKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.mediaKey) : message.mediaKey;
            if (message.caption != null && message.hasOwnProperty("caption"))
                object.caption = message.caption;
            if (message.gifPlayback != null && message.hasOwnProperty("gifPlayback"))
                object.gifPlayback = message.gifPlayback;
            if (message.height != null && message.hasOwnProperty("height"))
                object.height = message.height;
            if (message.width != null && message.hasOwnProperty("width"))
                object.width = message.width;
            if (message.fileEncSha256 != null && message.hasOwnProperty("fileEncSha256"))
                object.fileEncSha256 = options.bytes === String ? $util.base64.encode(message.fileEncSha256, 0, message.fileEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.fileEncSha256) : message.fileEncSha256;
            if (message.interactiveAnnotations && message.interactiveAnnotations.length) {
                object.interactiveAnnotations = [];
                for (var j = 0; j < message.interactiveAnnotations.length; ++j)
                    object.interactiveAnnotations[j] = $root.proto.InteractiveAnnotation.toObject(message.interactiveAnnotations[j], options);
            }
            if (message.directPath != null && message.hasOwnProperty("directPath"))
                object.directPath = message.directPath;
            if (message.mediaKeyTimestamp != null && message.hasOwnProperty("mediaKeyTimestamp"))
                if (typeof message.mediaKeyTimestamp === "number")
                    object.mediaKeyTimestamp = options.longs === String ? String(message.mediaKeyTimestamp) : message.mediaKeyTimestamp;
                else
                    object.mediaKeyTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.mediaKeyTimestamp) : options.longs === Number ? new $util.LongBits(message.mediaKeyTimestamp.low >>> 0, message.mediaKeyTimestamp.high >>> 0).toNumber() : message.mediaKeyTimestamp;
            if (message.jpegThumbnail != null && message.hasOwnProperty("jpegThumbnail"))
                object.jpegThumbnail = options.bytes === String ? $util.base64.encode(message.jpegThumbnail, 0, message.jpegThumbnail.length) : options.bytes === Array ? Array.prototype.slice.call(message.jpegThumbnail) : message.jpegThumbnail;
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo"))
                object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options);
            if (message.streamingSidecar != null && message.hasOwnProperty("streamingSidecar"))
                object.streamingSidecar = options.bytes === String ? $util.base64.encode(message.streamingSidecar, 0, message.streamingSidecar.length) : options.bytes === Array ? Array.prototype.slice.call(message.streamingSidecar) : message.streamingSidecar;
            if (message.gifAttribution != null && message.hasOwnProperty("gifAttribution"))
                object.gifAttribution = options.enums === String ? $root.proto.VideoMessage.VideoMessageAttribution[message.gifAttribution] : message.gifAttribution;
            if (message.viewOnce != null && message.hasOwnProperty("viewOnce"))
                object.viewOnce = message.viewOnce;
            if (message.thumbnailDirectPath != null && message.hasOwnProperty("thumbnailDirectPath"))
                object.thumbnailDirectPath = message.thumbnailDirectPath;
            if (message.thumbnailSha256 != null && message.hasOwnProperty("thumbnailSha256"))
                object.thumbnailSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailSha256, 0, message.thumbnailSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailSha256) : message.thumbnailSha256;
            if (message.thumbnailEncSha256 != null && message.hasOwnProperty("thumbnailEncSha256"))
                object.thumbnailEncSha256 = options.bytes === String ? $util.base64.encode(message.thumbnailEncSha256, 0, message.thumbnailEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnailEncSha256) : message.thumbnailEncSha256;
            if (message.staticUrl != null && message.hasOwnProperty("staticUrl"))
                object.staticUrl = message.staticUrl;
            return object;
        };

        /**
         * Converts this VideoMessage to JSON.
         * @function toJSON
         * @memberof proto.VideoMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        VideoMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * VideoMessageAttribution enum.
         * @name proto.VideoMessage.VideoMessageAttribution
         * @enum {number}
         * @property {number} NONE=0 NONE value
         * @property {number} GIPHY=1 GIPHY value
         * @property {number} TENOR=2 TENOR value
         */
        VideoMessage.VideoMessageAttribution = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "NONE"] = 0;
            values[valuesById[1] = "GIPHY"] = 1;
            values[valuesById[2] = "TENOR"] = 2;
            return values;
        })();

        return VideoMessage;
    })();

    proto.Call = (function() {

        /**
         * Properties of a Call.
         * @memberof proto
         * @interface ICall
         * @property {Uint8Array|null} [callKey] Call callKey
         * @property {string|null} [conversionSource] Call conversionSource
         * @property {Uint8Array|null} [conversionData] Call conversionData
         * @property {number|null} [conversionDelaySeconds] Call conversionDelaySeconds
         */

        /**
         * Constructs a new Call.
         * @memberof proto
         * @classdesc Represents a Call.
         * @implements ICall
         * @constructor
         * @param {proto.ICall=} [properties] Properties to set
         */
        function Call(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Call callKey.
         * @member {Uint8Array} callKey
         * @memberof proto.Call
         * @instance
         */
        Call.prototype.callKey = $util.newBuffer([]);

        /**
         * Call conversionSource.
         * @member {string} conversionSource
         * @memberof proto.Call
         * @instance
         */
        Call.prototype.conversionSource = "";

        /**
         * Call conversionData.
         * @member {Uint8Array} conversionData
         * @memberof proto.Call
         * @instance
         */
        Call.prototype.conversionData = $util.newBuffer([]);

        /**
         * Call conversionDelaySeconds.
         * @member {number} conversionDelaySeconds
         * @memberof proto.Call
         * @instance
         */
        Call.prototype.conversionDelaySeconds = 0;

        /**
         * Creates a new Call instance using the specified properties.
         * @function create
         * @memberof proto.Call
         * @static
         * @param {proto.ICall=} [properties] Properties to set
         * @returns {proto.Call} Call instance
         */
        Call.create = function create(properties) {
            return new Call(properties);
        };

        /**
         * Encodes the specified Call message. Does not implicitly {@link proto.Call.verify|verify} messages.
         * @function encode
         * @memberof proto.Call
         * @static
         * @param {proto.ICall} message Call message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Call.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.callKey != null && Object.hasOwnProperty.call(message, "callKey"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.callKey);
            if (message.conversionSource != null && Object.hasOwnProperty.call(message, "conversionSource"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.conversionSource);
            if (message.conversionData != null && Object.hasOwnProperty.call(message, "conversionData"))
                writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.conversionData);
            if (message.conversionDelaySeconds != null && Object.hasOwnProperty.call(message, "conversionDelaySeconds"))
                writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.conversionDelaySeconds);
            return writer;
        };

        /**
         * Encodes the specified Call message, length delimited. Does not implicitly {@link proto.Call.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.Call
         * @static
         * @param {proto.ICall} message Call message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Call.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a Call message from the specified reader or buffer.
         * @function decode
         * @memberof proto.Call
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.Call} Call
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Call.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Call();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.callKey = reader.bytes();
                    break;
                case 2:
                    message.conversionSource = reader.string();
                    break;
                case 3:
                    message.conversionData = reader.bytes();
                    break;
                case 4:
                    message.conversionDelaySeconds = reader.uint32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a Call message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.Call
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.Call} Call
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Call.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a Call message.
         * @function verify
         * @memberof proto.Call
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        Call.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.callKey != null && message.hasOwnProperty("callKey"))
                if (!(message.callKey && typeof message.callKey.length === "number" || $util.isString(message.callKey)))
                    return "callKey: buffer expected";
            if (message.conversionSource != null && message.hasOwnProperty("conversionSource"))
                if (!$util.isString(message.conversionSource))
                    return "conversionSource: string expected";
            if (message.conversionData != null && message.hasOwnProperty("conversionData"))
                if (!(message.conversionData && typeof message.conversionData.length === "number" || $util.isString(message.conversionData)))
                    return "conversionData: buffer expected";
            if (message.conversionDelaySeconds != null && message.hasOwnProperty("conversionDelaySeconds"))
                if (!$util.isInteger(message.conversionDelaySeconds))
                    return "conversionDelaySeconds: integer expected";
            return null;
        };

        /**
         * Creates a Call message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.Call
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.Call} Call
         */
        Call.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.Call)
                return object;
            var message = new $root.proto.Call();
            if (object.callKey != null)
                if (typeof object.callKey === "string")
                    $util.base64.decode(object.callKey, message.callKey = $util.newBuffer($util.base64.length(object.callKey)), 0);
                else if (object.callKey.length)
                    message.callKey = object.callKey;
            if (object.conversionSource != null)
                message.conversionSource = String(object.conversionSource);
            if (object.conversionData != null)
                if (typeof object.conversionData === "string")
                    $util.base64.decode(object.conversionData, message.conversionData = $util.newBuffer($util.base64.length(object.conversionData)), 0);
                else if (object.conversionData.length)
                    message.conversionData = object.conversionData;
            if (object.conversionDelaySeconds != null)
                message.conversionDelaySeconds = object.conversionDelaySeconds >>> 0;
            return message;
        };

        /**
         * Creates a plain object from a Call message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.Call
         * @static
         * @param {proto.Call} message Call
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        Call.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object.callKey = "";
                else {
                    object.callKey = [];
                    if (options.bytes !== Array)
                        object.callKey = $util.newBuffer(object.callKey);
                }
                object.conversionSource = "";
                if (options.bytes === String)
                    object.conversionData = "";
                else {
                    object.conversionData = [];
                    if (options.bytes !== Array)
                        object.conversionData = $util.newBuffer(object.conversionData);
                }
                object.conversionDelaySeconds = 0;
            }
            if (message.callKey != null && message.hasOwnProperty("callKey"))
                object.callKey = options.bytes === String ? $util.base64.encode(message.callKey, 0, message.callKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.callKey) : message.callKey;
            if (message.conversionSource != null && message.hasOwnProperty("conversionSource"))
                object.conversionSource = message.conversionSource;
            if (message.conversionData != null && message.hasOwnProperty("conversionData"))
                object.conversionData = options.bytes === String ? $util.base64.encode(message.conversionData, 0, message.conversionData.length) : options.bytes === Array ? Array.prototype.slice.call(message.conversionData) : message.conversionData;
            if (message.conversionDelaySeconds != null && message.hasOwnProperty("conversionDelaySeconds"))
                object.conversionDelaySeconds = message.conversionDelaySeconds;
            return object;
        };

        /**
         * Converts this Call to JSON.
         * @function toJSON
         * @memberof proto.Call
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        Call.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return Call;
    })();

    proto.Chat = (function() {

        /**
         * Properties of a Chat.
         * @memberof proto
         * @interface IChat
         * @property {string|null} [displayName] Chat displayName
         * @property {string|null} [id] Chat id
         */

        /**
         * Constructs a new Chat.
         * @memberof proto
         * @classdesc Represents a Chat.
         * @implements IChat
         * @constructor
         * @param {proto.IChat=} [properties] Properties to set
         */
        function Chat(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Chat displayName.
         * @member {string} displayName
         * @memberof proto.Chat
         * @instance
         */
        Chat.prototype.displayName = "";

        /**
         * Chat id.
         * @member {string} id
         * @memberof proto.Chat
         * @instance
         */
        Chat.prototype.id = "";

        /**
         * Creates a new Chat instance using the specified properties.
         * @function create
         * @memberof proto.Chat
         * @static
         * @param {proto.IChat=} [properties] Properties to set
         * @returns {proto.Chat} Chat instance
         */
        Chat.create = function create(properties) {
            return new Chat(properties);
        };

        /**
         * Encodes the specified Chat message. Does not implicitly {@link proto.Chat.verify|verify} messages.
         * @function encode
         * @memberof proto.Chat
         * @static
         * @param {proto.IChat} message Chat message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Chat.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.displayName != null && Object.hasOwnProperty.call(message, "displayName"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayName);
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.id);
            return writer;
        };

        /**
         * Encodes the specified Chat message, length delimited. Does not implicitly {@link proto.Chat.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.Chat
         * @static
         * @param {proto.IChat} message Chat message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Chat.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a Chat message from the specified reader or buffer.
         * @function decode
         * @memberof proto.Chat
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.Chat} Chat
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Chat.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Chat();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.displayName = reader.string();
                    break;
                case 2:
                    message.id = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a Chat message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.Chat
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.Chat} Chat
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Chat.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a Chat message.
         * @function verify
         * @memberof proto.Chat
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        Chat.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.displayName != null && message.hasOwnProperty("displayName"))
                if (!$util.isString(message.displayName))
                    return "displayName: string expected";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isString(message.id))
                    return "id: string expected";
            return null;
        };

        /**
         * Creates a Chat message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.Chat
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.Chat} Chat
         */
        Chat.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.Chat)
                return object;
            var message = new $root.proto.Chat();
            if (object.displayName != null)
                message.displayName = String(object.displayName);
            if (object.id != null)
                message.id = String(object.id);
            return message;
        };

        /**
         * Creates a plain object from a Chat message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.Chat
         * @static
         * @param {proto.Chat} message Chat
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        Chat.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.displayName = "";
                object.id = "";
            }
            if (message.displayName != null && message.hasOwnProperty("displayName"))
                object.displayName = message.displayName;
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            return object;
        };

        /**
         * Converts this Chat to JSON.
         * @function toJSON
         * @memberof proto.Chat
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        Chat.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return Chat;
    })();

    proto.ProtocolMessage = (function() {

        /**
         * Properties of a ProtocolMessage.
         * @memberof proto
         * @interface IProtocolMessage
         * @property {proto.IMessageKey|null} [key] ProtocolMessage key
         * @property {proto.ProtocolMessage.ProtocolMessageType|null} [type] ProtocolMessage type
         * @property {number|null} [ephemeralExpiration] ProtocolMessage ephemeralExpiration
         * @property {number|Long|null} [ephemeralSettingTimestamp] ProtocolMessage ephemeralSettingTimestamp
         * @property {proto.IHistorySyncNotification|null} [historySyncNotification] ProtocolMessage historySyncNotification
         * @property {proto.IAppStateSyncKeyShare|null} [appStateSyncKeyShare] ProtocolMessage appStateSyncKeyShare
         * @property {proto.IAppStateSyncKeyRequest|null} [appStateSyncKeyRequest] ProtocolMessage appStateSyncKeyRequest
         * @property {proto.IInitialSecurityNotificationSettingSync|null} [initialSecurityNotificationSettingSync] ProtocolMessage initialSecurityNotificationSettingSync
         * @property {proto.IAppStateFatalExceptionNotification|null} [appStateFatalExceptionNotification] ProtocolMessage appStateFatalExceptionNotification
         * @property {proto.IDisappearingMode|null} [disappearingMode] ProtocolMessage disappearingMode
         */

        /**
         * Constructs a new ProtocolMessage.
         * @memberof proto
         * @classdesc Represents a ProtocolMessage.
         * @implements IProtocolMessage
         * @constructor
         * @param {proto.IProtocolMessage=} [properties] Properties to set
         */
        function ProtocolMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ProtocolMessage key.
         * @member {proto.IMessageKey|null|undefined} key
         * @memberof proto.ProtocolMessage
         * @instance
         */
        ProtocolMessage.prototype.key = null;

        /**
         * ProtocolMessage type.
         * @member {proto.ProtocolMessage.ProtocolMessageType} type
         * @memberof proto.ProtocolMessage
         * @instance
         */
        ProtocolMessage.prototype.type = 0;

        /**
         * ProtocolMessage ephemeralExpiration.
         * @member {number} ephemeralExpiration
         * @memberof proto.ProtocolMessage
         * @instance
         */
        ProtocolMessage.prototype.ephemeralExpiration = 0;

        /**
         * ProtocolMessage ephemeralSettingTimestamp.
         * @member {number|Long} ephemeralSettingTimestamp
         * @memberof proto.ProtocolMessage
         * @instance
         */
        ProtocolMessage.prototype.ephemeralSettingTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * ProtocolMessage historySyncNotification.
         * @member {proto.IHistorySyncNotification|null|undefined} historySyncNotification
         * @memberof proto.ProtocolMessage
         * @instance
         */
        ProtocolMessage.prototype.historySyncNotification = null;

        /**
         * ProtocolMessage appStateSyncKeyShare.
         * @member {proto.IAppStateSyncKeyShare|null|undefined} appStateSyncKeyShare
         * @memberof proto.ProtocolMessage
         * @instance
         */
        ProtocolMessage.prototype.appStateSyncKeyShare = null;

        /**
         * ProtocolMessage appStateSyncKeyRequest.
         * @member {proto.IAppStateSyncKeyRequest|null|undefined} appStateSyncKeyRequest
         * @memberof proto.ProtocolMessage
         * @instance
         */
        ProtocolMessage.prototype.appStateSyncKeyRequest = null;

        /**
         * ProtocolMessage initialSecurityNotificationSettingSync.
         * @member {proto.IInitialSecurityNotificationSettingSync|null|undefined} initialSecurityNotificationSettingSync
         * @memberof proto.ProtocolMessage
         * @instance
         */
        ProtocolMessage.prototype.initialSecurityNotificationSettingSync = null;

        /**
         * ProtocolMessage appStateFatalExceptionNotification.
         * @member {proto.IAppStateFatalExceptionNotification|null|undefined} appStateFatalExceptionNotification
         * @memberof proto.ProtocolMessage
         * @instance
         */
        ProtocolMessage.prototype.appStateFatalExceptionNotification = null;

        /**
         * ProtocolMessage disappearingMode.
         * @member {proto.IDisappearingMode|null|undefined} disappearingMode
         * @memberof proto.ProtocolMessage
         * @instance
         */
        ProtocolMessage.prototype.disappearingMode = null;

        /**
         * Creates a new ProtocolMessage instance using the specified properties.
         * @function create
         * @memberof proto.ProtocolMessage
         * @static
         * @param {proto.IProtocolMessage=} [properties] Properties to set
         * @returns {proto.ProtocolMessage} ProtocolMessage instance
         */
        ProtocolMessage.create = function create(properties) {
            return new ProtocolMessage(properties);
        };

        /**
         * Encodes the specified ProtocolMessage message. Does not implicitly {@link proto.ProtocolMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.ProtocolMessage
         * @static
         * @param {proto.IProtocolMessage} message ProtocolMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ProtocolMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.key != null && Object.hasOwnProperty.call(message, "key"))
                $root.proto.MessageKey.encode(message.key, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.type != null && Object.hasOwnProperty.call(message, "type"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.type);
            if (message.ephemeralExpiration != null && Object.hasOwnProperty.call(message, "ephemeralExpiration"))
                writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.ephemeralExpiration);
            if (message.ephemeralSettingTimestamp != null && Object.hasOwnProperty.call(message, "ephemeralSettingTimestamp"))
                writer.uint32(/* id 5, wireType 0 =*/40).int64(message.ephemeralSettingTimestamp);
            if (message.historySyncNotification != null && Object.hasOwnProperty.call(message, "historySyncNotification"))
                $root.proto.HistorySyncNotification.encode(message.historySyncNotification, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim();
            if (message.appStateSyncKeyShare != null && Object.hasOwnProperty.call(message, "appStateSyncKeyShare"))
                $root.proto.AppStateSyncKeyShare.encode(message.appStateSyncKeyShare, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim();
            if (message.appStateSyncKeyRequest != null && Object.hasOwnProperty.call(message, "appStateSyncKeyRequest"))
                $root.proto.AppStateSyncKeyRequest.encode(message.appStateSyncKeyRequest, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim();
            if (message.initialSecurityNotificationSettingSync != null && Object.hasOwnProperty.call(message, "initialSecurityNotificationSettingSync"))
                $root.proto.InitialSecurityNotificationSettingSync.encode(message.initialSecurityNotificationSettingSync, writer.uint32(/* id 9, wireType 2 =*/74).fork()).ldelim();
            if (message.appStateFatalExceptionNotification != null && Object.hasOwnProperty.call(message, "appStateFatalExceptionNotification"))
                $root.proto.AppStateFatalExceptionNotification.encode(message.appStateFatalExceptionNotification, writer.uint32(/* id 10, wireType 2 =*/82).fork()).ldelim();
            if (message.disappearingMode != null && Object.hasOwnProperty.call(message, "disappearingMode"))
                $root.proto.DisappearingMode.encode(message.disappearingMode, writer.uint32(/* id 11, wireType 2 =*/90).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified ProtocolMessage message, length delimited. Does not implicitly {@link proto.ProtocolMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ProtocolMessage
         * @static
         * @param {proto.IProtocolMessage} message ProtocolMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ProtocolMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ProtocolMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ProtocolMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ProtocolMessage} ProtocolMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ProtocolMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ProtocolMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.key = $root.proto.MessageKey.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.type = reader.int32();
                    break;
                case 4:
                    message.ephemeralExpiration = reader.uint32();
                    break;
                case 5:
                    message.ephemeralSettingTimestamp = reader.int64();
                    break;
                case 6:
                    message.historySyncNotification = $root.proto.HistorySyncNotification.decode(reader, reader.uint32());
                    break;
                case 7:
                    message.appStateSyncKeyShare = $root.proto.AppStateSyncKeyShare.decode(reader, reader.uint32());
                    break;
                case 8:
                    message.appStateSyncKeyRequest = $root.proto.AppStateSyncKeyRequest.decode(reader, reader.uint32());
                    break;
                case 9:
                    message.initialSecurityNotificationSettingSync = $root.proto.InitialSecurityNotificationSettingSync.decode(reader, reader.uint32());
                    break;
                case 10:
                    message.appStateFatalExceptionNotification = $root.proto.AppStateFatalExceptionNotification.decode(reader, reader.uint32());
                    break;
                case 11:
                    message.disappearingMode = $root.proto.DisappearingMode.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ProtocolMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ProtocolMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ProtocolMessage} ProtocolMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ProtocolMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ProtocolMessage message.
         * @function verify
         * @memberof proto.ProtocolMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ProtocolMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.key != null && message.hasOwnProperty("key")) {
                var error = $root.proto.MessageKey.verify(message.key);
                if (error)
                    return "key." + error;
            }
            if (message.type != null && message.hasOwnProperty("type"))
                switch (message.type) {
                default:
                    return "type: enum value expected";
                case 0:
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                case 8:
                case 9:
                case 10:
                    break;
                }
            if (message.ephemeralExpiration != null && message.hasOwnProperty("ephemeralExpiration"))
                if (!$util.isInteger(message.ephemeralExpiration))
                    return "ephemeralExpiration: integer expected";
            if (message.ephemeralSettingTimestamp != null && message.hasOwnProperty("ephemeralSettingTimestamp"))
                if (!$util.isInteger(message.ephemeralSettingTimestamp) && !(message.ephemeralSettingTimestamp && $util.isInteger(message.ephemeralSettingTimestamp.low) && $util.isInteger(message.ephemeralSettingTimestamp.high)))
                    return "ephemeralSettingTimestamp: integer|Long expected";
            if (message.historySyncNotification != null && message.hasOwnProperty("historySyncNotification")) {
                var error = $root.proto.HistorySyncNotification.verify(message.historySyncNotification);
                if (error)
                    return "historySyncNotification." + error;
            }
            if (message.appStateSyncKeyShare != null && message.hasOwnProperty("appStateSyncKeyShare")) {
                var error = $root.proto.AppStateSyncKeyShare.verify(message.appStateSyncKeyShare);
                if (error)
                    return "appStateSyncKeyShare." + error;
            }
            if (message.appStateSyncKeyRequest != null && message.hasOwnProperty("appStateSyncKeyRequest")) {
                var error = $root.proto.AppStateSyncKeyRequest.verify(message.appStateSyncKeyRequest);
                if (error)
                    return "appStateSyncKeyRequest." + error;
            }
            if (message.initialSecurityNotificationSettingSync != null && message.hasOwnProperty("initialSecurityNotificationSettingSync")) {
                var error = $root.proto.InitialSecurityNotificationSettingSync.verify(message.initialSecurityNotificationSettingSync);
                if (error)
                    return "initialSecurityNotificationSettingSync." + error;
            }
            if (message.appStateFatalExceptionNotification != null && message.hasOwnProperty("appStateFatalExceptionNotification")) {
                var error = $root.proto.AppStateFatalExceptionNotification.verify(message.appStateFatalExceptionNotification);
                if (error)
                    return "appStateFatalExceptionNotification." + error;
            }
            if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode")) {
                var error = $root.proto.DisappearingMode.verify(message.disappearingMode);
                if (error)
                    return "disappearingMode." + error;
            }
            return null;
        };

        /**
         * Creates a ProtocolMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ProtocolMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ProtocolMessage} ProtocolMessage
         */
        ProtocolMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ProtocolMessage)
                return object;
            var message = new $root.proto.ProtocolMessage();
            if (object.key != null) {
                if (typeof object.key !== "object")
                    throw TypeError(".proto.ProtocolMessage.key: object expected");
                message.key = $root.proto.MessageKey.fromObject(object.key);
            }
            switch (object.type) {
            case "REVOKE":
            case 0:
                message.type = 0;
                break;
            case "EPHEMERAL_SETTING":
            case 3:
                message.type = 3;
                break;
            case "EPHEMERAL_SYNC_RESPONSE":
            case 4:
                message.type = 4;
                break;
            case "HISTORY_SYNC_NOTIFICATION":
            case 5:
                message.type = 5;
                break;
            case "APP_STATE_SYNC_KEY_SHARE":
            case 6:
                message.type = 6;
                break;
            case "APP_STATE_SYNC_KEY_REQUEST":
            case 7:
                message.type = 7;
                break;
            case "MSG_FANOUT_BACKFILL_REQUEST":
            case 8:
                message.type = 8;
                break;
            case "INITIAL_SECURITY_NOTIFICATION_SETTING_SYNC":
            case 9:
                message.type = 9;
                break;
            case "APP_STATE_FATAL_EXCEPTION_NOTIFICATION":
            case 10:
                message.type = 10;
                break;
            }
            if (object.ephemeralExpiration != null)
                message.ephemeralExpiration = object.ephemeralExpiration >>> 0;
            if (object.ephemeralSettingTimestamp != null)
                if ($util.Long)
                    (message.ephemeralSettingTimestamp = $util.Long.fromValue(object.ephemeralSettingTimestamp)).unsigned = false;
                else if (typeof object.ephemeralSettingTimestamp === "string")
                    message.ephemeralSettingTimestamp = parseInt(object.ephemeralSettingTimestamp, 10);
                else if (typeof object.ephemeralSettingTimestamp === "number")
                    message.ephemeralSettingTimestamp = object.ephemeralSettingTimestamp;
                else if (typeof object.ephemeralSettingTimestamp === "object")
                    message.ephemeralSettingTimestamp = new $util.LongBits(object.ephemeralSettingTimestamp.low >>> 0, object.ephemeralSettingTimestamp.high >>> 0).toNumber();
            if (object.historySyncNotification != null) {
                if (typeof object.historySyncNotification !== "object")
                    throw TypeError(".proto.ProtocolMessage.historySyncNotification: object expected");
                message.historySyncNotification = $root.proto.HistorySyncNotification.fromObject(object.historySyncNotification);
            }
            if (object.appStateSyncKeyShare != null) {
                if (typeof object.appStateSyncKeyShare !== "object")
                    throw TypeError(".proto.ProtocolMessage.appStateSyncKeyShare: object expected");
                message.appStateSyncKeyShare = $root.proto.AppStateSyncKeyShare.fromObject(object.appStateSyncKeyShare);
            }
            if (object.appStateSyncKeyRequest != null) {
                if (typeof object.appStateSyncKeyRequest !== "object")
                    throw TypeError(".proto.ProtocolMessage.appStateSyncKeyRequest: object expected");
                message.appStateSyncKeyRequest = $root.proto.AppStateSyncKeyRequest.fromObject(object.appStateSyncKeyRequest);
            }
            if (object.initialSecurityNotificationSettingSync != null) {
                if (typeof object.initialSecurityNotificationSettingSync !== "object")
                    throw TypeError(".proto.ProtocolMessage.initialSecurityNotificationSettingSync: object expected");
                message.initialSecurityNotificationSettingSync = $root.proto.InitialSecurityNotificationSettingSync.fromObject(object.initialSecurityNotificationSettingSync);
            }
            if (object.appStateFatalExceptionNotification != null) {
                if (typeof object.appStateFatalExceptionNotification !== "object")
                    throw TypeError(".proto.ProtocolMessage.appStateFatalExceptionNotification: object expected");
                message.appStateFatalExceptionNotification = $root.proto.AppStateFatalExceptionNotification.fromObject(object.appStateFatalExceptionNotification);
            }
            if (object.disappearingMode != null) {
                if (typeof object.disappearingMode !== "object")
                    throw TypeError(".proto.ProtocolMessage.disappearingMode: object expected");
                message.disappearingMode = $root.proto.DisappearingMode.fromObject(object.disappearingMode);
            }
            return message;
        };

        /**
         * Creates a plain object from a ProtocolMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ProtocolMessage
         * @static
         * @param {proto.ProtocolMessage} message ProtocolMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ProtocolMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.key = null;
                object.type = options.enums === String ? "REVOKE" : 0;
                object.ephemeralExpiration = 0;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.ephemeralSettingTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.ephemeralSettingTimestamp = options.longs === String ? "0" : 0;
                object.historySyncNotification = null;
                object.appStateSyncKeyShare = null;
                object.appStateSyncKeyRequest = null;
                object.initialSecurityNotificationSettingSync = null;
                object.appStateFatalExceptionNotification = null;
                object.disappearingMode = null;
            }
            if (message.key != null && message.hasOwnProperty("key"))
                object.key = $root.proto.MessageKey.toObject(message.key, options);
            if (message.type != null && message.hasOwnProperty("type"))
                object.type = options.enums === String ? $root.proto.ProtocolMessage.ProtocolMessageType[message.type] : message.type;
            if (message.ephemeralExpiration != null && message.hasOwnProperty("ephemeralExpiration"))
                object.ephemeralExpiration = message.ephemeralExpiration;
            if (message.ephemeralSettingTimestamp != null && message.hasOwnProperty("ephemeralSettingTimestamp"))
                if (typeof message.ephemeralSettingTimestamp === "number")
                    object.ephemeralSettingTimestamp = options.longs === String ? String(message.ephemeralSettingTimestamp) : message.ephemeralSettingTimestamp;
                else
                    object.ephemeralSettingTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.ephemeralSettingTimestamp) : options.longs === Number ? new $util.LongBits(message.ephemeralSettingTimestamp.low >>> 0, message.ephemeralSettingTimestamp.high >>> 0).toNumber() : message.ephemeralSettingTimestamp;
            if (message.historySyncNotification != null && message.hasOwnProperty("historySyncNotification"))
                object.historySyncNotification = $root.proto.HistorySyncNotification.toObject(message.historySyncNotification, options);
            if (message.appStateSyncKeyShare != null && message.hasOwnProperty("appStateSyncKeyShare"))
                object.appStateSyncKeyShare = $root.proto.AppStateSyncKeyShare.toObject(message.appStateSyncKeyShare, options);
            if (message.appStateSyncKeyRequest != null && message.hasOwnProperty("appStateSyncKeyRequest"))
                object.appStateSyncKeyRequest = $root.proto.AppStateSyncKeyRequest.toObject(message.appStateSyncKeyRequest, options);
            if (message.initialSecurityNotificationSettingSync != null && message.hasOwnProperty("initialSecurityNotificationSettingSync"))
                object.initialSecurityNotificationSettingSync = $root.proto.InitialSecurityNotificationSettingSync.toObject(message.initialSecurityNotificationSettingSync, options);
            if (message.appStateFatalExceptionNotification != null && message.hasOwnProperty("appStateFatalExceptionNotification"))
                object.appStateFatalExceptionNotification = $root.proto.AppStateFatalExceptionNotification.toObject(message.appStateFatalExceptionNotification, options);
            if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode"))
                object.disappearingMode = $root.proto.DisappearingMode.toObject(message.disappearingMode, options);
            return object;
        };

        /**
         * Converts this ProtocolMessage to JSON.
         * @function toJSON
         * @memberof proto.ProtocolMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ProtocolMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * ProtocolMessageType enum.
         * @name proto.ProtocolMessage.ProtocolMessageType
         * @enum {number}
         * @property {number} REVOKE=0 REVOKE value
         * @property {number} EPHEMERAL_SETTING=3 EPHEMERAL_SETTING value
         * @property {number} EPHEMERAL_SYNC_RESPONSE=4 EPHEMERAL_SYNC_RESPONSE value
         * @property {number} HISTORY_SYNC_NOTIFICATION=5 HISTORY_SYNC_NOTIFICATION value
         * @property {number} APP_STATE_SYNC_KEY_SHARE=6 APP_STATE_SYNC_KEY_SHARE value
         * @property {number} APP_STATE_SYNC_KEY_REQUEST=7 APP_STATE_SYNC_KEY_REQUEST value
         * @property {number} MSG_FANOUT_BACKFILL_REQUEST=8 MSG_FANOUT_BACKFILL_REQUEST value
         * @property {number} INITIAL_SECURITY_NOTIFICATION_SETTING_SYNC=9 INITIAL_SECURITY_NOTIFICATION_SETTING_SYNC value
         * @property {number} APP_STATE_FATAL_EXCEPTION_NOTIFICATION=10 APP_STATE_FATAL_EXCEPTION_NOTIFICATION value
         */
        ProtocolMessage.ProtocolMessageType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "REVOKE"] = 0;
            values[valuesById[3] = "EPHEMERAL_SETTING"] = 3;
            values[valuesById[4] = "EPHEMERAL_SYNC_RESPONSE"] = 4;
            values[valuesById[5] = "HISTORY_SYNC_NOTIFICATION"] = 5;
            values[valuesById[6] = "APP_STATE_SYNC_KEY_SHARE"] = 6;
            values[valuesById[7] = "APP_STATE_SYNC_KEY_REQUEST"] = 7;
            values[valuesById[8] = "MSG_FANOUT_BACKFILL_REQUEST"] = 8;
            values[valuesById[9] = "INITIAL_SECURITY_NOTIFICATION_SETTING_SYNC"] = 9;
            values[valuesById[10] = "APP_STATE_FATAL_EXCEPTION_NOTIFICATION"] = 10;
            return values;
        })();

        return ProtocolMessage;
    })();

    proto.HistorySyncNotification = (function() {

        /**
         * Properties of a HistorySyncNotification.
         * @memberof proto
         * @interface IHistorySyncNotification
         * @property {Uint8Array|null} [fileSha256] HistorySyncNotification fileSha256
         * @property {number|Long|null} [fileLength] HistorySyncNotification fileLength
         * @property {Uint8Array|null} [mediaKey] HistorySyncNotification mediaKey
         * @property {Uint8Array|null} [fileEncSha256] HistorySyncNotification fileEncSha256
         * @property {string|null} [directPath] HistorySyncNotification directPath
         * @property {proto.HistorySyncNotification.HistorySyncNotificationHistorySyncType|null} [syncType] HistorySyncNotification syncType
         * @property {number|null} [chunkOrder] HistorySyncNotification chunkOrder
         * @property {string|null} [originalMessageId] HistorySyncNotification originalMessageId
         */

        /**
         * Constructs a new HistorySyncNotification.
         * @memberof proto
         * @classdesc Represents a HistorySyncNotification.
         * @implements IHistorySyncNotification
         * @constructor
         * @param {proto.IHistorySyncNotification=} [properties] Properties to set
         */
        function HistorySyncNotification(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * HistorySyncNotification fileSha256.
         * @member {Uint8Array} fileSha256
         * @memberof proto.HistorySyncNotification
         * @instance
         */
        HistorySyncNotification.prototype.fileSha256 = $util.newBuffer([]);

        /**
         * HistorySyncNotification fileLength.
         * @member {number|Long} fileLength
         * @memberof proto.HistorySyncNotification
         * @instance
         */
        HistorySyncNotification.prototype.fileLength = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * HistorySyncNotification mediaKey.
         * @member {Uint8Array} mediaKey
         * @memberof proto.HistorySyncNotification
         * @instance
         */
        HistorySyncNotification.prototype.mediaKey = $util.newBuffer([]);

        /**
         * HistorySyncNotification fileEncSha256.
         * @member {Uint8Array} fileEncSha256
         * @memberof proto.HistorySyncNotification
         * @instance
         */
        HistorySyncNotification.prototype.fileEncSha256 = $util.newBuffer([]);

        /**
         * HistorySyncNotification directPath.
         * @member {string} directPath
         * @memberof proto.HistorySyncNotification
         * @instance
         */
        HistorySyncNotification.prototype.directPath = "";

        /**
         * HistorySyncNotification syncType.
         * @member {proto.HistorySyncNotification.HistorySyncNotificationHistorySyncType} syncType
         * @memberof proto.HistorySyncNotification
         * @instance
         */
        HistorySyncNotification.prototype.syncType = 0;

        /**
         * HistorySyncNotification chunkOrder.
         * @member {number} chunkOrder
         * @memberof proto.HistorySyncNotification
         * @instance
         */
        HistorySyncNotification.prototype.chunkOrder = 0;

        /**
         * HistorySyncNotification originalMessageId.
         * @member {string} originalMessageId
         * @memberof proto.HistorySyncNotification
         * @instance
         */
        HistorySyncNotification.prototype.originalMessageId = "";

        /**
         * Creates a new HistorySyncNotification instance using the specified properties.
         * @function create
         * @memberof proto.HistorySyncNotification
         * @static
         * @param {proto.IHistorySyncNotification=} [properties] Properties to set
         * @returns {proto.HistorySyncNotification} HistorySyncNotification instance
         */
        HistorySyncNotification.create = function create(properties) {
            return new HistorySyncNotification(properties);
        };

        /**
         * Encodes the specified HistorySyncNotification message. Does not implicitly {@link proto.HistorySyncNotification.verify|verify} messages.
         * @function encode
         * @memberof proto.HistorySyncNotification
         * @static
         * @param {proto.IHistorySyncNotification} message HistorySyncNotification message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HistorySyncNotification.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.fileSha256 != null && Object.hasOwnProperty.call(message, "fileSha256"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.fileSha256);
            if (message.fileLength != null && Object.hasOwnProperty.call(message, "fileLength"))
                writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.fileLength);
            if (message.mediaKey != null && Object.hasOwnProperty.call(message, "mediaKey"))
                writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.mediaKey);
            if (message.fileEncSha256 != null && Object.hasOwnProperty.call(message, "fileEncSha256"))
                writer.uint32(/* id 4, wireType 2 =*/34).bytes(message.fileEncSha256);
            if (message.directPath != null && Object.hasOwnProperty.call(message, "directPath"))
                writer.uint32(/* id 5, wireType 2 =*/42).string(message.directPath);
            if (message.syncType != null && Object.hasOwnProperty.call(message, "syncType"))
                writer.uint32(/* id 6, wireType 0 =*/48).int32(message.syncType);
            if (message.chunkOrder != null && Object.hasOwnProperty.call(message, "chunkOrder"))
                writer.uint32(/* id 7, wireType 0 =*/56).uint32(message.chunkOrder);
            if (message.originalMessageId != null && Object.hasOwnProperty.call(message, "originalMessageId"))
                writer.uint32(/* id 8, wireType 2 =*/66).string(message.originalMessageId);
            return writer;
        };

        /**
         * Encodes the specified HistorySyncNotification message, length delimited. Does not implicitly {@link proto.HistorySyncNotification.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.HistorySyncNotification
         * @static
         * @param {proto.IHistorySyncNotification} message HistorySyncNotification message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HistorySyncNotification.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a HistorySyncNotification message from the specified reader or buffer.
         * @function decode
         * @memberof proto.HistorySyncNotification
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.HistorySyncNotification} HistorySyncNotification
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HistorySyncNotification.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HistorySyncNotification();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.fileSha256 = reader.bytes();
                    break;
                case 2:
                    message.fileLength = reader.uint64();
                    break;
                case 3:
                    message.mediaKey = reader.bytes();
                    break;
                case 4:
                    message.fileEncSha256 = reader.bytes();
                    break;
                case 5:
                    message.directPath = reader.string();
                    break;
                case 6:
                    message.syncType = reader.int32();
                    break;
                case 7:
                    message.chunkOrder = reader.uint32();
                    break;
                case 8:
                    message.originalMessageId = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a HistorySyncNotification message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.HistorySyncNotification
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.HistorySyncNotification} HistorySyncNotification
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HistorySyncNotification.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a HistorySyncNotification message.
         * @function verify
         * @memberof proto.HistorySyncNotification
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        HistorySyncNotification.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.fileSha256 != null && message.hasOwnProperty("fileSha256"))
                if (!(message.fileSha256 && typeof message.fileSha256.length === "number" || $util.isString(message.fileSha256)))
                    return "fileSha256: buffer expected";
            if (message.fileLength != null && message.hasOwnProperty("fileLength"))
                if (!$util.isInteger(message.fileLength) && !(message.fileLength && $util.isInteger(message.fileLength.low) && $util.isInteger(message.fileLength.high)))
                    return "fileLength: integer|Long expected";
            if (message.mediaKey != null && message.hasOwnProperty("mediaKey"))
                if (!(message.mediaKey && typeof message.mediaKey.length === "number" || $util.isString(message.mediaKey)))
                    return "mediaKey: buffer expected";
            if (message.fileEncSha256 != null && message.hasOwnProperty("fileEncSha256"))
                if (!(message.fileEncSha256 && typeof message.fileEncSha256.length === "number" || $util.isString(message.fileEncSha256)))
                    return "fileEncSha256: buffer expected";
            if (message.directPath != null && message.hasOwnProperty("directPath"))
                if (!$util.isString(message.directPath))
                    return "directPath: string expected";
            if (message.syncType != null && message.hasOwnProperty("syncType"))
                switch (message.syncType) {
                default:
                    return "syncType: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                    break;
                }
            if (message.chunkOrder != null && message.hasOwnProperty("chunkOrder"))
                if (!$util.isInteger(message.chunkOrder))
                    return "chunkOrder: integer expected";
            if (message.originalMessageId != null && message.hasOwnProperty("originalMessageId"))
                if (!$util.isString(message.originalMessageId))
                    return "originalMessageId: string expected";
            return null;
        };

        /**
         * Creates a HistorySyncNotification message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.HistorySyncNotification
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.HistorySyncNotification} HistorySyncNotification
         */
        HistorySyncNotification.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.HistorySyncNotification)
                return object;
            var message = new $root.proto.HistorySyncNotification();
            if (object.fileSha256 != null)
                if (typeof object.fileSha256 === "string")
                    $util.base64.decode(object.fileSha256, message.fileSha256 = $util.newBuffer($util.base64.length(object.fileSha256)), 0);
                else if (object.fileSha256.length)
                    message.fileSha256 = object.fileSha256;
            if (object.fileLength != null)
                if ($util.Long)
                    (message.fileLength = $util.Long.fromValue(object.fileLength)).unsigned = true;
                else if (typeof object.fileLength === "string")
                    message.fileLength = parseInt(object.fileLength, 10);
                else if (typeof object.fileLength === "number")
                    message.fileLength = object.fileLength;
                else if (typeof object.fileLength === "object")
                    message.fileLength = new $util.LongBits(object.fileLength.low >>> 0, object.fileLength.high >>> 0).toNumber(true);
            if (object.mediaKey != null)
                if (typeof object.mediaKey === "string")
                    $util.base64.decode(object.mediaKey, message.mediaKey = $util.newBuffer($util.base64.length(object.mediaKey)), 0);
                else if (object.mediaKey.length)
                    message.mediaKey = object.mediaKey;
            if (object.fileEncSha256 != null)
                if (typeof object.fileEncSha256 === "string")
                    $util.base64.decode(object.fileEncSha256, message.fileEncSha256 = $util.newBuffer($util.base64.length(object.fileEncSha256)), 0);
                else if (object.fileEncSha256.length)
                    message.fileEncSha256 = object.fileEncSha256;
            if (object.directPath != null)
                message.directPath = String(object.directPath);
            switch (object.syncType) {
            case "INITIAL_BOOTSTRAP":
            case 0:
                message.syncType = 0;
                break;
            case "INITIAL_STATUS_V3":
            case 1:
                message.syncType = 1;
                break;
            case "FULL":
            case 2:
                message.syncType = 2;
                break;
            case "RECENT":
            case 3:
                message.syncType = 3;
                break;
            case "PUSH_NAME":
            case 4:
                message.syncType = 4;
                break;
            }
            if (object.chunkOrder != null)
                message.chunkOrder = object.chunkOrder >>> 0;
            if (object.originalMessageId != null)
                message.originalMessageId = String(object.originalMessageId);
            return message;
        };

        /**
         * Creates a plain object from a HistorySyncNotification message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.HistorySyncNotification
         * @static
         * @param {proto.HistorySyncNotification} message HistorySyncNotification
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        HistorySyncNotification.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object.fileSha256 = "";
                else {
                    object.fileSha256 = [];
                    if (options.bytes !== Array)
                        object.fileSha256 = $util.newBuffer(object.fileSha256);
                }
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.fileLength = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.fileLength = options.longs === String ? "0" : 0;
                if (options.bytes === String)
                    object.mediaKey = "";
                else {
                    object.mediaKey = [];
                    if (options.bytes !== Array)
                        object.mediaKey = $util.newBuffer(object.mediaKey);
                }
                if (options.bytes === String)
                    object.fileEncSha256 = "";
                else {
                    object.fileEncSha256 = [];
                    if (options.bytes !== Array)
                        object.fileEncSha256 = $util.newBuffer(object.fileEncSha256);
                }
                object.directPath = "";
                object.syncType = options.enums === String ? "INITIAL_BOOTSTRAP" : 0;
                object.chunkOrder = 0;
                object.originalMessageId = "";
            }
            if (message.fileSha256 != null && message.hasOwnProperty("fileSha256"))
                object.fileSha256 = options.bytes === String ? $util.base64.encode(message.fileSha256, 0, message.fileSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.fileSha256) : message.fileSha256;
            if (message.fileLength != null && message.hasOwnProperty("fileLength"))
                if (typeof message.fileLength === "number")
                    object.fileLength = options.longs === String ? String(message.fileLength) : message.fileLength;
                else
                    object.fileLength = options.longs === String ? $util.Long.prototype.toString.call(message.fileLength) : options.longs === Number ? new $util.LongBits(message.fileLength.low >>> 0, message.fileLength.high >>> 0).toNumber(true) : message.fileLength;
            if (message.mediaKey != null && message.hasOwnProperty("mediaKey"))
                object.mediaKey = options.bytes === String ? $util.base64.encode(message.mediaKey, 0, message.mediaKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.mediaKey) : message.mediaKey;
            if (message.fileEncSha256 != null && message.hasOwnProperty("fileEncSha256"))
                object.fileEncSha256 = options.bytes === String ? $util.base64.encode(message.fileEncSha256, 0, message.fileEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.fileEncSha256) : message.fileEncSha256;
            if (message.directPath != null && message.hasOwnProperty("directPath"))
                object.directPath = message.directPath;
            if (message.syncType != null && message.hasOwnProperty("syncType"))
                object.syncType = options.enums === String ? $root.proto.HistorySyncNotification.HistorySyncNotificationHistorySyncType[message.syncType] : message.syncType;
            if (message.chunkOrder != null && message.hasOwnProperty("chunkOrder"))
                object.chunkOrder = message.chunkOrder;
            if (message.originalMessageId != null && message.hasOwnProperty("originalMessageId"))
                object.originalMessageId = message.originalMessageId;
            return object;
        };

        /**
         * Converts this HistorySyncNotification to JSON.
         * @function toJSON
         * @memberof proto.HistorySyncNotification
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        HistorySyncNotification.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * HistorySyncNotificationHistorySyncType enum.
         * @name proto.HistorySyncNotification.HistorySyncNotificationHistorySyncType
         * @enum {number}
         * @property {number} INITIAL_BOOTSTRAP=0 INITIAL_BOOTSTRAP value
         * @property {number} INITIAL_STATUS_V3=1 INITIAL_STATUS_V3 value
         * @property {number} FULL=2 FULL value
         * @property {number} RECENT=3 RECENT value
         * @property {number} PUSH_NAME=4 PUSH_NAME value
         */
        HistorySyncNotification.HistorySyncNotificationHistorySyncType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "INITIAL_BOOTSTRAP"] = 0;
            values[valuesById[1] = "INITIAL_STATUS_V3"] = 1;
            values[valuesById[2] = "FULL"] = 2;
            values[valuesById[3] = "RECENT"] = 3;
            values[valuesById[4] = "PUSH_NAME"] = 4;
            return values;
        })();

        return HistorySyncNotification;
    })();

    proto.AppStateSyncKey = (function() {

        /**
         * Properties of an AppStateSyncKey.
         * @memberof proto
         * @interface IAppStateSyncKey
         * @property {proto.IAppStateSyncKeyId|null} [keyId] AppStateSyncKey keyId
         * @property {proto.IAppStateSyncKeyData|null} [keyData] AppStateSyncKey keyData
         */

        /**
         * Constructs a new AppStateSyncKey.
         * @memberof proto
         * @classdesc Represents an AppStateSyncKey.
         * @implements IAppStateSyncKey
         * @constructor
         * @param {proto.IAppStateSyncKey=} [properties] Properties to set
         */
        function AppStateSyncKey(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * AppStateSyncKey keyId.
         * @member {proto.IAppStateSyncKeyId|null|undefined} keyId
         * @memberof proto.AppStateSyncKey
         * @instance
         */
        AppStateSyncKey.prototype.keyId = null;

        /**
         * AppStateSyncKey keyData.
         * @member {proto.IAppStateSyncKeyData|null|undefined} keyData
         * @memberof proto.AppStateSyncKey
         * @instance
         */
        AppStateSyncKey.prototype.keyData = null;

        /**
         * Creates a new AppStateSyncKey instance using the specified properties.
         * @function create
         * @memberof proto.AppStateSyncKey
         * @static
         * @param {proto.IAppStateSyncKey=} [properties] Properties to set
         * @returns {proto.AppStateSyncKey} AppStateSyncKey instance
         */
        AppStateSyncKey.create = function create(properties) {
            return new AppStateSyncKey(properties);
        };

        /**
         * Encodes the specified AppStateSyncKey message. Does not implicitly {@link proto.AppStateSyncKey.verify|verify} messages.
         * @function encode
         * @memberof proto.AppStateSyncKey
         * @static
         * @param {proto.IAppStateSyncKey} message AppStateSyncKey message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AppStateSyncKey.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.keyId != null && Object.hasOwnProperty.call(message, "keyId"))
                $root.proto.AppStateSyncKeyId.encode(message.keyId, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.keyData != null && Object.hasOwnProperty.call(message, "keyData"))
                $root.proto.AppStateSyncKeyData.encode(message.keyData, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified AppStateSyncKey message, length delimited. Does not implicitly {@link proto.AppStateSyncKey.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.AppStateSyncKey
         * @static
         * @param {proto.IAppStateSyncKey} message AppStateSyncKey message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AppStateSyncKey.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an AppStateSyncKey message from the specified reader or buffer.
         * @function decode
         * @memberof proto.AppStateSyncKey
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.AppStateSyncKey} AppStateSyncKey
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AppStateSyncKey.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.AppStateSyncKey();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.keyId = $root.proto.AppStateSyncKeyId.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.keyData = $root.proto.AppStateSyncKeyData.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an AppStateSyncKey message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.AppStateSyncKey
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.AppStateSyncKey} AppStateSyncKey
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AppStateSyncKey.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an AppStateSyncKey message.
         * @function verify
         * @memberof proto.AppStateSyncKey
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        AppStateSyncKey.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.keyId != null && message.hasOwnProperty("keyId")) {
                var error = $root.proto.AppStateSyncKeyId.verify(message.keyId);
                if (error)
                    return "keyId." + error;
            }
            if (message.keyData != null && message.hasOwnProperty("keyData")) {
                var error = $root.proto.AppStateSyncKeyData.verify(message.keyData);
                if (error)
                    return "keyData." + error;
            }
            return null;
        };

        /**
         * Creates an AppStateSyncKey message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.AppStateSyncKey
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.AppStateSyncKey} AppStateSyncKey
         */
        AppStateSyncKey.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.AppStateSyncKey)
                return object;
            var message = new $root.proto.AppStateSyncKey();
            if (object.keyId != null) {
                if (typeof object.keyId !== "object")
                    throw TypeError(".proto.AppStateSyncKey.keyId: object expected");
                message.keyId = $root.proto.AppStateSyncKeyId.fromObject(object.keyId);
            }
            if (object.keyData != null) {
                if (typeof object.keyData !== "object")
                    throw TypeError(".proto.AppStateSyncKey.keyData: object expected");
                message.keyData = $root.proto.AppStateSyncKeyData.fromObject(object.keyData);
            }
            return message;
        };

        /**
         * Creates a plain object from an AppStateSyncKey message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.AppStateSyncKey
         * @static
         * @param {proto.AppStateSyncKey} message AppStateSyncKey
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        AppStateSyncKey.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.keyId = null;
                object.keyData = null;
            }
            if (message.keyId != null && message.hasOwnProperty("keyId"))
                object.keyId = $root.proto.AppStateSyncKeyId.toObject(message.keyId, options);
            if (message.keyData != null && message.hasOwnProperty("keyData"))
                object.keyData = $root.proto.AppStateSyncKeyData.toObject(message.keyData, options);
            return object;
        };

        /**
         * Converts this AppStateSyncKey to JSON.
         * @function toJSON
         * @memberof proto.AppStateSyncKey
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        AppStateSyncKey.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return AppStateSyncKey;
    })();

    proto.AppStateSyncKeyId = (function() {

        /**
         * Properties of an AppStateSyncKeyId.
         * @memberof proto
         * @interface IAppStateSyncKeyId
         * @property {Uint8Array|null} [keyId] AppStateSyncKeyId keyId
         */

        /**
         * Constructs a new AppStateSyncKeyId.
         * @memberof proto
         * @classdesc Represents an AppStateSyncKeyId.
         * @implements IAppStateSyncKeyId
         * @constructor
         * @param {proto.IAppStateSyncKeyId=} [properties] Properties to set
         */
        function AppStateSyncKeyId(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * AppStateSyncKeyId keyId.
         * @member {Uint8Array} keyId
         * @memberof proto.AppStateSyncKeyId
         * @instance
         */
        AppStateSyncKeyId.prototype.keyId = $util.newBuffer([]);

        /**
         * Creates a new AppStateSyncKeyId instance using the specified properties.
         * @function create
         * @memberof proto.AppStateSyncKeyId
         * @static
         * @param {proto.IAppStateSyncKeyId=} [properties] Properties to set
         * @returns {proto.AppStateSyncKeyId} AppStateSyncKeyId instance
         */
        AppStateSyncKeyId.create = function create(properties) {
            return new AppStateSyncKeyId(properties);
        };

        /**
         * Encodes the specified AppStateSyncKeyId message. Does not implicitly {@link proto.AppStateSyncKeyId.verify|verify} messages.
         * @function encode
         * @memberof proto.AppStateSyncKeyId
         * @static
         * @param {proto.IAppStateSyncKeyId} message AppStateSyncKeyId message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AppStateSyncKeyId.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.keyId != null && Object.hasOwnProperty.call(message, "keyId"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.keyId);
            return writer;
        };

        /**
         * Encodes the specified AppStateSyncKeyId message, length delimited. Does not implicitly {@link proto.AppStateSyncKeyId.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.AppStateSyncKeyId
         * @static
         * @param {proto.IAppStateSyncKeyId} message AppStateSyncKeyId message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AppStateSyncKeyId.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an AppStateSyncKeyId message from the specified reader or buffer.
         * @function decode
         * @memberof proto.AppStateSyncKeyId
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.AppStateSyncKeyId} AppStateSyncKeyId
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AppStateSyncKeyId.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.AppStateSyncKeyId();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.keyId = reader.bytes();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an AppStateSyncKeyId message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.AppStateSyncKeyId
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.AppStateSyncKeyId} AppStateSyncKeyId
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AppStateSyncKeyId.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an AppStateSyncKeyId message.
         * @function verify
         * @memberof proto.AppStateSyncKeyId
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        AppStateSyncKeyId.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.keyId != null && message.hasOwnProperty("keyId"))
                if (!(message.keyId && typeof message.keyId.length === "number" || $util.isString(message.keyId)))
                    return "keyId: buffer expected";
            return null;
        };

        /**
         * Creates an AppStateSyncKeyId message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.AppStateSyncKeyId
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.AppStateSyncKeyId} AppStateSyncKeyId
         */
        AppStateSyncKeyId.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.AppStateSyncKeyId)
                return object;
            var message = new $root.proto.AppStateSyncKeyId();
            if (object.keyId != null)
                if (typeof object.keyId === "string")
                    $util.base64.decode(object.keyId, message.keyId = $util.newBuffer($util.base64.length(object.keyId)), 0);
                else if (object.keyId.length)
                    message.keyId = object.keyId;
            return message;
        };

        /**
         * Creates a plain object from an AppStateSyncKeyId message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.AppStateSyncKeyId
         * @static
         * @param {proto.AppStateSyncKeyId} message AppStateSyncKeyId
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        AppStateSyncKeyId.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                if (options.bytes === String)
                    object.keyId = "";
                else {
                    object.keyId = [];
                    if (options.bytes !== Array)
                        object.keyId = $util.newBuffer(object.keyId);
                }
            if (message.keyId != null && message.hasOwnProperty("keyId"))
                object.keyId = options.bytes === String ? $util.base64.encode(message.keyId, 0, message.keyId.length) : options.bytes === Array ? Array.prototype.slice.call(message.keyId) : message.keyId;
            return object;
        };

        /**
         * Converts this AppStateSyncKeyId to JSON.
         * @function toJSON
         * @memberof proto.AppStateSyncKeyId
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        AppStateSyncKeyId.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return AppStateSyncKeyId;
    })();

    proto.AppStateSyncKeyFingerprint = (function() {

        /**
         * Properties of an AppStateSyncKeyFingerprint.
         * @memberof proto
         * @interface IAppStateSyncKeyFingerprint
         * @property {number|null} [rawId] AppStateSyncKeyFingerprint rawId
         * @property {number|null} [currentIndex] AppStateSyncKeyFingerprint currentIndex
         * @property {Array.<number>|null} [deviceIndexes] AppStateSyncKeyFingerprint deviceIndexes
         */

        /**
         * Constructs a new AppStateSyncKeyFingerprint.
         * @memberof proto
         * @classdesc Represents an AppStateSyncKeyFingerprint.
         * @implements IAppStateSyncKeyFingerprint
         * @constructor
         * @param {proto.IAppStateSyncKeyFingerprint=} [properties] Properties to set
         */
        function AppStateSyncKeyFingerprint(properties) {
            this.deviceIndexes = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * AppStateSyncKeyFingerprint rawId.
         * @member {number} rawId
         * @memberof proto.AppStateSyncKeyFingerprint
         * @instance
         */
        AppStateSyncKeyFingerprint.prototype.rawId = 0;

        /**
         * AppStateSyncKeyFingerprint currentIndex.
         * @member {number} currentIndex
         * @memberof proto.AppStateSyncKeyFingerprint
         * @instance
         */
        AppStateSyncKeyFingerprint.prototype.currentIndex = 0;

        /**
         * AppStateSyncKeyFingerprint deviceIndexes.
         * @member {Array.<number>} deviceIndexes
         * @memberof proto.AppStateSyncKeyFingerprint
         * @instance
         */
        AppStateSyncKeyFingerprint.prototype.deviceIndexes = $util.emptyArray;

        /**
         * Creates a new AppStateSyncKeyFingerprint instance using the specified properties.
         * @function create
         * @memberof proto.AppStateSyncKeyFingerprint
         * @static
         * @param {proto.IAppStateSyncKeyFingerprint=} [properties] Properties to set
         * @returns {proto.AppStateSyncKeyFingerprint} AppStateSyncKeyFingerprint instance
         */
        AppStateSyncKeyFingerprint.create = function create(properties) {
            return new AppStateSyncKeyFingerprint(properties);
        };

        /**
         * Encodes the specified AppStateSyncKeyFingerprint message. Does not implicitly {@link proto.AppStateSyncKeyFingerprint.verify|verify} messages.
         * @function encode
         * @memberof proto.AppStateSyncKeyFingerprint
         * @static
         * @param {proto.IAppStateSyncKeyFingerprint} message AppStateSyncKeyFingerprint message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AppStateSyncKeyFingerprint.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.rawId != null && Object.hasOwnProperty.call(message, "rawId"))
                writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.rawId);
            if (message.currentIndex != null && Object.hasOwnProperty.call(message, "currentIndex"))
                writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.currentIndex);
            if (message.deviceIndexes != null && message.deviceIndexes.length) {
                writer.uint32(/* id 3, wireType 2 =*/26).fork();
                for (var i = 0; i < message.deviceIndexes.length; ++i)
                    writer.uint32(message.deviceIndexes[i]);
                writer.ldelim();
            }
            return writer;
        };

        /**
         * Encodes the specified AppStateSyncKeyFingerprint message, length delimited. Does not implicitly {@link proto.AppStateSyncKeyFingerprint.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.AppStateSyncKeyFingerprint
         * @static
         * @param {proto.IAppStateSyncKeyFingerprint} message AppStateSyncKeyFingerprint message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AppStateSyncKeyFingerprint.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an AppStateSyncKeyFingerprint message from the specified reader or buffer.
         * @function decode
         * @memberof proto.AppStateSyncKeyFingerprint
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.AppStateSyncKeyFingerprint} AppStateSyncKeyFingerprint
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AppStateSyncKeyFingerprint.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.AppStateSyncKeyFingerprint();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.rawId = reader.uint32();
                    break;
                case 2:
                    message.currentIndex = reader.uint32();
                    break;
                case 3:
                    if (!(message.deviceIndexes && message.deviceIndexes.length))
                        message.deviceIndexes = [];
                    if ((tag & 7) === 2) {
                        var end2 = reader.uint32() + reader.pos;
                        while (reader.pos < end2)
                            message.deviceIndexes.push(reader.uint32());
                    } else
                        message.deviceIndexes.push(reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an AppStateSyncKeyFingerprint message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.AppStateSyncKeyFingerprint
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.AppStateSyncKeyFingerprint} AppStateSyncKeyFingerprint
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AppStateSyncKeyFingerprint.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an AppStateSyncKeyFingerprint message.
         * @function verify
         * @memberof proto.AppStateSyncKeyFingerprint
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        AppStateSyncKeyFingerprint.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.rawId != null && message.hasOwnProperty("rawId"))
                if (!$util.isInteger(message.rawId))
                    return "rawId: integer expected";
            if (message.currentIndex != null && message.hasOwnProperty("currentIndex"))
                if (!$util.isInteger(message.currentIndex))
                    return "currentIndex: integer expected";
            if (message.deviceIndexes != null && message.hasOwnProperty("deviceIndexes")) {
                if (!Array.isArray(message.deviceIndexes))
                    return "deviceIndexes: array expected";
                for (var i = 0; i < message.deviceIndexes.length; ++i)
                    if (!$util.isInteger(message.deviceIndexes[i]))
                        return "deviceIndexes: integer[] expected";
            }
            return null;
        };

        /**
         * Creates an AppStateSyncKeyFingerprint message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.AppStateSyncKeyFingerprint
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.AppStateSyncKeyFingerprint} AppStateSyncKeyFingerprint
         */
        AppStateSyncKeyFingerprint.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.AppStateSyncKeyFingerprint)
                return object;
            var message = new $root.proto.AppStateSyncKeyFingerprint();
            if (object.rawId != null)
                message.rawId = object.rawId >>> 0;
            if (object.currentIndex != null)
                message.currentIndex = object.currentIndex >>> 0;
            if (object.deviceIndexes) {
                if (!Array.isArray(object.deviceIndexes))
                    throw TypeError(".proto.AppStateSyncKeyFingerprint.deviceIndexes: array expected");
                message.deviceIndexes = [];
                for (var i = 0; i < object.deviceIndexes.length; ++i)
                    message.deviceIndexes[i] = object.deviceIndexes[i] >>> 0;
            }
            return message;
        };

        /**
         * Creates a plain object from an AppStateSyncKeyFingerprint message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.AppStateSyncKeyFingerprint
         * @static
         * @param {proto.AppStateSyncKeyFingerprint} message AppStateSyncKeyFingerprint
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        AppStateSyncKeyFingerprint.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.deviceIndexes = [];
            if (options.defaults) {
                object.rawId = 0;
                object.currentIndex = 0;
            }
            if (message.rawId != null && message.hasOwnProperty("rawId"))
                object.rawId = message.rawId;
            if (message.currentIndex != null && message.hasOwnProperty("currentIndex"))
                object.currentIndex = message.currentIndex;
            if (message.deviceIndexes && message.deviceIndexes.length) {
                object.deviceIndexes = [];
                for (var j = 0; j < message.deviceIndexes.length; ++j)
                    object.deviceIndexes[j] = message.deviceIndexes[j];
            }
            return object;
        };

        /**
         * Converts this AppStateSyncKeyFingerprint to JSON.
         * @function toJSON
         * @memberof proto.AppStateSyncKeyFingerprint
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        AppStateSyncKeyFingerprint.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return AppStateSyncKeyFingerprint;
    })();

    proto.AppStateSyncKeyData = (function() {

        /**
         * Properties of an AppStateSyncKeyData.
         * @memberof proto
         * @interface IAppStateSyncKeyData
         * @property {Uint8Array|null} [keyData] AppStateSyncKeyData keyData
         * @property {proto.IAppStateSyncKeyFingerprint|null} [fingerprint] AppStateSyncKeyData fingerprint
         * @property {number|Long|null} [timestamp] AppStateSyncKeyData timestamp
         */

        /**
         * Constructs a new AppStateSyncKeyData.
         * @memberof proto
         * @classdesc Represents an AppStateSyncKeyData.
         * @implements IAppStateSyncKeyData
         * @constructor
         * @param {proto.IAppStateSyncKeyData=} [properties] Properties to set
         */
        function AppStateSyncKeyData(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * AppStateSyncKeyData keyData.
         * @member {Uint8Array} keyData
         * @memberof proto.AppStateSyncKeyData
         * @instance
         */
        AppStateSyncKeyData.prototype.keyData = $util.newBuffer([]);

        /**
         * AppStateSyncKeyData fingerprint.
         * @member {proto.IAppStateSyncKeyFingerprint|null|undefined} fingerprint
         * @memberof proto.AppStateSyncKeyData
         * @instance
         */
        AppStateSyncKeyData.prototype.fingerprint = null;

        /**
         * AppStateSyncKeyData timestamp.
         * @member {number|Long} timestamp
         * @memberof proto.AppStateSyncKeyData
         * @instance
         */
        AppStateSyncKeyData.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * Creates a new AppStateSyncKeyData instance using the specified properties.
         * @function create
         * @memberof proto.AppStateSyncKeyData
         * @static
         * @param {proto.IAppStateSyncKeyData=} [properties] Properties to set
         * @returns {proto.AppStateSyncKeyData} AppStateSyncKeyData instance
         */
        AppStateSyncKeyData.create = function create(properties) {
            return new AppStateSyncKeyData(properties);
        };

        /**
         * Encodes the specified AppStateSyncKeyData message. Does not implicitly {@link proto.AppStateSyncKeyData.verify|verify} messages.
         * @function encode
         * @memberof proto.AppStateSyncKeyData
         * @static
         * @param {proto.IAppStateSyncKeyData} message AppStateSyncKeyData message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AppStateSyncKeyData.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.keyData != null && Object.hasOwnProperty.call(message, "keyData"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.keyData);
            if (message.fingerprint != null && Object.hasOwnProperty.call(message, "fingerprint"))
                $root.proto.AppStateSyncKeyFingerprint.encode(message.fingerprint, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp"))
                writer.uint32(/* id 3, wireType 0 =*/24).int64(message.timestamp);
            return writer;
        };

        /**
         * Encodes the specified AppStateSyncKeyData message, length delimited. Does not implicitly {@link proto.AppStateSyncKeyData.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.AppStateSyncKeyData
         * @static
         * @param {proto.IAppStateSyncKeyData} message AppStateSyncKeyData message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AppStateSyncKeyData.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an AppStateSyncKeyData message from the specified reader or buffer.
         * @function decode
         * @memberof proto.AppStateSyncKeyData
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.AppStateSyncKeyData} AppStateSyncKeyData
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AppStateSyncKeyData.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.AppStateSyncKeyData();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.keyData = reader.bytes();
                    break;
                case 2:
                    message.fingerprint = $root.proto.AppStateSyncKeyFingerprint.decode(reader, reader.uint32());
                    break;
                case 3:
                    message.timestamp = reader.int64();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an AppStateSyncKeyData message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.AppStateSyncKeyData
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.AppStateSyncKeyData} AppStateSyncKeyData
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AppStateSyncKeyData.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an AppStateSyncKeyData message.
         * @function verify
         * @memberof proto.AppStateSyncKeyData
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        AppStateSyncKeyData.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.keyData != null && message.hasOwnProperty("keyData"))
                if (!(message.keyData && typeof message.keyData.length === "number" || $util.isString(message.keyData)))
                    return "keyData: buffer expected";
            if (message.fingerprint != null && message.hasOwnProperty("fingerprint")) {
                var error = $root.proto.AppStateSyncKeyFingerprint.verify(message.fingerprint);
                if (error)
                    return "fingerprint." + error;
            }
            if (message.timestamp != null && message.hasOwnProperty("timestamp"))
                if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high)))
                    return "timestamp: integer|Long expected";
            return null;
        };

        /**
         * Creates an AppStateSyncKeyData message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.AppStateSyncKeyData
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.AppStateSyncKeyData} AppStateSyncKeyData
         */
        AppStateSyncKeyData.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.AppStateSyncKeyData)
                return object;
            var message = new $root.proto.AppStateSyncKeyData();
            if (object.keyData != null)
                if (typeof object.keyData === "string")
                    $util.base64.decode(object.keyData, message.keyData = $util.newBuffer($util.base64.length(object.keyData)), 0);
                else if (object.keyData.length)
                    message.keyData = object.keyData;
            if (object.fingerprint != null) {
                if (typeof object.fingerprint !== "object")
                    throw TypeError(".proto.AppStateSyncKeyData.fingerprint: object expected");
                message.fingerprint = $root.proto.AppStateSyncKeyFingerprint.fromObject(object.fingerprint);
            }
            if (object.timestamp != null)
                if ($util.Long)
                    (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = false;
                else if (typeof object.timestamp === "string")
                    message.timestamp = parseInt(object.timestamp, 10);
                else if (typeof object.timestamp === "number")
                    message.timestamp = object.timestamp;
                else if (typeof object.timestamp === "object")
                    message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber();
            return message;
        };

        /**
         * Creates a plain object from an AppStateSyncKeyData message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.AppStateSyncKeyData
         * @static
         * @param {proto.AppStateSyncKeyData} message AppStateSyncKeyData
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        AppStateSyncKeyData.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object.keyData = "";
                else {
                    object.keyData = [];
                    if (options.bytes !== Array)
                        object.keyData = $util.newBuffer(object.keyData);
                }
                object.fingerprint = null;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.timestamp = options.longs === String ? "0" : 0;
            }
            if (message.keyData != null && message.hasOwnProperty("keyData"))
                object.keyData = options.bytes === String ? $util.base64.encode(message.keyData, 0, message.keyData.length) : options.bytes === Array ? Array.prototype.slice.call(message.keyData) : message.keyData;
            if (message.fingerprint != null && message.hasOwnProperty("fingerprint"))
                object.fingerprint = $root.proto.AppStateSyncKeyFingerprint.toObject(message.fingerprint, options);
            if (message.timestamp != null && message.hasOwnProperty("timestamp"))
                if (typeof message.timestamp === "number")
                    object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp;
                else
                    object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber() : message.timestamp;
            return object;
        };

        /**
         * Converts this AppStateSyncKeyData to JSON.
         * @function toJSON
         * @memberof proto.AppStateSyncKeyData
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        AppStateSyncKeyData.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return AppStateSyncKeyData;
    })();

    proto.AppStateSyncKeyShare = (function() {

        /**
         * Properties of an AppStateSyncKeyShare.
         * @memberof proto
         * @interface IAppStateSyncKeyShare
         * @property {Array.<proto.IAppStateSyncKey>|null} [keys] AppStateSyncKeyShare keys
         */

        /**
         * Constructs a new AppStateSyncKeyShare.
         * @memberof proto
         * @classdesc Represents an AppStateSyncKeyShare.
         * @implements IAppStateSyncKeyShare
         * @constructor
         * @param {proto.IAppStateSyncKeyShare=} [properties] Properties to set
         */
        function AppStateSyncKeyShare(properties) {
            this.keys = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * AppStateSyncKeyShare keys.
         * @member {Array.<proto.IAppStateSyncKey>} keys
         * @memberof proto.AppStateSyncKeyShare
         * @instance
         */
        AppStateSyncKeyShare.prototype.keys = $util.emptyArray;

        /**
         * Creates a new AppStateSyncKeyShare instance using the specified properties.
         * @function create
         * @memberof proto.AppStateSyncKeyShare
         * @static
         * @param {proto.IAppStateSyncKeyShare=} [properties] Properties to set
         * @returns {proto.AppStateSyncKeyShare} AppStateSyncKeyShare instance
         */
        AppStateSyncKeyShare.create = function create(properties) {
            return new AppStateSyncKeyShare(properties);
        };

        /**
         * Encodes the specified AppStateSyncKeyShare message. Does not implicitly {@link proto.AppStateSyncKeyShare.verify|verify} messages.
         * @function encode
         * @memberof proto.AppStateSyncKeyShare
         * @static
         * @param {proto.IAppStateSyncKeyShare} message AppStateSyncKeyShare message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AppStateSyncKeyShare.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.keys != null && message.keys.length)
                for (var i = 0; i < message.keys.length; ++i)
                    $root.proto.AppStateSyncKey.encode(message.keys[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified AppStateSyncKeyShare message, length delimited. Does not implicitly {@link proto.AppStateSyncKeyShare.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.AppStateSyncKeyShare
         * @static
         * @param {proto.IAppStateSyncKeyShare} message AppStateSyncKeyShare message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AppStateSyncKeyShare.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an AppStateSyncKeyShare message from the specified reader or buffer.
         * @function decode
         * @memberof proto.AppStateSyncKeyShare
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.AppStateSyncKeyShare} AppStateSyncKeyShare
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AppStateSyncKeyShare.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.AppStateSyncKeyShare();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    if (!(message.keys && message.keys.length))
                        message.keys = [];
                    message.keys.push($root.proto.AppStateSyncKey.decode(reader, reader.uint32()));
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an AppStateSyncKeyShare message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.AppStateSyncKeyShare
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.AppStateSyncKeyShare} AppStateSyncKeyShare
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AppStateSyncKeyShare.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an AppStateSyncKeyShare message.
         * @function verify
         * @memberof proto.AppStateSyncKeyShare
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        AppStateSyncKeyShare.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.keys != null && message.hasOwnProperty("keys")) {
                if (!Array.isArray(message.keys))
                    return "keys: array expected";
                for (var i = 0; i < message.keys.length; ++i) {
                    var error = $root.proto.AppStateSyncKey.verify(message.keys[i]);
                    if (error)
                        return "keys." + error;
                }
            }
            return null;
        };

        /**
         * Creates an AppStateSyncKeyShare message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.AppStateSyncKeyShare
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.AppStateSyncKeyShare} AppStateSyncKeyShare
         */
        AppStateSyncKeyShare.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.AppStateSyncKeyShare)
                return object;
            var message = new $root.proto.AppStateSyncKeyShare();
            if (object.keys) {
                if (!Array.isArray(object.keys))
                    throw TypeError(".proto.AppStateSyncKeyShare.keys: array expected");
                message.keys = [];
                for (var i = 0; i < object.keys.length; ++i) {
                    if (typeof object.keys[i] !== "object")
                        throw TypeError(".proto.AppStateSyncKeyShare.keys: object expected");
                    message.keys[i] = $root.proto.AppStateSyncKey.fromObject(object.keys[i]);
                }
            }
            return message;
        };

        /**
         * Creates a plain object from an AppStateSyncKeyShare message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.AppStateSyncKeyShare
         * @static
         * @param {proto.AppStateSyncKeyShare} message AppStateSyncKeyShare
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        AppStateSyncKeyShare.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.keys = [];
            if (message.keys && message.keys.length) {
                object.keys = [];
                for (var j = 0; j < message.keys.length; ++j)
                    object.keys[j] = $root.proto.AppStateSyncKey.toObject(message.keys[j], options);
            }
            return object;
        };

        /**
         * Converts this AppStateSyncKeyShare to JSON.
         * @function toJSON
         * @memberof proto.AppStateSyncKeyShare
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        AppStateSyncKeyShare.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return AppStateSyncKeyShare;
    })();

    proto.AppStateSyncKeyRequest = (function() {

        /**
         * Properties of an AppStateSyncKeyRequest.
         * @memberof proto
         * @interface IAppStateSyncKeyRequest
         * @property {Array.<proto.IAppStateSyncKeyId>|null} [keyIds] AppStateSyncKeyRequest keyIds
         */

        /**
         * Constructs a new AppStateSyncKeyRequest.
         * @memberof proto
         * @classdesc Represents an AppStateSyncKeyRequest.
         * @implements IAppStateSyncKeyRequest
         * @constructor
         * @param {proto.IAppStateSyncKeyRequest=} [properties] Properties to set
         */
        function AppStateSyncKeyRequest(properties) {
            this.keyIds = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * AppStateSyncKeyRequest keyIds.
         * @member {Array.<proto.IAppStateSyncKeyId>} keyIds
         * @memberof proto.AppStateSyncKeyRequest
         * @instance
         */
        AppStateSyncKeyRequest.prototype.keyIds = $util.emptyArray;

        /**
         * Creates a new AppStateSyncKeyRequest instance using the specified properties.
         * @function create
         * @memberof proto.AppStateSyncKeyRequest
         * @static
         * @param {proto.IAppStateSyncKeyRequest=} [properties] Properties to set
         * @returns {proto.AppStateSyncKeyRequest} AppStateSyncKeyRequest instance
         */
        AppStateSyncKeyRequest.create = function create(properties) {
            return new AppStateSyncKeyRequest(properties);
        };

        /**
         * Encodes the specified AppStateSyncKeyRequest message. Does not implicitly {@link proto.AppStateSyncKeyRequest.verify|verify} messages.
         * @function encode
         * @memberof proto.AppStateSyncKeyRequest
         * @static
         * @param {proto.IAppStateSyncKeyRequest} message AppStateSyncKeyRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AppStateSyncKeyRequest.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.keyIds != null && message.keyIds.length)
                for (var i = 0; i < message.keyIds.length; ++i)
                    $root.proto.AppStateSyncKeyId.encode(message.keyIds[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified AppStateSyncKeyRequest message, length delimited. Does not implicitly {@link proto.AppStateSyncKeyRequest.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.AppStateSyncKeyRequest
         * @static
         * @param {proto.IAppStateSyncKeyRequest} message AppStateSyncKeyRequest message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AppStateSyncKeyRequest.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an AppStateSyncKeyRequest message from the specified reader or buffer.
         * @function decode
         * @memberof proto.AppStateSyncKeyRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.AppStateSyncKeyRequest} AppStateSyncKeyRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AppStateSyncKeyRequest.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.AppStateSyncKeyRequest();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    if (!(message.keyIds && message.keyIds.length))
                        message.keyIds = [];
                    message.keyIds.push($root.proto.AppStateSyncKeyId.decode(reader, reader.uint32()));
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an AppStateSyncKeyRequest message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.AppStateSyncKeyRequest
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.AppStateSyncKeyRequest} AppStateSyncKeyRequest
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AppStateSyncKeyRequest.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an AppStateSyncKeyRequest message.
         * @function verify
         * @memberof proto.AppStateSyncKeyRequest
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        AppStateSyncKeyRequest.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.keyIds != null && message.hasOwnProperty("keyIds")) {
                if (!Array.isArray(message.keyIds))
                    return "keyIds: array expected";
                for (var i = 0; i < message.keyIds.length; ++i) {
                    var error = $root.proto.AppStateSyncKeyId.verify(message.keyIds[i]);
                    if (error)
                        return "keyIds." + error;
                }
            }
            return null;
        };

        /**
         * Creates an AppStateSyncKeyRequest message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.AppStateSyncKeyRequest
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.AppStateSyncKeyRequest} AppStateSyncKeyRequest
         */
        AppStateSyncKeyRequest.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.AppStateSyncKeyRequest)
                return object;
            var message = new $root.proto.AppStateSyncKeyRequest();
            if (object.keyIds) {
                if (!Array.isArray(object.keyIds))
                    throw TypeError(".proto.AppStateSyncKeyRequest.keyIds: array expected");
                message.keyIds = [];
                for (var i = 0; i < object.keyIds.length; ++i) {
                    if (typeof object.keyIds[i] !== "object")
                        throw TypeError(".proto.AppStateSyncKeyRequest.keyIds: object expected");
                    message.keyIds[i] = $root.proto.AppStateSyncKeyId.fromObject(object.keyIds[i]);
                }
            }
            return message;
        };

        /**
         * Creates a plain object from an AppStateSyncKeyRequest message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.AppStateSyncKeyRequest
         * @static
         * @param {proto.AppStateSyncKeyRequest} message AppStateSyncKeyRequest
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        AppStateSyncKeyRequest.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.keyIds = [];
            if (message.keyIds && message.keyIds.length) {
                object.keyIds = [];
                for (var j = 0; j < message.keyIds.length; ++j)
                    object.keyIds[j] = $root.proto.AppStateSyncKeyId.toObject(message.keyIds[j], options);
            }
            return object;
        };

        /**
         * Converts this AppStateSyncKeyRequest to JSON.
         * @function toJSON
         * @memberof proto.AppStateSyncKeyRequest
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        AppStateSyncKeyRequest.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return AppStateSyncKeyRequest;
    })();

    proto.AppStateFatalExceptionNotification = (function() {

        /**
         * Properties of an AppStateFatalExceptionNotification.
         * @memberof proto
         * @interface IAppStateFatalExceptionNotification
         * @property {Array.<string>|null} [collectionNames] AppStateFatalExceptionNotification collectionNames
         * @property {number|Long|null} [timestamp] AppStateFatalExceptionNotification timestamp
         */

        /**
         * Constructs a new AppStateFatalExceptionNotification.
         * @memberof proto
         * @classdesc Represents an AppStateFatalExceptionNotification.
         * @implements IAppStateFatalExceptionNotification
         * @constructor
         * @param {proto.IAppStateFatalExceptionNotification=} [properties] Properties to set
         */
        function AppStateFatalExceptionNotification(properties) {
            this.collectionNames = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * AppStateFatalExceptionNotification collectionNames.
         * @member {Array.<string>} collectionNames
         * @memberof proto.AppStateFatalExceptionNotification
         * @instance
         */
        AppStateFatalExceptionNotification.prototype.collectionNames = $util.emptyArray;

        /**
         * AppStateFatalExceptionNotification timestamp.
         * @member {number|Long} timestamp
         * @memberof proto.AppStateFatalExceptionNotification
         * @instance
         */
        AppStateFatalExceptionNotification.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * Creates a new AppStateFatalExceptionNotification instance using the specified properties.
         * @function create
         * @memberof proto.AppStateFatalExceptionNotification
         * @static
         * @param {proto.IAppStateFatalExceptionNotification=} [properties] Properties to set
         * @returns {proto.AppStateFatalExceptionNotification} AppStateFatalExceptionNotification instance
         */
        AppStateFatalExceptionNotification.create = function create(properties) {
            return new AppStateFatalExceptionNotification(properties);
        };

        /**
         * Encodes the specified AppStateFatalExceptionNotification message. Does not implicitly {@link proto.AppStateFatalExceptionNotification.verify|verify} messages.
         * @function encode
         * @memberof proto.AppStateFatalExceptionNotification
         * @static
         * @param {proto.IAppStateFatalExceptionNotification} message AppStateFatalExceptionNotification message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AppStateFatalExceptionNotification.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.collectionNames != null && message.collectionNames.length)
                for (var i = 0; i < message.collectionNames.length; ++i)
                    writer.uint32(/* id 1, wireType 2 =*/10).string(message.collectionNames[i]);
            if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp"))
                writer.uint32(/* id 2, wireType 0 =*/16).int64(message.timestamp);
            return writer;
        };

        /**
         * Encodes the specified AppStateFatalExceptionNotification message, length delimited. Does not implicitly {@link proto.AppStateFatalExceptionNotification.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.AppStateFatalExceptionNotification
         * @static
         * @param {proto.IAppStateFatalExceptionNotification} message AppStateFatalExceptionNotification message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        AppStateFatalExceptionNotification.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an AppStateFatalExceptionNotification message from the specified reader or buffer.
         * @function decode
         * @memberof proto.AppStateFatalExceptionNotification
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.AppStateFatalExceptionNotification} AppStateFatalExceptionNotification
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AppStateFatalExceptionNotification.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.AppStateFatalExceptionNotification();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    if (!(message.collectionNames && message.collectionNames.length))
                        message.collectionNames = [];
                    message.collectionNames.push(reader.string());
                    break;
                case 2:
                    message.timestamp = reader.int64();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an AppStateFatalExceptionNotification message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.AppStateFatalExceptionNotification
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.AppStateFatalExceptionNotification} AppStateFatalExceptionNotification
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        AppStateFatalExceptionNotification.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an AppStateFatalExceptionNotification message.
         * @function verify
         * @memberof proto.AppStateFatalExceptionNotification
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        AppStateFatalExceptionNotification.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.collectionNames != null && message.hasOwnProperty("collectionNames")) {
                if (!Array.isArray(message.collectionNames))
                    return "collectionNames: array expected";
                for (var i = 0; i < message.collectionNames.length; ++i)
                    if (!$util.isString(message.collectionNames[i]))
                        return "collectionNames: string[] expected";
            }
            if (message.timestamp != null && message.hasOwnProperty("timestamp"))
                if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high)))
                    return "timestamp: integer|Long expected";
            return null;
        };

        /**
         * Creates an AppStateFatalExceptionNotification message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.AppStateFatalExceptionNotification
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.AppStateFatalExceptionNotification} AppStateFatalExceptionNotification
         */
        AppStateFatalExceptionNotification.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.AppStateFatalExceptionNotification)
                return object;
            var message = new $root.proto.AppStateFatalExceptionNotification();
            if (object.collectionNames) {
                if (!Array.isArray(object.collectionNames))
                    throw TypeError(".proto.AppStateFatalExceptionNotification.collectionNames: array expected");
                message.collectionNames = [];
                for (var i = 0; i < object.collectionNames.length; ++i)
                    message.collectionNames[i] = String(object.collectionNames[i]);
            }
            if (object.timestamp != null)
                if ($util.Long)
                    (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = false;
                else if (typeof object.timestamp === "string")
                    message.timestamp = parseInt(object.timestamp, 10);
                else if (typeof object.timestamp === "number")
                    message.timestamp = object.timestamp;
                else if (typeof object.timestamp === "object")
                    message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber();
            return message;
        };

        /**
         * Creates a plain object from an AppStateFatalExceptionNotification message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.AppStateFatalExceptionNotification
         * @static
         * @param {proto.AppStateFatalExceptionNotification} message AppStateFatalExceptionNotification
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        AppStateFatalExceptionNotification.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.collectionNames = [];
            if (options.defaults)
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.timestamp = options.longs === String ? "0" : 0;
            if (message.collectionNames && message.collectionNames.length) {
                object.collectionNames = [];
                for (var j = 0; j < message.collectionNames.length; ++j)
                    object.collectionNames[j] = message.collectionNames[j];
            }
            if (message.timestamp != null && message.hasOwnProperty("timestamp"))
                if (typeof message.timestamp === "number")
                    object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp;
                else
                    object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber() : message.timestamp;
            return object;
        };

        /**
         * Converts this AppStateFatalExceptionNotification to JSON.
         * @function toJSON
         * @memberof proto.AppStateFatalExceptionNotification
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        AppStateFatalExceptionNotification.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return AppStateFatalExceptionNotification;
    })();

    proto.InitialSecurityNotificationSettingSync = (function() {

        /**
         * Properties of an InitialSecurityNotificationSettingSync.
         * @memberof proto
         * @interface IInitialSecurityNotificationSettingSync
         * @property {boolean|null} [securityNotificationEnabled] InitialSecurityNotificationSettingSync securityNotificationEnabled
         */

        /**
         * Constructs a new InitialSecurityNotificationSettingSync.
         * @memberof proto
         * @classdesc Represents an InitialSecurityNotificationSettingSync.
         * @implements IInitialSecurityNotificationSettingSync
         * @constructor
         * @param {proto.IInitialSecurityNotificationSettingSync=} [properties] Properties to set
         */
        function InitialSecurityNotificationSettingSync(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * InitialSecurityNotificationSettingSync securityNotificationEnabled.
         * @member {boolean} securityNotificationEnabled
         * @memberof proto.InitialSecurityNotificationSettingSync
         * @instance
         */
        InitialSecurityNotificationSettingSync.prototype.securityNotificationEnabled = false;

        /**
         * Creates a new InitialSecurityNotificationSettingSync instance using the specified properties.
         * @function create
         * @memberof proto.InitialSecurityNotificationSettingSync
         * @static
         * @param {proto.IInitialSecurityNotificationSettingSync=} [properties] Properties to set
         * @returns {proto.InitialSecurityNotificationSettingSync} InitialSecurityNotificationSettingSync instance
         */
        InitialSecurityNotificationSettingSync.create = function create(properties) {
            return new InitialSecurityNotificationSettingSync(properties);
        };

        /**
         * Encodes the specified InitialSecurityNotificationSettingSync message. Does not implicitly {@link proto.InitialSecurityNotificationSettingSync.verify|verify} messages.
         * @function encode
         * @memberof proto.InitialSecurityNotificationSettingSync
         * @static
         * @param {proto.IInitialSecurityNotificationSettingSync} message InitialSecurityNotificationSettingSync message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        InitialSecurityNotificationSettingSync.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.securityNotificationEnabled != null && Object.hasOwnProperty.call(message, "securityNotificationEnabled"))
                writer.uint32(/* id 1, wireType 0 =*/8).bool(message.securityNotificationEnabled);
            return writer;
        };

        /**
         * Encodes the specified InitialSecurityNotificationSettingSync message, length delimited. Does not implicitly {@link proto.InitialSecurityNotificationSettingSync.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.InitialSecurityNotificationSettingSync
         * @static
         * @param {proto.IInitialSecurityNotificationSettingSync} message InitialSecurityNotificationSettingSync message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        InitialSecurityNotificationSettingSync.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an InitialSecurityNotificationSettingSync message from the specified reader or buffer.
         * @function decode
         * @memberof proto.InitialSecurityNotificationSettingSync
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.InitialSecurityNotificationSettingSync} InitialSecurityNotificationSettingSync
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        InitialSecurityNotificationSettingSync.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.InitialSecurityNotificationSettingSync();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.securityNotificationEnabled = reader.bool();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an InitialSecurityNotificationSettingSync message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.InitialSecurityNotificationSettingSync
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.InitialSecurityNotificationSettingSync} InitialSecurityNotificationSettingSync
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        InitialSecurityNotificationSettingSync.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an InitialSecurityNotificationSettingSync message.
         * @function verify
         * @memberof proto.InitialSecurityNotificationSettingSync
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        InitialSecurityNotificationSettingSync.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.securityNotificationEnabled != null && message.hasOwnProperty("securityNotificationEnabled"))
                if (typeof message.securityNotificationEnabled !== "boolean")
                    return "securityNotificationEnabled: boolean expected";
            return null;
        };

        /**
         * Creates an InitialSecurityNotificationSettingSync message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.InitialSecurityNotificationSettingSync
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.InitialSecurityNotificationSettingSync} InitialSecurityNotificationSettingSync
         */
        InitialSecurityNotificationSettingSync.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.InitialSecurityNotificationSettingSync)
                return object;
            var message = new $root.proto.InitialSecurityNotificationSettingSync();
            if (object.securityNotificationEnabled != null)
                message.securityNotificationEnabled = Boolean(object.securityNotificationEnabled);
            return message;
        };

        /**
         * Creates a plain object from an InitialSecurityNotificationSettingSync message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.InitialSecurityNotificationSettingSync
         * @static
         * @param {proto.InitialSecurityNotificationSettingSync} message InitialSecurityNotificationSettingSync
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        InitialSecurityNotificationSettingSync.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                object.securityNotificationEnabled = false;
            if (message.securityNotificationEnabled != null && message.hasOwnProperty("securityNotificationEnabled"))
                object.securityNotificationEnabled = message.securityNotificationEnabled;
            return object;
        };

        /**
         * Converts this InitialSecurityNotificationSettingSync to JSON.
         * @function toJSON
         * @memberof proto.InitialSecurityNotificationSettingSync
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        InitialSecurityNotificationSettingSync.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return InitialSecurityNotificationSettingSync;
    })();

    proto.ContactsArrayMessage = (function() {

        /**
         * Properties of a ContactsArrayMessage.
         * @memberof proto
         * @interface IContactsArrayMessage
         * @property {string|null} [displayName] ContactsArrayMessage displayName
         * @property {Array.<proto.IContactMessage>|null} [contacts] ContactsArrayMessage contacts
         * @property {proto.IContextInfo|null} [contextInfo] ContactsArrayMessage contextInfo
         */

        /**
         * Constructs a new ContactsArrayMessage.
         * @memberof proto
         * @classdesc Represents a ContactsArrayMessage.
         * @implements IContactsArrayMessage
         * @constructor
         * @param {proto.IContactsArrayMessage=} [properties] Properties to set
         */
        function ContactsArrayMessage(properties) {
            this.contacts = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ContactsArrayMessage displayName.
         * @member {string} displayName
         * @memberof proto.ContactsArrayMessage
         * @instance
         */
        ContactsArrayMessage.prototype.displayName = "";

        /**
         * ContactsArrayMessage contacts.
         * @member {Array.<proto.IContactMessage>} contacts
         * @memberof proto.ContactsArrayMessage
         * @instance
         */
        ContactsArrayMessage.prototype.contacts = $util.emptyArray;

        /**
         * ContactsArrayMessage contextInfo.
         * @member {proto.IContextInfo|null|undefined} contextInfo
         * @memberof proto.ContactsArrayMessage
         * @instance
         */
        ContactsArrayMessage.prototype.contextInfo = null;

        /**
         * Creates a new ContactsArrayMessage instance using the specified properties.
         * @function create
         * @memberof proto.ContactsArrayMessage
         * @static
         * @param {proto.IContactsArrayMessage=} [properties] Properties to set
         * @returns {proto.ContactsArrayMessage} ContactsArrayMessage instance
         */
        ContactsArrayMessage.create = function create(properties) {
            return new ContactsArrayMessage(properties);
        };

        /**
         * Encodes the specified ContactsArrayMessage message. Does not implicitly {@link proto.ContactsArrayMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.ContactsArrayMessage
         * @static
         * @param {proto.IContactsArrayMessage} message ContactsArrayMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ContactsArrayMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.displayName != null && Object.hasOwnProperty.call(message, "displayName"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayName);
            if (message.contacts != null && message.contacts.length)
                for (var i = 0; i < message.contacts.length; ++i)
                    $root.proto.ContactMessage.encode(message.contacts[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo"))
                $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 17, wireType 2 =*/138).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified ContactsArrayMessage message, length delimited. Does not implicitly {@link proto.ContactsArrayMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ContactsArrayMessage
         * @static
         * @param {proto.IContactsArrayMessage} message ContactsArrayMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ContactsArrayMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ContactsArrayMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ContactsArrayMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ContactsArrayMessage} ContactsArrayMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ContactsArrayMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ContactsArrayMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.displayName = reader.string();
                    break;
                case 2:
                    if (!(message.contacts && message.contacts.length))
                        message.contacts = [];
                    message.contacts.push($root.proto.ContactMessage.decode(reader, reader.uint32()));
                    break;
                case 17:
                    message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ContactsArrayMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ContactsArrayMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ContactsArrayMessage} ContactsArrayMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ContactsArrayMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ContactsArrayMessage message.
         * @function verify
         * @memberof proto.ContactsArrayMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ContactsArrayMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.displayName != null && message.hasOwnProperty("displayName"))
                if (!$util.isString(message.displayName))
                    return "displayName: string expected";
            if (message.contacts != null && message.hasOwnProperty("contacts")) {
                if (!Array.isArray(message.contacts))
                    return "contacts: array expected";
                for (var i = 0; i < message.contacts.length; ++i) {
                    var error = $root.proto.ContactMessage.verify(message.contacts[i]);
                    if (error)
                        return "contacts." + error;
                }
            }
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) {
                var error = $root.proto.ContextInfo.verify(message.contextInfo);
                if (error)
                    return "contextInfo." + error;
            }
            return null;
        };

        /**
         * Creates a ContactsArrayMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ContactsArrayMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ContactsArrayMessage} ContactsArrayMessage
         */
        ContactsArrayMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ContactsArrayMessage)
                return object;
            var message = new $root.proto.ContactsArrayMessage();
            if (object.displayName != null)
                message.displayName = String(object.displayName);
            if (object.contacts) {
                if (!Array.isArray(object.contacts))
                    throw TypeError(".proto.ContactsArrayMessage.contacts: array expected");
                message.contacts = [];
                for (var i = 0; i < object.contacts.length; ++i) {
                    if (typeof object.contacts[i] !== "object")
                        throw TypeError(".proto.ContactsArrayMessage.contacts: object expected");
                    message.contacts[i] = $root.proto.ContactMessage.fromObject(object.contacts[i]);
                }
            }
            if (object.contextInfo != null) {
                if (typeof object.contextInfo !== "object")
                    throw TypeError(".proto.ContactsArrayMessage.contextInfo: object expected");
                message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo);
            }
            return message;
        };

        /**
         * Creates a plain object from a ContactsArrayMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ContactsArrayMessage
         * @static
         * @param {proto.ContactsArrayMessage} message ContactsArrayMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ContactsArrayMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.contacts = [];
            if (options.defaults) {
                object.displayName = "";
                object.contextInfo = null;
            }
            if (message.displayName != null && message.hasOwnProperty("displayName"))
                object.displayName = message.displayName;
            if (message.contacts && message.contacts.length) {
                object.contacts = [];
                for (var j = 0; j < message.contacts.length; ++j)
                    object.contacts[j] = $root.proto.ContactMessage.toObject(message.contacts[j], options);
            }
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo"))
                object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options);
            return object;
        };

        /**
         * Converts this ContactsArrayMessage to JSON.
         * @function toJSON
         * @memberof proto.ContactsArrayMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ContactsArrayMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ContactsArrayMessage;
    })();

    proto.HSMCurrency = (function() {

        /**
         * Properties of a HSMCurrency.
         * @memberof proto
         * @interface IHSMCurrency
         * @property {string|null} [currencyCode] HSMCurrency currencyCode
         * @property {number|Long|null} [amount1000] HSMCurrency amount1000
         */

        /**
         * Constructs a new HSMCurrency.
         * @memberof proto
         * @classdesc Represents a HSMCurrency.
         * @implements IHSMCurrency
         * @constructor
         * @param {proto.IHSMCurrency=} [properties] Properties to set
         */
        function HSMCurrency(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * HSMCurrency currencyCode.
         * @member {string} currencyCode
         * @memberof proto.HSMCurrency
         * @instance
         */
        HSMCurrency.prototype.currencyCode = "";

        /**
         * HSMCurrency amount1000.
         * @member {number|Long} amount1000
         * @memberof proto.HSMCurrency
         * @instance
         */
        HSMCurrency.prototype.amount1000 = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * Creates a new HSMCurrency instance using the specified properties.
         * @function create
         * @memberof proto.HSMCurrency
         * @static
         * @param {proto.IHSMCurrency=} [properties] Properties to set
         * @returns {proto.HSMCurrency} HSMCurrency instance
         */
        HSMCurrency.create = function create(properties) {
            return new HSMCurrency(properties);
        };

        /**
         * Encodes the specified HSMCurrency message. Does not implicitly {@link proto.HSMCurrency.verify|verify} messages.
         * @function encode
         * @memberof proto.HSMCurrency
         * @static
         * @param {proto.IHSMCurrency} message HSMCurrency message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HSMCurrency.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.currencyCode != null && Object.hasOwnProperty.call(message, "currencyCode"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.currencyCode);
            if (message.amount1000 != null && Object.hasOwnProperty.call(message, "amount1000"))
                writer.uint32(/* id 2, wireType 0 =*/16).int64(message.amount1000);
            return writer;
        };

        /**
         * Encodes the specified HSMCurrency message, length delimited. Does not implicitly {@link proto.HSMCurrency.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.HSMCurrency
         * @static
         * @param {proto.IHSMCurrency} message HSMCurrency message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HSMCurrency.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a HSMCurrency message from the specified reader or buffer.
         * @function decode
         * @memberof proto.HSMCurrency
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.HSMCurrency} HSMCurrency
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HSMCurrency.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HSMCurrency();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.currencyCode = reader.string();
                    break;
                case 2:
                    message.amount1000 = reader.int64();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a HSMCurrency message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.HSMCurrency
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.HSMCurrency} HSMCurrency
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HSMCurrency.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a HSMCurrency message.
         * @function verify
         * @memberof proto.HSMCurrency
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        HSMCurrency.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.currencyCode != null && message.hasOwnProperty("currencyCode"))
                if (!$util.isString(message.currencyCode))
                    return "currencyCode: string expected";
            if (message.amount1000 != null && message.hasOwnProperty("amount1000"))
                if (!$util.isInteger(message.amount1000) && !(message.amount1000 && $util.isInteger(message.amount1000.low) && $util.isInteger(message.amount1000.high)))
                    return "amount1000: integer|Long expected";
            return null;
        };

        /**
         * Creates a HSMCurrency message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.HSMCurrency
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.HSMCurrency} HSMCurrency
         */
        HSMCurrency.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.HSMCurrency)
                return object;
            var message = new $root.proto.HSMCurrency();
            if (object.currencyCode != null)
                message.currencyCode = String(object.currencyCode);
            if (object.amount1000 != null)
                if ($util.Long)
                    (message.amount1000 = $util.Long.fromValue(object.amount1000)).unsigned = false;
                else if (typeof object.amount1000 === "string")
                    message.amount1000 = parseInt(object.amount1000, 10);
                else if (typeof object.amount1000 === "number")
                    message.amount1000 = object.amount1000;
                else if (typeof object.amount1000 === "object")
                    message.amount1000 = new $util.LongBits(object.amount1000.low >>> 0, object.amount1000.high >>> 0).toNumber();
            return message;
        };

        /**
         * Creates a plain object from a HSMCurrency message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.HSMCurrency
         * @static
         * @param {proto.HSMCurrency} message HSMCurrency
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        HSMCurrency.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.currencyCode = "";
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.amount1000 = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.amount1000 = options.longs === String ? "0" : 0;
            }
            if (message.currencyCode != null && message.hasOwnProperty("currencyCode"))
                object.currencyCode = message.currencyCode;
            if (message.amount1000 != null && message.hasOwnProperty("amount1000"))
                if (typeof message.amount1000 === "number")
                    object.amount1000 = options.longs === String ? String(message.amount1000) : message.amount1000;
                else
                    object.amount1000 = options.longs === String ? $util.Long.prototype.toString.call(message.amount1000) : options.longs === Number ? new $util.LongBits(message.amount1000.low >>> 0, message.amount1000.high >>> 0).toNumber() : message.amount1000;
            return object;
        };

        /**
         * Converts this HSMCurrency to JSON.
         * @function toJSON
         * @memberof proto.HSMCurrency
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        HSMCurrency.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return HSMCurrency;
    })();

    proto.HSMDateTimeComponent = (function() {

        /**
         * Properties of a HSMDateTimeComponent.
         * @memberof proto
         * @interface IHSMDateTimeComponent
         * @property {proto.HSMDateTimeComponent.HSMDateTimeComponentDayOfWeekType|null} [dayOfWeek] HSMDateTimeComponent dayOfWeek
         * @property {number|null} [year] HSMDateTimeComponent year
         * @property {number|null} [month] HSMDateTimeComponent month
         * @property {number|null} [dayOfMonth] HSMDateTimeComponent dayOfMonth
         * @property {number|null} [hour] HSMDateTimeComponent hour
         * @property {number|null} [minute] HSMDateTimeComponent minute
         * @property {proto.HSMDateTimeComponent.HSMDateTimeComponentCalendarType|null} [calendar] HSMDateTimeComponent calendar
         */

        /**
         * Constructs a new HSMDateTimeComponent.
         * @memberof proto
         * @classdesc Represents a HSMDateTimeComponent.
         * @implements IHSMDateTimeComponent
         * @constructor
         * @param {proto.IHSMDateTimeComponent=} [properties] Properties to set
         */
        function HSMDateTimeComponent(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * HSMDateTimeComponent dayOfWeek.
         * @member {proto.HSMDateTimeComponent.HSMDateTimeComponentDayOfWeekType} dayOfWeek
         * @memberof proto.HSMDateTimeComponent
         * @instance
         */
        HSMDateTimeComponent.prototype.dayOfWeek = 1;

        /**
         * HSMDateTimeComponent year.
         * @member {number} year
         * @memberof proto.HSMDateTimeComponent
         * @instance
         */
        HSMDateTimeComponent.prototype.year = 0;

        /**
         * HSMDateTimeComponent month.
         * @member {number} month
         * @memberof proto.HSMDateTimeComponent
         * @instance
         */
        HSMDateTimeComponent.prototype.month = 0;

        /**
         * HSMDateTimeComponent dayOfMonth.
         * @member {number} dayOfMonth
         * @memberof proto.HSMDateTimeComponent
         * @instance
         */
        HSMDateTimeComponent.prototype.dayOfMonth = 0;

        /**
         * HSMDateTimeComponent hour.
         * @member {number} hour
         * @memberof proto.HSMDateTimeComponent
         * @instance
         */
        HSMDateTimeComponent.prototype.hour = 0;

        /**
         * HSMDateTimeComponent minute.
         * @member {number} minute
         * @memberof proto.HSMDateTimeComponent
         * @instance
         */
        HSMDateTimeComponent.prototype.minute = 0;

        /**
         * HSMDateTimeComponent calendar.
         * @member {proto.HSMDateTimeComponent.HSMDateTimeComponentCalendarType} calendar
         * @memberof proto.HSMDateTimeComponent
         * @instance
         */
        HSMDateTimeComponent.prototype.calendar = 1;

        /**
         * Creates a new HSMDateTimeComponent instance using the specified properties.
         * @function create
         * @memberof proto.HSMDateTimeComponent
         * @static
         * @param {proto.IHSMDateTimeComponent=} [properties] Properties to set
         * @returns {proto.HSMDateTimeComponent} HSMDateTimeComponent instance
         */
        HSMDateTimeComponent.create = function create(properties) {
            return new HSMDateTimeComponent(properties);
        };

        /**
         * Encodes the specified HSMDateTimeComponent message. Does not implicitly {@link proto.HSMDateTimeComponent.verify|verify} messages.
         * @function encode
         * @memberof proto.HSMDateTimeComponent
         * @static
         * @param {proto.IHSMDateTimeComponent} message HSMDateTimeComponent message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HSMDateTimeComponent.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.dayOfWeek != null && Object.hasOwnProperty.call(message, "dayOfWeek"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.dayOfWeek);
            if (message.year != null && Object.hasOwnProperty.call(message, "year"))
                writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.year);
            if (message.month != null && Object.hasOwnProperty.call(message, "month"))
                writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.month);
            if (message.dayOfMonth != null && Object.hasOwnProperty.call(message, "dayOfMonth"))
                writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.dayOfMonth);
            if (message.hour != null && Object.hasOwnProperty.call(message, "hour"))
                writer.uint32(/* id 5, wireType 0 =*/40).uint32(message.hour);
            if (message.minute != null && Object.hasOwnProperty.call(message, "minute"))
                writer.uint32(/* id 6, wireType 0 =*/48).uint32(message.minute);
            if (message.calendar != null && Object.hasOwnProperty.call(message, "calendar"))
                writer.uint32(/* id 7, wireType 0 =*/56).int32(message.calendar);
            return writer;
        };

        /**
         * Encodes the specified HSMDateTimeComponent message, length delimited. Does not implicitly {@link proto.HSMDateTimeComponent.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.HSMDateTimeComponent
         * @static
         * @param {proto.IHSMDateTimeComponent} message HSMDateTimeComponent message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HSMDateTimeComponent.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a HSMDateTimeComponent message from the specified reader or buffer.
         * @function decode
         * @memberof proto.HSMDateTimeComponent
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.HSMDateTimeComponent} HSMDateTimeComponent
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HSMDateTimeComponent.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HSMDateTimeComponent();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.dayOfWeek = reader.int32();
                    break;
                case 2:
                    message.year = reader.uint32();
                    break;
                case 3:
                    message.month = reader.uint32();
                    break;
                case 4:
                    message.dayOfMonth = reader.uint32();
                    break;
                case 5:
                    message.hour = reader.uint32();
                    break;
                case 6:
                    message.minute = reader.uint32();
                    break;
                case 7:
                    message.calendar = reader.int32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a HSMDateTimeComponent message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.HSMDateTimeComponent
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.HSMDateTimeComponent} HSMDateTimeComponent
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HSMDateTimeComponent.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a HSMDateTimeComponent message.
         * @function verify
         * @memberof proto.HSMDateTimeComponent
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        HSMDateTimeComponent.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.dayOfWeek != null && message.hasOwnProperty("dayOfWeek"))
                switch (message.dayOfWeek) {
                default:
                    return "dayOfWeek: enum value expected";
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                    break;
                }
            if (message.year != null && message.hasOwnProperty("year"))
                if (!$util.isInteger(message.year))
                    return "year: integer expected";
            if (message.month != null && message.hasOwnProperty("month"))
                if (!$util.isInteger(message.month))
                    return "month: integer expected";
            if (message.dayOfMonth != null && message.hasOwnProperty("dayOfMonth"))
                if (!$util.isInteger(message.dayOfMonth))
                    return "dayOfMonth: integer expected";
            if (message.hour != null && message.hasOwnProperty("hour"))
                if (!$util.isInteger(message.hour))
                    return "hour: integer expected";
            if (message.minute != null && message.hasOwnProperty("minute"))
                if (!$util.isInteger(message.minute))
                    return "minute: integer expected";
            if (message.calendar != null && message.hasOwnProperty("calendar"))
                switch (message.calendar) {
                default:
                    return "calendar: enum value expected";
                case 1:
                case 2:
                    break;
                }
            return null;
        };

        /**
         * Creates a HSMDateTimeComponent message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.HSMDateTimeComponent
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.HSMDateTimeComponent} HSMDateTimeComponent
         */
        HSMDateTimeComponent.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.HSMDateTimeComponent)
                return object;
            var message = new $root.proto.HSMDateTimeComponent();
            switch (object.dayOfWeek) {
            case "MONDAY":
            case 1:
                message.dayOfWeek = 1;
                break;
            case "TUESDAY":
            case 2:
                message.dayOfWeek = 2;
                break;
            case "WEDNESDAY":
            case 3:
                message.dayOfWeek = 3;
                break;
            case "THURSDAY":
            case 4:
                message.dayOfWeek = 4;
                break;
            case "FRIDAY":
            case 5:
                message.dayOfWeek = 5;
                break;
            case "SATURDAY":
            case 6:
                message.dayOfWeek = 6;
                break;
            case "SUNDAY":
            case 7:
                message.dayOfWeek = 7;
                break;
            }
            if (object.year != null)
                message.year = object.year >>> 0;
            if (object.month != null)
                message.month = object.month >>> 0;
            if (object.dayOfMonth != null)
                message.dayOfMonth = object.dayOfMonth >>> 0;
            if (object.hour != null)
                message.hour = object.hour >>> 0;
            if (object.minute != null)
                message.minute = object.minute >>> 0;
            switch (object.calendar) {
            case "GREGORIAN":
            case 1:
                message.calendar = 1;
                break;
            case "SOLAR_HIJRI":
            case 2:
                message.calendar = 2;
                break;
            }
            return message;
        };

        /**
         * Creates a plain object from a HSMDateTimeComponent message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.HSMDateTimeComponent
         * @static
         * @param {proto.HSMDateTimeComponent} message HSMDateTimeComponent
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        HSMDateTimeComponent.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.dayOfWeek = options.enums === String ? "MONDAY" : 1;
                object.year = 0;
                object.month = 0;
                object.dayOfMonth = 0;
                object.hour = 0;
                object.minute = 0;
                object.calendar = options.enums === String ? "GREGORIAN" : 1;
            }
            if (message.dayOfWeek != null && message.hasOwnProperty("dayOfWeek"))
                object.dayOfWeek = options.enums === String ? $root.proto.HSMDateTimeComponent.HSMDateTimeComponentDayOfWeekType[message.dayOfWeek] : message.dayOfWeek;
            if (message.year != null && message.hasOwnProperty("year"))
                object.year = message.year;
            if (message.month != null && message.hasOwnProperty("month"))
                object.month = message.month;
            if (message.dayOfMonth != null && message.hasOwnProperty("dayOfMonth"))
                object.dayOfMonth = message.dayOfMonth;
            if (message.hour != null && message.hasOwnProperty("hour"))
                object.hour = message.hour;
            if (message.minute != null && message.hasOwnProperty("minute"))
                object.minute = message.minute;
            if (message.calendar != null && message.hasOwnProperty("calendar"))
                object.calendar = options.enums === String ? $root.proto.HSMDateTimeComponent.HSMDateTimeComponentCalendarType[message.calendar] : message.calendar;
            return object;
        };

        /**
         * Converts this HSMDateTimeComponent to JSON.
         * @function toJSON
         * @memberof proto.HSMDateTimeComponent
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        HSMDateTimeComponent.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * HSMDateTimeComponentDayOfWeekType enum.
         * @name proto.HSMDateTimeComponent.HSMDateTimeComponentDayOfWeekType
         * @enum {number}
         * @property {number} MONDAY=1 MONDAY value
         * @property {number} TUESDAY=2 TUESDAY value
         * @property {number} WEDNESDAY=3 WEDNESDAY value
         * @property {number} THURSDAY=4 THURSDAY value
         * @property {number} FRIDAY=5 FRIDAY value
         * @property {number} SATURDAY=6 SATURDAY value
         * @property {number} SUNDAY=7 SUNDAY value
         */
        HSMDateTimeComponent.HSMDateTimeComponentDayOfWeekType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[1] = "MONDAY"] = 1;
            values[valuesById[2] = "TUESDAY"] = 2;
            values[valuesById[3] = "WEDNESDAY"] = 3;
            values[valuesById[4] = "THURSDAY"] = 4;
            values[valuesById[5] = "FRIDAY"] = 5;
            values[valuesById[6] = "SATURDAY"] = 6;
            values[valuesById[7] = "SUNDAY"] = 7;
            return values;
        })();

        /**
         * HSMDateTimeComponentCalendarType enum.
         * @name proto.HSMDateTimeComponent.HSMDateTimeComponentCalendarType
         * @enum {number}
         * @property {number} GREGORIAN=1 GREGORIAN value
         * @property {number} SOLAR_HIJRI=2 SOLAR_HIJRI value
         */
        HSMDateTimeComponent.HSMDateTimeComponentCalendarType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[1] = "GREGORIAN"] = 1;
            values[valuesById[2] = "SOLAR_HIJRI"] = 2;
            return values;
        })();

        return HSMDateTimeComponent;
    })();

    proto.HSMDateTimeUnixEpoch = (function() {

        /**
         * Properties of a HSMDateTimeUnixEpoch.
         * @memberof proto
         * @interface IHSMDateTimeUnixEpoch
         * @property {number|Long|null} [timestamp] HSMDateTimeUnixEpoch timestamp
         */

        /**
         * Constructs a new HSMDateTimeUnixEpoch.
         * @memberof proto
         * @classdesc Represents a HSMDateTimeUnixEpoch.
         * @implements IHSMDateTimeUnixEpoch
         * @constructor
         * @param {proto.IHSMDateTimeUnixEpoch=} [properties] Properties to set
         */
        function HSMDateTimeUnixEpoch(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * HSMDateTimeUnixEpoch timestamp.
         * @member {number|Long} timestamp
         * @memberof proto.HSMDateTimeUnixEpoch
         * @instance
         */
        HSMDateTimeUnixEpoch.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * Creates a new HSMDateTimeUnixEpoch instance using the specified properties.
         * @function create
         * @memberof proto.HSMDateTimeUnixEpoch
         * @static
         * @param {proto.IHSMDateTimeUnixEpoch=} [properties] Properties to set
         * @returns {proto.HSMDateTimeUnixEpoch} HSMDateTimeUnixEpoch instance
         */
        HSMDateTimeUnixEpoch.create = function create(properties) {
            return new HSMDateTimeUnixEpoch(properties);
        };

        /**
         * Encodes the specified HSMDateTimeUnixEpoch message. Does not implicitly {@link proto.HSMDateTimeUnixEpoch.verify|verify} messages.
         * @function encode
         * @memberof proto.HSMDateTimeUnixEpoch
         * @static
         * @param {proto.IHSMDateTimeUnixEpoch} message HSMDateTimeUnixEpoch message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HSMDateTimeUnixEpoch.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp"))
                writer.uint32(/* id 1, wireType 0 =*/8).int64(message.timestamp);
            return writer;
        };

        /**
         * Encodes the specified HSMDateTimeUnixEpoch message, length delimited. Does not implicitly {@link proto.HSMDateTimeUnixEpoch.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.HSMDateTimeUnixEpoch
         * @static
         * @param {proto.IHSMDateTimeUnixEpoch} message HSMDateTimeUnixEpoch message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HSMDateTimeUnixEpoch.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a HSMDateTimeUnixEpoch message from the specified reader or buffer.
         * @function decode
         * @memberof proto.HSMDateTimeUnixEpoch
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.HSMDateTimeUnixEpoch} HSMDateTimeUnixEpoch
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HSMDateTimeUnixEpoch.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HSMDateTimeUnixEpoch();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.timestamp = reader.int64();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a HSMDateTimeUnixEpoch message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.HSMDateTimeUnixEpoch
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.HSMDateTimeUnixEpoch} HSMDateTimeUnixEpoch
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HSMDateTimeUnixEpoch.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a HSMDateTimeUnixEpoch message.
         * @function verify
         * @memberof proto.HSMDateTimeUnixEpoch
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        HSMDateTimeUnixEpoch.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.timestamp != null && message.hasOwnProperty("timestamp"))
                if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high)))
                    return "timestamp: integer|Long expected";
            return null;
        };

        /**
         * Creates a HSMDateTimeUnixEpoch message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.HSMDateTimeUnixEpoch
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.HSMDateTimeUnixEpoch} HSMDateTimeUnixEpoch
         */
        HSMDateTimeUnixEpoch.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.HSMDateTimeUnixEpoch)
                return object;
            var message = new $root.proto.HSMDateTimeUnixEpoch();
            if (object.timestamp != null)
                if ($util.Long)
                    (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = false;
                else if (typeof object.timestamp === "string")
                    message.timestamp = parseInt(object.timestamp, 10);
                else if (typeof object.timestamp === "number")
                    message.timestamp = object.timestamp;
                else if (typeof object.timestamp === "object")
                    message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber();
            return message;
        };

        /**
         * Creates a plain object from a HSMDateTimeUnixEpoch message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.HSMDateTimeUnixEpoch
         * @static
         * @param {proto.HSMDateTimeUnixEpoch} message HSMDateTimeUnixEpoch
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        HSMDateTimeUnixEpoch.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.timestamp = options.longs === String ? "0" : 0;
            if (message.timestamp != null && message.hasOwnProperty("timestamp"))
                if (typeof message.timestamp === "number")
                    object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp;
                else
                    object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber() : message.timestamp;
            return object;
        };

        /**
         * Converts this HSMDateTimeUnixEpoch to JSON.
         * @function toJSON
         * @memberof proto.HSMDateTimeUnixEpoch
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        HSMDateTimeUnixEpoch.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return HSMDateTimeUnixEpoch;
    })();

    proto.HSMDateTime = (function() {

        /**
         * Properties of a HSMDateTime.
         * @memberof proto
         * @interface IHSMDateTime
         * @property {proto.IHSMDateTimeComponent|null} [component] HSMDateTime component
         * @property {proto.IHSMDateTimeUnixEpoch|null} [unixEpoch] HSMDateTime unixEpoch
         */

        /**
         * Constructs a new HSMDateTime.
         * @memberof proto
         * @classdesc Represents a HSMDateTime.
         * @implements IHSMDateTime
         * @constructor
         * @param {proto.IHSMDateTime=} [properties] Properties to set
         */
        function HSMDateTime(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * HSMDateTime component.
         * @member {proto.IHSMDateTimeComponent|null|undefined} component
         * @memberof proto.HSMDateTime
         * @instance
         */
        HSMDateTime.prototype.component = null;

        /**
         * HSMDateTime unixEpoch.
         * @member {proto.IHSMDateTimeUnixEpoch|null|undefined} unixEpoch
         * @memberof proto.HSMDateTime
         * @instance
         */
        HSMDateTime.prototype.unixEpoch = null;

        // OneOf field names bound to virtual getters and setters
        var $oneOfFields;

        /**
         * HSMDateTime datetimeOneof.
         * @member {"component"|"unixEpoch"|undefined} datetimeOneof
         * @memberof proto.HSMDateTime
         * @instance
         */
        Object.defineProperty(HSMDateTime.prototype, "datetimeOneof", {
            get: $util.oneOfGetter($oneOfFields = ["component", "unixEpoch"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new HSMDateTime instance using the specified properties.
         * @function create
         * @memberof proto.HSMDateTime
         * @static
         * @param {proto.IHSMDateTime=} [properties] Properties to set
         * @returns {proto.HSMDateTime} HSMDateTime instance
         */
        HSMDateTime.create = function create(properties) {
            return new HSMDateTime(properties);
        };

        /**
         * Encodes the specified HSMDateTime message. Does not implicitly {@link proto.HSMDateTime.verify|verify} messages.
         * @function encode
         * @memberof proto.HSMDateTime
         * @static
         * @param {proto.IHSMDateTime} message HSMDateTime message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HSMDateTime.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.component != null && Object.hasOwnProperty.call(message, "component"))
                $root.proto.HSMDateTimeComponent.encode(message.component, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.unixEpoch != null && Object.hasOwnProperty.call(message, "unixEpoch"))
                $root.proto.HSMDateTimeUnixEpoch.encode(message.unixEpoch, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified HSMDateTime message, length delimited. Does not implicitly {@link proto.HSMDateTime.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.HSMDateTime
         * @static
         * @param {proto.IHSMDateTime} message HSMDateTime message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HSMDateTime.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a HSMDateTime message from the specified reader or buffer.
         * @function decode
         * @memberof proto.HSMDateTime
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.HSMDateTime} HSMDateTime
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HSMDateTime.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HSMDateTime();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.component = $root.proto.HSMDateTimeComponent.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.unixEpoch = $root.proto.HSMDateTimeUnixEpoch.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a HSMDateTime message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.HSMDateTime
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.HSMDateTime} HSMDateTime
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HSMDateTime.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a HSMDateTime message.
         * @function verify
         * @memberof proto.HSMDateTime
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        HSMDateTime.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            var properties = {};
            if (message.component != null && message.hasOwnProperty("component")) {
                properties.datetimeOneof = 1;
                {
                    var error = $root.proto.HSMDateTimeComponent.verify(message.component);
                    if (error)
                        return "component." + error;
                }
            }
            if (message.unixEpoch != null && message.hasOwnProperty("unixEpoch")) {
                if (properties.datetimeOneof === 1)
                    return "datetimeOneof: multiple values";
                properties.datetimeOneof = 1;
                {
                    var error = $root.proto.HSMDateTimeUnixEpoch.verify(message.unixEpoch);
                    if (error)
                        return "unixEpoch." + error;
                }
            }
            return null;
        };

        /**
         * Creates a HSMDateTime message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.HSMDateTime
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.HSMDateTime} HSMDateTime
         */
        HSMDateTime.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.HSMDateTime)
                return object;
            var message = new $root.proto.HSMDateTime();
            if (object.component != null) {
                if (typeof object.component !== "object")
                    throw TypeError(".proto.HSMDateTime.component: object expected");
                message.component = $root.proto.HSMDateTimeComponent.fromObject(object.component);
            }
            if (object.unixEpoch != null) {
                if (typeof object.unixEpoch !== "object")
                    throw TypeError(".proto.HSMDateTime.unixEpoch: object expected");
                message.unixEpoch = $root.proto.HSMDateTimeUnixEpoch.fromObject(object.unixEpoch);
            }
            return message;
        };

        /**
         * Creates a plain object from a HSMDateTime message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.HSMDateTime
         * @static
         * @param {proto.HSMDateTime} message HSMDateTime
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        HSMDateTime.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (message.component != null && message.hasOwnProperty("component")) {
                object.component = $root.proto.HSMDateTimeComponent.toObject(message.component, options);
                if (options.oneofs)
                    object.datetimeOneof = "component";
            }
            if (message.unixEpoch != null && message.hasOwnProperty("unixEpoch")) {
                object.unixEpoch = $root.proto.HSMDateTimeUnixEpoch.toObject(message.unixEpoch, options);
                if (options.oneofs)
                    object.datetimeOneof = "unixEpoch";
            }
            return object;
        };

        /**
         * Converts this HSMDateTime to JSON.
         * @function toJSON
         * @memberof proto.HSMDateTime
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        HSMDateTime.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return HSMDateTime;
    })();

    proto.HSMLocalizableParameter = (function() {

        /**
         * Properties of a HSMLocalizableParameter.
         * @memberof proto
         * @interface IHSMLocalizableParameter
         * @property {string|null} ["default"] HSMLocalizableParameter default
         * @property {proto.IHSMCurrency|null} [currency] HSMLocalizableParameter currency
         * @property {proto.IHSMDateTime|null} [dateTime] HSMLocalizableParameter dateTime
         */

        /**
         * Constructs a new HSMLocalizableParameter.
         * @memberof proto
         * @classdesc Represents a HSMLocalizableParameter.
         * @implements IHSMLocalizableParameter
         * @constructor
         * @param {proto.IHSMLocalizableParameter=} [properties] Properties to set
         */
        function HSMLocalizableParameter(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * HSMLocalizableParameter default.
         * @member {string} default
         * @memberof proto.HSMLocalizableParameter
         * @instance
         */
        HSMLocalizableParameter.prototype["default"] = "";

        /**
         * HSMLocalizableParameter currency.
         * @member {proto.IHSMCurrency|null|undefined} currency
         * @memberof proto.HSMLocalizableParameter
         * @instance
         */
        HSMLocalizableParameter.prototype.currency = null;

        /**
         * HSMLocalizableParameter dateTime.
         * @member {proto.IHSMDateTime|null|undefined} dateTime
         * @memberof proto.HSMLocalizableParameter
         * @instance
         */
        HSMLocalizableParameter.prototype.dateTime = null;

        // OneOf field names bound to virtual getters and setters
        var $oneOfFields;

        /**
         * HSMLocalizableParameter paramOneof.
         * @member {"currency"|"dateTime"|undefined} paramOneof
         * @memberof proto.HSMLocalizableParameter
         * @instance
         */
        Object.defineProperty(HSMLocalizableParameter.prototype, "paramOneof", {
            get: $util.oneOfGetter($oneOfFields = ["currency", "dateTime"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new HSMLocalizableParameter instance using the specified properties.
         * @function create
         * @memberof proto.HSMLocalizableParameter
         * @static
         * @param {proto.IHSMLocalizableParameter=} [properties] Properties to set
         * @returns {proto.HSMLocalizableParameter} HSMLocalizableParameter instance
         */
        HSMLocalizableParameter.create = function create(properties) {
            return new HSMLocalizableParameter(properties);
        };

        /**
         * Encodes the specified HSMLocalizableParameter message. Does not implicitly {@link proto.HSMLocalizableParameter.verify|verify} messages.
         * @function encode
         * @memberof proto.HSMLocalizableParameter
         * @static
         * @param {proto.IHSMLocalizableParameter} message HSMLocalizableParameter message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HSMLocalizableParameter.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message["default"] != null && Object.hasOwnProperty.call(message, "default"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message["default"]);
            if (message.currency != null && Object.hasOwnProperty.call(message, "currency"))
                $root.proto.HSMCurrency.encode(message.currency, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.dateTime != null && Object.hasOwnProperty.call(message, "dateTime"))
                $root.proto.HSMDateTime.encode(message.dateTime, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified HSMLocalizableParameter message, length delimited. Does not implicitly {@link proto.HSMLocalizableParameter.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.HSMLocalizableParameter
         * @static
         * @param {proto.IHSMLocalizableParameter} message HSMLocalizableParameter message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HSMLocalizableParameter.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a HSMLocalizableParameter message from the specified reader or buffer.
         * @function decode
         * @memberof proto.HSMLocalizableParameter
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.HSMLocalizableParameter} HSMLocalizableParameter
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HSMLocalizableParameter.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HSMLocalizableParameter();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message["default"] = reader.string();
                    break;
                case 2:
                    message.currency = $root.proto.HSMCurrency.decode(reader, reader.uint32());
                    break;
                case 3:
                    message.dateTime = $root.proto.HSMDateTime.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a HSMLocalizableParameter message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.HSMLocalizableParameter
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.HSMLocalizableParameter} HSMLocalizableParameter
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HSMLocalizableParameter.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a HSMLocalizableParameter message.
         * @function verify
         * @memberof proto.HSMLocalizableParameter
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        HSMLocalizableParameter.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            var properties = {};
            if (message["default"] != null && message.hasOwnProperty("default"))
                if (!$util.isString(message["default"]))
                    return "default: string expected";
            if (message.currency != null && message.hasOwnProperty("currency")) {
                properties.paramOneof = 1;
                {
                    var error = $root.proto.HSMCurrency.verify(message.currency);
                    if (error)
                        return "currency." + error;
                }
            }
            if (message.dateTime != null && message.hasOwnProperty("dateTime")) {
                if (properties.paramOneof === 1)
                    return "paramOneof: multiple values";
                properties.paramOneof = 1;
                {
                    var error = $root.proto.HSMDateTime.verify(message.dateTime);
                    if (error)
                        return "dateTime." + error;
                }
            }
            return null;
        };

        /**
         * Creates a HSMLocalizableParameter message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.HSMLocalizableParameter
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.HSMLocalizableParameter} HSMLocalizableParameter
         */
        HSMLocalizableParameter.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.HSMLocalizableParameter)
                return object;
            var message = new $root.proto.HSMLocalizableParameter();
            if (object["default"] != null)
                message["default"] = String(object["default"]);
            if (object.currency != null) {
                if (typeof object.currency !== "object")
                    throw TypeError(".proto.HSMLocalizableParameter.currency: object expected");
                message.currency = $root.proto.HSMCurrency.fromObject(object.currency);
            }
            if (object.dateTime != null) {
                if (typeof object.dateTime !== "object")
                    throw TypeError(".proto.HSMLocalizableParameter.dateTime: object expected");
                message.dateTime = $root.proto.HSMDateTime.fromObject(object.dateTime);
            }
            return message;
        };

        /**
         * Creates a plain object from a HSMLocalizableParameter message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.HSMLocalizableParameter
         * @static
         * @param {proto.HSMLocalizableParameter} message HSMLocalizableParameter
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        HSMLocalizableParameter.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                object["default"] = "";
            if (message["default"] != null && message.hasOwnProperty("default"))
                object["default"] = message["default"];
            if (message.currency != null && message.hasOwnProperty("currency")) {
                object.currency = $root.proto.HSMCurrency.toObject(message.currency, options);
                if (options.oneofs)
                    object.paramOneof = "currency";
            }
            if (message.dateTime != null && message.hasOwnProperty("dateTime")) {
                object.dateTime = $root.proto.HSMDateTime.toObject(message.dateTime, options);
                if (options.oneofs)
                    object.paramOneof = "dateTime";
            }
            return object;
        };

        /**
         * Converts this HSMLocalizableParameter to JSON.
         * @function toJSON
         * @memberof proto.HSMLocalizableParameter
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        HSMLocalizableParameter.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return HSMLocalizableParameter;
    })();

    proto.HighlyStructuredMessage = (function() {

        /**
         * Properties of a HighlyStructuredMessage.
         * @memberof proto
         * @interface IHighlyStructuredMessage
         * @property {string|null} [namespace] HighlyStructuredMessage namespace
         * @property {string|null} [elementName] HighlyStructuredMessage elementName
         * @property {Array.<string>|null} [params] HighlyStructuredMessage params
         * @property {string|null} [fallbackLg] HighlyStructuredMessage fallbackLg
         * @property {string|null} [fallbackLc] HighlyStructuredMessage fallbackLc
         * @property {Array.<proto.IHSMLocalizableParameter>|null} [localizableParams] HighlyStructuredMessage localizableParams
         * @property {string|null} [deterministicLg] HighlyStructuredMessage deterministicLg
         * @property {string|null} [deterministicLc] HighlyStructuredMessage deterministicLc
         * @property {proto.ITemplateMessage|null} [hydratedHsm] HighlyStructuredMessage hydratedHsm
         */

        /**
         * Constructs a new HighlyStructuredMessage.
         * @memberof proto
         * @classdesc Represents a HighlyStructuredMessage.
         * @implements IHighlyStructuredMessage
         * @constructor
         * @param {proto.IHighlyStructuredMessage=} [properties] Properties to set
         */
        function HighlyStructuredMessage(properties) {
            this.params = [];
            this.localizableParams = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * HighlyStructuredMessage namespace.
         * @member {string} namespace
         * @memberof proto.HighlyStructuredMessage
         * @instance
         */
        HighlyStructuredMessage.prototype.namespace = "";

        /**
         * HighlyStructuredMessage elementName.
         * @member {string} elementName
         * @memberof proto.HighlyStructuredMessage
         * @instance
         */
        HighlyStructuredMessage.prototype.elementName = "";

        /**
         * HighlyStructuredMessage params.
         * @member {Array.<string>} params
         * @memberof proto.HighlyStructuredMessage
         * @instance
         */
        HighlyStructuredMessage.prototype.params = $util.emptyArray;

        /**
         * HighlyStructuredMessage fallbackLg.
         * @member {string} fallbackLg
         * @memberof proto.HighlyStructuredMessage
         * @instance
         */
        HighlyStructuredMessage.prototype.fallbackLg = "";

        /**
         * HighlyStructuredMessage fallbackLc.
         * @member {string} fallbackLc
         * @memberof proto.HighlyStructuredMessage
         * @instance
         */
        HighlyStructuredMessage.prototype.fallbackLc = "";

        /**
         * HighlyStructuredMessage localizableParams.
         * @member {Array.<proto.IHSMLocalizableParameter>} localizableParams
         * @memberof proto.HighlyStructuredMessage
         * @instance
         */
        HighlyStructuredMessage.prototype.localizableParams = $util.emptyArray;

        /**
         * HighlyStructuredMessage deterministicLg.
         * @member {string} deterministicLg
         * @memberof proto.HighlyStructuredMessage
         * @instance
         */
        HighlyStructuredMessage.prototype.deterministicLg = "";

        /**
         * HighlyStructuredMessage deterministicLc.
         * @member {string} deterministicLc
         * @memberof proto.HighlyStructuredMessage
         * @instance
         */
        HighlyStructuredMessage.prototype.deterministicLc = "";

        /**
         * HighlyStructuredMessage hydratedHsm.
         * @member {proto.ITemplateMessage|null|undefined} hydratedHsm
         * @memberof proto.HighlyStructuredMessage
         * @instance
         */
        HighlyStructuredMessage.prototype.hydratedHsm = null;

        /**
         * Creates a new HighlyStructuredMessage instance using the specified properties.
         * @function create
         * @memberof proto.HighlyStructuredMessage
         * @static
         * @param {proto.IHighlyStructuredMessage=} [properties] Properties to set
         * @returns {proto.HighlyStructuredMessage} HighlyStructuredMessage instance
         */
        HighlyStructuredMessage.create = function create(properties) {
            return new HighlyStructuredMessage(properties);
        };

        /**
         * Encodes the specified HighlyStructuredMessage message. Does not implicitly {@link proto.HighlyStructuredMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.HighlyStructuredMessage
         * @static
         * @param {proto.IHighlyStructuredMessage} message HighlyStructuredMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HighlyStructuredMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.namespace != null && Object.hasOwnProperty.call(message, "namespace"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.namespace);
            if (message.elementName != null && Object.hasOwnProperty.call(message, "elementName"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.elementName);
            if (message.params != null && message.params.length)
                for (var i = 0; i < message.params.length; ++i)
                    writer.uint32(/* id 3, wireType 2 =*/26).string(message.params[i]);
            if (message.fallbackLg != null && Object.hasOwnProperty.call(message, "fallbackLg"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.fallbackLg);
            if (message.fallbackLc != null && Object.hasOwnProperty.call(message, "fallbackLc"))
                writer.uint32(/* id 5, wireType 2 =*/42).string(message.fallbackLc);
            if (message.localizableParams != null && message.localizableParams.length)
                for (var i = 0; i < message.localizableParams.length; ++i)
                    $root.proto.HSMLocalizableParameter.encode(message.localizableParams[i], writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim();
            if (message.deterministicLg != null && Object.hasOwnProperty.call(message, "deterministicLg"))
                writer.uint32(/* id 7, wireType 2 =*/58).string(message.deterministicLg);
            if (message.deterministicLc != null && Object.hasOwnProperty.call(message, "deterministicLc"))
                writer.uint32(/* id 8, wireType 2 =*/66).string(message.deterministicLc);
            if (message.hydratedHsm != null && Object.hasOwnProperty.call(message, "hydratedHsm"))
                $root.proto.TemplateMessage.encode(message.hydratedHsm, writer.uint32(/* id 9, wireType 2 =*/74).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified HighlyStructuredMessage message, length delimited. Does not implicitly {@link proto.HighlyStructuredMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.HighlyStructuredMessage
         * @static
         * @param {proto.IHighlyStructuredMessage} message HighlyStructuredMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HighlyStructuredMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a HighlyStructuredMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.HighlyStructuredMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.HighlyStructuredMessage} HighlyStructuredMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HighlyStructuredMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HighlyStructuredMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.namespace = reader.string();
                    break;
                case 2:
                    message.elementName = reader.string();
                    break;
                case 3:
                    if (!(message.params && message.params.length))
                        message.params = [];
                    message.params.push(reader.string());
                    break;
                case 4:
                    message.fallbackLg = reader.string();
                    break;
                case 5:
                    message.fallbackLc = reader.string();
                    break;
                case 6:
                    if (!(message.localizableParams && message.localizableParams.length))
                        message.localizableParams = [];
                    message.localizableParams.push($root.proto.HSMLocalizableParameter.decode(reader, reader.uint32()));
                    break;
                case 7:
                    message.deterministicLg = reader.string();
                    break;
                case 8:
                    message.deterministicLc = reader.string();
                    break;
                case 9:
                    message.hydratedHsm = $root.proto.TemplateMessage.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a HighlyStructuredMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.HighlyStructuredMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.HighlyStructuredMessage} HighlyStructuredMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HighlyStructuredMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a HighlyStructuredMessage message.
         * @function verify
         * @memberof proto.HighlyStructuredMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        HighlyStructuredMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.namespace != null && message.hasOwnProperty("namespace"))
                if (!$util.isString(message.namespace))
                    return "namespace: string expected";
            if (message.elementName != null && message.hasOwnProperty("elementName"))
                if (!$util.isString(message.elementName))
                    return "elementName: string expected";
            if (message.params != null && message.hasOwnProperty("params")) {
                if (!Array.isArray(message.params))
                    return "params: array expected";
                for (var i = 0; i < message.params.length; ++i)
                    if (!$util.isString(message.params[i]))
                        return "params: string[] expected";
            }
            if (message.fallbackLg != null && message.hasOwnProperty("fallbackLg"))
                if (!$util.isString(message.fallbackLg))
                    return "fallbackLg: string expected";
            if (message.fallbackLc != null && message.hasOwnProperty("fallbackLc"))
                if (!$util.isString(message.fallbackLc))
                    return "fallbackLc: string expected";
            if (message.localizableParams != null && message.hasOwnProperty("localizableParams")) {
                if (!Array.isArray(message.localizableParams))
                    return "localizableParams: array expected";
                for (var i = 0; i < message.localizableParams.length; ++i) {
                    var error = $root.proto.HSMLocalizableParameter.verify(message.localizableParams[i]);
                    if (error)
                        return "localizableParams." + error;
                }
            }
            if (message.deterministicLg != null && message.hasOwnProperty("deterministicLg"))
                if (!$util.isString(message.deterministicLg))
                    return "deterministicLg: string expected";
            if (message.deterministicLc != null && message.hasOwnProperty("deterministicLc"))
                if (!$util.isString(message.deterministicLc))
                    return "deterministicLc: string expected";
            if (message.hydratedHsm != null && message.hasOwnProperty("hydratedHsm")) {
                var error = $root.proto.TemplateMessage.verify(message.hydratedHsm);
                if (error)
                    return "hydratedHsm." + error;
            }
            return null;
        };

        /**
         * Creates a HighlyStructuredMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.HighlyStructuredMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.HighlyStructuredMessage} HighlyStructuredMessage
         */
        HighlyStructuredMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.HighlyStructuredMessage)
                return object;
            var message = new $root.proto.HighlyStructuredMessage();
            if (object.namespace != null)
                message.namespace = String(object.namespace);
            if (object.elementName != null)
                message.elementName = String(object.elementName);
            if (object.params) {
                if (!Array.isArray(object.params))
                    throw TypeError(".proto.HighlyStructuredMessage.params: array expected");
                message.params = [];
                for (var i = 0; i < object.params.length; ++i)
                    message.params[i] = String(object.params[i]);
            }
            if (object.fallbackLg != null)
                message.fallbackLg = String(object.fallbackLg);
            if (object.fallbackLc != null)
                message.fallbackLc = String(object.fallbackLc);
            if (object.localizableParams) {
                if (!Array.isArray(object.localizableParams))
                    throw TypeError(".proto.HighlyStructuredMessage.localizableParams: array expected");
                message.localizableParams = [];
                for (var i = 0; i < object.localizableParams.length; ++i) {
                    if (typeof object.localizableParams[i] !== "object")
                        throw TypeError(".proto.HighlyStructuredMessage.localizableParams: object expected");
                    message.localizableParams[i] = $root.proto.HSMLocalizableParameter.fromObject(object.localizableParams[i]);
                }
            }
            if (object.deterministicLg != null)
                message.deterministicLg = String(object.deterministicLg);
            if (object.deterministicLc != null)
                message.deterministicLc = String(object.deterministicLc);
            if (object.hydratedHsm != null) {
                if (typeof object.hydratedHsm !== "object")
                    throw TypeError(".proto.HighlyStructuredMessage.hydratedHsm: object expected");
                message.hydratedHsm = $root.proto.TemplateMessage.fromObject(object.hydratedHsm);
            }
            return message;
        };

        /**
         * Creates a plain object from a HighlyStructuredMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.HighlyStructuredMessage
         * @static
         * @param {proto.HighlyStructuredMessage} message HighlyStructuredMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        HighlyStructuredMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults) {
                object.params = [];
                object.localizableParams = [];
            }
            if (options.defaults) {
                object.namespace = "";
                object.elementName = "";
                object.fallbackLg = "";
                object.fallbackLc = "";
                object.deterministicLg = "";
                object.deterministicLc = "";
                object.hydratedHsm = null;
            }
            if (message.namespace != null && message.hasOwnProperty("namespace"))
                object.namespace = message.namespace;
            if (message.elementName != null && message.hasOwnProperty("elementName"))
                object.elementName = message.elementName;
            if (message.params && message.params.length) {
                object.params = [];
                for (var j = 0; j < message.params.length; ++j)
                    object.params[j] = message.params[j];
            }
            if (message.fallbackLg != null && message.hasOwnProperty("fallbackLg"))
                object.fallbackLg = message.fallbackLg;
            if (message.fallbackLc != null && message.hasOwnProperty("fallbackLc"))
                object.fallbackLc = message.fallbackLc;
            if (message.localizableParams && message.localizableParams.length) {
                object.localizableParams = [];
                for (var j = 0; j < message.localizableParams.length; ++j)
                    object.localizableParams[j] = $root.proto.HSMLocalizableParameter.toObject(message.localizableParams[j], options);
            }
            if (message.deterministicLg != null && message.hasOwnProperty("deterministicLg"))
                object.deterministicLg = message.deterministicLg;
            if (message.deterministicLc != null && message.hasOwnProperty("deterministicLc"))
                object.deterministicLc = message.deterministicLc;
            if (message.hydratedHsm != null && message.hasOwnProperty("hydratedHsm"))
                object.hydratedHsm = $root.proto.TemplateMessage.toObject(message.hydratedHsm, options);
            return object;
        };

        /**
         * Converts this HighlyStructuredMessage to JSON.
         * @function toJSON
         * @memberof proto.HighlyStructuredMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        HighlyStructuredMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return HighlyStructuredMessage;
    })();

    proto.SendPaymentMessage = (function() {

        /**
         * Properties of a SendPaymentMessage.
         * @memberof proto
         * @interface ISendPaymentMessage
         * @property {proto.IMessage|null} [noteMessage] SendPaymentMessage noteMessage
         * @property {proto.IMessageKey|null} [requestMessageKey] SendPaymentMessage requestMessageKey
         * @property {proto.IPaymentBackground|null} [background] SendPaymentMessage background
         */

        /**
         * Constructs a new SendPaymentMessage.
         * @memberof proto
         * @classdesc Represents a SendPaymentMessage.
         * @implements ISendPaymentMessage
         * @constructor
         * @param {proto.ISendPaymentMessage=} [properties] Properties to set
         */
        function SendPaymentMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * SendPaymentMessage noteMessage.
         * @member {proto.IMessage|null|undefined} noteMessage
         * @memberof proto.SendPaymentMessage
         * @instance
         */
        SendPaymentMessage.prototype.noteMessage = null;

        /**
         * SendPaymentMessage requestMessageKey.
         * @member {proto.IMessageKey|null|undefined} requestMessageKey
         * @memberof proto.SendPaymentMessage
         * @instance
         */
        SendPaymentMessage.prototype.requestMessageKey = null;

        /**
         * SendPaymentMessage background.
         * @member {proto.IPaymentBackground|null|undefined} background
         * @memberof proto.SendPaymentMessage
         * @instance
         */
        SendPaymentMessage.prototype.background = null;

        /**
         * Creates a new SendPaymentMessage instance using the specified properties.
         * @function create
         * @memberof proto.SendPaymentMessage
         * @static
         * @param {proto.ISendPaymentMessage=} [properties] Properties to set
         * @returns {proto.SendPaymentMessage} SendPaymentMessage instance
         */
        SendPaymentMessage.create = function create(properties) {
            return new SendPaymentMessage(properties);
        };

        /**
         * Encodes the specified SendPaymentMessage message. Does not implicitly {@link proto.SendPaymentMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.SendPaymentMessage
         * @static
         * @param {proto.ISendPaymentMessage} message SendPaymentMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SendPaymentMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.noteMessage != null && Object.hasOwnProperty.call(message, "noteMessage"))
                $root.proto.Message.encode(message.noteMessage, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.requestMessageKey != null && Object.hasOwnProperty.call(message, "requestMessageKey"))
                $root.proto.MessageKey.encode(message.requestMessageKey, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.background != null && Object.hasOwnProperty.call(message, "background"))
                $root.proto.PaymentBackground.encode(message.background, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified SendPaymentMessage message, length delimited. Does not implicitly {@link proto.SendPaymentMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.SendPaymentMessage
         * @static
         * @param {proto.ISendPaymentMessage} message SendPaymentMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SendPaymentMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a SendPaymentMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.SendPaymentMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.SendPaymentMessage} SendPaymentMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SendPaymentMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SendPaymentMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 2:
                    message.noteMessage = $root.proto.Message.decode(reader, reader.uint32());
                    break;
                case 3:
                    message.requestMessageKey = $root.proto.MessageKey.decode(reader, reader.uint32());
                    break;
                case 4:
                    message.background = $root.proto.PaymentBackground.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a SendPaymentMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.SendPaymentMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.SendPaymentMessage} SendPaymentMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SendPaymentMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a SendPaymentMessage message.
         * @function verify
         * @memberof proto.SendPaymentMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        SendPaymentMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.noteMessage != null && message.hasOwnProperty("noteMessage")) {
                var error = $root.proto.Message.verify(message.noteMessage);
                if (error)
                    return "noteMessage." + error;
            }
            if (message.requestMessageKey != null && message.hasOwnProperty("requestMessageKey")) {
                var error = $root.proto.MessageKey.verify(message.requestMessageKey);
                if (error)
                    return "requestMessageKey." + error;
            }
            if (message.background != null && message.hasOwnProperty("background")) {
                var error = $root.proto.PaymentBackground.verify(message.background);
                if (error)
                    return "background." + error;
            }
            return null;
        };

        /**
         * Creates a SendPaymentMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.SendPaymentMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.SendPaymentMessage} SendPaymentMessage
         */
        SendPaymentMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.SendPaymentMessage)
                return object;
            var message = new $root.proto.SendPaymentMessage();
            if (object.noteMessage != null) {
                if (typeof object.noteMessage !== "object")
                    throw TypeError(".proto.SendPaymentMessage.noteMessage: object expected");
                message.noteMessage = $root.proto.Message.fromObject(object.noteMessage);
            }
            if (object.requestMessageKey != null) {
                if (typeof object.requestMessageKey !== "object")
                    throw TypeError(".proto.SendPaymentMessage.requestMessageKey: object expected");
                message.requestMessageKey = $root.proto.MessageKey.fromObject(object.requestMessageKey);
            }
            if (object.background != null) {
                if (typeof object.background !== "object")
                    throw TypeError(".proto.SendPaymentMessage.background: object expected");
                message.background = $root.proto.PaymentBackground.fromObject(object.background);
            }
            return message;
        };

        /**
         * Creates a plain object from a SendPaymentMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.SendPaymentMessage
         * @static
         * @param {proto.SendPaymentMessage} message SendPaymentMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        SendPaymentMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.noteMessage = null;
                object.requestMessageKey = null;
                object.background = null;
            }
            if (message.noteMessage != null && message.hasOwnProperty("noteMessage"))
                object.noteMessage = $root.proto.Message.toObject(message.noteMessage, options);
            if (message.requestMessageKey != null && message.hasOwnProperty("requestMessageKey"))
                object.requestMessageKey = $root.proto.MessageKey.toObject(message.requestMessageKey, options);
            if (message.background != null && message.hasOwnProperty("background"))
                object.background = $root.proto.PaymentBackground.toObject(message.background, options);
            return object;
        };

        /**
         * Converts this SendPaymentMessage to JSON.
         * @function toJSON
         * @memberof proto.SendPaymentMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        SendPaymentMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return SendPaymentMessage;
    })();

    proto.RequestPaymentMessage = (function() {

        /**
         * Properties of a RequestPaymentMessage.
         * @memberof proto
         * @interface IRequestPaymentMessage
         * @property {proto.IMessage|null} [noteMessage] RequestPaymentMessage noteMessage
         * @property {string|null} [currencyCodeIso4217] RequestPaymentMessage currencyCodeIso4217
         * @property {number|Long|null} [amount1000] RequestPaymentMessage amount1000
         * @property {string|null} [requestFrom] RequestPaymentMessage requestFrom
         * @property {number|Long|null} [expiryTimestamp] RequestPaymentMessage expiryTimestamp
         * @property {proto.IMoney|null} [amount] RequestPaymentMessage amount
         * @property {proto.IPaymentBackground|null} [background] RequestPaymentMessage background
         */

        /**
         * Constructs a new RequestPaymentMessage.
         * @memberof proto
         * @classdesc Represents a RequestPaymentMessage.
         * @implements IRequestPaymentMessage
         * @constructor
         * @param {proto.IRequestPaymentMessage=} [properties] Properties to set
         */
        function RequestPaymentMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * RequestPaymentMessage noteMessage.
         * @member {proto.IMessage|null|undefined} noteMessage
         * @memberof proto.RequestPaymentMessage
         * @instance
         */
        RequestPaymentMessage.prototype.noteMessage = null;

        /**
         * RequestPaymentMessage currencyCodeIso4217.
         * @member {string} currencyCodeIso4217
         * @memberof proto.RequestPaymentMessage
         * @instance
         */
        RequestPaymentMessage.prototype.currencyCodeIso4217 = "";

        /**
         * RequestPaymentMessage amount1000.
         * @member {number|Long} amount1000
         * @memberof proto.RequestPaymentMessage
         * @instance
         */
        RequestPaymentMessage.prototype.amount1000 = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * RequestPaymentMessage requestFrom.
         * @member {string} requestFrom
         * @memberof proto.RequestPaymentMessage
         * @instance
         */
        RequestPaymentMessage.prototype.requestFrom = "";

        /**
         * RequestPaymentMessage expiryTimestamp.
         * @member {number|Long} expiryTimestamp
         * @memberof proto.RequestPaymentMessage
         * @instance
         */
        RequestPaymentMessage.prototype.expiryTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * RequestPaymentMessage amount.
         * @member {proto.IMoney|null|undefined} amount
         * @memberof proto.RequestPaymentMessage
         * @instance
         */
        RequestPaymentMessage.prototype.amount = null;

        /**
         * RequestPaymentMessage background.
         * @member {proto.IPaymentBackground|null|undefined} background
         * @memberof proto.RequestPaymentMessage
         * @instance
         */
        RequestPaymentMessage.prototype.background = null;

        /**
         * Creates a new RequestPaymentMessage instance using the specified properties.
         * @function create
         * @memberof proto.RequestPaymentMessage
         * @static
         * @param {proto.IRequestPaymentMessage=} [properties] Properties to set
         * @returns {proto.RequestPaymentMessage} RequestPaymentMessage instance
         */
        RequestPaymentMessage.create = function create(properties) {
            return new RequestPaymentMessage(properties);
        };

        /**
         * Encodes the specified RequestPaymentMessage message. Does not implicitly {@link proto.RequestPaymentMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.RequestPaymentMessage
         * @static
         * @param {proto.IRequestPaymentMessage} message RequestPaymentMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RequestPaymentMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.currencyCodeIso4217 != null && Object.hasOwnProperty.call(message, "currencyCodeIso4217"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.currencyCodeIso4217);
            if (message.amount1000 != null && Object.hasOwnProperty.call(message, "amount1000"))
                writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.amount1000);
            if (message.requestFrom != null && Object.hasOwnProperty.call(message, "requestFrom"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.requestFrom);
            if (message.noteMessage != null && Object.hasOwnProperty.call(message, "noteMessage"))
                $root.proto.Message.encode(message.noteMessage, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
            if (message.expiryTimestamp != null && Object.hasOwnProperty.call(message, "expiryTimestamp"))
                writer.uint32(/* id 5, wireType 0 =*/40).int64(message.expiryTimestamp);
            if (message.amount != null && Object.hasOwnProperty.call(message, "amount"))
                $root.proto.Money.encode(message.amount, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim();
            if (message.background != null && Object.hasOwnProperty.call(message, "background"))
                $root.proto.PaymentBackground.encode(message.background, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified RequestPaymentMessage message, length delimited. Does not implicitly {@link proto.RequestPaymentMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.RequestPaymentMessage
         * @static
         * @param {proto.IRequestPaymentMessage} message RequestPaymentMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        RequestPaymentMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a RequestPaymentMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.RequestPaymentMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.RequestPaymentMessage} RequestPaymentMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RequestPaymentMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.RequestPaymentMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 4:
                    message.noteMessage = $root.proto.Message.decode(reader, reader.uint32());
                    break;
                case 1:
                    message.currencyCodeIso4217 = reader.string();
                    break;
                case 2:
                    message.amount1000 = reader.uint64();
                    break;
                case 3:
                    message.requestFrom = reader.string();
                    break;
                case 5:
                    message.expiryTimestamp = reader.int64();
                    break;
                case 6:
                    message.amount = $root.proto.Money.decode(reader, reader.uint32());
                    break;
                case 7:
                    message.background = $root.proto.PaymentBackground.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a RequestPaymentMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.RequestPaymentMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.RequestPaymentMessage} RequestPaymentMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        RequestPaymentMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a RequestPaymentMessage message.
         * @function verify
         * @memberof proto.RequestPaymentMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        RequestPaymentMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.noteMessage != null && message.hasOwnProperty("noteMessage")) {
                var error = $root.proto.Message.verify(message.noteMessage);
                if (error)
                    return "noteMessage." + error;
            }
            if (message.currencyCodeIso4217 != null && message.hasOwnProperty("currencyCodeIso4217"))
                if (!$util.isString(message.currencyCodeIso4217))
                    return "currencyCodeIso4217: string expected";
            if (message.amount1000 != null && message.hasOwnProperty("amount1000"))
                if (!$util.isInteger(message.amount1000) && !(message.amount1000 && $util.isInteger(message.amount1000.low) && $util.isInteger(message.amount1000.high)))
                    return "amount1000: integer|Long expected";
            if (message.requestFrom != null && message.hasOwnProperty("requestFrom"))
                if (!$util.isString(message.requestFrom))
                    return "requestFrom: string expected";
            if (message.expiryTimestamp != null && message.hasOwnProperty("expiryTimestamp"))
                if (!$util.isInteger(message.expiryTimestamp) && !(message.expiryTimestamp && $util.isInteger(message.expiryTimestamp.low) && $util.isInteger(message.expiryTimestamp.high)))
                    return "expiryTimestamp: integer|Long expected";
            if (message.amount != null && message.hasOwnProperty("amount")) {
                var error = $root.proto.Money.verify(message.amount);
                if (error)
                    return "amount." + error;
            }
            if (message.background != null && message.hasOwnProperty("background")) {
                var error = $root.proto.PaymentBackground.verify(message.background);
                if (error)
                    return "background." + error;
            }
            return null;
        };

        /**
         * Creates a RequestPaymentMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.RequestPaymentMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.RequestPaymentMessage} RequestPaymentMessage
         */
        RequestPaymentMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.RequestPaymentMessage)
                return object;
            var message = new $root.proto.RequestPaymentMessage();
            if (object.noteMessage != null) {
                if (typeof object.noteMessage !== "object")
                    throw TypeError(".proto.RequestPaymentMessage.noteMessage: object expected");
                message.noteMessage = $root.proto.Message.fromObject(object.noteMessage);
            }
            if (object.currencyCodeIso4217 != null)
                message.currencyCodeIso4217 = String(object.currencyCodeIso4217);
            if (object.amount1000 != null)
                if ($util.Long)
                    (message.amount1000 = $util.Long.fromValue(object.amount1000)).unsigned = true;
                else if (typeof object.amount1000 === "string")
                    message.amount1000 = parseInt(object.amount1000, 10);
                else if (typeof object.amount1000 === "number")
                    message.amount1000 = object.amount1000;
                else if (typeof object.amount1000 === "object")
                    message.amount1000 = new $util.LongBits(object.amount1000.low >>> 0, object.amount1000.high >>> 0).toNumber(true);
            if (object.requestFrom != null)
                message.requestFrom = String(object.requestFrom);
            if (object.expiryTimestamp != null)
                if ($util.Long)
                    (message.expiryTimestamp = $util.Long.fromValue(object.expiryTimestamp)).unsigned = false;
                else if (typeof object.expiryTimestamp === "string")
                    message.expiryTimestamp = parseInt(object.expiryTimestamp, 10);
                else if (typeof object.expiryTimestamp === "number")
                    message.expiryTimestamp = object.expiryTimestamp;
                else if (typeof object.expiryTimestamp === "object")
                    message.expiryTimestamp = new $util.LongBits(object.expiryTimestamp.low >>> 0, object.expiryTimestamp.high >>> 0).toNumber();
            if (object.amount != null) {
                if (typeof object.amount !== "object")
                    throw TypeError(".proto.RequestPaymentMessage.amount: object expected");
                message.amount = $root.proto.Money.fromObject(object.amount);
            }
            if (object.background != null) {
                if (typeof object.background !== "object")
                    throw TypeError(".proto.RequestPaymentMessage.background: object expected");
                message.background = $root.proto.PaymentBackground.fromObject(object.background);
            }
            return message;
        };

        /**
         * Creates a plain object from a RequestPaymentMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.RequestPaymentMessage
         * @static
         * @param {proto.RequestPaymentMessage} message RequestPaymentMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        RequestPaymentMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.currencyCodeIso4217 = "";
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.amount1000 = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.amount1000 = options.longs === String ? "0" : 0;
                object.requestFrom = "";
                object.noteMessage = null;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.expiryTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.expiryTimestamp = options.longs === String ? "0" : 0;
                object.amount = null;
                object.background = null;
            }
            if (message.currencyCodeIso4217 != null && message.hasOwnProperty("currencyCodeIso4217"))
                object.currencyCodeIso4217 = message.currencyCodeIso4217;
            if (message.amount1000 != null && message.hasOwnProperty("amount1000"))
                if (typeof message.amount1000 === "number")
                    object.amount1000 = options.longs === String ? String(message.amount1000) : message.amount1000;
                else
                    object.amount1000 = options.longs === String ? $util.Long.prototype.toString.call(message.amount1000) : options.longs === Number ? new $util.LongBits(message.amount1000.low >>> 0, message.amount1000.high >>> 0).toNumber(true) : message.amount1000;
            if (message.requestFrom != null && message.hasOwnProperty("requestFrom"))
                object.requestFrom = message.requestFrom;
            if (message.noteMessage != null && message.hasOwnProperty("noteMessage"))
                object.noteMessage = $root.proto.Message.toObject(message.noteMessage, options);
            if (message.expiryTimestamp != null && message.hasOwnProperty("expiryTimestamp"))
                if (typeof message.expiryTimestamp === "number")
                    object.expiryTimestamp = options.longs === String ? String(message.expiryTimestamp) : message.expiryTimestamp;
                else
                    object.expiryTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.expiryTimestamp) : options.longs === Number ? new $util.LongBits(message.expiryTimestamp.low >>> 0, message.expiryTimestamp.high >>> 0).toNumber() : message.expiryTimestamp;
            if (message.amount != null && message.hasOwnProperty("amount"))
                object.amount = $root.proto.Money.toObject(message.amount, options);
            if (message.background != null && message.hasOwnProperty("background"))
                object.background = $root.proto.PaymentBackground.toObject(message.background, options);
            return object;
        };

        /**
         * Converts this RequestPaymentMessage to JSON.
         * @function toJSON
         * @memberof proto.RequestPaymentMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        RequestPaymentMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return RequestPaymentMessage;
    })();

    proto.DeclinePaymentRequestMessage = (function() {

        /**
         * Properties of a DeclinePaymentRequestMessage.
         * @memberof proto
         * @interface IDeclinePaymentRequestMessage
         * @property {proto.IMessageKey|null} [key] DeclinePaymentRequestMessage key
         */

        /**
         * Constructs a new DeclinePaymentRequestMessage.
         * @memberof proto
         * @classdesc Represents a DeclinePaymentRequestMessage.
         * @implements IDeclinePaymentRequestMessage
         * @constructor
         * @param {proto.IDeclinePaymentRequestMessage=} [properties] Properties to set
         */
        function DeclinePaymentRequestMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * DeclinePaymentRequestMessage key.
         * @member {proto.IMessageKey|null|undefined} key
         * @memberof proto.DeclinePaymentRequestMessage
         * @instance
         */
        DeclinePaymentRequestMessage.prototype.key = null;

        /**
         * Creates a new DeclinePaymentRequestMessage instance using the specified properties.
         * @function create
         * @memberof proto.DeclinePaymentRequestMessage
         * @static
         * @param {proto.IDeclinePaymentRequestMessage=} [properties] Properties to set
         * @returns {proto.DeclinePaymentRequestMessage} DeclinePaymentRequestMessage instance
         */
        DeclinePaymentRequestMessage.create = function create(properties) {
            return new DeclinePaymentRequestMessage(properties);
        };

        /**
         * Encodes the specified DeclinePaymentRequestMessage message. Does not implicitly {@link proto.DeclinePaymentRequestMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.DeclinePaymentRequestMessage
         * @static
         * @param {proto.IDeclinePaymentRequestMessage} message DeclinePaymentRequestMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        DeclinePaymentRequestMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.key != null && Object.hasOwnProperty.call(message, "key"))
                $root.proto.MessageKey.encode(message.key, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified DeclinePaymentRequestMessage message, length delimited. Does not implicitly {@link proto.DeclinePaymentRequestMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.DeclinePaymentRequestMessage
         * @static
         * @param {proto.IDeclinePaymentRequestMessage} message DeclinePaymentRequestMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        DeclinePaymentRequestMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a DeclinePaymentRequestMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.DeclinePaymentRequestMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.DeclinePaymentRequestMessage} DeclinePaymentRequestMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        DeclinePaymentRequestMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.DeclinePaymentRequestMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.key = $root.proto.MessageKey.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a DeclinePaymentRequestMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.DeclinePaymentRequestMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.DeclinePaymentRequestMessage} DeclinePaymentRequestMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        DeclinePaymentRequestMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a DeclinePaymentRequestMessage message.
         * @function verify
         * @memberof proto.DeclinePaymentRequestMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        DeclinePaymentRequestMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.key != null && message.hasOwnProperty("key")) {
                var error = $root.proto.MessageKey.verify(message.key);
                if (error)
                    return "key." + error;
            }
            return null;
        };

        /**
         * Creates a DeclinePaymentRequestMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.DeclinePaymentRequestMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.DeclinePaymentRequestMessage} DeclinePaymentRequestMessage
         */
        DeclinePaymentRequestMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.DeclinePaymentRequestMessage)
                return object;
            var message = new $root.proto.DeclinePaymentRequestMessage();
            if (object.key != null) {
                if (typeof object.key !== "object")
                    throw TypeError(".proto.DeclinePaymentRequestMessage.key: object expected");
                message.key = $root.proto.MessageKey.fromObject(object.key);
            }
            return message;
        };

        /**
         * Creates a plain object from a DeclinePaymentRequestMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.DeclinePaymentRequestMessage
         * @static
         * @param {proto.DeclinePaymentRequestMessage} message DeclinePaymentRequestMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        DeclinePaymentRequestMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                object.key = null;
            if (message.key != null && message.hasOwnProperty("key"))
                object.key = $root.proto.MessageKey.toObject(message.key, options);
            return object;
        };

        /**
         * Converts this DeclinePaymentRequestMessage to JSON.
         * @function toJSON
         * @memberof proto.DeclinePaymentRequestMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        DeclinePaymentRequestMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return DeclinePaymentRequestMessage;
    })();

    proto.CancelPaymentRequestMessage = (function() {

        /**
         * Properties of a CancelPaymentRequestMessage.
         * @memberof proto
         * @interface ICancelPaymentRequestMessage
         * @property {proto.IMessageKey|null} [key] CancelPaymentRequestMessage key
         */

        /**
         * Constructs a new CancelPaymentRequestMessage.
         * @memberof proto
         * @classdesc Represents a CancelPaymentRequestMessage.
         * @implements ICancelPaymentRequestMessage
         * @constructor
         * @param {proto.ICancelPaymentRequestMessage=} [properties] Properties to set
         */
        function CancelPaymentRequestMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * CancelPaymentRequestMessage key.
         * @member {proto.IMessageKey|null|undefined} key
         * @memberof proto.CancelPaymentRequestMessage
         * @instance
         */
        CancelPaymentRequestMessage.prototype.key = null;

        /**
         * Creates a new CancelPaymentRequestMessage instance using the specified properties.
         * @function create
         * @memberof proto.CancelPaymentRequestMessage
         * @static
         * @param {proto.ICancelPaymentRequestMessage=} [properties] Properties to set
         * @returns {proto.CancelPaymentRequestMessage} CancelPaymentRequestMessage instance
         */
        CancelPaymentRequestMessage.create = function create(properties) {
            return new CancelPaymentRequestMessage(properties);
        };

        /**
         * Encodes the specified CancelPaymentRequestMessage message. Does not implicitly {@link proto.CancelPaymentRequestMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.CancelPaymentRequestMessage
         * @static
         * @param {proto.ICancelPaymentRequestMessage} message CancelPaymentRequestMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CancelPaymentRequestMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.key != null && Object.hasOwnProperty.call(message, "key"))
                $root.proto.MessageKey.encode(message.key, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified CancelPaymentRequestMessage message, length delimited. Does not implicitly {@link proto.CancelPaymentRequestMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.CancelPaymentRequestMessage
         * @static
         * @param {proto.ICancelPaymentRequestMessage} message CancelPaymentRequestMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CancelPaymentRequestMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a CancelPaymentRequestMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.CancelPaymentRequestMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.CancelPaymentRequestMessage} CancelPaymentRequestMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CancelPaymentRequestMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.CancelPaymentRequestMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.key = $root.proto.MessageKey.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a CancelPaymentRequestMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.CancelPaymentRequestMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.CancelPaymentRequestMessage} CancelPaymentRequestMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CancelPaymentRequestMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a CancelPaymentRequestMessage message.
         * @function verify
         * @memberof proto.CancelPaymentRequestMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        CancelPaymentRequestMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.key != null && message.hasOwnProperty("key")) {
                var error = $root.proto.MessageKey.verify(message.key);
                if (error)
                    return "key." + error;
            }
            return null;
        };

        /**
         * Creates a CancelPaymentRequestMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.CancelPaymentRequestMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.CancelPaymentRequestMessage} CancelPaymentRequestMessage
         */
        CancelPaymentRequestMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.CancelPaymentRequestMessage)
                return object;
            var message = new $root.proto.CancelPaymentRequestMessage();
            if (object.key != null) {
                if (typeof object.key !== "object")
                    throw TypeError(".proto.CancelPaymentRequestMessage.key: object expected");
                message.key = $root.proto.MessageKey.fromObject(object.key);
            }
            return message;
        };

        /**
         * Creates a plain object from a CancelPaymentRequestMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.CancelPaymentRequestMessage
         * @static
         * @param {proto.CancelPaymentRequestMessage} message CancelPaymentRequestMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        CancelPaymentRequestMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                object.key = null;
            if (message.key != null && message.hasOwnProperty("key"))
                object.key = $root.proto.MessageKey.toObject(message.key, options);
            return object;
        };

        /**
         * Converts this CancelPaymentRequestMessage to JSON.
         * @function toJSON
         * @memberof proto.CancelPaymentRequestMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        CancelPaymentRequestMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return CancelPaymentRequestMessage;
    })();

    proto.PaymentInviteMessage = (function() {

        /**
         * Properties of a PaymentInviteMessage.
         * @memberof proto
         * @interface IPaymentInviteMessage
         * @property {proto.PaymentInviteMessage.PaymentInviteMessageServiceType|null} [serviceType] PaymentInviteMessage serviceType
         * @property {number|Long|null} [expiryTimestamp] PaymentInviteMessage expiryTimestamp
         */

        /**
         * Constructs a new PaymentInviteMessage.
         * @memberof proto
         * @classdesc Represents a PaymentInviteMessage.
         * @implements IPaymentInviteMessage
         * @constructor
         * @param {proto.IPaymentInviteMessage=} [properties] Properties to set
         */
        function PaymentInviteMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * PaymentInviteMessage serviceType.
         * @member {proto.PaymentInviteMessage.PaymentInviteMessageServiceType} serviceType
         * @memberof proto.PaymentInviteMessage
         * @instance
         */
        PaymentInviteMessage.prototype.serviceType = 0;

        /**
         * PaymentInviteMessage expiryTimestamp.
         * @member {number|Long} expiryTimestamp
         * @memberof proto.PaymentInviteMessage
         * @instance
         */
        PaymentInviteMessage.prototype.expiryTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * Creates a new PaymentInviteMessage instance using the specified properties.
         * @function create
         * @memberof proto.PaymentInviteMessage
         * @static
         * @param {proto.IPaymentInviteMessage=} [properties] Properties to set
         * @returns {proto.PaymentInviteMessage} PaymentInviteMessage instance
         */
        PaymentInviteMessage.create = function create(properties) {
            return new PaymentInviteMessage(properties);
        };

        /**
         * Encodes the specified PaymentInviteMessage message. Does not implicitly {@link proto.PaymentInviteMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.PaymentInviteMessage
         * @static
         * @param {proto.IPaymentInviteMessage} message PaymentInviteMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PaymentInviteMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.serviceType != null && Object.hasOwnProperty.call(message, "serviceType"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.serviceType);
            if (message.expiryTimestamp != null && Object.hasOwnProperty.call(message, "expiryTimestamp"))
                writer.uint32(/* id 2, wireType 0 =*/16).int64(message.expiryTimestamp);
            return writer;
        };

        /**
         * Encodes the specified PaymentInviteMessage message, length delimited. Does not implicitly {@link proto.PaymentInviteMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.PaymentInviteMessage
         * @static
         * @param {proto.IPaymentInviteMessage} message PaymentInviteMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PaymentInviteMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a PaymentInviteMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.PaymentInviteMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.PaymentInviteMessage} PaymentInviteMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PaymentInviteMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.PaymentInviteMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.serviceType = reader.int32();
                    break;
                case 2:
                    message.expiryTimestamp = reader.int64();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a PaymentInviteMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.PaymentInviteMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.PaymentInviteMessage} PaymentInviteMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PaymentInviteMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a PaymentInviteMessage message.
         * @function verify
         * @memberof proto.PaymentInviteMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        PaymentInviteMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.serviceType != null && message.hasOwnProperty("serviceType"))
                switch (message.serviceType) {
                default:
                    return "serviceType: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.expiryTimestamp != null && message.hasOwnProperty("expiryTimestamp"))
                if (!$util.isInteger(message.expiryTimestamp) && !(message.expiryTimestamp && $util.isInteger(message.expiryTimestamp.low) && $util.isInteger(message.expiryTimestamp.high)))
                    return "expiryTimestamp: integer|Long expected";
            return null;
        };

        /**
         * Creates a PaymentInviteMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.PaymentInviteMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.PaymentInviteMessage} PaymentInviteMessage
         */
        PaymentInviteMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.PaymentInviteMessage)
                return object;
            var message = new $root.proto.PaymentInviteMessage();
            switch (object.serviceType) {
            case "UNKNOWN":
            case 0:
                message.serviceType = 0;
                break;
            case "FBPAY":
            case 1:
                message.serviceType = 1;
                break;
            case "NOVI":
            case 2:
                message.serviceType = 2;
                break;
            case "UPI":
            case 3:
                message.serviceType = 3;
                break;
            }
            if (object.expiryTimestamp != null)
                if ($util.Long)
                    (message.expiryTimestamp = $util.Long.fromValue(object.expiryTimestamp)).unsigned = false;
                else if (typeof object.expiryTimestamp === "string")
                    message.expiryTimestamp = parseInt(object.expiryTimestamp, 10);
                else if (typeof object.expiryTimestamp === "number")
                    message.expiryTimestamp = object.expiryTimestamp;
                else if (typeof object.expiryTimestamp === "object")
                    message.expiryTimestamp = new $util.LongBits(object.expiryTimestamp.low >>> 0, object.expiryTimestamp.high >>> 0).toNumber();
            return message;
        };

        /**
         * Creates a plain object from a PaymentInviteMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.PaymentInviteMessage
         * @static
         * @param {proto.PaymentInviteMessage} message PaymentInviteMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        PaymentInviteMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.serviceType = options.enums === String ? "UNKNOWN" : 0;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.expiryTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.expiryTimestamp = options.longs === String ? "0" : 0;
            }
            if (message.serviceType != null && message.hasOwnProperty("serviceType"))
                object.serviceType = options.enums === String ? $root.proto.PaymentInviteMessage.PaymentInviteMessageServiceType[message.serviceType] : message.serviceType;
            if (message.expiryTimestamp != null && message.hasOwnProperty("expiryTimestamp"))
                if (typeof message.expiryTimestamp === "number")
                    object.expiryTimestamp = options.longs === String ? String(message.expiryTimestamp) : message.expiryTimestamp;
                else
                    object.expiryTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.expiryTimestamp) : options.longs === Number ? new $util.LongBits(message.expiryTimestamp.low >>> 0, message.expiryTimestamp.high >>> 0).toNumber() : message.expiryTimestamp;
            return object;
        };

        /**
         * Converts this PaymentInviteMessage to JSON.
         * @function toJSON
         * @memberof proto.PaymentInviteMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        PaymentInviteMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * PaymentInviteMessageServiceType enum.
         * @name proto.PaymentInviteMessage.PaymentInviteMessageServiceType
         * @enum {number}
         * @property {number} UNKNOWN=0 UNKNOWN value
         * @property {number} FBPAY=1 FBPAY value
         * @property {number} NOVI=2 NOVI value
         * @property {number} UPI=3 UPI value
         */
        PaymentInviteMessage.PaymentInviteMessageServiceType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "UNKNOWN"] = 0;
            values[valuesById[1] = "FBPAY"] = 1;
            values[valuesById[2] = "NOVI"] = 2;
            values[valuesById[3] = "UPI"] = 3;
            return values;
        })();

        return PaymentInviteMessage;
    })();

    proto.LiveLocationMessage = (function() {

        /**
         * Properties of a LiveLocationMessage.
         * @memberof proto
         * @interface ILiveLocationMessage
         * @property {number|null} [degreesLatitude] LiveLocationMessage degreesLatitude
         * @property {number|null} [degreesLongitude] LiveLocationMessage degreesLongitude
         * @property {number|null} [accuracyInMeters] LiveLocationMessage accuracyInMeters
         * @property {number|null} [speedInMps] LiveLocationMessage speedInMps
         * @property {number|null} [degreesClockwiseFromMagneticNorth] LiveLocationMessage degreesClockwiseFromMagneticNorth
         * @property {string|null} [caption] LiveLocationMessage caption
         * @property {number|Long|null} [sequenceNumber] LiveLocationMessage sequenceNumber
         * @property {number|null} [timeOffset] LiveLocationMessage timeOffset
         * @property {Uint8Array|null} [jpegThumbnail] LiveLocationMessage jpegThumbnail
         * @property {proto.IContextInfo|null} [contextInfo] LiveLocationMessage contextInfo
         */

        /**
         * Constructs a new LiveLocationMessage.
         * @memberof proto
         * @classdesc Represents a LiveLocationMessage.
         * @implements ILiveLocationMessage
         * @constructor
         * @param {proto.ILiveLocationMessage=} [properties] Properties to set
         */
        function LiveLocationMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * LiveLocationMessage degreesLatitude.
         * @member {number} degreesLatitude
         * @memberof proto.LiveLocationMessage
         * @instance
         */
        LiveLocationMessage.prototype.degreesLatitude = 0;

        /**
         * LiveLocationMessage degreesLongitude.
         * @member {number} degreesLongitude
         * @memberof proto.LiveLocationMessage
         * @instance
         */
        LiveLocationMessage.prototype.degreesLongitude = 0;

        /**
         * LiveLocationMessage accuracyInMeters.
         * @member {number} accuracyInMeters
         * @memberof proto.LiveLocationMessage
         * @instance
         */
        LiveLocationMessage.prototype.accuracyInMeters = 0;

        /**
         * LiveLocationMessage speedInMps.
         * @member {number} speedInMps
         * @memberof proto.LiveLocationMessage
         * @instance
         */
        LiveLocationMessage.prototype.speedInMps = 0;

        /**
         * LiveLocationMessage degreesClockwiseFromMagneticNorth.
         * @member {number} degreesClockwiseFromMagneticNorth
         * @memberof proto.LiveLocationMessage
         * @instance
         */
        LiveLocationMessage.prototype.degreesClockwiseFromMagneticNorth = 0;

        /**
         * LiveLocationMessage caption.
         * @member {string} caption
         * @memberof proto.LiveLocationMessage
         * @instance
         */
        LiveLocationMessage.prototype.caption = "";

        /**
         * LiveLocationMessage sequenceNumber.
         * @member {number|Long} sequenceNumber
         * @memberof proto.LiveLocationMessage
         * @instance
         */
        LiveLocationMessage.prototype.sequenceNumber = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * LiveLocationMessage timeOffset.
         * @member {number} timeOffset
         * @memberof proto.LiveLocationMessage
         * @instance
         */
        LiveLocationMessage.prototype.timeOffset = 0;

        /**
         * LiveLocationMessage jpegThumbnail.
         * @member {Uint8Array} jpegThumbnail
         * @memberof proto.LiveLocationMessage
         * @instance
         */
        LiveLocationMessage.prototype.jpegThumbnail = $util.newBuffer([]);

        /**
         * LiveLocationMessage contextInfo.
         * @member {proto.IContextInfo|null|undefined} contextInfo
         * @memberof proto.LiveLocationMessage
         * @instance
         */
        LiveLocationMessage.prototype.contextInfo = null;

        /**
         * Creates a new LiveLocationMessage instance using the specified properties.
         * @function create
         * @memberof proto.LiveLocationMessage
         * @static
         * @param {proto.ILiveLocationMessage=} [properties] Properties to set
         * @returns {proto.LiveLocationMessage} LiveLocationMessage instance
         */
        LiveLocationMessage.create = function create(properties) {
            return new LiveLocationMessage(properties);
        };

        /**
         * Encodes the specified LiveLocationMessage message. Does not implicitly {@link proto.LiveLocationMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.LiveLocationMessage
         * @static
         * @param {proto.ILiveLocationMessage} message LiveLocationMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        LiveLocationMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.degreesLatitude != null && Object.hasOwnProperty.call(message, "degreesLatitude"))
                writer.uint32(/* id 1, wireType 1 =*/9).double(message.degreesLatitude);
            if (message.degreesLongitude != null && Object.hasOwnProperty.call(message, "degreesLongitude"))
                writer.uint32(/* id 2, wireType 1 =*/17).double(message.degreesLongitude);
            if (message.accuracyInMeters != null && Object.hasOwnProperty.call(message, "accuracyInMeters"))
                writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.accuracyInMeters);
            if (message.speedInMps != null && Object.hasOwnProperty.call(message, "speedInMps"))
                writer.uint32(/* id 4, wireType 5 =*/37).float(message.speedInMps);
            if (message.degreesClockwiseFromMagneticNorth != null && Object.hasOwnProperty.call(message, "degreesClockwiseFromMagneticNorth"))
                writer.uint32(/* id 5, wireType 0 =*/40).uint32(message.degreesClockwiseFromMagneticNorth);
            if (message.caption != null && Object.hasOwnProperty.call(message, "caption"))
                writer.uint32(/* id 6, wireType 2 =*/50).string(message.caption);
            if (message.sequenceNumber != null && Object.hasOwnProperty.call(message, "sequenceNumber"))
                writer.uint32(/* id 7, wireType 0 =*/56).int64(message.sequenceNumber);
            if (message.timeOffset != null && Object.hasOwnProperty.call(message, "timeOffset"))
                writer.uint32(/* id 8, wireType 0 =*/64).uint32(message.timeOffset);
            if (message.jpegThumbnail != null && Object.hasOwnProperty.call(message, "jpegThumbnail"))
                writer.uint32(/* id 16, wireType 2 =*/130).bytes(message.jpegThumbnail);
            if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo"))
                $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 17, wireType 2 =*/138).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified LiveLocationMessage message, length delimited. Does not implicitly {@link proto.LiveLocationMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.LiveLocationMessage
         * @static
         * @param {proto.ILiveLocationMessage} message LiveLocationMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        LiveLocationMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a LiveLocationMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.LiveLocationMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.LiveLocationMessage} LiveLocationMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        LiveLocationMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.LiveLocationMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.degreesLatitude = reader.double();
                    break;
                case 2:
                    message.degreesLongitude = reader.double();
                    break;
                case 3:
                    message.accuracyInMeters = reader.uint32();
                    break;
                case 4:
                    message.speedInMps = reader.float();
                    break;
                case 5:
                    message.degreesClockwiseFromMagneticNorth = reader.uint32();
                    break;
                case 6:
                    message.caption = reader.string();
                    break;
                case 7:
                    message.sequenceNumber = reader.int64();
                    break;
                case 8:
                    message.timeOffset = reader.uint32();
                    break;
                case 16:
                    message.jpegThumbnail = reader.bytes();
                    break;
                case 17:
                    message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a LiveLocationMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.LiveLocationMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.LiveLocationMessage} LiveLocationMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        LiveLocationMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a LiveLocationMessage message.
         * @function verify
         * @memberof proto.LiveLocationMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        LiveLocationMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.degreesLatitude != null && message.hasOwnProperty("degreesLatitude"))
                if (typeof message.degreesLatitude !== "number")
                    return "degreesLatitude: number expected";
            if (message.degreesLongitude != null && message.hasOwnProperty("degreesLongitude"))
                if (typeof message.degreesLongitude !== "number")
                    return "degreesLongitude: number expected";
            if (message.accuracyInMeters != null && message.hasOwnProperty("accuracyInMeters"))
                if (!$util.isInteger(message.accuracyInMeters))
                    return "accuracyInMeters: integer expected";
            if (message.speedInMps != null && message.hasOwnProperty("speedInMps"))
                if (typeof message.speedInMps !== "number")
                    return "speedInMps: number expected";
            if (message.degreesClockwiseFromMagneticNorth != null && message.hasOwnProperty("degreesClockwiseFromMagneticNorth"))
                if (!$util.isInteger(message.degreesClockwiseFromMagneticNorth))
                    return "degreesClockwiseFromMagneticNorth: integer expected";
            if (message.caption != null && message.hasOwnProperty("caption"))
                if (!$util.isString(message.caption))
                    return "caption: string expected";
            if (message.sequenceNumber != null && message.hasOwnProperty("sequenceNumber"))
                if (!$util.isInteger(message.sequenceNumber) && !(message.sequenceNumber && $util.isInteger(message.sequenceNumber.low) && $util.isInteger(message.sequenceNumber.high)))
                    return "sequenceNumber: integer|Long expected";
            if (message.timeOffset != null && message.hasOwnProperty("timeOffset"))
                if (!$util.isInteger(message.timeOffset))
                    return "timeOffset: integer expected";
            if (message.jpegThumbnail != null && message.hasOwnProperty("jpegThumbnail"))
                if (!(message.jpegThumbnail && typeof message.jpegThumbnail.length === "number" || $util.isString(message.jpegThumbnail)))
                    return "jpegThumbnail: buffer expected";
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) {
                var error = $root.proto.ContextInfo.verify(message.contextInfo);
                if (error)
                    return "contextInfo." + error;
            }
            return null;
        };

        /**
         * Creates a LiveLocationMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.LiveLocationMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.LiveLocationMessage} LiveLocationMessage
         */
        LiveLocationMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.LiveLocationMessage)
                return object;
            var message = new $root.proto.LiveLocationMessage();
            if (object.degreesLatitude != null)
                message.degreesLatitude = Number(object.degreesLatitude);
            if (object.degreesLongitude != null)
                message.degreesLongitude = Number(object.degreesLongitude);
            if (object.accuracyInMeters != null)
                message.accuracyInMeters = object.accuracyInMeters >>> 0;
            if (object.speedInMps != null)
                message.speedInMps = Number(object.speedInMps);
            if (object.degreesClockwiseFromMagneticNorth != null)
                message.degreesClockwiseFromMagneticNorth = object.degreesClockwiseFromMagneticNorth >>> 0;
            if (object.caption != null)
                message.caption = String(object.caption);
            if (object.sequenceNumber != null)
                if ($util.Long)
                    (message.sequenceNumber = $util.Long.fromValue(object.sequenceNumber)).unsigned = false;
                else if (typeof object.sequenceNumber === "string")
                    message.sequenceNumber = parseInt(object.sequenceNumber, 10);
                else if (typeof object.sequenceNumber === "number")
                    message.sequenceNumber = object.sequenceNumber;
                else if (typeof object.sequenceNumber === "object")
                    message.sequenceNumber = new $util.LongBits(object.sequenceNumber.low >>> 0, object.sequenceNumber.high >>> 0).toNumber();
            if (object.timeOffset != null)
                message.timeOffset = object.timeOffset >>> 0;
            if (object.jpegThumbnail != null)
                if (typeof object.jpegThumbnail === "string")
                    $util.base64.decode(object.jpegThumbnail, message.jpegThumbnail = $util.newBuffer($util.base64.length(object.jpegThumbnail)), 0);
                else if (object.jpegThumbnail.length)
                    message.jpegThumbnail = object.jpegThumbnail;
            if (object.contextInfo != null) {
                if (typeof object.contextInfo !== "object")
                    throw TypeError(".proto.LiveLocationMessage.contextInfo: object expected");
                message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo);
            }
            return message;
        };

        /**
         * Creates a plain object from a LiveLocationMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.LiveLocationMessage
         * @static
         * @param {proto.LiveLocationMessage} message LiveLocationMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        LiveLocationMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.degreesLatitude = 0;
                object.degreesLongitude = 0;
                object.accuracyInMeters = 0;
                object.speedInMps = 0;
                object.degreesClockwiseFromMagneticNorth = 0;
                object.caption = "";
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.sequenceNumber = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.sequenceNumber = options.longs === String ? "0" : 0;
                object.timeOffset = 0;
                if (options.bytes === String)
                    object.jpegThumbnail = "";
                else {
                    object.jpegThumbnail = [];
                    if (options.bytes !== Array)
                        object.jpegThumbnail = $util.newBuffer(object.jpegThumbnail);
                }
                object.contextInfo = null;
            }
            if (message.degreesLatitude != null && message.hasOwnProperty("degreesLatitude"))
                object.degreesLatitude = options.json && !isFinite(message.degreesLatitude) ? String(message.degreesLatitude) : message.degreesLatitude;
            if (message.degreesLongitude != null && message.hasOwnProperty("degreesLongitude"))
                object.degreesLongitude = options.json && !isFinite(message.degreesLongitude) ? String(message.degreesLongitude) : message.degreesLongitude;
            if (message.accuracyInMeters != null && message.hasOwnProperty("accuracyInMeters"))
                object.accuracyInMeters = message.accuracyInMeters;
            if (message.speedInMps != null && message.hasOwnProperty("speedInMps"))
                object.speedInMps = options.json && !isFinite(message.speedInMps) ? String(message.speedInMps) : message.speedInMps;
            if (message.degreesClockwiseFromMagneticNorth != null && message.hasOwnProperty("degreesClockwiseFromMagneticNorth"))
                object.degreesClockwiseFromMagneticNorth = message.degreesClockwiseFromMagneticNorth;
            if (message.caption != null && message.hasOwnProperty("caption"))
                object.caption = message.caption;
            if (message.sequenceNumber != null && message.hasOwnProperty("sequenceNumber"))
                if (typeof message.sequenceNumber === "number")
                    object.sequenceNumber = options.longs === String ? String(message.sequenceNumber) : message.sequenceNumber;
                else
                    object.sequenceNumber = options.longs === String ? $util.Long.prototype.toString.call(message.sequenceNumber) : options.longs === Number ? new $util.LongBits(message.sequenceNumber.low >>> 0, message.sequenceNumber.high >>> 0).toNumber() : message.sequenceNumber;
            if (message.timeOffset != null && message.hasOwnProperty("timeOffset"))
                object.timeOffset = message.timeOffset;
            if (message.jpegThumbnail != null && message.hasOwnProperty("jpegThumbnail"))
                object.jpegThumbnail = options.bytes === String ? $util.base64.encode(message.jpegThumbnail, 0, message.jpegThumbnail.length) : options.bytes === Array ? Array.prototype.slice.call(message.jpegThumbnail) : message.jpegThumbnail;
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo"))
                object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options);
            return object;
        };

        /**
         * Converts this LiveLocationMessage to JSON.
         * @function toJSON
         * @memberof proto.LiveLocationMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        LiveLocationMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return LiveLocationMessage;
    })();

    proto.StickerMessage = (function() {

        /**
         * Properties of a StickerMessage.
         * @memberof proto
         * @interface IStickerMessage
         * @property {string|null} [url] StickerMessage url
         * @property {Uint8Array|null} [fileSha256] StickerMessage fileSha256
         * @property {Uint8Array|null} [fileEncSha256] StickerMessage fileEncSha256
         * @property {Uint8Array|null} [mediaKey] StickerMessage mediaKey
         * @property {string|null} [mimetype] StickerMessage mimetype
         * @property {number|null} [height] StickerMessage height
         * @property {number|null} [width] StickerMessage width
         * @property {string|null} [directPath] StickerMessage directPath
         * @property {number|Long|null} [fileLength] StickerMessage fileLength
         * @property {number|Long|null} [mediaKeyTimestamp] StickerMessage mediaKeyTimestamp
         * @property {number|null} [firstFrameLength] StickerMessage firstFrameLength
         * @property {Uint8Array|null} [firstFrameSidecar] StickerMessage firstFrameSidecar
         * @property {boolean|null} [isAnimated] StickerMessage isAnimated
         * @property {Uint8Array|null} [pngThumbnail] StickerMessage pngThumbnail
         * @property {proto.IContextInfo|null} [contextInfo] StickerMessage contextInfo
         */

        /**
         * Constructs a new StickerMessage.
         * @memberof proto
         * @classdesc Represents a StickerMessage.
         * @implements IStickerMessage
         * @constructor
         * @param {proto.IStickerMessage=} [properties] Properties to set
         */
        function StickerMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * StickerMessage url.
         * @member {string} url
         * @memberof proto.StickerMessage
         * @instance
         */
        StickerMessage.prototype.url = "";

        /**
         * StickerMessage fileSha256.
         * @member {Uint8Array} fileSha256
         * @memberof proto.StickerMessage
         * @instance
         */
        StickerMessage.prototype.fileSha256 = $util.newBuffer([]);

        /**
         * StickerMessage fileEncSha256.
         * @member {Uint8Array} fileEncSha256
         * @memberof proto.StickerMessage
         * @instance
         */
        StickerMessage.prototype.fileEncSha256 = $util.newBuffer([]);

        /**
         * StickerMessage mediaKey.
         * @member {Uint8Array} mediaKey
         * @memberof proto.StickerMessage
         * @instance
         */
        StickerMessage.prototype.mediaKey = $util.newBuffer([]);

        /**
         * StickerMessage mimetype.
         * @member {string} mimetype
         * @memberof proto.StickerMessage
         * @instance
         */
        StickerMessage.prototype.mimetype = "";

        /**
         * StickerMessage height.
         * @member {number} height
         * @memberof proto.StickerMessage
         * @instance
         */
        StickerMessage.prototype.height = 0;

        /**
         * StickerMessage width.
         * @member {number} width
         * @memberof proto.StickerMessage
         * @instance
         */
        StickerMessage.prototype.width = 0;

        /**
         * StickerMessage directPath.
         * @member {string} directPath
         * @memberof proto.StickerMessage
         * @instance
         */
        StickerMessage.prototype.directPath = "";

        /**
         * StickerMessage fileLength.
         * @member {number|Long} fileLength
         * @memberof proto.StickerMessage
         * @instance
         */
        StickerMessage.prototype.fileLength = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * StickerMessage mediaKeyTimestamp.
         * @member {number|Long} mediaKeyTimestamp
         * @memberof proto.StickerMessage
         * @instance
         */
        StickerMessage.prototype.mediaKeyTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * StickerMessage firstFrameLength.
         * @member {number} firstFrameLength
         * @memberof proto.StickerMessage
         * @instance
         */
        StickerMessage.prototype.firstFrameLength = 0;

        /**
         * StickerMessage firstFrameSidecar.
         * @member {Uint8Array} firstFrameSidecar
         * @memberof proto.StickerMessage
         * @instance
         */
        StickerMessage.prototype.firstFrameSidecar = $util.newBuffer([]);

        /**
         * StickerMessage isAnimated.
         * @member {boolean} isAnimated
         * @memberof proto.StickerMessage
         * @instance
         */
        StickerMessage.prototype.isAnimated = false;

        /**
         * StickerMessage pngThumbnail.
         * @member {Uint8Array} pngThumbnail
         * @memberof proto.StickerMessage
         * @instance
         */
        StickerMessage.prototype.pngThumbnail = $util.newBuffer([]);

        /**
         * StickerMessage contextInfo.
         * @member {proto.IContextInfo|null|undefined} contextInfo
         * @memberof proto.StickerMessage
         * @instance
         */
        StickerMessage.prototype.contextInfo = null;

        /**
         * Creates a new StickerMessage instance using the specified properties.
         * @function create
         * @memberof proto.StickerMessage
         * @static
         * @param {proto.IStickerMessage=} [properties] Properties to set
         * @returns {proto.StickerMessage} StickerMessage instance
         */
        StickerMessage.create = function create(properties) {
            return new StickerMessage(properties);
        };

        /**
         * Encodes the specified StickerMessage message. Does not implicitly {@link proto.StickerMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.StickerMessage
         * @static
         * @param {proto.IStickerMessage} message StickerMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        StickerMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.url != null && Object.hasOwnProperty.call(message, "url"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.url);
            if (message.fileSha256 != null && Object.hasOwnProperty.call(message, "fileSha256"))
                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.fileSha256);
            if (message.fileEncSha256 != null && Object.hasOwnProperty.call(message, "fileEncSha256"))
                writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.fileEncSha256);
            if (message.mediaKey != null && Object.hasOwnProperty.call(message, "mediaKey"))
                writer.uint32(/* id 4, wireType 2 =*/34).bytes(message.mediaKey);
            if (message.mimetype != null && Object.hasOwnProperty.call(message, "mimetype"))
                writer.uint32(/* id 5, wireType 2 =*/42).string(message.mimetype);
            if (message.height != null && Object.hasOwnProperty.call(message, "height"))
                writer.uint32(/* id 6, wireType 0 =*/48).uint32(message.height);
            if (message.width != null && Object.hasOwnProperty.call(message, "width"))
                writer.uint32(/* id 7, wireType 0 =*/56).uint32(message.width);
            if (message.directPath != null && Object.hasOwnProperty.call(message, "directPath"))
                writer.uint32(/* id 8, wireType 2 =*/66).string(message.directPath);
            if (message.fileLength != null && Object.hasOwnProperty.call(message, "fileLength"))
                writer.uint32(/* id 9, wireType 0 =*/72).uint64(message.fileLength);
            if (message.mediaKeyTimestamp != null && Object.hasOwnProperty.call(message, "mediaKeyTimestamp"))
                writer.uint32(/* id 10, wireType 0 =*/80).int64(message.mediaKeyTimestamp);
            if (message.firstFrameLength != null && Object.hasOwnProperty.call(message, "firstFrameLength"))
                writer.uint32(/* id 11, wireType 0 =*/88).uint32(message.firstFrameLength);
            if (message.firstFrameSidecar != null && Object.hasOwnProperty.call(message, "firstFrameSidecar"))
                writer.uint32(/* id 12, wireType 2 =*/98).bytes(message.firstFrameSidecar);
            if (message.isAnimated != null && Object.hasOwnProperty.call(message, "isAnimated"))
                writer.uint32(/* id 13, wireType 0 =*/104).bool(message.isAnimated);
            if (message.pngThumbnail != null && Object.hasOwnProperty.call(message, "pngThumbnail"))
                writer.uint32(/* id 16, wireType 2 =*/130).bytes(message.pngThumbnail);
            if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo"))
                $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 17, wireType 2 =*/138).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified StickerMessage message, length delimited. Does not implicitly {@link proto.StickerMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.StickerMessage
         * @static
         * @param {proto.IStickerMessage} message StickerMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        StickerMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a StickerMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.StickerMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.StickerMessage} StickerMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        StickerMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.StickerMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.url = reader.string();
                    break;
                case 2:
                    message.fileSha256 = reader.bytes();
                    break;
                case 3:
                    message.fileEncSha256 = reader.bytes();
                    break;
                case 4:
                    message.mediaKey = reader.bytes();
                    break;
                case 5:
                    message.mimetype = reader.string();
                    break;
                case 6:
                    message.height = reader.uint32();
                    break;
                case 7:
                    message.width = reader.uint32();
                    break;
                case 8:
                    message.directPath = reader.string();
                    break;
                case 9:
                    message.fileLength = reader.uint64();
                    break;
                case 10:
                    message.mediaKeyTimestamp = reader.int64();
                    break;
                case 11:
                    message.firstFrameLength = reader.uint32();
                    break;
                case 12:
                    message.firstFrameSidecar = reader.bytes();
                    break;
                case 13:
                    message.isAnimated = reader.bool();
                    break;
                case 16:
                    message.pngThumbnail = reader.bytes();
                    break;
                case 17:
                    message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a StickerMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.StickerMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.StickerMessage} StickerMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        StickerMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a StickerMessage message.
         * @function verify
         * @memberof proto.StickerMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        StickerMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.url != null && message.hasOwnProperty("url"))
                if (!$util.isString(message.url))
                    return "url: string expected";
            if (message.fileSha256 != null && message.hasOwnProperty("fileSha256"))
                if (!(message.fileSha256 && typeof message.fileSha256.length === "number" || $util.isString(message.fileSha256)))
                    return "fileSha256: buffer expected";
            if (message.fileEncSha256 != null && message.hasOwnProperty("fileEncSha256"))
                if (!(message.fileEncSha256 && typeof message.fileEncSha256.length === "number" || $util.isString(message.fileEncSha256)))
                    return "fileEncSha256: buffer expected";
            if (message.mediaKey != null && message.hasOwnProperty("mediaKey"))
                if (!(message.mediaKey && typeof message.mediaKey.length === "number" || $util.isString(message.mediaKey)))
                    return "mediaKey: buffer expected";
            if (message.mimetype != null && message.hasOwnProperty("mimetype"))
                if (!$util.isString(message.mimetype))
                    return "mimetype: string expected";
            if (message.height != null && message.hasOwnProperty("height"))
                if (!$util.isInteger(message.height))
                    return "height: integer expected";
            if (message.width != null && message.hasOwnProperty("width"))
                if (!$util.isInteger(message.width))
                    return "width: integer expected";
            if (message.directPath != null && message.hasOwnProperty("directPath"))
                if (!$util.isString(message.directPath))
                    return "directPath: string expected";
            if (message.fileLength != null && message.hasOwnProperty("fileLength"))
                if (!$util.isInteger(message.fileLength) && !(message.fileLength && $util.isInteger(message.fileLength.low) && $util.isInteger(message.fileLength.high)))
                    return "fileLength: integer|Long expected";
            if (message.mediaKeyTimestamp != null && message.hasOwnProperty("mediaKeyTimestamp"))
                if (!$util.isInteger(message.mediaKeyTimestamp) && !(message.mediaKeyTimestamp && $util.isInteger(message.mediaKeyTimestamp.low) && $util.isInteger(message.mediaKeyTimestamp.high)))
                    return "mediaKeyTimestamp: integer|Long expected";
            if (message.firstFrameLength != null && message.hasOwnProperty("firstFrameLength"))
                if (!$util.isInteger(message.firstFrameLength))
                    return "firstFrameLength: integer expected";
            if (message.firstFrameSidecar != null && message.hasOwnProperty("firstFrameSidecar"))
                if (!(message.firstFrameSidecar && typeof message.firstFrameSidecar.length === "number" || $util.isString(message.firstFrameSidecar)))
                    return "firstFrameSidecar: buffer expected";
            if (message.isAnimated != null && message.hasOwnProperty("isAnimated"))
                if (typeof message.isAnimated !== "boolean")
                    return "isAnimated: boolean expected";
            if (message.pngThumbnail != null && message.hasOwnProperty("pngThumbnail"))
                if (!(message.pngThumbnail && typeof message.pngThumbnail.length === "number" || $util.isString(message.pngThumbnail)))
                    return "pngThumbnail: buffer expected";
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) {
                var error = $root.proto.ContextInfo.verify(message.contextInfo);
                if (error)
                    return "contextInfo." + error;
            }
            return null;
        };

        /**
         * Creates a StickerMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.StickerMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.StickerMessage} StickerMessage
         */
        StickerMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.StickerMessage)
                return object;
            var message = new $root.proto.StickerMessage();
            if (object.url != null)
                message.url = String(object.url);
            if (object.fileSha256 != null)
                if (typeof object.fileSha256 === "string")
                    $util.base64.decode(object.fileSha256, message.fileSha256 = $util.newBuffer($util.base64.length(object.fileSha256)), 0);
                else if (object.fileSha256.length)
                    message.fileSha256 = object.fileSha256;
            if (object.fileEncSha256 != null)
                if (typeof object.fileEncSha256 === "string")
                    $util.base64.decode(object.fileEncSha256, message.fileEncSha256 = $util.newBuffer($util.base64.length(object.fileEncSha256)), 0);
                else if (object.fileEncSha256.length)
                    message.fileEncSha256 = object.fileEncSha256;
            if (object.mediaKey != null)
                if (typeof object.mediaKey === "string")
                    $util.base64.decode(object.mediaKey, message.mediaKey = $util.newBuffer($util.base64.length(object.mediaKey)), 0);
                else if (object.mediaKey.length)
                    message.mediaKey = object.mediaKey;
            if (object.mimetype != null)
                message.mimetype = String(object.mimetype);
            if (object.height != null)
                message.height = object.height >>> 0;
            if (object.width != null)
                message.width = object.width >>> 0;
            if (object.directPath != null)
                message.directPath = String(object.directPath);
            if (object.fileLength != null)
                if ($util.Long)
                    (message.fileLength = $util.Long.fromValue(object.fileLength)).unsigned = true;
                else if (typeof object.fileLength === "string")
                    message.fileLength = parseInt(object.fileLength, 10);
                else if (typeof object.fileLength === "number")
                    message.fileLength = object.fileLength;
                else if (typeof object.fileLength === "object")
                    message.fileLength = new $util.LongBits(object.fileLength.low >>> 0, object.fileLength.high >>> 0).toNumber(true);
            if (object.mediaKeyTimestamp != null)
                if ($util.Long)
                    (message.mediaKeyTimestamp = $util.Long.fromValue(object.mediaKeyTimestamp)).unsigned = false;
                else if (typeof object.mediaKeyTimestamp === "string")
                    message.mediaKeyTimestamp = parseInt(object.mediaKeyTimestamp, 10);
                else if (typeof object.mediaKeyTimestamp === "number")
                    message.mediaKeyTimestamp = object.mediaKeyTimestamp;
                else if (typeof object.mediaKeyTimestamp === "object")
                    message.mediaKeyTimestamp = new $util.LongBits(object.mediaKeyTimestamp.low >>> 0, object.mediaKeyTimestamp.high >>> 0).toNumber();
            if (object.firstFrameLength != null)
                message.firstFrameLength = object.firstFrameLength >>> 0;
            if (object.firstFrameSidecar != null)
                if (typeof object.firstFrameSidecar === "string")
                    $util.base64.decode(object.firstFrameSidecar, message.firstFrameSidecar = $util.newBuffer($util.base64.length(object.firstFrameSidecar)), 0);
                else if (object.firstFrameSidecar.length)
                    message.firstFrameSidecar = object.firstFrameSidecar;
            if (object.isAnimated != null)
                message.isAnimated = Boolean(object.isAnimated);
            if (object.pngThumbnail != null)
                if (typeof object.pngThumbnail === "string")
                    $util.base64.decode(object.pngThumbnail, message.pngThumbnail = $util.newBuffer($util.base64.length(object.pngThumbnail)), 0);
                else if (object.pngThumbnail.length)
                    message.pngThumbnail = object.pngThumbnail;
            if (object.contextInfo != null) {
                if (typeof object.contextInfo !== "object")
                    throw TypeError(".proto.StickerMessage.contextInfo: object expected");
                message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo);
            }
            return message;
        };

        /**
         * Creates a plain object from a StickerMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.StickerMessage
         * @static
         * @param {proto.StickerMessage} message StickerMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        StickerMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.url = "";
                if (options.bytes === String)
                    object.fileSha256 = "";
                else {
                    object.fileSha256 = [];
                    if (options.bytes !== Array)
                        object.fileSha256 = $util.newBuffer(object.fileSha256);
                }
                if (options.bytes === String)
                    object.fileEncSha256 = "";
                else {
                    object.fileEncSha256 = [];
                    if (options.bytes !== Array)
                        object.fileEncSha256 = $util.newBuffer(object.fileEncSha256);
                }
                if (options.bytes === String)
                    object.mediaKey = "";
                else {
                    object.mediaKey = [];
                    if (options.bytes !== Array)
                        object.mediaKey = $util.newBuffer(object.mediaKey);
                }
                object.mimetype = "";
                object.height = 0;
                object.width = 0;
                object.directPath = "";
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.fileLength = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.fileLength = options.longs === String ? "0" : 0;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.mediaKeyTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.mediaKeyTimestamp = options.longs === String ? "0" : 0;
                object.firstFrameLength = 0;
                if (options.bytes === String)
                    object.firstFrameSidecar = "";
                else {
                    object.firstFrameSidecar = [];
                    if (options.bytes !== Array)
                        object.firstFrameSidecar = $util.newBuffer(object.firstFrameSidecar);
                }
                object.isAnimated = false;
                if (options.bytes === String)
                    object.pngThumbnail = "";
                else {
                    object.pngThumbnail = [];
                    if (options.bytes !== Array)
                        object.pngThumbnail = $util.newBuffer(object.pngThumbnail);
                }
                object.contextInfo = null;
            }
            if (message.url != null && message.hasOwnProperty("url"))
                object.url = message.url;
            if (message.fileSha256 != null && message.hasOwnProperty("fileSha256"))
                object.fileSha256 = options.bytes === String ? $util.base64.encode(message.fileSha256, 0, message.fileSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.fileSha256) : message.fileSha256;
            if (message.fileEncSha256 != null && message.hasOwnProperty("fileEncSha256"))
                object.fileEncSha256 = options.bytes === String ? $util.base64.encode(message.fileEncSha256, 0, message.fileEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.fileEncSha256) : message.fileEncSha256;
            if (message.mediaKey != null && message.hasOwnProperty("mediaKey"))
                object.mediaKey = options.bytes === String ? $util.base64.encode(message.mediaKey, 0, message.mediaKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.mediaKey) : message.mediaKey;
            if (message.mimetype != null && message.hasOwnProperty("mimetype"))
                object.mimetype = message.mimetype;
            if (message.height != null && message.hasOwnProperty("height"))
                object.height = message.height;
            if (message.width != null && message.hasOwnProperty("width"))
                object.width = message.width;
            if (message.directPath != null && message.hasOwnProperty("directPath"))
                object.directPath = message.directPath;
            if (message.fileLength != null && message.hasOwnProperty("fileLength"))
                if (typeof message.fileLength === "number")
                    object.fileLength = options.longs === String ? String(message.fileLength) : message.fileLength;
                else
                    object.fileLength = options.longs === String ? $util.Long.prototype.toString.call(message.fileLength) : options.longs === Number ? new $util.LongBits(message.fileLength.low >>> 0, message.fileLength.high >>> 0).toNumber(true) : message.fileLength;
            if (message.mediaKeyTimestamp != null && message.hasOwnProperty("mediaKeyTimestamp"))
                if (typeof message.mediaKeyTimestamp === "number")
                    object.mediaKeyTimestamp = options.longs === String ? String(message.mediaKeyTimestamp) : message.mediaKeyTimestamp;
                else
                    object.mediaKeyTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.mediaKeyTimestamp) : options.longs === Number ? new $util.LongBits(message.mediaKeyTimestamp.low >>> 0, message.mediaKeyTimestamp.high >>> 0).toNumber() : message.mediaKeyTimestamp;
            if (message.firstFrameLength != null && message.hasOwnProperty("firstFrameLength"))
                object.firstFrameLength = message.firstFrameLength;
            if (message.firstFrameSidecar != null && message.hasOwnProperty("firstFrameSidecar"))
                object.firstFrameSidecar = options.bytes === String ? $util.base64.encode(message.firstFrameSidecar, 0, message.firstFrameSidecar.length) : options.bytes === Array ? Array.prototype.slice.call(message.firstFrameSidecar) : message.firstFrameSidecar;
            if (message.isAnimated != null && message.hasOwnProperty("isAnimated"))
                object.isAnimated = message.isAnimated;
            if (message.pngThumbnail != null && message.hasOwnProperty("pngThumbnail"))
                object.pngThumbnail = options.bytes === String ? $util.base64.encode(message.pngThumbnail, 0, message.pngThumbnail.length) : options.bytes === Array ? Array.prototype.slice.call(message.pngThumbnail) : message.pngThumbnail;
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo"))
                object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options);
            return object;
        };

        /**
         * Converts this StickerMessage to JSON.
         * @function toJSON
         * @memberof proto.StickerMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        StickerMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return StickerMessage;
    })();

    proto.FourRowTemplate = (function() {

        /**
         * Properties of a FourRowTemplate.
         * @memberof proto
         * @interface IFourRowTemplate
         * @property {proto.IHighlyStructuredMessage|null} [content] FourRowTemplate content
         * @property {proto.IHighlyStructuredMessage|null} [footer] FourRowTemplate footer
         * @property {Array.<proto.ITemplateButton>|null} [buttons] FourRowTemplate buttons
         * @property {proto.IDocumentMessage|null} [documentMessage] FourRowTemplate documentMessage
         * @property {proto.IHighlyStructuredMessage|null} [highlyStructuredMessage] FourRowTemplate highlyStructuredMessage
         * @property {proto.IImageMessage|null} [imageMessage] FourRowTemplate imageMessage
         * @property {proto.IVideoMessage|null} [videoMessage] FourRowTemplate videoMessage
         * @property {proto.ILocationMessage|null} [locationMessage] FourRowTemplate locationMessage
         */

        /**
         * Constructs a new FourRowTemplate.
         * @memberof proto
         * @classdesc Represents a FourRowTemplate.
         * @implements IFourRowTemplate
         * @constructor
         * @param {proto.IFourRowTemplate=} [properties] Properties to set
         */
        function FourRowTemplate(properties) {
            this.buttons = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * FourRowTemplate content.
         * @member {proto.IHighlyStructuredMessage|null|undefined} content
         * @memberof proto.FourRowTemplate
         * @instance
         */
        FourRowTemplate.prototype.content = null;

        /**
         * FourRowTemplate footer.
         * @member {proto.IHighlyStructuredMessage|null|undefined} footer
         * @memberof proto.FourRowTemplate
         * @instance
         */
        FourRowTemplate.prototype.footer = null;

        /**
         * FourRowTemplate buttons.
         * @member {Array.<proto.ITemplateButton>} buttons
         * @memberof proto.FourRowTemplate
         * @instance
         */
        FourRowTemplate.prototype.buttons = $util.emptyArray;

        /**
         * FourRowTemplate documentMessage.
         * @member {proto.IDocumentMessage|null|undefined} documentMessage
         * @memberof proto.FourRowTemplate
         * @instance
         */
        FourRowTemplate.prototype.documentMessage = null;

        /**
         * FourRowTemplate highlyStructuredMessage.
         * @member {proto.IHighlyStructuredMessage|null|undefined} highlyStructuredMessage
         * @memberof proto.FourRowTemplate
         * @instance
         */
        FourRowTemplate.prototype.highlyStructuredMessage = null;

        /**
         * FourRowTemplate imageMessage.
         * @member {proto.IImageMessage|null|undefined} imageMessage
         * @memberof proto.FourRowTemplate
         * @instance
         */
        FourRowTemplate.prototype.imageMessage = null;

        /**
         * FourRowTemplate videoMessage.
         * @member {proto.IVideoMessage|null|undefined} videoMessage
         * @memberof proto.FourRowTemplate
         * @instance
         */
        FourRowTemplate.prototype.videoMessage = null;

        /**
         * FourRowTemplate locationMessage.
         * @member {proto.ILocationMessage|null|undefined} locationMessage
         * @memberof proto.FourRowTemplate
         * @instance
         */
        FourRowTemplate.prototype.locationMessage = null;

        // OneOf field names bound to virtual getters and setters
        var $oneOfFields;

        /**
         * FourRowTemplate title.
         * @member {"documentMessage"|"highlyStructuredMessage"|"imageMessage"|"videoMessage"|"locationMessage"|undefined} title
         * @memberof proto.FourRowTemplate
         * @instance
         */
        Object.defineProperty(FourRowTemplate.prototype, "title", {
            get: $util.oneOfGetter($oneOfFields = ["documentMessage", "highlyStructuredMessage", "imageMessage", "videoMessage", "locationMessage"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new FourRowTemplate instance using the specified properties.
         * @function create
         * @memberof proto.FourRowTemplate
         * @static
         * @param {proto.IFourRowTemplate=} [properties] Properties to set
         * @returns {proto.FourRowTemplate} FourRowTemplate instance
         */
        FourRowTemplate.create = function create(properties) {
            return new FourRowTemplate(properties);
        };

        /**
         * Encodes the specified FourRowTemplate message. Does not implicitly {@link proto.FourRowTemplate.verify|verify} messages.
         * @function encode
         * @memberof proto.FourRowTemplate
         * @static
         * @param {proto.IFourRowTemplate} message FourRowTemplate message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FourRowTemplate.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.documentMessage != null && Object.hasOwnProperty.call(message, "documentMessage"))
                $root.proto.DocumentMessage.encode(message.documentMessage, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.highlyStructuredMessage != null && Object.hasOwnProperty.call(message, "highlyStructuredMessage"))
                $root.proto.HighlyStructuredMessage.encode(message.highlyStructuredMessage, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.imageMessage != null && Object.hasOwnProperty.call(message, "imageMessage"))
                $root.proto.ImageMessage.encode(message.imageMessage, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.videoMessage != null && Object.hasOwnProperty.call(message, "videoMessage"))
                $root.proto.VideoMessage.encode(message.videoMessage, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
            if (message.locationMessage != null && Object.hasOwnProperty.call(message, "locationMessage"))
                $root.proto.LocationMessage.encode(message.locationMessage, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim();
            if (message.content != null && Object.hasOwnProperty.call(message, "content"))
                $root.proto.HighlyStructuredMessage.encode(message.content, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim();
            if (message.footer != null && Object.hasOwnProperty.call(message, "footer"))
                $root.proto.HighlyStructuredMessage.encode(message.footer, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim();
            if (message.buttons != null && message.buttons.length)
                for (var i = 0; i < message.buttons.length; ++i)
                    $root.proto.TemplateButton.encode(message.buttons[i], writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified FourRowTemplate message, length delimited. Does not implicitly {@link proto.FourRowTemplate.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.FourRowTemplate
         * @static
         * @param {proto.IFourRowTemplate} message FourRowTemplate message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FourRowTemplate.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a FourRowTemplate message from the specified reader or buffer.
         * @function decode
         * @memberof proto.FourRowTemplate
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.FourRowTemplate} FourRowTemplate
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FourRowTemplate.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.FourRowTemplate();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 6:
                    message.content = $root.proto.HighlyStructuredMessage.decode(reader, reader.uint32());
                    break;
                case 7:
                    message.footer = $root.proto.HighlyStructuredMessage.decode(reader, reader.uint32());
                    break;
                case 8:
                    if (!(message.buttons && message.buttons.length))
                        message.buttons = [];
                    message.buttons.push($root.proto.TemplateButton.decode(reader, reader.uint32()));
                    break;
                case 1:
                    message.documentMessage = $root.proto.DocumentMessage.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.highlyStructuredMessage = $root.proto.HighlyStructuredMessage.decode(reader, reader.uint32());
                    break;
                case 3:
                    message.imageMessage = $root.proto.ImageMessage.decode(reader, reader.uint32());
                    break;
                case 4:
                    message.videoMessage = $root.proto.VideoMessage.decode(reader, reader.uint32());
                    break;
                case 5:
                    message.locationMessage = $root.proto.LocationMessage.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a FourRowTemplate message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.FourRowTemplate
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.FourRowTemplate} FourRowTemplate
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FourRowTemplate.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a FourRowTemplate message.
         * @function verify
         * @memberof proto.FourRowTemplate
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        FourRowTemplate.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            var properties = {};
            if (message.content != null && message.hasOwnProperty("content")) {
                var error = $root.proto.HighlyStructuredMessage.verify(message.content);
                if (error)
                    return "content." + error;
            }
            if (message.footer != null && message.hasOwnProperty("footer")) {
                var error = $root.proto.HighlyStructuredMessage.verify(message.footer);
                if (error)
                    return "footer." + error;
            }
            if (message.buttons != null && message.hasOwnProperty("buttons")) {
                if (!Array.isArray(message.buttons))
                    return "buttons: array expected";
                for (var i = 0; i < message.buttons.length; ++i) {
                    var error = $root.proto.TemplateButton.verify(message.buttons[i]);
                    if (error)
                        return "buttons." + error;
                }
            }
            if (message.documentMessage != null && message.hasOwnProperty("documentMessage")) {
                properties.title = 1;
                {
                    var error = $root.proto.DocumentMessage.verify(message.documentMessage);
                    if (error)
                        return "documentMessage." + error;
                }
            }
            if (message.highlyStructuredMessage != null && message.hasOwnProperty("highlyStructuredMessage")) {
                if (properties.title === 1)
                    return "title: multiple values";
                properties.title = 1;
                {
                    var error = $root.proto.HighlyStructuredMessage.verify(message.highlyStructuredMessage);
                    if (error)
                        return "highlyStructuredMessage." + error;
                }
            }
            if (message.imageMessage != null && message.hasOwnProperty("imageMessage")) {
                if (properties.title === 1)
                    return "title: multiple values";
                properties.title = 1;
                {
                    var error = $root.proto.ImageMessage.verify(message.imageMessage);
                    if (error)
                        return "imageMessage." + error;
                }
            }
            if (message.videoMessage != null && message.hasOwnProperty("videoMessage")) {
                if (properties.title === 1)
                    return "title: multiple values";
                properties.title = 1;
                {
                    var error = $root.proto.VideoMessage.verify(message.videoMessage);
                    if (error)
                        return "videoMessage." + error;
                }
            }
            if (message.locationMessage != null && message.hasOwnProperty("locationMessage")) {
                if (properties.title === 1)
                    return "title: multiple values";
                properties.title = 1;
                {
                    var error = $root.proto.LocationMessage.verify(message.locationMessage);
                    if (error)
                        return "locationMessage." + error;
                }
            }
            return null;
        };

        /**
         * Creates a FourRowTemplate message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.FourRowTemplate
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.FourRowTemplate} FourRowTemplate
         */
        FourRowTemplate.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.FourRowTemplate)
                return object;
            var message = new $root.proto.FourRowTemplate();
            if (object.content != null) {
                if (typeof object.content !== "object")
                    throw TypeError(".proto.FourRowTemplate.content: object expected");
                message.content = $root.proto.HighlyStructuredMessage.fromObject(object.content);
            }
            if (object.footer != null) {
                if (typeof object.footer !== "object")
                    throw TypeError(".proto.FourRowTemplate.footer: object expected");
                message.footer = $root.proto.HighlyStructuredMessage.fromObject(object.footer);
            }
            if (object.buttons) {
                if (!Array.isArray(object.buttons))
                    throw TypeError(".proto.FourRowTemplate.buttons: array expected");
                message.buttons = [];
                for (var i = 0; i < object.buttons.length; ++i) {
                    if (typeof object.buttons[i] !== "object")
                        throw TypeError(".proto.FourRowTemplate.buttons: object expected");
                    message.buttons[i] = $root.proto.TemplateButton.fromObject(object.buttons[i]);
                }
            }
            if (object.documentMessage != null) {
                if (typeof object.documentMessage !== "object")
                    throw TypeError(".proto.FourRowTemplate.documentMessage: object expected");
                message.documentMessage = $root.proto.DocumentMessage.fromObject(object.documentMessage);
            }
            if (object.highlyStructuredMessage != null) {
                if (typeof object.highlyStructuredMessage !== "object")
                    throw TypeError(".proto.FourRowTemplate.highlyStructuredMessage: object expected");
                message.highlyStructuredMessage = $root.proto.HighlyStructuredMessage.fromObject(object.highlyStructuredMessage);
            }
            if (object.imageMessage != null) {
                if (typeof object.imageMessage !== "object")
                    throw TypeError(".proto.FourRowTemplate.imageMessage: object expected");
                message.imageMessage = $root.proto.ImageMessage.fromObject(object.imageMessage);
            }
            if (object.videoMessage != null) {
                if (typeof object.videoMessage !== "object")
                    throw TypeError(".proto.FourRowTemplate.videoMessage: object expected");
                message.videoMessage = $root.proto.VideoMessage.fromObject(object.videoMessage);
            }
            if (object.locationMessage != null) {
                if (typeof object.locationMessage !== "object")
                    throw TypeError(".proto.FourRowTemplate.locationMessage: object expected");
                message.locationMessage = $root.proto.LocationMessage.fromObject(object.locationMessage);
            }
            return message;
        };

        /**
         * Creates a plain object from a FourRowTemplate message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.FourRowTemplate
         * @static
         * @param {proto.FourRowTemplate} message FourRowTemplate
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        FourRowTemplate.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.buttons = [];
            if (options.defaults) {
                object.content = null;
                object.footer = null;
            }
            if (message.documentMessage != null && message.hasOwnProperty("documentMessage")) {
                object.documentMessage = $root.proto.DocumentMessage.toObject(message.documentMessage, options);
                if (options.oneofs)
                    object.title = "documentMessage";
            }
            if (message.highlyStructuredMessage != null && message.hasOwnProperty("highlyStructuredMessage")) {
                object.highlyStructuredMessage = $root.proto.HighlyStructuredMessage.toObject(message.highlyStructuredMessage, options);
                if (options.oneofs)
                    object.title = "highlyStructuredMessage";
            }
            if (message.imageMessage != null && message.hasOwnProperty("imageMessage")) {
                object.imageMessage = $root.proto.ImageMessage.toObject(message.imageMessage, options);
                if (options.oneofs)
                    object.title = "imageMessage";
            }
            if (message.videoMessage != null && message.hasOwnProperty("videoMessage")) {
                object.videoMessage = $root.proto.VideoMessage.toObject(message.videoMessage, options);
                if (options.oneofs)
                    object.title = "videoMessage";
            }
            if (message.locationMessage != null && message.hasOwnProperty("locationMessage")) {
                object.locationMessage = $root.proto.LocationMessage.toObject(message.locationMessage, options);
                if (options.oneofs)
                    object.title = "locationMessage";
            }
            if (message.content != null && message.hasOwnProperty("content"))
                object.content = $root.proto.HighlyStructuredMessage.toObject(message.content, options);
            if (message.footer != null && message.hasOwnProperty("footer"))
                object.footer = $root.proto.HighlyStructuredMessage.toObject(message.footer, options);
            if (message.buttons && message.buttons.length) {
                object.buttons = [];
                for (var j = 0; j < message.buttons.length; ++j)
                    object.buttons[j] = $root.proto.TemplateButton.toObject(message.buttons[j], options);
            }
            return object;
        };

        /**
         * Converts this FourRowTemplate to JSON.
         * @function toJSON
         * @memberof proto.FourRowTemplate
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        FourRowTemplate.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return FourRowTemplate;
    })();

    proto.HydratedFourRowTemplate = (function() {

        /**
         * Properties of a HydratedFourRowTemplate.
         * @memberof proto
         * @interface IHydratedFourRowTemplate
         * @property {string|null} [hydratedContentText] HydratedFourRowTemplate hydratedContentText
         * @property {string|null} [hydratedFooterText] HydratedFourRowTemplate hydratedFooterText
         * @property {Array.<proto.IHydratedTemplateButton>|null} [hydratedButtons] HydratedFourRowTemplate hydratedButtons
         * @property {string|null} [templateId] HydratedFourRowTemplate templateId
         * @property {proto.IDocumentMessage|null} [documentMessage] HydratedFourRowTemplate documentMessage
         * @property {string|null} [hydratedTitleText] HydratedFourRowTemplate hydratedTitleText
         * @property {proto.IImageMessage|null} [imageMessage] HydratedFourRowTemplate imageMessage
         * @property {proto.IVideoMessage|null} [videoMessage] HydratedFourRowTemplate videoMessage
         * @property {proto.ILocationMessage|null} [locationMessage] HydratedFourRowTemplate locationMessage
         */

        /**
         * Constructs a new HydratedFourRowTemplate.
         * @memberof proto
         * @classdesc Represents a HydratedFourRowTemplate.
         * @implements IHydratedFourRowTemplate
         * @constructor
         * @param {proto.IHydratedFourRowTemplate=} [properties] Properties to set
         */
        function HydratedFourRowTemplate(properties) {
            this.hydratedButtons = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * HydratedFourRowTemplate hydratedContentText.
         * @member {string} hydratedContentText
         * @memberof proto.HydratedFourRowTemplate
         * @instance
         */
        HydratedFourRowTemplate.prototype.hydratedContentText = "";

        /**
         * HydratedFourRowTemplate hydratedFooterText.
         * @member {string} hydratedFooterText
         * @memberof proto.HydratedFourRowTemplate
         * @instance
         */
        HydratedFourRowTemplate.prototype.hydratedFooterText = "";

        /**
         * HydratedFourRowTemplate hydratedButtons.
         * @member {Array.<proto.IHydratedTemplateButton>} hydratedButtons
         * @memberof proto.HydratedFourRowTemplate
         * @instance
         */
        HydratedFourRowTemplate.prototype.hydratedButtons = $util.emptyArray;

        /**
         * HydratedFourRowTemplate templateId.
         * @member {string} templateId
         * @memberof proto.HydratedFourRowTemplate
         * @instance
         */
        HydratedFourRowTemplate.prototype.templateId = "";

        /**
         * HydratedFourRowTemplate documentMessage.
         * @member {proto.IDocumentMessage|null|undefined} documentMessage
         * @memberof proto.HydratedFourRowTemplate
         * @instance
         */
        HydratedFourRowTemplate.prototype.documentMessage = null;

        /**
         * HydratedFourRowTemplate hydratedTitleText.
         * @member {string|null|undefined} hydratedTitleText
         * @memberof proto.HydratedFourRowTemplate
         * @instance
         */
        HydratedFourRowTemplate.prototype.hydratedTitleText = null;

        /**
         * HydratedFourRowTemplate imageMessage.
         * @member {proto.IImageMessage|null|undefined} imageMessage
         * @memberof proto.HydratedFourRowTemplate
         * @instance
         */
        HydratedFourRowTemplate.prototype.imageMessage = null;

        /**
         * HydratedFourRowTemplate videoMessage.
         * @member {proto.IVideoMessage|null|undefined} videoMessage
         * @memberof proto.HydratedFourRowTemplate
         * @instance
         */
        HydratedFourRowTemplate.prototype.videoMessage = null;

        /**
         * HydratedFourRowTemplate locationMessage.
         * @member {proto.ILocationMessage|null|undefined} locationMessage
         * @memberof proto.HydratedFourRowTemplate
         * @instance
         */
        HydratedFourRowTemplate.prototype.locationMessage = null;

        // OneOf field names bound to virtual getters and setters
        var $oneOfFields;

        /**
         * HydratedFourRowTemplate title.
         * @member {"documentMessage"|"hydratedTitleText"|"imageMessage"|"videoMessage"|"locationMessage"|undefined} title
         * @memberof proto.HydratedFourRowTemplate
         * @instance
         */
        Object.defineProperty(HydratedFourRowTemplate.prototype, "title", {
            get: $util.oneOfGetter($oneOfFields = ["documentMessage", "hydratedTitleText", "imageMessage", "videoMessage", "locationMessage"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new HydratedFourRowTemplate instance using the specified properties.
         * @function create
         * @memberof proto.HydratedFourRowTemplate
         * @static
         * @param {proto.IHydratedFourRowTemplate=} [properties] Properties to set
         * @returns {proto.HydratedFourRowTemplate} HydratedFourRowTemplate instance
         */
        HydratedFourRowTemplate.create = function create(properties) {
            return new HydratedFourRowTemplate(properties);
        };

        /**
         * Encodes the specified HydratedFourRowTemplate message. Does not implicitly {@link proto.HydratedFourRowTemplate.verify|verify} messages.
         * @function encode
         * @memberof proto.HydratedFourRowTemplate
         * @static
         * @param {proto.IHydratedFourRowTemplate} message HydratedFourRowTemplate message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HydratedFourRowTemplate.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.documentMessage != null && Object.hasOwnProperty.call(message, "documentMessage"))
                $root.proto.DocumentMessage.encode(message.documentMessage, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.hydratedTitleText != null && Object.hasOwnProperty.call(message, "hydratedTitleText"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.hydratedTitleText);
            if (message.imageMessage != null && Object.hasOwnProperty.call(message, "imageMessage"))
                $root.proto.ImageMessage.encode(message.imageMessage, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.videoMessage != null && Object.hasOwnProperty.call(message, "videoMessage"))
                $root.proto.VideoMessage.encode(message.videoMessage, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
            if (message.locationMessage != null && Object.hasOwnProperty.call(message, "locationMessage"))
                $root.proto.LocationMessage.encode(message.locationMessage, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim();
            if (message.hydratedContentText != null && Object.hasOwnProperty.call(message, "hydratedContentText"))
                writer.uint32(/* id 6, wireType 2 =*/50).string(message.hydratedContentText);
            if (message.hydratedFooterText != null && Object.hasOwnProperty.call(message, "hydratedFooterText"))
                writer.uint32(/* id 7, wireType 2 =*/58).string(message.hydratedFooterText);
            if (message.hydratedButtons != null && message.hydratedButtons.length)
                for (var i = 0; i < message.hydratedButtons.length; ++i)
                    $root.proto.HydratedTemplateButton.encode(message.hydratedButtons[i], writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim();
            if (message.templateId != null && Object.hasOwnProperty.call(message, "templateId"))
                writer.uint32(/* id 9, wireType 2 =*/74).string(message.templateId);
            return writer;
        };

        /**
         * Encodes the specified HydratedFourRowTemplate message, length delimited. Does not implicitly {@link proto.HydratedFourRowTemplate.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.HydratedFourRowTemplate
         * @static
         * @param {proto.IHydratedFourRowTemplate} message HydratedFourRowTemplate message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HydratedFourRowTemplate.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a HydratedFourRowTemplate message from the specified reader or buffer.
         * @function decode
         * @memberof proto.HydratedFourRowTemplate
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.HydratedFourRowTemplate} HydratedFourRowTemplate
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HydratedFourRowTemplate.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedFourRowTemplate();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 6:
                    message.hydratedContentText = reader.string();
                    break;
                case 7:
                    message.hydratedFooterText = reader.string();
                    break;
                case 8:
                    if (!(message.hydratedButtons && message.hydratedButtons.length))
                        message.hydratedButtons = [];
                    message.hydratedButtons.push($root.proto.HydratedTemplateButton.decode(reader, reader.uint32()));
                    break;
                case 9:
                    message.templateId = reader.string();
                    break;
                case 1:
                    message.documentMessage = $root.proto.DocumentMessage.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.hydratedTitleText = reader.string();
                    break;
                case 3:
                    message.imageMessage = $root.proto.ImageMessage.decode(reader, reader.uint32());
                    break;
                case 4:
                    message.videoMessage = $root.proto.VideoMessage.decode(reader, reader.uint32());
                    break;
                case 5:
                    message.locationMessage = $root.proto.LocationMessage.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a HydratedFourRowTemplate message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.HydratedFourRowTemplate
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.HydratedFourRowTemplate} HydratedFourRowTemplate
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HydratedFourRowTemplate.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a HydratedFourRowTemplate message.
         * @function verify
         * @memberof proto.HydratedFourRowTemplate
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        HydratedFourRowTemplate.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            var properties = {};
            if (message.hydratedContentText != null && message.hasOwnProperty("hydratedContentText"))
                if (!$util.isString(message.hydratedContentText))
                    return "hydratedContentText: string expected";
            if (message.hydratedFooterText != null && message.hasOwnProperty("hydratedFooterText"))
                if (!$util.isString(message.hydratedFooterText))
                    return "hydratedFooterText: string expected";
            if (message.hydratedButtons != null && message.hasOwnProperty("hydratedButtons")) {
                if (!Array.isArray(message.hydratedButtons))
                    return "hydratedButtons: array expected";
                for (var i = 0; i < message.hydratedButtons.length; ++i) {
                    var error = $root.proto.HydratedTemplateButton.verify(message.hydratedButtons[i]);
                    if (error)
                        return "hydratedButtons." + error;
                }
            }
            if (message.templateId != null && message.hasOwnProperty("templateId"))
                if (!$util.isString(message.templateId))
                    return "templateId: string expected";
            if (message.documentMessage != null && message.hasOwnProperty("documentMessage")) {
                properties.title = 1;
                {
                    var error = $root.proto.DocumentMessage.verify(message.documentMessage);
                    if (error)
                        return "documentMessage." + error;
                }
            }
            if (message.hydratedTitleText != null && message.hasOwnProperty("hydratedTitleText")) {
                if (properties.title === 1)
                    return "title: multiple values";
                properties.title = 1;
                if (!$util.isString(message.hydratedTitleText))
                    return "hydratedTitleText: string expected";
            }
            if (message.imageMessage != null && message.hasOwnProperty("imageMessage")) {
                if (properties.title === 1)
                    return "title: multiple values";
                properties.title = 1;
                {
                    var error = $root.proto.ImageMessage.verify(message.imageMessage);
                    if (error)
                        return "imageMessage." + error;
                }
            }
            if (message.videoMessage != null && message.hasOwnProperty("videoMessage")) {
                if (properties.title === 1)
                    return "title: multiple values";
                properties.title = 1;
                {
                    var error = $root.proto.VideoMessage.verify(message.videoMessage);
                    if (error)
                        return "videoMessage." + error;
                }
            }
            if (message.locationMessage != null && message.hasOwnProperty("locationMessage")) {
                if (properties.title === 1)
                    return "title: multiple values";
                properties.title = 1;
                {
                    var error = $root.proto.LocationMessage.verify(message.locationMessage);
                    if (error)
                        return "locationMessage." + error;
                }
            }
            return null;
        };

        /**
         * Creates a HydratedFourRowTemplate message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.HydratedFourRowTemplate
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.HydratedFourRowTemplate} HydratedFourRowTemplate
         */
        HydratedFourRowTemplate.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.HydratedFourRowTemplate)
                return object;
            var message = new $root.proto.HydratedFourRowTemplate();
            if (object.hydratedContentText != null)
                message.hydratedContentText = String(object.hydratedContentText);
            if (object.hydratedFooterText != null)
                message.hydratedFooterText = String(object.hydratedFooterText);
            if (object.hydratedButtons) {
                if (!Array.isArray(object.hydratedButtons))
                    throw TypeError(".proto.HydratedFourRowTemplate.hydratedButtons: array expected");
                message.hydratedButtons = [];
                for (var i = 0; i < object.hydratedButtons.length; ++i) {
                    if (typeof object.hydratedButtons[i] !== "object")
                        throw TypeError(".proto.HydratedFourRowTemplate.hydratedButtons: object expected");
                    message.hydratedButtons[i] = $root.proto.HydratedTemplateButton.fromObject(object.hydratedButtons[i]);
                }
            }
            if (object.templateId != null)
                message.templateId = String(object.templateId);
            if (object.documentMessage != null) {
                if (typeof object.documentMessage !== "object")
                    throw TypeError(".proto.HydratedFourRowTemplate.documentMessage: object expected");
                message.documentMessage = $root.proto.DocumentMessage.fromObject(object.documentMessage);
            }
            if (object.hydratedTitleText != null)
                message.hydratedTitleText = String(object.hydratedTitleText);
            if (object.imageMessage != null) {
                if (typeof object.imageMessage !== "object")
                    throw TypeError(".proto.HydratedFourRowTemplate.imageMessage: object expected");
                message.imageMessage = $root.proto.ImageMessage.fromObject(object.imageMessage);
            }
            if (object.videoMessage != null) {
                if (typeof object.videoMessage !== "object")
                    throw TypeError(".proto.HydratedFourRowTemplate.videoMessage: object expected");
                message.videoMessage = $root.proto.VideoMessage.fromObject(object.videoMessage);
            }
            if (object.locationMessage != null) {
                if (typeof object.locationMessage !== "object")
                    throw TypeError(".proto.HydratedFourRowTemplate.locationMessage: object expected");
                message.locationMessage = $root.proto.LocationMessage.fromObject(object.locationMessage);
            }
            return message;
        };

        /**
         * Creates a plain object from a HydratedFourRowTemplate message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.HydratedFourRowTemplate
         * @static
         * @param {proto.HydratedFourRowTemplate} message HydratedFourRowTemplate
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        HydratedFourRowTemplate.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.hydratedButtons = [];
            if (options.defaults) {
                object.hydratedContentText = "";
                object.hydratedFooterText = "";
                object.templateId = "";
            }
            if (message.documentMessage != null && message.hasOwnProperty("documentMessage")) {
                object.documentMessage = $root.proto.DocumentMessage.toObject(message.documentMessage, options);
                if (options.oneofs)
                    object.title = "documentMessage";
            }
            if (message.hydratedTitleText != null && message.hasOwnProperty("hydratedTitleText")) {
                object.hydratedTitleText = message.hydratedTitleText;
                if (options.oneofs)
                    object.title = "hydratedTitleText";
            }
            if (message.imageMessage != null && message.hasOwnProperty("imageMessage")) {
                object.imageMessage = $root.proto.ImageMessage.toObject(message.imageMessage, options);
                if (options.oneofs)
                    object.title = "imageMessage";
            }
            if (message.videoMessage != null && message.hasOwnProperty("videoMessage")) {
                object.videoMessage = $root.proto.VideoMessage.toObject(message.videoMessage, options);
                if (options.oneofs)
                    object.title = "videoMessage";
            }
            if (message.locationMessage != null && message.hasOwnProperty("locationMessage")) {
                object.locationMessage = $root.proto.LocationMessage.toObject(message.locationMessage, options);
                if (options.oneofs)
                    object.title = "locationMessage";
            }
            if (message.hydratedContentText != null && message.hasOwnProperty("hydratedContentText"))
                object.hydratedContentText = message.hydratedContentText;
            if (message.hydratedFooterText != null && message.hasOwnProperty("hydratedFooterText"))
                object.hydratedFooterText = message.hydratedFooterText;
            if (message.hydratedButtons && message.hydratedButtons.length) {
                object.hydratedButtons = [];
                for (var j = 0; j < message.hydratedButtons.length; ++j)
                    object.hydratedButtons[j] = $root.proto.HydratedTemplateButton.toObject(message.hydratedButtons[j], options);
            }
            if (message.templateId != null && message.hasOwnProperty("templateId"))
                object.templateId = message.templateId;
            return object;
        };

        /**
         * Converts this HydratedFourRowTemplate to JSON.
         * @function toJSON
         * @memberof proto.HydratedFourRowTemplate
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        HydratedFourRowTemplate.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return HydratedFourRowTemplate;
    })();

    proto.TemplateMessage = (function() {

        /**
         * Properties of a TemplateMessage.
         * @memberof proto
         * @interface ITemplateMessage
         * @property {proto.IContextInfo|null} [contextInfo] TemplateMessage contextInfo
         * @property {proto.IHydratedFourRowTemplate|null} [hydratedTemplate] TemplateMessage hydratedTemplate
         * @property {proto.IFourRowTemplate|null} [fourRowTemplate] TemplateMessage fourRowTemplate
         * @property {proto.IHydratedFourRowTemplate|null} [hydratedFourRowTemplate] TemplateMessage hydratedFourRowTemplate
         */

        /**
         * Constructs a new TemplateMessage.
         * @memberof proto
         * @classdesc Represents a TemplateMessage.
         * @implements ITemplateMessage
         * @constructor
         * @param {proto.ITemplateMessage=} [properties] Properties to set
         */
        function TemplateMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * TemplateMessage contextInfo.
         * @member {proto.IContextInfo|null|undefined} contextInfo
         * @memberof proto.TemplateMessage
         * @instance
         */
        TemplateMessage.prototype.contextInfo = null;

        /**
         * TemplateMessage hydratedTemplate.
         * @member {proto.IHydratedFourRowTemplate|null|undefined} hydratedTemplate
         * @memberof proto.TemplateMessage
         * @instance
         */
        TemplateMessage.prototype.hydratedTemplate = null;

        /**
         * TemplateMessage fourRowTemplate.
         * @member {proto.IFourRowTemplate|null|undefined} fourRowTemplate
         * @memberof proto.TemplateMessage
         * @instance
         */
        TemplateMessage.prototype.fourRowTemplate = null;

        /**
         * TemplateMessage hydratedFourRowTemplate.
         * @member {proto.IHydratedFourRowTemplate|null|undefined} hydratedFourRowTemplate
         * @memberof proto.TemplateMessage
         * @instance
         */
        TemplateMessage.prototype.hydratedFourRowTemplate = null;

        // OneOf field names bound to virtual getters and setters
        var $oneOfFields;

        /**
         * TemplateMessage format.
         * @member {"fourRowTemplate"|"hydratedFourRowTemplate"|undefined} format
         * @memberof proto.TemplateMessage
         * @instance
         */
        Object.defineProperty(TemplateMessage.prototype, "format", {
            get: $util.oneOfGetter($oneOfFields = ["fourRowTemplate", "hydratedFourRowTemplate"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new TemplateMessage instance using the specified properties.
         * @function create
         * @memberof proto.TemplateMessage
         * @static
         * @param {proto.ITemplateMessage=} [properties] Properties to set
         * @returns {proto.TemplateMessage} TemplateMessage instance
         */
        TemplateMessage.create = function create(properties) {
            return new TemplateMessage(properties);
        };

        /**
         * Encodes the specified TemplateMessage message. Does not implicitly {@link proto.TemplateMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.TemplateMessage
         * @static
         * @param {proto.ITemplateMessage} message TemplateMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TemplateMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.fourRowTemplate != null && Object.hasOwnProperty.call(message, "fourRowTemplate"))
                $root.proto.FourRowTemplate.encode(message.fourRowTemplate, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.hydratedFourRowTemplate != null && Object.hasOwnProperty.call(message, "hydratedFourRowTemplate"))
                $root.proto.HydratedFourRowTemplate.encode(message.hydratedFourRowTemplate, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo"))
                $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.hydratedTemplate != null && Object.hasOwnProperty.call(message, "hydratedTemplate"))
                $root.proto.HydratedFourRowTemplate.encode(message.hydratedTemplate, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified TemplateMessage message, length delimited. Does not implicitly {@link proto.TemplateMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.TemplateMessage
         * @static
         * @param {proto.ITemplateMessage} message TemplateMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TemplateMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a TemplateMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.TemplateMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.TemplateMessage} TemplateMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TemplateMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.TemplateMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 3:
                    message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32());
                    break;
                case 4:
                    message.hydratedTemplate = $root.proto.HydratedFourRowTemplate.decode(reader, reader.uint32());
                    break;
                case 1:
                    message.fourRowTemplate = $root.proto.FourRowTemplate.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.hydratedFourRowTemplate = $root.proto.HydratedFourRowTemplate.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a TemplateMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.TemplateMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.TemplateMessage} TemplateMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TemplateMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a TemplateMessage message.
         * @function verify
         * @memberof proto.TemplateMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        TemplateMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            var properties = {};
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) {
                var error = $root.proto.ContextInfo.verify(message.contextInfo);
                if (error)
                    return "contextInfo." + error;
            }
            if (message.hydratedTemplate != null && message.hasOwnProperty("hydratedTemplate")) {
                var error = $root.proto.HydratedFourRowTemplate.verify(message.hydratedTemplate);
                if (error)
                    return "hydratedTemplate." + error;
            }
            if (message.fourRowTemplate != null && message.hasOwnProperty("fourRowTemplate")) {
                properties.format = 1;
                {
                    var error = $root.proto.FourRowTemplate.verify(message.fourRowTemplate);
                    if (error)
                        return "fourRowTemplate." + error;
                }
            }
            if (message.hydratedFourRowTemplate != null && message.hasOwnProperty("hydratedFourRowTemplate")) {
                if (properties.format === 1)
                    return "format: multiple values";
                properties.format = 1;
                {
                    var error = $root.proto.HydratedFourRowTemplate.verify(message.hydratedFourRowTemplate);
                    if (error)
                        return "hydratedFourRowTemplate." + error;
                }
            }
            return null;
        };

        /**
         * Creates a TemplateMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.TemplateMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.TemplateMessage} TemplateMessage
         */
        TemplateMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.TemplateMessage)
                return object;
            var message = new $root.proto.TemplateMessage();
            if (object.contextInfo != null) {
                if (typeof object.contextInfo !== "object")
                    throw TypeError(".proto.TemplateMessage.contextInfo: object expected");
                message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo);
            }
            if (object.hydratedTemplate != null) {
                if (typeof object.hydratedTemplate !== "object")
                    throw TypeError(".proto.TemplateMessage.hydratedTemplate: object expected");
                message.hydratedTemplate = $root.proto.HydratedFourRowTemplate.fromObject(object.hydratedTemplate);
            }
            if (object.fourRowTemplate != null) {
                if (typeof object.fourRowTemplate !== "object")
                    throw TypeError(".proto.TemplateMessage.fourRowTemplate: object expected");
                message.fourRowTemplate = $root.proto.FourRowTemplate.fromObject(object.fourRowTemplate);
            }
            if (object.hydratedFourRowTemplate != null) {
                if (typeof object.hydratedFourRowTemplate !== "object")
                    throw TypeError(".proto.TemplateMessage.hydratedFourRowTemplate: object expected");
                message.hydratedFourRowTemplate = $root.proto.HydratedFourRowTemplate.fromObject(object.hydratedFourRowTemplate);
            }
            return message;
        };

        /**
         * Creates a plain object from a TemplateMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.TemplateMessage
         * @static
         * @param {proto.TemplateMessage} message TemplateMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        TemplateMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.contextInfo = null;
                object.hydratedTemplate = null;
            }
            if (message.fourRowTemplate != null && message.hasOwnProperty("fourRowTemplate")) {
                object.fourRowTemplate = $root.proto.FourRowTemplate.toObject(message.fourRowTemplate, options);
                if (options.oneofs)
                    object.format = "fourRowTemplate";
            }
            if (message.hydratedFourRowTemplate != null && message.hasOwnProperty("hydratedFourRowTemplate")) {
                object.hydratedFourRowTemplate = $root.proto.HydratedFourRowTemplate.toObject(message.hydratedFourRowTemplate, options);
                if (options.oneofs)
                    object.format = "hydratedFourRowTemplate";
            }
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo"))
                object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options);
            if (message.hydratedTemplate != null && message.hasOwnProperty("hydratedTemplate"))
                object.hydratedTemplate = $root.proto.HydratedFourRowTemplate.toObject(message.hydratedTemplate, options);
            return object;
        };

        /**
         * Converts this TemplateMessage to JSON.
         * @function toJSON
         * @memberof proto.TemplateMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        TemplateMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return TemplateMessage;
    })();

    proto.TemplateButtonReplyMessage = (function() {

        /**
         * Properties of a TemplateButtonReplyMessage.
         * @memberof proto
         * @interface ITemplateButtonReplyMessage
         * @property {string|null} [selectedId] TemplateButtonReplyMessage selectedId
         * @property {string|null} [selectedDisplayText] TemplateButtonReplyMessage selectedDisplayText
         * @property {proto.IContextInfo|null} [contextInfo] TemplateButtonReplyMessage contextInfo
         * @property {number|null} [selectedIndex] TemplateButtonReplyMessage selectedIndex
         */

        /**
         * Constructs a new TemplateButtonReplyMessage.
         * @memberof proto
         * @classdesc Represents a TemplateButtonReplyMessage.
         * @implements ITemplateButtonReplyMessage
         * @constructor
         * @param {proto.ITemplateButtonReplyMessage=} [properties] Properties to set
         */
        function TemplateButtonReplyMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * TemplateButtonReplyMessage selectedId.
         * @member {string} selectedId
         * @memberof proto.TemplateButtonReplyMessage
         * @instance
         */
        TemplateButtonReplyMessage.prototype.selectedId = "";

        /**
         * TemplateButtonReplyMessage selectedDisplayText.
         * @member {string} selectedDisplayText
         * @memberof proto.TemplateButtonReplyMessage
         * @instance
         */
        TemplateButtonReplyMessage.prototype.selectedDisplayText = "";

        /**
         * TemplateButtonReplyMessage contextInfo.
         * @member {proto.IContextInfo|null|undefined} contextInfo
         * @memberof proto.TemplateButtonReplyMessage
         * @instance
         */
        TemplateButtonReplyMessage.prototype.contextInfo = null;

        /**
         * TemplateButtonReplyMessage selectedIndex.
         * @member {number} selectedIndex
         * @memberof proto.TemplateButtonReplyMessage
         * @instance
         */
        TemplateButtonReplyMessage.prototype.selectedIndex = 0;

        /**
         * Creates a new TemplateButtonReplyMessage instance using the specified properties.
         * @function create
         * @memberof proto.TemplateButtonReplyMessage
         * @static
         * @param {proto.ITemplateButtonReplyMessage=} [properties] Properties to set
         * @returns {proto.TemplateButtonReplyMessage} TemplateButtonReplyMessage instance
         */
        TemplateButtonReplyMessage.create = function create(properties) {
            return new TemplateButtonReplyMessage(properties);
        };

        /**
         * Encodes the specified TemplateButtonReplyMessage message. Does not implicitly {@link proto.TemplateButtonReplyMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.TemplateButtonReplyMessage
         * @static
         * @param {proto.ITemplateButtonReplyMessage} message TemplateButtonReplyMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TemplateButtonReplyMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.selectedId != null && Object.hasOwnProperty.call(message, "selectedId"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.selectedId);
            if (message.selectedDisplayText != null && Object.hasOwnProperty.call(message, "selectedDisplayText"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.selectedDisplayText);
            if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo"))
                $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.selectedIndex != null && Object.hasOwnProperty.call(message, "selectedIndex"))
                writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.selectedIndex);
            return writer;
        };

        /**
         * Encodes the specified TemplateButtonReplyMessage message, length delimited. Does not implicitly {@link proto.TemplateButtonReplyMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.TemplateButtonReplyMessage
         * @static
         * @param {proto.ITemplateButtonReplyMessage} message TemplateButtonReplyMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TemplateButtonReplyMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a TemplateButtonReplyMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.TemplateButtonReplyMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.TemplateButtonReplyMessage} TemplateButtonReplyMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TemplateButtonReplyMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.TemplateButtonReplyMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.selectedId = reader.string();
                    break;
                case 2:
                    message.selectedDisplayText = reader.string();
                    break;
                case 3:
                    message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32());
                    break;
                case 4:
                    message.selectedIndex = reader.uint32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a TemplateButtonReplyMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.TemplateButtonReplyMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.TemplateButtonReplyMessage} TemplateButtonReplyMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TemplateButtonReplyMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a TemplateButtonReplyMessage message.
         * @function verify
         * @memberof proto.TemplateButtonReplyMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        TemplateButtonReplyMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.selectedId != null && message.hasOwnProperty("selectedId"))
                if (!$util.isString(message.selectedId))
                    return "selectedId: string expected";
            if (message.selectedDisplayText != null && message.hasOwnProperty("selectedDisplayText"))
                if (!$util.isString(message.selectedDisplayText))
                    return "selectedDisplayText: string expected";
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) {
                var error = $root.proto.ContextInfo.verify(message.contextInfo);
                if (error)
                    return "contextInfo." + error;
            }
            if (message.selectedIndex != null && message.hasOwnProperty("selectedIndex"))
                if (!$util.isInteger(message.selectedIndex))
                    return "selectedIndex: integer expected";
            return null;
        };

        /**
         * Creates a TemplateButtonReplyMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.TemplateButtonReplyMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.TemplateButtonReplyMessage} TemplateButtonReplyMessage
         */
        TemplateButtonReplyMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.TemplateButtonReplyMessage)
                return object;
            var message = new $root.proto.TemplateButtonReplyMessage();
            if (object.selectedId != null)
                message.selectedId = String(object.selectedId);
            if (object.selectedDisplayText != null)
                message.selectedDisplayText = String(object.selectedDisplayText);
            if (object.contextInfo != null) {
                if (typeof object.contextInfo !== "object")
                    throw TypeError(".proto.TemplateButtonReplyMessage.contextInfo: object expected");
                message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo);
            }
            if (object.selectedIndex != null)
                message.selectedIndex = object.selectedIndex >>> 0;
            return message;
        };

        /**
         * Creates a plain object from a TemplateButtonReplyMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.TemplateButtonReplyMessage
         * @static
         * @param {proto.TemplateButtonReplyMessage} message TemplateButtonReplyMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        TemplateButtonReplyMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.selectedId = "";
                object.selectedDisplayText = "";
                object.contextInfo = null;
                object.selectedIndex = 0;
            }
            if (message.selectedId != null && message.hasOwnProperty("selectedId"))
                object.selectedId = message.selectedId;
            if (message.selectedDisplayText != null && message.hasOwnProperty("selectedDisplayText"))
                object.selectedDisplayText = message.selectedDisplayText;
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo"))
                object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options);
            if (message.selectedIndex != null && message.hasOwnProperty("selectedIndex"))
                object.selectedIndex = message.selectedIndex;
            return object;
        };

        /**
         * Converts this TemplateButtonReplyMessage to JSON.
         * @function toJSON
         * @memberof proto.TemplateButtonReplyMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        TemplateButtonReplyMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return TemplateButtonReplyMessage;
    })();

    proto.CatalogSnapshot = (function() {

        /**
         * Properties of a CatalogSnapshot.
         * @memberof proto
         * @interface ICatalogSnapshot
         * @property {proto.IImageMessage|null} [catalogImage] CatalogSnapshot catalogImage
         * @property {string|null} [title] CatalogSnapshot title
         * @property {string|null} [description] CatalogSnapshot description
         */

        /**
         * Constructs a new CatalogSnapshot.
         * @memberof proto
         * @classdesc Represents a CatalogSnapshot.
         * @implements ICatalogSnapshot
         * @constructor
         * @param {proto.ICatalogSnapshot=} [properties] Properties to set
         */
        function CatalogSnapshot(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * CatalogSnapshot catalogImage.
         * @member {proto.IImageMessage|null|undefined} catalogImage
         * @memberof proto.CatalogSnapshot
         * @instance
         */
        CatalogSnapshot.prototype.catalogImage = null;

        /**
         * CatalogSnapshot title.
         * @member {string} title
         * @memberof proto.CatalogSnapshot
         * @instance
         */
        CatalogSnapshot.prototype.title = "";

        /**
         * CatalogSnapshot description.
         * @member {string} description
         * @memberof proto.CatalogSnapshot
         * @instance
         */
        CatalogSnapshot.prototype.description = "";

        /**
         * Creates a new CatalogSnapshot instance using the specified properties.
         * @function create
         * @memberof proto.CatalogSnapshot
         * @static
         * @param {proto.ICatalogSnapshot=} [properties] Properties to set
         * @returns {proto.CatalogSnapshot} CatalogSnapshot instance
         */
        CatalogSnapshot.create = function create(properties) {
            return new CatalogSnapshot(properties);
        };

        /**
         * Encodes the specified CatalogSnapshot message. Does not implicitly {@link proto.CatalogSnapshot.verify|verify} messages.
         * @function encode
         * @memberof proto.CatalogSnapshot
         * @static
         * @param {proto.ICatalogSnapshot} message CatalogSnapshot message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CatalogSnapshot.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.catalogImage != null && Object.hasOwnProperty.call(message, "catalogImage"))
                $root.proto.ImageMessage.encode(message.catalogImage, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.title != null && Object.hasOwnProperty.call(message, "title"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.title);
            if (message.description != null && Object.hasOwnProperty.call(message, "description"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.description);
            return writer;
        };

        /**
         * Encodes the specified CatalogSnapshot message, length delimited. Does not implicitly {@link proto.CatalogSnapshot.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.CatalogSnapshot
         * @static
         * @param {proto.ICatalogSnapshot} message CatalogSnapshot message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CatalogSnapshot.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a CatalogSnapshot message from the specified reader or buffer.
         * @function decode
         * @memberof proto.CatalogSnapshot
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.CatalogSnapshot} CatalogSnapshot
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CatalogSnapshot.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.CatalogSnapshot();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.catalogImage = $root.proto.ImageMessage.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.title = reader.string();
                    break;
                case 3:
                    message.description = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a CatalogSnapshot message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.CatalogSnapshot
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.CatalogSnapshot} CatalogSnapshot
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CatalogSnapshot.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a CatalogSnapshot message.
         * @function verify
         * @memberof proto.CatalogSnapshot
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        CatalogSnapshot.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.catalogImage != null && message.hasOwnProperty("catalogImage")) {
                var error = $root.proto.ImageMessage.verify(message.catalogImage);
                if (error)
                    return "catalogImage." + error;
            }
            if (message.title != null && message.hasOwnProperty("title"))
                if (!$util.isString(message.title))
                    return "title: string expected";
            if (message.description != null && message.hasOwnProperty("description"))
                if (!$util.isString(message.description))
                    return "description: string expected";
            return null;
        };

        /**
         * Creates a CatalogSnapshot message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.CatalogSnapshot
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.CatalogSnapshot} CatalogSnapshot
         */
        CatalogSnapshot.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.CatalogSnapshot)
                return object;
            var message = new $root.proto.CatalogSnapshot();
            if (object.catalogImage != null) {
                if (typeof object.catalogImage !== "object")
                    throw TypeError(".proto.CatalogSnapshot.catalogImage: object expected");
                message.catalogImage = $root.proto.ImageMessage.fromObject(object.catalogImage);
            }
            if (object.title != null)
                message.title = String(object.title);
            if (object.description != null)
                message.description = String(object.description);
            return message;
        };

        /**
         * Creates a plain object from a CatalogSnapshot message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.CatalogSnapshot
         * @static
         * @param {proto.CatalogSnapshot} message CatalogSnapshot
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        CatalogSnapshot.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.catalogImage = null;
                object.title = "";
                object.description = "";
            }
            if (message.catalogImage != null && message.hasOwnProperty("catalogImage"))
                object.catalogImage = $root.proto.ImageMessage.toObject(message.catalogImage, options);
            if (message.title != null && message.hasOwnProperty("title"))
                object.title = message.title;
            if (message.description != null && message.hasOwnProperty("description"))
                object.description = message.description;
            return object;
        };

        /**
         * Converts this CatalogSnapshot to JSON.
         * @function toJSON
         * @memberof proto.CatalogSnapshot
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        CatalogSnapshot.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return CatalogSnapshot;
    })();

    proto.ProductSnapshot = (function() {

        /**
         * Properties of a ProductSnapshot.
         * @memberof proto
         * @interface IProductSnapshot
         * @property {proto.IImageMessage|null} [productImage] ProductSnapshot productImage
         * @property {string|null} [productId] ProductSnapshot productId
         * @property {string|null} [title] ProductSnapshot title
         * @property {string|null} [description] ProductSnapshot description
         * @property {string|null} [currencyCode] ProductSnapshot currencyCode
         * @property {number|Long|null} [priceAmount1000] ProductSnapshot priceAmount1000
         * @property {string|null} [retailerId] ProductSnapshot retailerId
         * @property {string|null} [url] ProductSnapshot url
         * @property {number|null} [productImageCount] ProductSnapshot productImageCount
         * @property {string|null} [firstImageId] ProductSnapshot firstImageId
         * @property {number|Long|null} [salePriceAmount1000] ProductSnapshot salePriceAmount1000
         */

        /**
         * Constructs a new ProductSnapshot.
         * @memberof proto
         * @classdesc Represents a ProductSnapshot.
         * @implements IProductSnapshot
         * @constructor
         * @param {proto.IProductSnapshot=} [properties] Properties to set
         */
        function ProductSnapshot(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ProductSnapshot productImage.
         * @member {proto.IImageMessage|null|undefined} productImage
         * @memberof proto.ProductSnapshot
         * @instance
         */
        ProductSnapshot.prototype.productImage = null;

        /**
         * ProductSnapshot productId.
         * @member {string} productId
         * @memberof proto.ProductSnapshot
         * @instance
         */
        ProductSnapshot.prototype.productId = "";

        /**
         * ProductSnapshot title.
         * @member {string} title
         * @memberof proto.ProductSnapshot
         * @instance
         */
        ProductSnapshot.prototype.title = "";

        /**
         * ProductSnapshot description.
         * @member {string} description
         * @memberof proto.ProductSnapshot
         * @instance
         */
        ProductSnapshot.prototype.description = "";

        /**
         * ProductSnapshot currencyCode.
         * @member {string} currencyCode
         * @memberof proto.ProductSnapshot
         * @instance
         */
        ProductSnapshot.prototype.currencyCode = "";

        /**
         * ProductSnapshot priceAmount1000.
         * @member {number|Long} priceAmount1000
         * @memberof proto.ProductSnapshot
         * @instance
         */
        ProductSnapshot.prototype.priceAmount1000 = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * ProductSnapshot retailerId.
         * @member {string} retailerId
         * @memberof proto.ProductSnapshot
         * @instance
         */
        ProductSnapshot.prototype.retailerId = "";

        /**
         * ProductSnapshot url.
         * @member {string} url
         * @memberof proto.ProductSnapshot
         * @instance
         */
        ProductSnapshot.prototype.url = "";

        /**
         * ProductSnapshot productImageCount.
         * @member {number} productImageCount
         * @memberof proto.ProductSnapshot
         * @instance
         */
        ProductSnapshot.prototype.productImageCount = 0;

        /**
         * ProductSnapshot firstImageId.
         * @member {string} firstImageId
         * @memberof proto.ProductSnapshot
         * @instance
         */
        ProductSnapshot.prototype.firstImageId = "";

        /**
         * ProductSnapshot salePriceAmount1000.
         * @member {number|Long} salePriceAmount1000
         * @memberof proto.ProductSnapshot
         * @instance
         */
        ProductSnapshot.prototype.salePriceAmount1000 = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * Creates a new ProductSnapshot instance using the specified properties.
         * @function create
         * @memberof proto.ProductSnapshot
         * @static
         * @param {proto.IProductSnapshot=} [properties] Properties to set
         * @returns {proto.ProductSnapshot} ProductSnapshot instance
         */
        ProductSnapshot.create = function create(properties) {
            return new ProductSnapshot(properties);
        };

        /**
         * Encodes the specified ProductSnapshot message. Does not implicitly {@link proto.ProductSnapshot.verify|verify} messages.
         * @function encode
         * @memberof proto.ProductSnapshot
         * @static
         * @param {proto.IProductSnapshot} message ProductSnapshot message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ProductSnapshot.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.productImage != null && Object.hasOwnProperty.call(message, "productImage"))
                $root.proto.ImageMessage.encode(message.productImage, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.productId != null && Object.hasOwnProperty.call(message, "productId"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.productId);
            if (message.title != null && Object.hasOwnProperty.call(message, "title"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.title);
            if (message.description != null && Object.hasOwnProperty.call(message, "description"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.description);
            if (message.currencyCode != null && Object.hasOwnProperty.call(message, "currencyCode"))
                writer.uint32(/* id 5, wireType 2 =*/42).string(message.currencyCode);
            if (message.priceAmount1000 != null && Object.hasOwnProperty.call(message, "priceAmount1000"))
                writer.uint32(/* id 6, wireType 0 =*/48).int64(message.priceAmount1000);
            if (message.retailerId != null && Object.hasOwnProperty.call(message, "retailerId"))
                writer.uint32(/* id 7, wireType 2 =*/58).string(message.retailerId);
            if (message.url != null && Object.hasOwnProperty.call(message, "url"))
                writer.uint32(/* id 8, wireType 2 =*/66).string(message.url);
            if (message.productImageCount != null && Object.hasOwnProperty.call(message, "productImageCount"))
                writer.uint32(/* id 9, wireType 0 =*/72).uint32(message.productImageCount);
            if (message.firstImageId != null && Object.hasOwnProperty.call(message, "firstImageId"))
                writer.uint32(/* id 11, wireType 2 =*/90).string(message.firstImageId);
            if (message.salePriceAmount1000 != null && Object.hasOwnProperty.call(message, "salePriceAmount1000"))
                writer.uint32(/* id 12, wireType 0 =*/96).int64(message.salePriceAmount1000);
            return writer;
        };

        /**
         * Encodes the specified ProductSnapshot message, length delimited. Does not implicitly {@link proto.ProductSnapshot.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ProductSnapshot
         * @static
         * @param {proto.IProductSnapshot} message ProductSnapshot message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ProductSnapshot.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ProductSnapshot message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ProductSnapshot
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ProductSnapshot} ProductSnapshot
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ProductSnapshot.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ProductSnapshot();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.productImage = $root.proto.ImageMessage.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.productId = reader.string();
                    break;
                case 3:
                    message.title = reader.string();
                    break;
                case 4:
                    message.description = reader.string();
                    break;
                case 5:
                    message.currencyCode = reader.string();
                    break;
                case 6:
                    message.priceAmount1000 = reader.int64();
                    break;
                case 7:
                    message.retailerId = reader.string();
                    break;
                case 8:
                    message.url = reader.string();
                    break;
                case 9:
                    message.productImageCount = reader.uint32();
                    break;
                case 11:
                    message.firstImageId = reader.string();
                    break;
                case 12:
                    message.salePriceAmount1000 = reader.int64();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ProductSnapshot message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ProductSnapshot
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ProductSnapshot} ProductSnapshot
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ProductSnapshot.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ProductSnapshot message.
         * @function verify
         * @memberof proto.ProductSnapshot
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ProductSnapshot.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.productImage != null && message.hasOwnProperty("productImage")) {
                var error = $root.proto.ImageMessage.verify(message.productImage);
                if (error)
                    return "productImage." + error;
            }
            if (message.productId != null && message.hasOwnProperty("productId"))
                if (!$util.isString(message.productId))
                    return "productId: string expected";
            if (message.title != null && message.hasOwnProperty("title"))
                if (!$util.isString(message.title))
                    return "title: string expected";
            if (message.description != null && message.hasOwnProperty("description"))
                if (!$util.isString(message.description))
                    return "description: string expected";
            if (message.currencyCode != null && message.hasOwnProperty("currencyCode"))
                if (!$util.isString(message.currencyCode))
                    return "currencyCode: string expected";
            if (message.priceAmount1000 != null && message.hasOwnProperty("priceAmount1000"))
                if (!$util.isInteger(message.priceAmount1000) && !(message.priceAmount1000 && $util.isInteger(message.priceAmount1000.low) && $util.isInteger(message.priceAmount1000.high)))
                    return "priceAmount1000: integer|Long expected";
            if (message.retailerId != null && message.hasOwnProperty("retailerId"))
                if (!$util.isString(message.retailerId))
                    return "retailerId: string expected";
            if (message.url != null && message.hasOwnProperty("url"))
                if (!$util.isString(message.url))
                    return "url: string expected";
            if (message.productImageCount != null && message.hasOwnProperty("productImageCount"))
                if (!$util.isInteger(message.productImageCount))
                    return "productImageCount: integer expected";
            if (message.firstImageId != null && message.hasOwnProperty("firstImageId"))
                if (!$util.isString(message.firstImageId))
                    return "firstImageId: string expected";
            if (message.salePriceAmount1000 != null && message.hasOwnProperty("salePriceAmount1000"))
                if (!$util.isInteger(message.salePriceAmount1000) && !(message.salePriceAmount1000 && $util.isInteger(message.salePriceAmount1000.low) && $util.isInteger(message.salePriceAmount1000.high)))
                    return "salePriceAmount1000: integer|Long expected";
            return null;
        };

        /**
         * Creates a ProductSnapshot message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ProductSnapshot
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ProductSnapshot} ProductSnapshot
         */
        ProductSnapshot.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ProductSnapshot)
                return object;
            var message = new $root.proto.ProductSnapshot();
            if (object.productImage != null) {
                if (typeof object.productImage !== "object")
                    throw TypeError(".proto.ProductSnapshot.productImage: object expected");
                message.productImage = $root.proto.ImageMessage.fromObject(object.productImage);
            }
            if (object.productId != null)
                message.productId = String(object.productId);
            if (object.title != null)
                message.title = String(object.title);
            if (object.description != null)
                message.description = String(object.description);
            if (object.currencyCode != null)
                message.currencyCode = String(object.currencyCode);
            if (object.priceAmount1000 != null)
                if ($util.Long)
                    (message.priceAmount1000 = $util.Long.fromValue(object.priceAmount1000)).unsigned = false;
                else if (typeof object.priceAmount1000 === "string")
                    message.priceAmount1000 = parseInt(object.priceAmount1000, 10);
                else if (typeof object.priceAmount1000 === "number")
                    message.priceAmount1000 = object.priceAmount1000;
                else if (typeof object.priceAmount1000 === "object")
                    message.priceAmount1000 = new $util.LongBits(object.priceAmount1000.low >>> 0, object.priceAmount1000.high >>> 0).toNumber();
            if (object.retailerId != null)
                message.retailerId = String(object.retailerId);
            if (object.url != null)
                message.url = String(object.url);
            if (object.productImageCount != null)
                message.productImageCount = object.productImageCount >>> 0;
            if (object.firstImageId != null)
                message.firstImageId = String(object.firstImageId);
            if (object.salePriceAmount1000 != null)
                if ($util.Long)
                    (message.salePriceAmount1000 = $util.Long.fromValue(object.salePriceAmount1000)).unsigned = false;
                else if (typeof object.salePriceAmount1000 === "string")
                    message.salePriceAmount1000 = parseInt(object.salePriceAmount1000, 10);
                else if (typeof object.salePriceAmount1000 === "number")
                    message.salePriceAmount1000 = object.salePriceAmount1000;
                else if (typeof object.salePriceAmount1000 === "object")
                    message.salePriceAmount1000 = new $util.LongBits(object.salePriceAmount1000.low >>> 0, object.salePriceAmount1000.high >>> 0).toNumber();
            return message;
        };

        /**
         * Creates a plain object from a ProductSnapshot message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ProductSnapshot
         * @static
         * @param {proto.ProductSnapshot} message ProductSnapshot
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ProductSnapshot.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.productImage = null;
                object.productId = "";
                object.title = "";
                object.description = "";
                object.currencyCode = "";
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.priceAmount1000 = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.priceAmount1000 = options.longs === String ? "0" : 0;
                object.retailerId = "";
                object.url = "";
                object.productImageCount = 0;
                object.firstImageId = "";
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.salePriceAmount1000 = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.salePriceAmount1000 = options.longs === String ? "0" : 0;
            }
            if (message.productImage != null && message.hasOwnProperty("productImage"))
                object.productImage = $root.proto.ImageMessage.toObject(message.productImage, options);
            if (message.productId != null && message.hasOwnProperty("productId"))
                object.productId = message.productId;
            if (message.title != null && message.hasOwnProperty("title"))
                object.title = message.title;
            if (message.description != null && message.hasOwnProperty("description"))
                object.description = message.description;
            if (message.currencyCode != null && message.hasOwnProperty("currencyCode"))
                object.currencyCode = message.currencyCode;
            if (message.priceAmount1000 != null && message.hasOwnProperty("priceAmount1000"))
                if (typeof message.priceAmount1000 === "number")
                    object.priceAmount1000 = options.longs === String ? String(message.priceAmount1000) : message.priceAmount1000;
                else
                    object.priceAmount1000 = options.longs === String ? $util.Long.prototype.toString.call(message.priceAmount1000) : options.longs === Number ? new $util.LongBits(message.priceAmount1000.low >>> 0, message.priceAmount1000.high >>> 0).toNumber() : message.priceAmount1000;
            if (message.retailerId != null && message.hasOwnProperty("retailerId"))
                object.retailerId = message.retailerId;
            if (message.url != null && message.hasOwnProperty("url"))
                object.url = message.url;
            if (message.productImageCount != null && message.hasOwnProperty("productImageCount"))
                object.productImageCount = message.productImageCount;
            if (message.firstImageId != null && message.hasOwnProperty("firstImageId"))
                object.firstImageId = message.firstImageId;
            if (message.salePriceAmount1000 != null && message.hasOwnProperty("salePriceAmount1000"))
                if (typeof message.salePriceAmount1000 === "number")
                    object.salePriceAmount1000 = options.longs === String ? String(message.salePriceAmount1000) : message.salePriceAmount1000;
                else
                    object.salePriceAmount1000 = options.longs === String ? $util.Long.prototype.toString.call(message.salePriceAmount1000) : options.longs === Number ? new $util.LongBits(message.salePriceAmount1000.low >>> 0, message.salePriceAmount1000.high >>> 0).toNumber() : message.salePriceAmount1000;
            return object;
        };

        /**
         * Converts this ProductSnapshot to JSON.
         * @function toJSON
         * @memberof proto.ProductSnapshot
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ProductSnapshot.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ProductSnapshot;
    })();

    proto.ProductMessage = (function() {

        /**
         * Properties of a ProductMessage.
         * @memberof proto
         * @interface IProductMessage
         * @property {proto.IProductSnapshot|null} [product] ProductMessage product
         * @property {string|null} [businessOwnerJid] ProductMessage businessOwnerJid
         * @property {proto.ICatalogSnapshot|null} [catalog] ProductMessage catalog
         * @property {string|null} [body] ProductMessage body
         * @property {string|null} [footer] ProductMessage footer
         * @property {proto.IContextInfo|null} [contextInfo] ProductMessage contextInfo
         */

        /**
         * Constructs a new ProductMessage.
         * @memberof proto
         * @classdesc Represents a ProductMessage.
         * @implements IProductMessage
         * @constructor
         * @param {proto.IProductMessage=} [properties] Properties to set
         */
        function ProductMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ProductMessage product.
         * @member {proto.IProductSnapshot|null|undefined} product
         * @memberof proto.ProductMessage
         * @instance
         */
        ProductMessage.prototype.product = null;

        /**
         * ProductMessage businessOwnerJid.
         * @member {string} businessOwnerJid
         * @memberof proto.ProductMessage
         * @instance
         */
        ProductMessage.prototype.businessOwnerJid = "";

        /**
         * ProductMessage catalog.
         * @member {proto.ICatalogSnapshot|null|undefined} catalog
         * @memberof proto.ProductMessage
         * @instance
         */
        ProductMessage.prototype.catalog = null;

        /**
         * ProductMessage body.
         * @member {string} body
         * @memberof proto.ProductMessage
         * @instance
         */
        ProductMessage.prototype.body = "";

        /**
         * ProductMessage footer.
         * @member {string} footer
         * @memberof proto.ProductMessage
         * @instance
         */
        ProductMessage.prototype.footer = "";

        /**
         * ProductMessage contextInfo.
         * @member {proto.IContextInfo|null|undefined} contextInfo
         * @memberof proto.ProductMessage
         * @instance
         */
        ProductMessage.prototype.contextInfo = null;

        /**
         * Creates a new ProductMessage instance using the specified properties.
         * @function create
         * @memberof proto.ProductMessage
         * @static
         * @param {proto.IProductMessage=} [properties] Properties to set
         * @returns {proto.ProductMessage} ProductMessage instance
         */
        ProductMessage.create = function create(properties) {
            return new ProductMessage(properties);
        };

        /**
         * Encodes the specified ProductMessage message. Does not implicitly {@link proto.ProductMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.ProductMessage
         * @static
         * @param {proto.IProductMessage} message ProductMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ProductMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.product != null && Object.hasOwnProperty.call(message, "product"))
                $root.proto.ProductSnapshot.encode(message.product, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.businessOwnerJid != null && Object.hasOwnProperty.call(message, "businessOwnerJid"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.businessOwnerJid);
            if (message.catalog != null && Object.hasOwnProperty.call(message, "catalog"))
                $root.proto.CatalogSnapshot.encode(message.catalog, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
            if (message.body != null && Object.hasOwnProperty.call(message, "body"))
                writer.uint32(/* id 5, wireType 2 =*/42).string(message.body);
            if (message.footer != null && Object.hasOwnProperty.call(message, "footer"))
                writer.uint32(/* id 6, wireType 2 =*/50).string(message.footer);
            if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo"))
                $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 17, wireType 2 =*/138).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified ProductMessage message, length delimited. Does not implicitly {@link proto.ProductMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ProductMessage
         * @static
         * @param {proto.IProductMessage} message ProductMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ProductMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ProductMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ProductMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ProductMessage} ProductMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ProductMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ProductMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.product = $root.proto.ProductSnapshot.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.businessOwnerJid = reader.string();
                    break;
                case 4:
                    message.catalog = $root.proto.CatalogSnapshot.decode(reader, reader.uint32());
                    break;
                case 5:
                    message.body = reader.string();
                    break;
                case 6:
                    message.footer = reader.string();
                    break;
                case 17:
                    message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ProductMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ProductMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ProductMessage} ProductMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ProductMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ProductMessage message.
         * @function verify
         * @memberof proto.ProductMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ProductMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.product != null && message.hasOwnProperty("product")) {
                var error = $root.proto.ProductSnapshot.verify(message.product);
                if (error)
                    return "product." + error;
            }
            if (message.businessOwnerJid != null && message.hasOwnProperty("businessOwnerJid"))
                if (!$util.isString(message.businessOwnerJid))
                    return "businessOwnerJid: string expected";
            if (message.catalog != null && message.hasOwnProperty("catalog")) {
                var error = $root.proto.CatalogSnapshot.verify(message.catalog);
                if (error)
                    return "catalog." + error;
            }
            if (message.body != null && message.hasOwnProperty("body"))
                if (!$util.isString(message.body))
                    return "body: string expected";
            if (message.footer != null && message.hasOwnProperty("footer"))
                if (!$util.isString(message.footer))
                    return "footer: string expected";
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) {
                var error = $root.proto.ContextInfo.verify(message.contextInfo);
                if (error)
                    return "contextInfo." + error;
            }
            return null;
        };

        /**
         * Creates a ProductMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ProductMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ProductMessage} ProductMessage
         */
        ProductMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ProductMessage)
                return object;
            var message = new $root.proto.ProductMessage();
            if (object.product != null) {
                if (typeof object.product !== "object")
                    throw TypeError(".proto.ProductMessage.product: object expected");
                message.product = $root.proto.ProductSnapshot.fromObject(object.product);
            }
            if (object.businessOwnerJid != null)
                message.businessOwnerJid = String(object.businessOwnerJid);
            if (object.catalog != null) {
                if (typeof object.catalog !== "object")
                    throw TypeError(".proto.ProductMessage.catalog: object expected");
                message.catalog = $root.proto.CatalogSnapshot.fromObject(object.catalog);
            }
            if (object.body != null)
                message.body = String(object.body);
            if (object.footer != null)
                message.footer = String(object.footer);
            if (object.contextInfo != null) {
                if (typeof object.contextInfo !== "object")
                    throw TypeError(".proto.ProductMessage.contextInfo: object expected");
                message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo);
            }
            return message;
        };

        /**
         * Creates a plain object from a ProductMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ProductMessage
         * @static
         * @param {proto.ProductMessage} message ProductMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ProductMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.product = null;
                object.businessOwnerJid = "";
                object.catalog = null;
                object.body = "";
                object.footer = "";
                object.contextInfo = null;
            }
            if (message.product != null && message.hasOwnProperty("product"))
                object.product = $root.proto.ProductSnapshot.toObject(message.product, options);
            if (message.businessOwnerJid != null && message.hasOwnProperty("businessOwnerJid"))
                object.businessOwnerJid = message.businessOwnerJid;
            if (message.catalog != null && message.hasOwnProperty("catalog"))
                object.catalog = $root.proto.CatalogSnapshot.toObject(message.catalog, options);
            if (message.body != null && message.hasOwnProperty("body"))
                object.body = message.body;
            if (message.footer != null && message.hasOwnProperty("footer"))
                object.footer = message.footer;
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo"))
                object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options);
            return object;
        };

        /**
         * Converts this ProductMessage to JSON.
         * @function toJSON
         * @memberof proto.ProductMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ProductMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ProductMessage;
    })();

    proto.OrderMessage = (function() {

        /**
         * Properties of an OrderMessage.
         * @memberof proto
         * @interface IOrderMessage
         * @property {string|null} [orderId] OrderMessage orderId
         * @property {Uint8Array|null} [thumbnail] OrderMessage thumbnail
         * @property {number|null} [itemCount] OrderMessage itemCount
         * @property {proto.OrderMessage.OrderMessageOrderStatus|null} [status] OrderMessage status
         * @property {proto.OrderMessage.OrderMessageOrderSurface|null} [surface] OrderMessage surface
         * @property {string|null} [message] OrderMessage message
         * @property {string|null} [orderTitle] OrderMessage orderTitle
         * @property {string|null} [sellerJid] OrderMessage sellerJid
         * @property {string|null} [token] OrderMessage token
         * @property {number|Long|null} [totalAmount1000] OrderMessage totalAmount1000
         * @property {string|null} [totalCurrencyCode] OrderMessage totalCurrencyCode
         * @property {proto.IContextInfo|null} [contextInfo] OrderMessage contextInfo
         */

        /**
         * Constructs a new OrderMessage.
         * @memberof proto
         * @classdesc Represents an OrderMessage.
         * @implements IOrderMessage
         * @constructor
         * @param {proto.IOrderMessage=} [properties] Properties to set
         */
        function OrderMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * OrderMessage orderId.
         * @member {string} orderId
         * @memberof proto.OrderMessage
         * @instance
         */
        OrderMessage.prototype.orderId = "";

        /**
         * OrderMessage thumbnail.
         * @member {Uint8Array} thumbnail
         * @memberof proto.OrderMessage
         * @instance
         */
        OrderMessage.prototype.thumbnail = $util.newBuffer([]);

        /**
         * OrderMessage itemCount.
         * @member {number} itemCount
         * @memberof proto.OrderMessage
         * @instance
         */
        OrderMessage.prototype.itemCount = 0;

        /**
         * OrderMessage status.
         * @member {proto.OrderMessage.OrderMessageOrderStatus} status
         * @memberof proto.OrderMessage
         * @instance
         */
        OrderMessage.prototype.status = 1;

        /**
         * OrderMessage surface.
         * @member {proto.OrderMessage.OrderMessageOrderSurface} surface
         * @memberof proto.OrderMessage
         * @instance
         */
        OrderMessage.prototype.surface = 1;

        /**
         * OrderMessage message.
         * @member {string} message
         * @memberof proto.OrderMessage
         * @instance
         */
        OrderMessage.prototype.message = "";

        /**
         * OrderMessage orderTitle.
         * @member {string} orderTitle
         * @memberof proto.OrderMessage
         * @instance
         */
        OrderMessage.prototype.orderTitle = "";

        /**
         * OrderMessage sellerJid.
         * @member {string} sellerJid
         * @memberof proto.OrderMessage
         * @instance
         */
        OrderMessage.prototype.sellerJid = "";

        /**
         * OrderMessage token.
         * @member {string} token
         * @memberof proto.OrderMessage
         * @instance
         */
        OrderMessage.prototype.token = "";

        /**
         * OrderMessage totalAmount1000.
         * @member {number|Long} totalAmount1000
         * @memberof proto.OrderMessage
         * @instance
         */
        OrderMessage.prototype.totalAmount1000 = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * OrderMessage totalCurrencyCode.
         * @member {string} totalCurrencyCode
         * @memberof proto.OrderMessage
         * @instance
         */
        OrderMessage.prototype.totalCurrencyCode = "";

        /**
         * OrderMessage contextInfo.
         * @member {proto.IContextInfo|null|undefined} contextInfo
         * @memberof proto.OrderMessage
         * @instance
         */
        OrderMessage.prototype.contextInfo = null;

        /**
         * Creates a new OrderMessage instance using the specified properties.
         * @function create
         * @memberof proto.OrderMessage
         * @static
         * @param {proto.IOrderMessage=} [properties] Properties to set
         * @returns {proto.OrderMessage} OrderMessage instance
         */
        OrderMessage.create = function create(properties) {
            return new OrderMessage(properties);
        };

        /**
         * Encodes the specified OrderMessage message. Does not implicitly {@link proto.OrderMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.OrderMessage
         * @static
         * @param {proto.IOrderMessage} message OrderMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        OrderMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.orderId != null && Object.hasOwnProperty.call(message, "orderId"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.orderId);
            if (message.thumbnail != null && Object.hasOwnProperty.call(message, "thumbnail"))
                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.thumbnail);
            if (message.itemCount != null && Object.hasOwnProperty.call(message, "itemCount"))
                writer.uint32(/* id 3, wireType 0 =*/24).int32(message.itemCount);
            if (message.status != null && Object.hasOwnProperty.call(message, "status"))
                writer.uint32(/* id 4, wireType 0 =*/32).int32(message.status);
            if (message.surface != null && Object.hasOwnProperty.call(message, "surface"))
                writer.uint32(/* id 5, wireType 0 =*/40).int32(message.surface);
            if (message.message != null && Object.hasOwnProperty.call(message, "message"))
                writer.uint32(/* id 6, wireType 2 =*/50).string(message.message);
            if (message.orderTitle != null && Object.hasOwnProperty.call(message, "orderTitle"))
                writer.uint32(/* id 7, wireType 2 =*/58).string(message.orderTitle);
            if (message.sellerJid != null && Object.hasOwnProperty.call(message, "sellerJid"))
                writer.uint32(/* id 8, wireType 2 =*/66).string(message.sellerJid);
            if (message.token != null && Object.hasOwnProperty.call(message, "token"))
                writer.uint32(/* id 9, wireType 2 =*/74).string(message.token);
            if (message.totalAmount1000 != null && Object.hasOwnProperty.call(message, "totalAmount1000"))
                writer.uint32(/* id 10, wireType 0 =*/80).int64(message.totalAmount1000);
            if (message.totalCurrencyCode != null && Object.hasOwnProperty.call(message, "totalCurrencyCode"))
                writer.uint32(/* id 11, wireType 2 =*/90).string(message.totalCurrencyCode);
            if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo"))
                $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 17, wireType 2 =*/138).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified OrderMessage message, length delimited. Does not implicitly {@link proto.OrderMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.OrderMessage
         * @static
         * @param {proto.IOrderMessage} message OrderMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        OrderMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an OrderMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.OrderMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.OrderMessage} OrderMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        OrderMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.OrderMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.orderId = reader.string();
                    break;
                case 2:
                    message.thumbnail = reader.bytes();
                    break;
                case 3:
                    message.itemCount = reader.int32();
                    break;
                case 4:
                    message.status = reader.int32();
                    break;
                case 5:
                    message.surface = reader.int32();
                    break;
                case 6:
                    message.message = reader.string();
                    break;
                case 7:
                    message.orderTitle = reader.string();
                    break;
                case 8:
                    message.sellerJid = reader.string();
                    break;
                case 9:
                    message.token = reader.string();
                    break;
                case 10:
                    message.totalAmount1000 = reader.int64();
                    break;
                case 11:
                    message.totalCurrencyCode = reader.string();
                    break;
                case 17:
                    message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an OrderMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.OrderMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.OrderMessage} OrderMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        OrderMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an OrderMessage message.
         * @function verify
         * @memberof proto.OrderMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        OrderMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.orderId != null && message.hasOwnProperty("orderId"))
                if (!$util.isString(message.orderId))
                    return "orderId: string expected";
            if (message.thumbnail != null && message.hasOwnProperty("thumbnail"))
                if (!(message.thumbnail && typeof message.thumbnail.length === "number" || $util.isString(message.thumbnail)))
                    return "thumbnail: buffer expected";
            if (message.itemCount != null && message.hasOwnProperty("itemCount"))
                if (!$util.isInteger(message.itemCount))
                    return "itemCount: integer expected";
            if (message.status != null && message.hasOwnProperty("status"))
                switch (message.status) {
                default:
                    return "status: enum value expected";
                case 1:
                    break;
                }
            if (message.surface != null && message.hasOwnProperty("surface"))
                switch (message.surface) {
                default:
                    return "surface: enum value expected";
                case 1:
                    break;
                }
            if (message.message != null && message.hasOwnProperty("message"))
                if (!$util.isString(message.message))
                    return "message: string expected";
            if (message.orderTitle != null && message.hasOwnProperty("orderTitle"))
                if (!$util.isString(message.orderTitle))
                    return "orderTitle: string expected";
            if (message.sellerJid != null && message.hasOwnProperty("sellerJid"))
                if (!$util.isString(message.sellerJid))
                    return "sellerJid: string expected";
            if (message.token != null && message.hasOwnProperty("token"))
                if (!$util.isString(message.token))
                    return "token: string expected";
            if (message.totalAmount1000 != null && message.hasOwnProperty("totalAmount1000"))
                if (!$util.isInteger(message.totalAmount1000) && !(message.totalAmount1000 && $util.isInteger(message.totalAmount1000.low) && $util.isInteger(message.totalAmount1000.high)))
                    return "totalAmount1000: integer|Long expected";
            if (message.totalCurrencyCode != null && message.hasOwnProperty("totalCurrencyCode"))
                if (!$util.isString(message.totalCurrencyCode))
                    return "totalCurrencyCode: string expected";
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) {
                var error = $root.proto.ContextInfo.verify(message.contextInfo);
                if (error)
                    return "contextInfo." + error;
            }
            return null;
        };

        /**
         * Creates an OrderMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.OrderMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.OrderMessage} OrderMessage
         */
        OrderMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.OrderMessage)
                return object;
            var message = new $root.proto.OrderMessage();
            if (object.orderId != null)
                message.orderId = String(object.orderId);
            if (object.thumbnail != null)
                if (typeof object.thumbnail === "string")
                    $util.base64.decode(object.thumbnail, message.thumbnail = $util.newBuffer($util.base64.length(object.thumbnail)), 0);
                else if (object.thumbnail.length)
                    message.thumbnail = object.thumbnail;
            if (object.itemCount != null)
                message.itemCount = object.itemCount | 0;
            switch (object.status) {
            case "INQUIRY":
            case 1:
                message.status = 1;
                break;
            }
            switch (object.surface) {
            case "CATALOG":
            case 1:
                message.surface = 1;
                break;
            }
            if (object.message != null)
                message.message = String(object.message);
            if (object.orderTitle != null)
                message.orderTitle = String(object.orderTitle);
            if (object.sellerJid != null)
                message.sellerJid = String(object.sellerJid);
            if (object.token != null)
                message.token = String(object.token);
            if (object.totalAmount1000 != null)
                if ($util.Long)
                    (message.totalAmount1000 = $util.Long.fromValue(object.totalAmount1000)).unsigned = false;
                else if (typeof object.totalAmount1000 === "string")
                    message.totalAmount1000 = parseInt(object.totalAmount1000, 10);
                else if (typeof object.totalAmount1000 === "number")
                    message.totalAmount1000 = object.totalAmount1000;
                else if (typeof object.totalAmount1000 === "object")
                    message.totalAmount1000 = new $util.LongBits(object.totalAmount1000.low >>> 0, object.totalAmount1000.high >>> 0).toNumber();
            if (object.totalCurrencyCode != null)
                message.totalCurrencyCode = String(object.totalCurrencyCode);
            if (object.contextInfo != null) {
                if (typeof object.contextInfo !== "object")
                    throw TypeError(".proto.OrderMessage.contextInfo: object expected");
                message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo);
            }
            return message;
        };

        /**
         * Creates a plain object from an OrderMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.OrderMessage
         * @static
         * @param {proto.OrderMessage} message OrderMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        OrderMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.orderId = "";
                if (options.bytes === String)
                    object.thumbnail = "";
                else {
                    object.thumbnail = [];
                    if (options.bytes !== Array)
                        object.thumbnail = $util.newBuffer(object.thumbnail);
                }
                object.itemCount = 0;
                object.status = options.enums === String ? "INQUIRY" : 1;
                object.surface = options.enums === String ? "CATALOG" : 1;
                object.message = "";
                object.orderTitle = "";
                object.sellerJid = "";
                object.token = "";
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.totalAmount1000 = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.totalAmount1000 = options.longs === String ? "0" : 0;
                object.totalCurrencyCode = "";
                object.contextInfo = null;
            }
            if (message.orderId != null && message.hasOwnProperty("orderId"))
                object.orderId = message.orderId;
            if (message.thumbnail != null && message.hasOwnProperty("thumbnail"))
                object.thumbnail = options.bytes === String ? $util.base64.encode(message.thumbnail, 0, message.thumbnail.length) : options.bytes === Array ? Array.prototype.slice.call(message.thumbnail) : message.thumbnail;
            if (message.itemCount != null && message.hasOwnProperty("itemCount"))
                object.itemCount = message.itemCount;
            if (message.status != null && message.hasOwnProperty("status"))
                object.status = options.enums === String ? $root.proto.OrderMessage.OrderMessageOrderStatus[message.status] : message.status;
            if (message.surface != null && message.hasOwnProperty("surface"))
                object.surface = options.enums === String ? $root.proto.OrderMessage.OrderMessageOrderSurface[message.surface] : message.surface;
            if (message.message != null && message.hasOwnProperty("message"))
                object.message = message.message;
            if (message.orderTitle != null && message.hasOwnProperty("orderTitle"))
                object.orderTitle = message.orderTitle;
            if (message.sellerJid != null && message.hasOwnProperty("sellerJid"))
                object.sellerJid = message.sellerJid;
            if (message.token != null && message.hasOwnProperty("token"))
                object.token = message.token;
            if (message.totalAmount1000 != null && message.hasOwnProperty("totalAmount1000"))
                if (typeof message.totalAmount1000 === "number")
                    object.totalAmount1000 = options.longs === String ? String(message.totalAmount1000) : message.totalAmount1000;
                else
                    object.totalAmount1000 = options.longs === String ? $util.Long.prototype.toString.call(message.totalAmount1000) : options.longs === Number ? new $util.LongBits(message.totalAmount1000.low >>> 0, message.totalAmount1000.high >>> 0).toNumber() : message.totalAmount1000;
            if (message.totalCurrencyCode != null && message.hasOwnProperty("totalCurrencyCode"))
                object.totalCurrencyCode = message.totalCurrencyCode;
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo"))
                object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options);
            return object;
        };

        /**
         * Converts this OrderMessage to JSON.
         * @function toJSON
         * @memberof proto.OrderMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        OrderMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * OrderMessageOrderStatus enum.
         * @name proto.OrderMessage.OrderMessageOrderStatus
         * @enum {number}
         * @property {number} INQUIRY=1 INQUIRY value
         */
        OrderMessage.OrderMessageOrderStatus = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[1] = "INQUIRY"] = 1;
            return values;
        })();

        /**
         * OrderMessageOrderSurface enum.
         * @name proto.OrderMessage.OrderMessageOrderSurface
         * @enum {number}
         * @property {number} CATALOG=1 CATALOG value
         */
        OrderMessage.OrderMessageOrderSurface = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[1] = "CATALOG"] = 1;
            return values;
        })();

        return OrderMessage;
    })();

    proto.Row = (function() {

        /**
         * Properties of a Row.
         * @memberof proto
         * @interface IRow
         * @property {string|null} [title] Row title
         * @property {string|null} [description] Row description
         * @property {string|null} [rowId] Row rowId
         */

        /**
         * Constructs a new Row.
         * @memberof proto
         * @classdesc Represents a Row.
         * @implements IRow
         * @constructor
         * @param {proto.IRow=} [properties] Properties to set
         */
        function Row(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Row title.
         * @member {string} title
         * @memberof proto.Row
         * @instance
         */
        Row.prototype.title = "";

        /**
         * Row description.
         * @member {string} description
         * @memberof proto.Row
         * @instance
         */
        Row.prototype.description = "";

        /**
         * Row rowId.
         * @member {string} rowId
         * @memberof proto.Row
         * @instance
         */
        Row.prototype.rowId = "";

        /**
         * Creates a new Row instance using the specified properties.
         * @function create
         * @memberof proto.Row
         * @static
         * @param {proto.IRow=} [properties] Properties to set
         * @returns {proto.Row} Row instance
         */
        Row.create = function create(properties) {
            return new Row(properties);
        };

        /**
         * Encodes the specified Row message. Does not implicitly {@link proto.Row.verify|verify} messages.
         * @function encode
         * @memberof proto.Row
         * @static
         * @param {proto.IRow} message Row message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Row.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.title != null && Object.hasOwnProperty.call(message, "title"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.title);
            if (message.description != null && Object.hasOwnProperty.call(message, "description"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.description);
            if (message.rowId != null && Object.hasOwnProperty.call(message, "rowId"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.rowId);
            return writer;
        };

        /**
         * Encodes the specified Row message, length delimited. Does not implicitly {@link proto.Row.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.Row
         * @static
         * @param {proto.IRow} message Row message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Row.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a Row message from the specified reader or buffer.
         * @function decode
         * @memberof proto.Row
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.Row} Row
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Row.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Row();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.title = reader.string();
                    break;
                case 2:
                    message.description = reader.string();
                    break;
                case 3:
                    message.rowId = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a Row message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.Row
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.Row} Row
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Row.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a Row message.
         * @function verify
         * @memberof proto.Row
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        Row.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.title != null && message.hasOwnProperty("title"))
                if (!$util.isString(message.title))
                    return "title: string expected";
            if (message.description != null && message.hasOwnProperty("description"))
                if (!$util.isString(message.description))
                    return "description: string expected";
            if (message.rowId != null && message.hasOwnProperty("rowId"))
                if (!$util.isString(message.rowId))
                    return "rowId: string expected";
            return null;
        };

        /**
         * Creates a Row message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.Row
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.Row} Row
         */
        Row.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.Row)
                return object;
            var message = new $root.proto.Row();
            if (object.title != null)
                message.title = String(object.title);
            if (object.description != null)
                message.description = String(object.description);
            if (object.rowId != null)
                message.rowId = String(object.rowId);
            return message;
        };

        /**
         * Creates a plain object from a Row message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.Row
         * @static
         * @param {proto.Row} message Row
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        Row.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.title = "";
                object.description = "";
                object.rowId = "";
            }
            if (message.title != null && message.hasOwnProperty("title"))
                object.title = message.title;
            if (message.description != null && message.hasOwnProperty("description"))
                object.description = message.description;
            if (message.rowId != null && message.hasOwnProperty("rowId"))
                object.rowId = message.rowId;
            return object;
        };

        /**
         * Converts this Row to JSON.
         * @function toJSON
         * @memberof proto.Row
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        Row.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return Row;
    })();

    proto.Section = (function() {

        /**
         * Properties of a Section.
         * @memberof proto
         * @interface ISection
         * @property {string|null} [title] Section title
         * @property {Array.<proto.IRow>|null} [rows] Section rows
         */

        /**
         * Constructs a new Section.
         * @memberof proto
         * @classdesc Represents a Section.
         * @implements ISection
         * @constructor
         * @param {proto.ISection=} [properties] Properties to set
         */
        function Section(properties) {
            this.rows = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Section title.
         * @member {string} title
         * @memberof proto.Section
         * @instance
         */
        Section.prototype.title = "";

        /**
         * Section rows.
         * @member {Array.<proto.IRow>} rows
         * @memberof proto.Section
         * @instance
         */
        Section.prototype.rows = $util.emptyArray;

        /**
         * Creates a new Section instance using the specified properties.
         * @function create
         * @memberof proto.Section
         * @static
         * @param {proto.ISection=} [properties] Properties to set
         * @returns {proto.Section} Section instance
         */
        Section.create = function create(properties) {
            return new Section(properties);
        };

        /**
         * Encodes the specified Section message. Does not implicitly {@link proto.Section.verify|verify} messages.
         * @function encode
         * @memberof proto.Section
         * @static
         * @param {proto.ISection} message Section message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Section.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.title != null && Object.hasOwnProperty.call(message, "title"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.title);
            if (message.rows != null && message.rows.length)
                for (var i = 0; i < message.rows.length; ++i)
                    $root.proto.Row.encode(message.rows[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified Section message, length delimited. Does not implicitly {@link proto.Section.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.Section
         * @static
         * @param {proto.ISection} message Section message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Section.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a Section message from the specified reader or buffer.
         * @function decode
         * @memberof proto.Section
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.Section} Section
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Section.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Section();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.title = reader.string();
                    break;
                case 2:
                    if (!(message.rows && message.rows.length))
                        message.rows = [];
                    message.rows.push($root.proto.Row.decode(reader, reader.uint32()));
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a Section message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.Section
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.Section} Section
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Section.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a Section message.
         * @function verify
         * @memberof proto.Section
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        Section.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.title != null && message.hasOwnProperty("title"))
                if (!$util.isString(message.title))
                    return "title: string expected";
            if (message.rows != null && message.hasOwnProperty("rows")) {
                if (!Array.isArray(message.rows))
                    return "rows: array expected";
                for (var i = 0; i < message.rows.length; ++i) {
                    var error = $root.proto.Row.verify(message.rows[i]);
                    if (error)
                        return "rows." + error;
                }
            }
            return null;
        };

        /**
         * Creates a Section message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.Section
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.Section} Section
         */
        Section.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.Section)
                return object;
            var message = new $root.proto.Section();
            if (object.title != null)
                message.title = String(object.title);
            if (object.rows) {
                if (!Array.isArray(object.rows))
                    throw TypeError(".proto.Section.rows: array expected");
                message.rows = [];
                for (var i = 0; i < object.rows.length; ++i) {
                    if (typeof object.rows[i] !== "object")
                        throw TypeError(".proto.Section.rows: object expected");
                    message.rows[i] = $root.proto.Row.fromObject(object.rows[i]);
                }
            }
            return message;
        };

        /**
         * Creates a plain object from a Section message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.Section
         * @static
         * @param {proto.Section} message Section
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        Section.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.rows = [];
            if (options.defaults)
                object.title = "";
            if (message.title != null && message.hasOwnProperty("title"))
                object.title = message.title;
            if (message.rows && message.rows.length) {
                object.rows = [];
                for (var j = 0; j < message.rows.length; ++j)
                    object.rows[j] = $root.proto.Row.toObject(message.rows[j], options);
            }
            return object;
        };

        /**
         * Converts this Section to JSON.
         * @function toJSON
         * @memberof proto.Section
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        Section.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return Section;
    })();

    proto.Product = (function() {

        /**
         * Properties of a Product.
         * @memberof proto
         * @interface IProduct
         * @property {string|null} [productId] Product productId
         */

        /**
         * Constructs a new Product.
         * @memberof proto
         * @classdesc Represents a Product.
         * @implements IProduct
         * @constructor
         * @param {proto.IProduct=} [properties] Properties to set
         */
        function Product(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Product productId.
         * @member {string} productId
         * @memberof proto.Product
         * @instance
         */
        Product.prototype.productId = "";

        /**
         * Creates a new Product instance using the specified properties.
         * @function create
         * @memberof proto.Product
         * @static
         * @param {proto.IProduct=} [properties] Properties to set
         * @returns {proto.Product} Product instance
         */
        Product.create = function create(properties) {
            return new Product(properties);
        };

        /**
         * Encodes the specified Product message. Does not implicitly {@link proto.Product.verify|verify} messages.
         * @function encode
         * @memberof proto.Product
         * @static
         * @param {proto.IProduct} message Product message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Product.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.productId != null && Object.hasOwnProperty.call(message, "productId"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.productId);
            return writer;
        };

        /**
         * Encodes the specified Product message, length delimited. Does not implicitly {@link proto.Product.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.Product
         * @static
         * @param {proto.IProduct} message Product message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Product.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a Product message from the specified reader or buffer.
         * @function decode
         * @memberof proto.Product
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.Product} Product
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Product.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Product();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.productId = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a Product message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.Product
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.Product} Product
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Product.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a Product message.
         * @function verify
         * @memberof proto.Product
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        Product.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.productId != null && message.hasOwnProperty("productId"))
                if (!$util.isString(message.productId))
                    return "productId: string expected";
            return null;
        };

        /**
         * Creates a Product message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.Product
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.Product} Product
         */
        Product.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.Product)
                return object;
            var message = new $root.proto.Product();
            if (object.productId != null)
                message.productId = String(object.productId);
            return message;
        };

        /**
         * Creates a plain object from a Product message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.Product
         * @static
         * @param {proto.Product} message Product
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        Product.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                object.productId = "";
            if (message.productId != null && message.hasOwnProperty("productId"))
                object.productId = message.productId;
            return object;
        };

        /**
         * Converts this Product to JSON.
         * @function toJSON
         * @memberof proto.Product
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        Product.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return Product;
    })();

    proto.ProductSection = (function() {

        /**
         * Properties of a ProductSection.
         * @memberof proto
         * @interface IProductSection
         * @property {string|null} [title] ProductSection title
         * @property {Array.<proto.IProduct>|null} [products] ProductSection products
         */

        /**
         * Constructs a new ProductSection.
         * @memberof proto
         * @classdesc Represents a ProductSection.
         * @implements IProductSection
         * @constructor
         * @param {proto.IProductSection=} [properties] Properties to set
         */
        function ProductSection(properties) {
            this.products = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ProductSection title.
         * @member {string} title
         * @memberof proto.ProductSection
         * @instance
         */
        ProductSection.prototype.title = "";

        /**
         * ProductSection products.
         * @member {Array.<proto.IProduct>} products
         * @memberof proto.ProductSection
         * @instance
         */
        ProductSection.prototype.products = $util.emptyArray;

        /**
         * Creates a new ProductSection instance using the specified properties.
         * @function create
         * @memberof proto.ProductSection
         * @static
         * @param {proto.IProductSection=} [properties] Properties to set
         * @returns {proto.ProductSection} ProductSection instance
         */
        ProductSection.create = function create(properties) {
            return new ProductSection(properties);
        };

        /**
         * Encodes the specified ProductSection message. Does not implicitly {@link proto.ProductSection.verify|verify} messages.
         * @function encode
         * @memberof proto.ProductSection
         * @static
         * @param {proto.IProductSection} message ProductSection message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ProductSection.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.title != null && Object.hasOwnProperty.call(message, "title"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.title);
            if (message.products != null && message.products.length)
                for (var i = 0; i < message.products.length; ++i)
                    $root.proto.Product.encode(message.products[i], writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified ProductSection message, length delimited. Does not implicitly {@link proto.ProductSection.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ProductSection
         * @static
         * @param {proto.IProductSection} message ProductSection message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ProductSection.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ProductSection message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ProductSection
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ProductSection} ProductSection
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ProductSection.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ProductSection();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.title = reader.string();
                    break;
                case 2:
                    if (!(message.products && message.products.length))
                        message.products = [];
                    message.products.push($root.proto.Product.decode(reader, reader.uint32()));
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ProductSection message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ProductSection
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ProductSection} ProductSection
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ProductSection.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ProductSection message.
         * @function verify
         * @memberof proto.ProductSection
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ProductSection.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.title != null && message.hasOwnProperty("title"))
                if (!$util.isString(message.title))
                    return "title: string expected";
            if (message.products != null && message.hasOwnProperty("products")) {
                if (!Array.isArray(message.products))
                    return "products: array expected";
                for (var i = 0; i < message.products.length; ++i) {
                    var error = $root.proto.Product.verify(message.products[i]);
                    if (error)
                        return "products." + error;
                }
            }
            return null;
        };

        /**
         * Creates a ProductSection message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ProductSection
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ProductSection} ProductSection
         */
        ProductSection.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ProductSection)
                return object;
            var message = new $root.proto.ProductSection();
            if (object.title != null)
                message.title = String(object.title);
            if (object.products) {
                if (!Array.isArray(object.products))
                    throw TypeError(".proto.ProductSection.products: array expected");
                message.products = [];
                for (var i = 0; i < object.products.length; ++i) {
                    if (typeof object.products[i] !== "object")
                        throw TypeError(".proto.ProductSection.products: object expected");
                    message.products[i] = $root.proto.Product.fromObject(object.products[i]);
                }
            }
            return message;
        };

        /**
         * Creates a plain object from a ProductSection message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ProductSection
         * @static
         * @param {proto.ProductSection} message ProductSection
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ProductSection.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.products = [];
            if (options.defaults)
                object.title = "";
            if (message.title != null && message.hasOwnProperty("title"))
                object.title = message.title;
            if (message.products && message.products.length) {
                object.products = [];
                for (var j = 0; j < message.products.length; ++j)
                    object.products[j] = $root.proto.Product.toObject(message.products[j], options);
            }
            return object;
        };

        /**
         * Converts this ProductSection to JSON.
         * @function toJSON
         * @memberof proto.ProductSection
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ProductSection.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ProductSection;
    })();

    proto.ProductListHeaderImage = (function() {

        /**
         * Properties of a ProductListHeaderImage.
         * @memberof proto
         * @interface IProductListHeaderImage
         * @property {string|null} [productId] ProductListHeaderImage productId
         * @property {Uint8Array|null} [jpegThumbnail] ProductListHeaderImage jpegThumbnail
         */

        /**
         * Constructs a new ProductListHeaderImage.
         * @memberof proto
         * @classdesc Represents a ProductListHeaderImage.
         * @implements IProductListHeaderImage
         * @constructor
         * @param {proto.IProductListHeaderImage=} [properties] Properties to set
         */
        function ProductListHeaderImage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ProductListHeaderImage productId.
         * @member {string} productId
         * @memberof proto.ProductListHeaderImage
         * @instance
         */
        ProductListHeaderImage.prototype.productId = "";

        /**
         * ProductListHeaderImage jpegThumbnail.
         * @member {Uint8Array} jpegThumbnail
         * @memberof proto.ProductListHeaderImage
         * @instance
         */
        ProductListHeaderImage.prototype.jpegThumbnail = $util.newBuffer([]);

        /**
         * Creates a new ProductListHeaderImage instance using the specified properties.
         * @function create
         * @memberof proto.ProductListHeaderImage
         * @static
         * @param {proto.IProductListHeaderImage=} [properties] Properties to set
         * @returns {proto.ProductListHeaderImage} ProductListHeaderImage instance
         */
        ProductListHeaderImage.create = function create(properties) {
            return new ProductListHeaderImage(properties);
        };

        /**
         * Encodes the specified ProductListHeaderImage message. Does not implicitly {@link proto.ProductListHeaderImage.verify|verify} messages.
         * @function encode
         * @memberof proto.ProductListHeaderImage
         * @static
         * @param {proto.IProductListHeaderImage} message ProductListHeaderImage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ProductListHeaderImage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.productId != null && Object.hasOwnProperty.call(message, "productId"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.productId);
            if (message.jpegThumbnail != null && Object.hasOwnProperty.call(message, "jpegThumbnail"))
                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.jpegThumbnail);
            return writer;
        };

        /**
         * Encodes the specified ProductListHeaderImage message, length delimited. Does not implicitly {@link proto.ProductListHeaderImage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ProductListHeaderImage
         * @static
         * @param {proto.IProductListHeaderImage} message ProductListHeaderImage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ProductListHeaderImage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ProductListHeaderImage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ProductListHeaderImage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ProductListHeaderImage} ProductListHeaderImage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ProductListHeaderImage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ProductListHeaderImage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.productId = reader.string();
                    break;
                case 2:
                    message.jpegThumbnail = reader.bytes();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ProductListHeaderImage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ProductListHeaderImage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ProductListHeaderImage} ProductListHeaderImage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ProductListHeaderImage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ProductListHeaderImage message.
         * @function verify
         * @memberof proto.ProductListHeaderImage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ProductListHeaderImage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.productId != null && message.hasOwnProperty("productId"))
                if (!$util.isString(message.productId))
                    return "productId: string expected";
            if (message.jpegThumbnail != null && message.hasOwnProperty("jpegThumbnail"))
                if (!(message.jpegThumbnail && typeof message.jpegThumbnail.length === "number" || $util.isString(message.jpegThumbnail)))
                    return "jpegThumbnail: buffer expected";
            return null;
        };

        /**
         * Creates a ProductListHeaderImage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ProductListHeaderImage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ProductListHeaderImage} ProductListHeaderImage
         */
        ProductListHeaderImage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ProductListHeaderImage)
                return object;
            var message = new $root.proto.ProductListHeaderImage();
            if (object.productId != null)
                message.productId = String(object.productId);
            if (object.jpegThumbnail != null)
                if (typeof object.jpegThumbnail === "string")
                    $util.base64.decode(object.jpegThumbnail, message.jpegThumbnail = $util.newBuffer($util.base64.length(object.jpegThumbnail)), 0);
                else if (object.jpegThumbnail.length)
                    message.jpegThumbnail = object.jpegThumbnail;
            return message;
        };

        /**
         * Creates a plain object from a ProductListHeaderImage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ProductListHeaderImage
         * @static
         * @param {proto.ProductListHeaderImage} message ProductListHeaderImage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ProductListHeaderImage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.productId = "";
                if (options.bytes === String)
                    object.jpegThumbnail = "";
                else {
                    object.jpegThumbnail = [];
                    if (options.bytes !== Array)
                        object.jpegThumbnail = $util.newBuffer(object.jpegThumbnail);
                }
            }
            if (message.productId != null && message.hasOwnProperty("productId"))
                object.productId = message.productId;
            if (message.jpegThumbnail != null && message.hasOwnProperty("jpegThumbnail"))
                object.jpegThumbnail = options.bytes === String ? $util.base64.encode(message.jpegThumbnail, 0, message.jpegThumbnail.length) : options.bytes === Array ? Array.prototype.slice.call(message.jpegThumbnail) : message.jpegThumbnail;
            return object;
        };

        /**
         * Converts this ProductListHeaderImage to JSON.
         * @function toJSON
         * @memberof proto.ProductListHeaderImage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ProductListHeaderImage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ProductListHeaderImage;
    })();

    proto.ProductListInfo = (function() {

        /**
         * Properties of a ProductListInfo.
         * @memberof proto
         * @interface IProductListInfo
         * @property {Array.<proto.IProductSection>|null} [productSections] ProductListInfo productSections
         * @property {proto.IProductListHeaderImage|null} [headerImage] ProductListInfo headerImage
         * @property {string|null} [businessOwnerJid] ProductListInfo businessOwnerJid
         */

        /**
         * Constructs a new ProductListInfo.
         * @memberof proto
         * @classdesc Represents a ProductListInfo.
         * @implements IProductListInfo
         * @constructor
         * @param {proto.IProductListInfo=} [properties] Properties to set
         */
        function ProductListInfo(properties) {
            this.productSections = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ProductListInfo productSections.
         * @member {Array.<proto.IProductSection>} productSections
         * @memberof proto.ProductListInfo
         * @instance
         */
        ProductListInfo.prototype.productSections = $util.emptyArray;

        /**
         * ProductListInfo headerImage.
         * @member {proto.IProductListHeaderImage|null|undefined} headerImage
         * @memberof proto.ProductListInfo
         * @instance
         */
        ProductListInfo.prototype.headerImage = null;

        /**
         * ProductListInfo businessOwnerJid.
         * @member {string} businessOwnerJid
         * @memberof proto.ProductListInfo
         * @instance
         */
        ProductListInfo.prototype.businessOwnerJid = "";

        /**
         * Creates a new ProductListInfo instance using the specified properties.
         * @function create
         * @memberof proto.ProductListInfo
         * @static
         * @param {proto.IProductListInfo=} [properties] Properties to set
         * @returns {proto.ProductListInfo} ProductListInfo instance
         */
        ProductListInfo.create = function create(properties) {
            return new ProductListInfo(properties);
        };

        /**
         * Encodes the specified ProductListInfo message. Does not implicitly {@link proto.ProductListInfo.verify|verify} messages.
         * @function encode
         * @memberof proto.ProductListInfo
         * @static
         * @param {proto.IProductListInfo} message ProductListInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ProductListInfo.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.productSections != null && message.productSections.length)
                for (var i = 0; i < message.productSections.length; ++i)
                    $root.proto.ProductSection.encode(message.productSections[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.headerImage != null && Object.hasOwnProperty.call(message, "headerImage"))
                $root.proto.ProductListHeaderImage.encode(message.headerImage, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.businessOwnerJid != null && Object.hasOwnProperty.call(message, "businessOwnerJid"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.businessOwnerJid);
            return writer;
        };

        /**
         * Encodes the specified ProductListInfo message, length delimited. Does not implicitly {@link proto.ProductListInfo.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ProductListInfo
         * @static
         * @param {proto.IProductListInfo} message ProductListInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ProductListInfo.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ProductListInfo message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ProductListInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ProductListInfo} ProductListInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ProductListInfo.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ProductListInfo();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    if (!(message.productSections && message.productSections.length))
                        message.productSections = [];
                    message.productSections.push($root.proto.ProductSection.decode(reader, reader.uint32()));
                    break;
                case 2:
                    message.headerImage = $root.proto.ProductListHeaderImage.decode(reader, reader.uint32());
                    break;
                case 3:
                    message.businessOwnerJid = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ProductListInfo message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ProductListInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ProductListInfo} ProductListInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ProductListInfo.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ProductListInfo message.
         * @function verify
         * @memberof proto.ProductListInfo
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ProductListInfo.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.productSections != null && message.hasOwnProperty("productSections")) {
                if (!Array.isArray(message.productSections))
                    return "productSections: array expected";
                for (var i = 0; i < message.productSections.length; ++i) {
                    var error = $root.proto.ProductSection.verify(message.productSections[i]);
                    if (error)
                        return "productSections." + error;
                }
            }
            if (message.headerImage != null && message.hasOwnProperty("headerImage")) {
                var error = $root.proto.ProductListHeaderImage.verify(message.headerImage);
                if (error)
                    return "headerImage." + error;
            }
            if (message.businessOwnerJid != null && message.hasOwnProperty("businessOwnerJid"))
                if (!$util.isString(message.businessOwnerJid))
                    return "businessOwnerJid: string expected";
            return null;
        };

        /**
         * Creates a ProductListInfo message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ProductListInfo
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ProductListInfo} ProductListInfo
         */
        ProductListInfo.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ProductListInfo)
                return object;
            var message = new $root.proto.ProductListInfo();
            if (object.productSections) {
                if (!Array.isArray(object.productSections))
                    throw TypeError(".proto.ProductListInfo.productSections: array expected");
                message.productSections = [];
                for (var i = 0; i < object.productSections.length; ++i) {
                    if (typeof object.productSections[i] !== "object")
                        throw TypeError(".proto.ProductListInfo.productSections: object expected");
                    message.productSections[i] = $root.proto.ProductSection.fromObject(object.productSections[i]);
                }
            }
            if (object.headerImage != null) {
                if (typeof object.headerImage !== "object")
                    throw TypeError(".proto.ProductListInfo.headerImage: object expected");
                message.headerImage = $root.proto.ProductListHeaderImage.fromObject(object.headerImage);
            }
            if (object.businessOwnerJid != null)
                message.businessOwnerJid = String(object.businessOwnerJid);
            return message;
        };

        /**
         * Creates a plain object from a ProductListInfo message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ProductListInfo
         * @static
         * @param {proto.ProductListInfo} message ProductListInfo
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ProductListInfo.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.productSections = [];
            if (options.defaults) {
                object.headerImage = null;
                object.businessOwnerJid = "";
            }
            if (message.productSections && message.productSections.length) {
                object.productSections = [];
                for (var j = 0; j < message.productSections.length; ++j)
                    object.productSections[j] = $root.proto.ProductSection.toObject(message.productSections[j], options);
            }
            if (message.headerImage != null && message.hasOwnProperty("headerImage"))
                object.headerImage = $root.proto.ProductListHeaderImage.toObject(message.headerImage, options);
            if (message.businessOwnerJid != null && message.hasOwnProperty("businessOwnerJid"))
                object.businessOwnerJid = message.businessOwnerJid;
            return object;
        };

        /**
         * Converts this ProductListInfo to JSON.
         * @function toJSON
         * @memberof proto.ProductListInfo
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ProductListInfo.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ProductListInfo;
    })();

    proto.ListMessage = (function() {

        /**
         * Properties of a ListMessage.
         * @memberof proto
         * @interface IListMessage
         * @property {string|null} [title] ListMessage title
         * @property {string|null} [description] ListMessage description
         * @property {string|null} [buttonText] ListMessage buttonText
         * @property {proto.ListMessage.ListMessageListType|null} [listType] ListMessage listType
         * @property {Array.<proto.ISection>|null} [sections] ListMessage sections
         * @property {proto.IProductListInfo|null} [productListInfo] ListMessage productListInfo
         * @property {string|null} [footerText] ListMessage footerText
         * @property {proto.IContextInfo|null} [contextInfo] ListMessage contextInfo
         */

        /**
         * Constructs a new ListMessage.
         * @memberof proto
         * @classdesc Represents a ListMessage.
         * @implements IListMessage
         * @constructor
         * @param {proto.IListMessage=} [properties] Properties to set
         */
        function ListMessage(properties) {
            this.sections = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ListMessage title.
         * @member {string} title
         * @memberof proto.ListMessage
         * @instance
         */
        ListMessage.prototype.title = "";

        /**
         * ListMessage description.
         * @member {string} description
         * @memberof proto.ListMessage
         * @instance
         */
        ListMessage.prototype.description = "";

        /**
         * ListMessage buttonText.
         * @member {string} buttonText
         * @memberof proto.ListMessage
         * @instance
         */
        ListMessage.prototype.buttonText = "";

        /**
         * ListMessage listType.
         * @member {proto.ListMessage.ListMessageListType} listType
         * @memberof proto.ListMessage
         * @instance
         */
        ListMessage.prototype.listType = 0;

        /**
         * ListMessage sections.
         * @member {Array.<proto.ISection>} sections
         * @memberof proto.ListMessage
         * @instance
         */
        ListMessage.prototype.sections = $util.emptyArray;

        /**
         * ListMessage productListInfo.
         * @member {proto.IProductListInfo|null|undefined} productListInfo
         * @memberof proto.ListMessage
         * @instance
         */
        ListMessage.prototype.productListInfo = null;

        /**
         * ListMessage footerText.
         * @member {string} footerText
         * @memberof proto.ListMessage
         * @instance
         */
        ListMessage.prototype.footerText = "";

        /**
         * ListMessage contextInfo.
         * @member {proto.IContextInfo|null|undefined} contextInfo
         * @memberof proto.ListMessage
         * @instance
         */
        ListMessage.prototype.contextInfo = null;

        /**
         * Creates a new ListMessage instance using the specified properties.
         * @function create
         * @memberof proto.ListMessage
         * @static
         * @param {proto.IListMessage=} [properties] Properties to set
         * @returns {proto.ListMessage} ListMessage instance
         */
        ListMessage.create = function create(properties) {
            return new ListMessage(properties);
        };

        /**
         * Encodes the specified ListMessage message. Does not implicitly {@link proto.ListMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.ListMessage
         * @static
         * @param {proto.IListMessage} message ListMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ListMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.title != null && Object.hasOwnProperty.call(message, "title"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.title);
            if (message.description != null && Object.hasOwnProperty.call(message, "description"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.description);
            if (message.buttonText != null && Object.hasOwnProperty.call(message, "buttonText"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.buttonText);
            if (message.listType != null && Object.hasOwnProperty.call(message, "listType"))
                writer.uint32(/* id 4, wireType 0 =*/32).int32(message.listType);
            if (message.sections != null && message.sections.length)
                for (var i = 0; i < message.sections.length; ++i)
                    $root.proto.Section.encode(message.sections[i], writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim();
            if (message.productListInfo != null && Object.hasOwnProperty.call(message, "productListInfo"))
                $root.proto.ProductListInfo.encode(message.productListInfo, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim();
            if (message.footerText != null && Object.hasOwnProperty.call(message, "footerText"))
                writer.uint32(/* id 7, wireType 2 =*/58).string(message.footerText);
            if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo"))
                $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified ListMessage message, length delimited. Does not implicitly {@link proto.ListMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ListMessage
         * @static
         * @param {proto.IListMessage} message ListMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ListMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ListMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ListMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ListMessage} ListMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ListMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ListMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.title = reader.string();
                    break;
                case 2:
                    message.description = reader.string();
                    break;
                case 3:
                    message.buttonText = reader.string();
                    break;
                case 4:
                    message.listType = reader.int32();
                    break;
                case 5:
                    if (!(message.sections && message.sections.length))
                        message.sections = [];
                    message.sections.push($root.proto.Section.decode(reader, reader.uint32()));
                    break;
                case 6:
                    message.productListInfo = $root.proto.ProductListInfo.decode(reader, reader.uint32());
                    break;
                case 7:
                    message.footerText = reader.string();
                    break;
                case 8:
                    message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ListMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ListMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ListMessage} ListMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ListMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ListMessage message.
         * @function verify
         * @memberof proto.ListMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ListMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.title != null && message.hasOwnProperty("title"))
                if (!$util.isString(message.title))
                    return "title: string expected";
            if (message.description != null && message.hasOwnProperty("description"))
                if (!$util.isString(message.description))
                    return "description: string expected";
            if (message.buttonText != null && message.hasOwnProperty("buttonText"))
                if (!$util.isString(message.buttonText))
                    return "buttonText: string expected";
            if (message.listType != null && message.hasOwnProperty("listType"))
                switch (message.listType) {
                default:
                    return "listType: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            if (message.sections != null && message.hasOwnProperty("sections")) {
                if (!Array.isArray(message.sections))
                    return "sections: array expected";
                for (var i = 0; i < message.sections.length; ++i) {
                    var error = $root.proto.Section.verify(message.sections[i]);
                    if (error)
                        return "sections." + error;
                }
            }
            if (message.productListInfo != null && message.hasOwnProperty("productListInfo")) {
                var error = $root.proto.ProductListInfo.verify(message.productListInfo);
                if (error)
                    return "productListInfo." + error;
            }
            if (message.footerText != null && message.hasOwnProperty("footerText"))
                if (!$util.isString(message.footerText))
                    return "footerText: string expected";
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) {
                var error = $root.proto.ContextInfo.verify(message.contextInfo);
                if (error)
                    return "contextInfo." + error;
            }
            return null;
        };

        /**
         * Creates a ListMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ListMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ListMessage} ListMessage
         */
        ListMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ListMessage)
                return object;
            var message = new $root.proto.ListMessage();
            if (object.title != null)
                message.title = String(object.title);
            if (object.description != null)
                message.description = String(object.description);
            if (object.buttonText != null)
                message.buttonText = String(object.buttonText);
            switch (object.listType) {
            case "UNKNOWN":
            case 0:
                message.listType = 0;
                break;
            case "SINGLE_SELECT":
            case 1:
                message.listType = 1;
                break;
            case "PRODUCT_LIST":
            case 2:
                message.listType = 2;
                break;
            }
            if (object.sections) {
                if (!Array.isArray(object.sections))
                    throw TypeError(".proto.ListMessage.sections: array expected");
                message.sections = [];
                for (var i = 0; i < object.sections.length; ++i) {
                    if (typeof object.sections[i] !== "object")
                        throw TypeError(".proto.ListMessage.sections: object expected");
                    message.sections[i] = $root.proto.Section.fromObject(object.sections[i]);
                }
            }
            if (object.productListInfo != null) {
                if (typeof object.productListInfo !== "object")
                    throw TypeError(".proto.ListMessage.productListInfo: object expected");
                message.productListInfo = $root.proto.ProductListInfo.fromObject(object.productListInfo);
            }
            if (object.footerText != null)
                message.footerText = String(object.footerText);
            if (object.contextInfo != null) {
                if (typeof object.contextInfo !== "object")
                    throw TypeError(".proto.ListMessage.contextInfo: object expected");
                message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo);
            }
            return message;
        };

        /**
         * Creates a plain object from a ListMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ListMessage
         * @static
         * @param {proto.ListMessage} message ListMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ListMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.sections = [];
            if (options.defaults) {
                object.title = "";
                object.description = "";
                object.buttonText = "";
                object.listType = options.enums === String ? "UNKNOWN" : 0;
                object.productListInfo = null;
                object.footerText = "";
                object.contextInfo = null;
            }
            if (message.title != null && message.hasOwnProperty("title"))
                object.title = message.title;
            if (message.description != null && message.hasOwnProperty("description"))
                object.description = message.description;
            if (message.buttonText != null && message.hasOwnProperty("buttonText"))
                object.buttonText = message.buttonText;
            if (message.listType != null && message.hasOwnProperty("listType"))
                object.listType = options.enums === String ? $root.proto.ListMessage.ListMessageListType[message.listType] : message.listType;
            if (message.sections && message.sections.length) {
                object.sections = [];
                for (var j = 0; j < message.sections.length; ++j)
                    object.sections[j] = $root.proto.Section.toObject(message.sections[j], options);
            }
            if (message.productListInfo != null && message.hasOwnProperty("productListInfo"))
                object.productListInfo = $root.proto.ProductListInfo.toObject(message.productListInfo, options);
            if (message.footerText != null && message.hasOwnProperty("footerText"))
                object.footerText = message.footerText;
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo"))
                object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options);
            return object;
        };

        /**
         * Converts this ListMessage to JSON.
         * @function toJSON
         * @memberof proto.ListMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ListMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * ListMessageListType enum.
         * @name proto.ListMessage.ListMessageListType
         * @enum {number}
         * @property {number} UNKNOWN=0 UNKNOWN value
         * @property {number} SINGLE_SELECT=1 SINGLE_SELECT value
         * @property {number} PRODUCT_LIST=2 PRODUCT_LIST value
         */
        ListMessage.ListMessageListType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "UNKNOWN"] = 0;
            values[valuesById[1] = "SINGLE_SELECT"] = 1;
            values[valuesById[2] = "PRODUCT_LIST"] = 2;
            return values;
        })();

        return ListMessage;
    })();

    proto.SingleSelectReply = (function() {

        /**
         * Properties of a SingleSelectReply.
         * @memberof proto
         * @interface ISingleSelectReply
         * @property {string|null} [selectedRowId] SingleSelectReply selectedRowId
         */

        /**
         * Constructs a new SingleSelectReply.
         * @memberof proto
         * @classdesc Represents a SingleSelectReply.
         * @implements ISingleSelectReply
         * @constructor
         * @param {proto.ISingleSelectReply=} [properties] Properties to set
         */
        function SingleSelectReply(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * SingleSelectReply selectedRowId.
         * @member {string} selectedRowId
         * @memberof proto.SingleSelectReply
         * @instance
         */
        SingleSelectReply.prototype.selectedRowId = "";

        /**
         * Creates a new SingleSelectReply instance using the specified properties.
         * @function create
         * @memberof proto.SingleSelectReply
         * @static
         * @param {proto.ISingleSelectReply=} [properties] Properties to set
         * @returns {proto.SingleSelectReply} SingleSelectReply instance
         */
        SingleSelectReply.create = function create(properties) {
            return new SingleSelectReply(properties);
        };

        /**
         * Encodes the specified SingleSelectReply message. Does not implicitly {@link proto.SingleSelectReply.verify|verify} messages.
         * @function encode
         * @memberof proto.SingleSelectReply
         * @static
         * @param {proto.ISingleSelectReply} message SingleSelectReply message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SingleSelectReply.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.selectedRowId != null && Object.hasOwnProperty.call(message, "selectedRowId"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.selectedRowId);
            return writer;
        };

        /**
         * Encodes the specified SingleSelectReply message, length delimited. Does not implicitly {@link proto.SingleSelectReply.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.SingleSelectReply
         * @static
         * @param {proto.ISingleSelectReply} message SingleSelectReply message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        SingleSelectReply.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a SingleSelectReply message from the specified reader or buffer.
         * @function decode
         * @memberof proto.SingleSelectReply
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.SingleSelectReply} SingleSelectReply
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SingleSelectReply.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.SingleSelectReply();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.selectedRowId = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a SingleSelectReply message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.SingleSelectReply
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.SingleSelectReply} SingleSelectReply
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        SingleSelectReply.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a SingleSelectReply message.
         * @function verify
         * @memberof proto.SingleSelectReply
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        SingleSelectReply.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.selectedRowId != null && message.hasOwnProperty("selectedRowId"))
                if (!$util.isString(message.selectedRowId))
                    return "selectedRowId: string expected";
            return null;
        };

        /**
         * Creates a SingleSelectReply message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.SingleSelectReply
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.SingleSelectReply} SingleSelectReply
         */
        SingleSelectReply.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.SingleSelectReply)
                return object;
            var message = new $root.proto.SingleSelectReply();
            if (object.selectedRowId != null)
                message.selectedRowId = String(object.selectedRowId);
            return message;
        };

        /**
         * Creates a plain object from a SingleSelectReply message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.SingleSelectReply
         * @static
         * @param {proto.SingleSelectReply} message SingleSelectReply
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        SingleSelectReply.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                object.selectedRowId = "";
            if (message.selectedRowId != null && message.hasOwnProperty("selectedRowId"))
                object.selectedRowId = message.selectedRowId;
            return object;
        };

        /**
         * Converts this SingleSelectReply to JSON.
         * @function toJSON
         * @memberof proto.SingleSelectReply
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        SingleSelectReply.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return SingleSelectReply;
    })();

    proto.ListResponseMessage = (function() {

        /**
         * Properties of a ListResponseMessage.
         * @memberof proto
         * @interface IListResponseMessage
         * @property {string|null} [title] ListResponseMessage title
         * @property {proto.ListResponseMessage.ListResponseMessageListType|null} [listType] ListResponseMessage listType
         * @property {proto.ISingleSelectReply|null} [singleSelectReply] ListResponseMessage singleSelectReply
         * @property {proto.IContextInfo|null} [contextInfo] ListResponseMessage contextInfo
         * @property {string|null} [description] ListResponseMessage description
         */

        /**
         * Constructs a new ListResponseMessage.
         * @memberof proto
         * @classdesc Represents a ListResponseMessage.
         * @implements IListResponseMessage
         * @constructor
         * @param {proto.IListResponseMessage=} [properties] Properties to set
         */
        function ListResponseMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ListResponseMessage title.
         * @member {string} title
         * @memberof proto.ListResponseMessage
         * @instance
         */
        ListResponseMessage.prototype.title = "";

        /**
         * ListResponseMessage listType.
         * @member {proto.ListResponseMessage.ListResponseMessageListType} listType
         * @memberof proto.ListResponseMessage
         * @instance
         */
        ListResponseMessage.prototype.listType = 0;

        /**
         * ListResponseMessage singleSelectReply.
         * @member {proto.ISingleSelectReply|null|undefined} singleSelectReply
         * @memberof proto.ListResponseMessage
         * @instance
         */
        ListResponseMessage.prototype.singleSelectReply = null;

        /**
         * ListResponseMessage contextInfo.
         * @member {proto.IContextInfo|null|undefined} contextInfo
         * @memberof proto.ListResponseMessage
         * @instance
         */
        ListResponseMessage.prototype.contextInfo = null;

        /**
         * ListResponseMessage description.
         * @member {string} description
         * @memberof proto.ListResponseMessage
         * @instance
         */
        ListResponseMessage.prototype.description = "";

        /**
         * Creates a new ListResponseMessage instance using the specified properties.
         * @function create
         * @memberof proto.ListResponseMessage
         * @static
         * @param {proto.IListResponseMessage=} [properties] Properties to set
         * @returns {proto.ListResponseMessage} ListResponseMessage instance
         */
        ListResponseMessage.create = function create(properties) {
            return new ListResponseMessage(properties);
        };

        /**
         * Encodes the specified ListResponseMessage message. Does not implicitly {@link proto.ListResponseMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.ListResponseMessage
         * @static
         * @param {proto.IListResponseMessage} message ListResponseMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ListResponseMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.title != null && Object.hasOwnProperty.call(message, "title"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.title);
            if (message.listType != null && Object.hasOwnProperty.call(message, "listType"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.listType);
            if (message.singleSelectReply != null && Object.hasOwnProperty.call(message, "singleSelectReply"))
                $root.proto.SingleSelectReply.encode(message.singleSelectReply, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo"))
                $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
            if (message.description != null && Object.hasOwnProperty.call(message, "description"))
                writer.uint32(/* id 5, wireType 2 =*/42).string(message.description);
            return writer;
        };

        /**
         * Encodes the specified ListResponseMessage message, length delimited. Does not implicitly {@link proto.ListResponseMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ListResponseMessage
         * @static
         * @param {proto.IListResponseMessage} message ListResponseMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ListResponseMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ListResponseMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ListResponseMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ListResponseMessage} ListResponseMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ListResponseMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ListResponseMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.title = reader.string();
                    break;
                case 2:
                    message.listType = reader.int32();
                    break;
                case 3:
                    message.singleSelectReply = $root.proto.SingleSelectReply.decode(reader, reader.uint32());
                    break;
                case 4:
                    message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32());
                    break;
                case 5:
                    message.description = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ListResponseMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ListResponseMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ListResponseMessage} ListResponseMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ListResponseMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ListResponseMessage message.
         * @function verify
         * @memberof proto.ListResponseMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ListResponseMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.title != null && message.hasOwnProperty("title"))
                if (!$util.isString(message.title))
                    return "title: string expected";
            if (message.listType != null && message.hasOwnProperty("listType"))
                switch (message.listType) {
                default:
                    return "listType: enum value expected";
                case 0:
                case 1:
                    break;
                }
            if (message.singleSelectReply != null && message.hasOwnProperty("singleSelectReply")) {
                var error = $root.proto.SingleSelectReply.verify(message.singleSelectReply);
                if (error)
                    return "singleSelectReply." + error;
            }
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) {
                var error = $root.proto.ContextInfo.verify(message.contextInfo);
                if (error)
                    return "contextInfo." + error;
            }
            if (message.description != null && message.hasOwnProperty("description"))
                if (!$util.isString(message.description))
                    return "description: string expected";
            return null;
        };

        /**
         * Creates a ListResponseMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ListResponseMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ListResponseMessage} ListResponseMessage
         */
        ListResponseMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ListResponseMessage)
                return object;
            var message = new $root.proto.ListResponseMessage();
            if (object.title != null)
                message.title = String(object.title);
            switch (object.listType) {
            case "UNKNOWN":
            case 0:
                message.listType = 0;
                break;
            case "SINGLE_SELECT":
            case 1:
                message.listType = 1;
                break;
            }
            if (object.singleSelectReply != null) {
                if (typeof object.singleSelectReply !== "object")
                    throw TypeError(".proto.ListResponseMessage.singleSelectReply: object expected");
                message.singleSelectReply = $root.proto.SingleSelectReply.fromObject(object.singleSelectReply);
            }
            if (object.contextInfo != null) {
                if (typeof object.contextInfo !== "object")
                    throw TypeError(".proto.ListResponseMessage.contextInfo: object expected");
                message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo);
            }
            if (object.description != null)
                message.description = String(object.description);
            return message;
        };

        /**
         * Creates a plain object from a ListResponseMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ListResponseMessage
         * @static
         * @param {proto.ListResponseMessage} message ListResponseMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ListResponseMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.title = "";
                object.listType = options.enums === String ? "UNKNOWN" : 0;
                object.singleSelectReply = null;
                object.contextInfo = null;
                object.description = "";
            }
            if (message.title != null && message.hasOwnProperty("title"))
                object.title = message.title;
            if (message.listType != null && message.hasOwnProperty("listType"))
                object.listType = options.enums === String ? $root.proto.ListResponseMessage.ListResponseMessageListType[message.listType] : message.listType;
            if (message.singleSelectReply != null && message.hasOwnProperty("singleSelectReply"))
                object.singleSelectReply = $root.proto.SingleSelectReply.toObject(message.singleSelectReply, options);
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo"))
                object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options);
            if (message.description != null && message.hasOwnProperty("description"))
                object.description = message.description;
            return object;
        };

        /**
         * Converts this ListResponseMessage to JSON.
         * @function toJSON
         * @memberof proto.ListResponseMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ListResponseMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * ListResponseMessageListType enum.
         * @name proto.ListResponseMessage.ListResponseMessageListType
         * @enum {number}
         * @property {number} UNKNOWN=0 UNKNOWN value
         * @property {number} SINGLE_SELECT=1 SINGLE_SELECT value
         */
        ListResponseMessage.ListResponseMessageListType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "UNKNOWN"] = 0;
            values[valuesById[1] = "SINGLE_SELECT"] = 1;
            return values;
        })();

        return ListResponseMessage;
    })();

    proto.Header = (function() {

        /**
         * Properties of a Header.
         * @memberof proto
         * @interface IHeader
         * @property {string|null} [title] Header title
         * @property {string|null} [subtitle] Header subtitle
         * @property {boolean|null} [hasMediaAttachment] Header hasMediaAttachment
         * @property {proto.IDocumentMessage|null} [documentMessage] Header documentMessage
         * @property {proto.IImageMessage|null} [imageMessage] Header imageMessage
         * @property {Uint8Array|null} [jpegThumbnail] Header jpegThumbnail
         * @property {proto.IVideoMessage|null} [videoMessage] Header videoMessage
         */

        /**
         * Constructs a new Header.
         * @memberof proto
         * @classdesc Represents a Header.
         * @implements IHeader
         * @constructor
         * @param {proto.IHeader=} [properties] Properties to set
         */
        function Header(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Header title.
         * @member {string} title
         * @memberof proto.Header
         * @instance
         */
        Header.prototype.title = "";

        /**
         * Header subtitle.
         * @member {string} subtitle
         * @memberof proto.Header
         * @instance
         */
        Header.prototype.subtitle = "";

        /**
         * Header hasMediaAttachment.
         * @member {boolean} hasMediaAttachment
         * @memberof proto.Header
         * @instance
         */
        Header.prototype.hasMediaAttachment = false;

        /**
         * Header documentMessage.
         * @member {proto.IDocumentMessage|null|undefined} documentMessage
         * @memberof proto.Header
         * @instance
         */
        Header.prototype.documentMessage = null;

        /**
         * Header imageMessage.
         * @member {proto.IImageMessage|null|undefined} imageMessage
         * @memberof proto.Header
         * @instance
         */
        Header.prototype.imageMessage = null;

        /**
         * Header jpegThumbnail.
         * @member {Uint8Array|null|undefined} jpegThumbnail
         * @memberof proto.Header
         * @instance
         */
        Header.prototype.jpegThumbnail = null;

        /**
         * Header videoMessage.
         * @member {proto.IVideoMessage|null|undefined} videoMessage
         * @memberof proto.Header
         * @instance
         */
        Header.prototype.videoMessage = null;

        // OneOf field names bound to virtual getters and setters
        var $oneOfFields;

        /**
         * Header media.
         * @member {"documentMessage"|"imageMessage"|"jpegThumbnail"|"videoMessage"|undefined} media
         * @memberof proto.Header
         * @instance
         */
        Object.defineProperty(Header.prototype, "media", {
            get: $util.oneOfGetter($oneOfFields = ["documentMessage", "imageMessage", "jpegThumbnail", "videoMessage"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new Header instance using the specified properties.
         * @function create
         * @memberof proto.Header
         * @static
         * @param {proto.IHeader=} [properties] Properties to set
         * @returns {proto.Header} Header instance
         */
        Header.create = function create(properties) {
            return new Header(properties);
        };

        /**
         * Encodes the specified Header message. Does not implicitly {@link proto.Header.verify|verify} messages.
         * @function encode
         * @memberof proto.Header
         * @static
         * @param {proto.IHeader} message Header message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Header.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.title != null && Object.hasOwnProperty.call(message, "title"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.title);
            if (message.subtitle != null && Object.hasOwnProperty.call(message, "subtitle"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.subtitle);
            if (message.documentMessage != null && Object.hasOwnProperty.call(message, "documentMessage"))
                $root.proto.DocumentMessage.encode(message.documentMessage, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.imageMessage != null && Object.hasOwnProperty.call(message, "imageMessage"))
                $root.proto.ImageMessage.encode(message.imageMessage, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
            if (message.hasMediaAttachment != null && Object.hasOwnProperty.call(message, "hasMediaAttachment"))
                writer.uint32(/* id 5, wireType 0 =*/40).bool(message.hasMediaAttachment);
            if (message.jpegThumbnail != null && Object.hasOwnProperty.call(message, "jpegThumbnail"))
                writer.uint32(/* id 6, wireType 2 =*/50).bytes(message.jpegThumbnail);
            if (message.videoMessage != null && Object.hasOwnProperty.call(message, "videoMessage"))
                $root.proto.VideoMessage.encode(message.videoMessage, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified Header message, length delimited. Does not implicitly {@link proto.Header.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.Header
         * @static
         * @param {proto.IHeader} message Header message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Header.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a Header message from the specified reader or buffer.
         * @function decode
         * @memberof proto.Header
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.Header} Header
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Header.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Header();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.title = reader.string();
                    break;
                case 2:
                    message.subtitle = reader.string();
                    break;
                case 5:
                    message.hasMediaAttachment = reader.bool();
                    break;
                case 3:
                    message.documentMessage = $root.proto.DocumentMessage.decode(reader, reader.uint32());
                    break;
                case 4:
                    message.imageMessage = $root.proto.ImageMessage.decode(reader, reader.uint32());
                    break;
                case 6:
                    message.jpegThumbnail = reader.bytes();
                    break;
                case 7:
                    message.videoMessage = $root.proto.VideoMessage.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a Header message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.Header
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.Header} Header
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Header.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a Header message.
         * @function verify
         * @memberof proto.Header
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        Header.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            var properties = {};
            if (message.title != null && message.hasOwnProperty("title"))
                if (!$util.isString(message.title))
                    return "title: string expected";
            if (message.subtitle != null && message.hasOwnProperty("subtitle"))
                if (!$util.isString(message.subtitle))
                    return "subtitle: string expected";
            if (message.hasMediaAttachment != null && message.hasOwnProperty("hasMediaAttachment"))
                if (typeof message.hasMediaAttachment !== "boolean")
                    return "hasMediaAttachment: boolean expected";
            if (message.documentMessage != null && message.hasOwnProperty("documentMessage")) {
                properties.media = 1;
                {
                    var error = $root.proto.DocumentMessage.verify(message.documentMessage);
                    if (error)
                        return "documentMessage." + error;
                }
            }
            if (message.imageMessage != null && message.hasOwnProperty("imageMessage")) {
                if (properties.media === 1)
                    return "media: multiple values";
                properties.media = 1;
                {
                    var error = $root.proto.ImageMessage.verify(message.imageMessage);
                    if (error)
                        return "imageMessage." + error;
                }
            }
            if (message.jpegThumbnail != null && message.hasOwnProperty("jpegThumbnail")) {
                if (properties.media === 1)
                    return "media: multiple values";
                properties.media = 1;
                if (!(message.jpegThumbnail && typeof message.jpegThumbnail.length === "number" || $util.isString(message.jpegThumbnail)))
                    return "jpegThumbnail: buffer expected";
            }
            if (message.videoMessage != null && message.hasOwnProperty("videoMessage")) {
                if (properties.media === 1)
                    return "media: multiple values";
                properties.media = 1;
                {
                    var error = $root.proto.VideoMessage.verify(message.videoMessage);
                    if (error)
                        return "videoMessage." + error;
                }
            }
            return null;
        };

        /**
         * Creates a Header message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.Header
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.Header} Header
         */
        Header.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.Header)
                return object;
            var message = new $root.proto.Header();
            if (object.title != null)
                message.title = String(object.title);
            if (object.subtitle != null)
                message.subtitle = String(object.subtitle);
            if (object.hasMediaAttachment != null)
                message.hasMediaAttachment = Boolean(object.hasMediaAttachment);
            if (object.documentMessage != null) {
                if (typeof object.documentMessage !== "object")
                    throw TypeError(".proto.Header.documentMessage: object expected");
                message.documentMessage = $root.proto.DocumentMessage.fromObject(object.documentMessage);
            }
            if (object.imageMessage != null) {
                if (typeof object.imageMessage !== "object")
                    throw TypeError(".proto.Header.imageMessage: object expected");
                message.imageMessage = $root.proto.ImageMessage.fromObject(object.imageMessage);
            }
            if (object.jpegThumbnail != null)
                if (typeof object.jpegThumbnail === "string")
                    $util.base64.decode(object.jpegThumbnail, message.jpegThumbnail = $util.newBuffer($util.base64.length(object.jpegThumbnail)), 0);
                else if (object.jpegThumbnail.length)
                    message.jpegThumbnail = object.jpegThumbnail;
            if (object.videoMessage != null) {
                if (typeof object.videoMessage !== "object")
                    throw TypeError(".proto.Header.videoMessage: object expected");
                message.videoMessage = $root.proto.VideoMessage.fromObject(object.videoMessage);
            }
            return message;
        };

        /**
         * Creates a plain object from a Header message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.Header
         * @static
         * @param {proto.Header} message Header
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        Header.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.title = "";
                object.subtitle = "";
                object.hasMediaAttachment = false;
            }
            if (message.title != null && message.hasOwnProperty("title"))
                object.title = message.title;
            if (message.subtitle != null && message.hasOwnProperty("subtitle"))
                object.subtitle = message.subtitle;
            if (message.documentMessage != null && message.hasOwnProperty("documentMessage")) {
                object.documentMessage = $root.proto.DocumentMessage.toObject(message.documentMessage, options);
                if (options.oneofs)
                    object.media = "documentMessage";
            }
            if (message.imageMessage != null && message.hasOwnProperty("imageMessage")) {
                object.imageMessage = $root.proto.ImageMessage.toObject(message.imageMessage, options);
                if (options.oneofs)
                    object.media = "imageMessage";
            }
            if (message.hasMediaAttachment != null && message.hasOwnProperty("hasMediaAttachment"))
                object.hasMediaAttachment = message.hasMediaAttachment;
            if (message.jpegThumbnail != null && message.hasOwnProperty("jpegThumbnail")) {
                object.jpegThumbnail = options.bytes === String ? $util.base64.encode(message.jpegThumbnail, 0, message.jpegThumbnail.length) : options.bytes === Array ? Array.prototype.slice.call(message.jpegThumbnail) : message.jpegThumbnail;
                if (options.oneofs)
                    object.media = "jpegThumbnail";
            }
            if (message.videoMessage != null && message.hasOwnProperty("videoMessage")) {
                object.videoMessage = $root.proto.VideoMessage.toObject(message.videoMessage, options);
                if (options.oneofs)
                    object.media = "videoMessage";
            }
            return object;
        };

        /**
         * Converts this Header to JSON.
         * @function toJSON
         * @memberof proto.Header
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        Header.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return Header;
    })();

    proto.Body = (function() {

        /**
         * Properties of a Body.
         * @memberof proto
         * @interface IBody
         * @property {string|null} [text] Body text
         */

        /**
         * Constructs a new Body.
         * @memberof proto
         * @classdesc Represents a Body.
         * @implements IBody
         * @constructor
         * @param {proto.IBody=} [properties] Properties to set
         */
        function Body(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Body text.
         * @member {string} text
         * @memberof proto.Body
         * @instance
         */
        Body.prototype.text = "";

        /**
         * Creates a new Body instance using the specified properties.
         * @function create
         * @memberof proto.Body
         * @static
         * @param {proto.IBody=} [properties] Properties to set
         * @returns {proto.Body} Body instance
         */
        Body.create = function create(properties) {
            return new Body(properties);
        };

        /**
         * Encodes the specified Body message. Does not implicitly {@link proto.Body.verify|verify} messages.
         * @function encode
         * @memberof proto.Body
         * @static
         * @param {proto.IBody} message Body message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Body.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.text != null && Object.hasOwnProperty.call(message, "text"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.text);
            return writer;
        };

        /**
         * Encodes the specified Body message, length delimited. Does not implicitly {@link proto.Body.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.Body
         * @static
         * @param {proto.IBody} message Body message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Body.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a Body message from the specified reader or buffer.
         * @function decode
         * @memberof proto.Body
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.Body} Body
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Body.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Body();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.text = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a Body message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.Body
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.Body} Body
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Body.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a Body message.
         * @function verify
         * @memberof proto.Body
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        Body.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.text != null && message.hasOwnProperty("text"))
                if (!$util.isString(message.text))
                    return "text: string expected";
            return null;
        };

        /**
         * Creates a Body message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.Body
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.Body} Body
         */
        Body.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.Body)
                return object;
            var message = new $root.proto.Body();
            if (object.text != null)
                message.text = String(object.text);
            return message;
        };

        /**
         * Creates a plain object from a Body message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.Body
         * @static
         * @param {proto.Body} message Body
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        Body.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                object.text = "";
            if (message.text != null && message.hasOwnProperty("text"))
                object.text = message.text;
            return object;
        };

        /**
         * Converts this Body to JSON.
         * @function toJSON
         * @memberof proto.Body
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        Body.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return Body;
    })();

    proto.Footer = (function() {

        /**
         * Properties of a Footer.
         * @memberof proto
         * @interface IFooter
         * @property {string|null} [text] Footer text
         */

        /**
         * Constructs a new Footer.
         * @memberof proto
         * @classdesc Represents a Footer.
         * @implements IFooter
         * @constructor
         * @param {proto.IFooter=} [properties] Properties to set
         */
        function Footer(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Footer text.
         * @member {string} text
         * @memberof proto.Footer
         * @instance
         */
        Footer.prototype.text = "";

        /**
         * Creates a new Footer instance using the specified properties.
         * @function create
         * @memberof proto.Footer
         * @static
         * @param {proto.IFooter=} [properties] Properties to set
         * @returns {proto.Footer} Footer instance
         */
        Footer.create = function create(properties) {
            return new Footer(properties);
        };

        /**
         * Encodes the specified Footer message. Does not implicitly {@link proto.Footer.verify|verify} messages.
         * @function encode
         * @memberof proto.Footer
         * @static
         * @param {proto.IFooter} message Footer message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Footer.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.text != null && Object.hasOwnProperty.call(message, "text"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.text);
            return writer;
        };

        /**
         * Encodes the specified Footer message, length delimited. Does not implicitly {@link proto.Footer.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.Footer
         * @static
         * @param {proto.IFooter} message Footer message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Footer.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a Footer message from the specified reader or buffer.
         * @function decode
         * @memberof proto.Footer
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.Footer} Footer
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Footer.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Footer();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.text = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a Footer message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.Footer
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.Footer} Footer
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Footer.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a Footer message.
         * @function verify
         * @memberof proto.Footer
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        Footer.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.text != null && message.hasOwnProperty("text"))
                if (!$util.isString(message.text))
                    return "text: string expected";
            return null;
        };

        /**
         * Creates a Footer message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.Footer
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.Footer} Footer
         */
        Footer.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.Footer)
                return object;
            var message = new $root.proto.Footer();
            if (object.text != null)
                message.text = String(object.text);
            return message;
        };

        /**
         * Creates a plain object from a Footer message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.Footer
         * @static
         * @param {proto.Footer} message Footer
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        Footer.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                object.text = "";
            if (message.text != null && message.hasOwnProperty("text"))
                object.text = message.text;
            return object;
        };

        /**
         * Converts this Footer to JSON.
         * @function toJSON
         * @memberof proto.Footer
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        Footer.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return Footer;
    })();

    proto.ShopMessage = (function() {

        /**
         * Properties of a ShopMessage.
         * @memberof proto
         * @interface IShopMessage
         * @property {string|null} [id] ShopMessage id
         * @property {proto.ShopMessage.ShopMessageSurface|null} [surface] ShopMessage surface
         * @property {number|null} [messageVersion] ShopMessage messageVersion
         */

        /**
         * Constructs a new ShopMessage.
         * @memberof proto
         * @classdesc Represents a ShopMessage.
         * @implements IShopMessage
         * @constructor
         * @param {proto.IShopMessage=} [properties] Properties to set
         */
        function ShopMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ShopMessage id.
         * @member {string} id
         * @memberof proto.ShopMessage
         * @instance
         */
        ShopMessage.prototype.id = "";

        /**
         * ShopMessage surface.
         * @member {proto.ShopMessage.ShopMessageSurface} surface
         * @memberof proto.ShopMessage
         * @instance
         */
        ShopMessage.prototype.surface = 0;

        /**
         * ShopMessage messageVersion.
         * @member {number} messageVersion
         * @memberof proto.ShopMessage
         * @instance
         */
        ShopMessage.prototype.messageVersion = 0;

        /**
         * Creates a new ShopMessage instance using the specified properties.
         * @function create
         * @memberof proto.ShopMessage
         * @static
         * @param {proto.IShopMessage=} [properties] Properties to set
         * @returns {proto.ShopMessage} ShopMessage instance
         */
        ShopMessage.create = function create(properties) {
            return new ShopMessage(properties);
        };

        /**
         * Encodes the specified ShopMessage message. Does not implicitly {@link proto.ShopMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.ShopMessage
         * @static
         * @param {proto.IShopMessage} message ShopMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ShopMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.id);
            if (message.surface != null && Object.hasOwnProperty.call(message, "surface"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.surface);
            if (message.messageVersion != null && Object.hasOwnProperty.call(message, "messageVersion"))
                writer.uint32(/* id 3, wireType 0 =*/24).int32(message.messageVersion);
            return writer;
        };

        /**
         * Encodes the specified ShopMessage message, length delimited. Does not implicitly {@link proto.ShopMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ShopMessage
         * @static
         * @param {proto.IShopMessage} message ShopMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ShopMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ShopMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ShopMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ShopMessage} ShopMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ShopMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ShopMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.id = reader.string();
                    break;
                case 2:
                    message.surface = reader.int32();
                    break;
                case 3:
                    message.messageVersion = reader.int32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ShopMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ShopMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ShopMessage} ShopMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ShopMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ShopMessage message.
         * @function verify
         * @memberof proto.ShopMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ShopMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isString(message.id))
                    return "id: string expected";
            if (message.surface != null && message.hasOwnProperty("surface"))
                switch (message.surface) {
                default:
                    return "surface: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.messageVersion != null && message.hasOwnProperty("messageVersion"))
                if (!$util.isInteger(message.messageVersion))
                    return "messageVersion: integer expected";
            return null;
        };

        /**
         * Creates a ShopMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ShopMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ShopMessage} ShopMessage
         */
        ShopMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ShopMessage)
                return object;
            var message = new $root.proto.ShopMessage();
            if (object.id != null)
                message.id = String(object.id);
            switch (object.surface) {
            case "UNKNOWN_SURFACE":
            case 0:
                message.surface = 0;
                break;
            case "FB":
            case 1:
                message.surface = 1;
                break;
            case "IG":
            case 2:
                message.surface = 2;
                break;
            case "WA":
            case 3:
                message.surface = 3;
                break;
            }
            if (object.messageVersion != null)
                message.messageVersion = object.messageVersion | 0;
            return message;
        };

        /**
         * Creates a plain object from a ShopMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ShopMessage
         * @static
         * @param {proto.ShopMessage} message ShopMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ShopMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.id = "";
                object.surface = options.enums === String ? "UNKNOWN_SURFACE" : 0;
                object.messageVersion = 0;
            }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.surface != null && message.hasOwnProperty("surface"))
                object.surface = options.enums === String ? $root.proto.ShopMessage.ShopMessageSurface[message.surface] : message.surface;
            if (message.messageVersion != null && message.hasOwnProperty("messageVersion"))
                object.messageVersion = message.messageVersion;
            return object;
        };

        /**
         * Converts this ShopMessage to JSON.
         * @function toJSON
         * @memberof proto.ShopMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ShopMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * ShopMessageSurface enum.
         * @name proto.ShopMessage.ShopMessageSurface
         * @enum {number}
         * @property {number} UNKNOWN_SURFACE=0 UNKNOWN_SURFACE value
         * @property {number} FB=1 FB value
         * @property {number} IG=2 IG value
         * @property {number} WA=3 WA value
         */
        ShopMessage.ShopMessageSurface = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "UNKNOWN_SURFACE"] = 0;
            values[valuesById[1] = "FB"] = 1;
            values[valuesById[2] = "IG"] = 2;
            values[valuesById[3] = "WA"] = 3;
            return values;
        })();

        return ShopMessage;
    })();

    proto.CollectionMessage = (function() {

        /**
         * Properties of a CollectionMessage.
         * @memberof proto
         * @interface ICollectionMessage
         * @property {string|null} [bizJid] CollectionMessage bizJid
         * @property {string|null} [id] CollectionMessage id
         * @property {number|null} [messageVersion] CollectionMessage messageVersion
         */

        /**
         * Constructs a new CollectionMessage.
         * @memberof proto
         * @classdesc Represents a CollectionMessage.
         * @implements ICollectionMessage
         * @constructor
         * @param {proto.ICollectionMessage=} [properties] Properties to set
         */
        function CollectionMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * CollectionMessage bizJid.
         * @member {string} bizJid
         * @memberof proto.CollectionMessage
         * @instance
         */
        CollectionMessage.prototype.bizJid = "";

        /**
         * CollectionMessage id.
         * @member {string} id
         * @memberof proto.CollectionMessage
         * @instance
         */
        CollectionMessage.prototype.id = "";

        /**
         * CollectionMessage messageVersion.
         * @member {number} messageVersion
         * @memberof proto.CollectionMessage
         * @instance
         */
        CollectionMessage.prototype.messageVersion = 0;

        /**
         * Creates a new CollectionMessage instance using the specified properties.
         * @function create
         * @memberof proto.CollectionMessage
         * @static
         * @param {proto.ICollectionMessage=} [properties] Properties to set
         * @returns {proto.CollectionMessage} CollectionMessage instance
         */
        CollectionMessage.create = function create(properties) {
            return new CollectionMessage(properties);
        };

        /**
         * Encodes the specified CollectionMessage message. Does not implicitly {@link proto.CollectionMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.CollectionMessage
         * @static
         * @param {proto.ICollectionMessage} message CollectionMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CollectionMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.bizJid != null && Object.hasOwnProperty.call(message, "bizJid"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.bizJid);
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.id);
            if (message.messageVersion != null && Object.hasOwnProperty.call(message, "messageVersion"))
                writer.uint32(/* id 3, wireType 0 =*/24).int32(message.messageVersion);
            return writer;
        };

        /**
         * Encodes the specified CollectionMessage message, length delimited. Does not implicitly {@link proto.CollectionMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.CollectionMessage
         * @static
         * @param {proto.ICollectionMessage} message CollectionMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CollectionMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a CollectionMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.CollectionMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.CollectionMessage} CollectionMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CollectionMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.CollectionMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.bizJid = reader.string();
                    break;
                case 2:
                    message.id = reader.string();
                    break;
                case 3:
                    message.messageVersion = reader.int32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a CollectionMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.CollectionMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.CollectionMessage} CollectionMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CollectionMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a CollectionMessage message.
         * @function verify
         * @memberof proto.CollectionMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        CollectionMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.bizJid != null && message.hasOwnProperty("bizJid"))
                if (!$util.isString(message.bizJid))
                    return "bizJid: string expected";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isString(message.id))
                    return "id: string expected";
            if (message.messageVersion != null && message.hasOwnProperty("messageVersion"))
                if (!$util.isInteger(message.messageVersion))
                    return "messageVersion: integer expected";
            return null;
        };

        /**
         * Creates a CollectionMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.CollectionMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.CollectionMessage} CollectionMessage
         */
        CollectionMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.CollectionMessage)
                return object;
            var message = new $root.proto.CollectionMessage();
            if (object.bizJid != null)
                message.bizJid = String(object.bizJid);
            if (object.id != null)
                message.id = String(object.id);
            if (object.messageVersion != null)
                message.messageVersion = object.messageVersion | 0;
            return message;
        };

        /**
         * Creates a plain object from a CollectionMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.CollectionMessage
         * @static
         * @param {proto.CollectionMessage} message CollectionMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        CollectionMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.bizJid = "";
                object.id = "";
                object.messageVersion = 0;
            }
            if (message.bizJid != null && message.hasOwnProperty("bizJid"))
                object.bizJid = message.bizJid;
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.messageVersion != null && message.hasOwnProperty("messageVersion"))
                object.messageVersion = message.messageVersion;
            return object;
        };

        /**
         * Converts this CollectionMessage to JSON.
         * @function toJSON
         * @memberof proto.CollectionMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        CollectionMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return CollectionMessage;
    })();

    proto.NativeFlowButton = (function() {

        /**
         * Properties of a NativeFlowButton.
         * @memberof proto
         * @interface INativeFlowButton
         * @property {string|null} [name] NativeFlowButton name
         * @property {string|null} [buttonParamsJson] NativeFlowButton buttonParamsJson
         */

        /**
         * Constructs a new NativeFlowButton.
         * @memberof proto
         * @classdesc Represents a NativeFlowButton.
         * @implements INativeFlowButton
         * @constructor
         * @param {proto.INativeFlowButton=} [properties] Properties to set
         */
        function NativeFlowButton(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * NativeFlowButton name.
         * @member {string} name
         * @memberof proto.NativeFlowButton
         * @instance
         */
        NativeFlowButton.prototype.name = "";

        /**
         * NativeFlowButton buttonParamsJson.
         * @member {string} buttonParamsJson
         * @memberof proto.NativeFlowButton
         * @instance
         */
        NativeFlowButton.prototype.buttonParamsJson = "";

        /**
         * Creates a new NativeFlowButton instance using the specified properties.
         * @function create
         * @memberof proto.NativeFlowButton
         * @static
         * @param {proto.INativeFlowButton=} [properties] Properties to set
         * @returns {proto.NativeFlowButton} NativeFlowButton instance
         */
        NativeFlowButton.create = function create(properties) {
            return new NativeFlowButton(properties);
        };

        /**
         * Encodes the specified NativeFlowButton message. Does not implicitly {@link proto.NativeFlowButton.verify|verify} messages.
         * @function encode
         * @memberof proto.NativeFlowButton
         * @static
         * @param {proto.INativeFlowButton} message NativeFlowButton message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        NativeFlowButton.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.name != null && Object.hasOwnProperty.call(message, "name"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.name);
            if (message.buttonParamsJson != null && Object.hasOwnProperty.call(message, "buttonParamsJson"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.buttonParamsJson);
            return writer;
        };

        /**
         * Encodes the specified NativeFlowButton message, length delimited. Does not implicitly {@link proto.NativeFlowButton.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.NativeFlowButton
         * @static
         * @param {proto.INativeFlowButton} message NativeFlowButton message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        NativeFlowButton.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a NativeFlowButton message from the specified reader or buffer.
         * @function decode
         * @memberof proto.NativeFlowButton
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.NativeFlowButton} NativeFlowButton
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        NativeFlowButton.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.NativeFlowButton();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.name = reader.string();
                    break;
                case 2:
                    message.buttonParamsJson = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a NativeFlowButton message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.NativeFlowButton
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.NativeFlowButton} NativeFlowButton
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        NativeFlowButton.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a NativeFlowButton message.
         * @function verify
         * @memberof proto.NativeFlowButton
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        NativeFlowButton.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.name != null && message.hasOwnProperty("name"))
                if (!$util.isString(message.name))
                    return "name: string expected";
            if (message.buttonParamsJson != null && message.hasOwnProperty("buttonParamsJson"))
                if (!$util.isString(message.buttonParamsJson))
                    return "buttonParamsJson: string expected";
            return null;
        };

        /**
         * Creates a NativeFlowButton message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.NativeFlowButton
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.NativeFlowButton} NativeFlowButton
         */
        NativeFlowButton.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.NativeFlowButton)
                return object;
            var message = new $root.proto.NativeFlowButton();
            if (object.name != null)
                message.name = String(object.name);
            if (object.buttonParamsJson != null)
                message.buttonParamsJson = String(object.buttonParamsJson);
            return message;
        };

        /**
         * Creates a plain object from a NativeFlowButton message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.NativeFlowButton
         * @static
         * @param {proto.NativeFlowButton} message NativeFlowButton
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        NativeFlowButton.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.name = "";
                object.buttonParamsJson = "";
            }
            if (message.name != null && message.hasOwnProperty("name"))
                object.name = message.name;
            if (message.buttonParamsJson != null && message.hasOwnProperty("buttonParamsJson"))
                object.buttonParamsJson = message.buttonParamsJson;
            return object;
        };

        /**
         * Converts this NativeFlowButton to JSON.
         * @function toJSON
         * @memberof proto.NativeFlowButton
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        NativeFlowButton.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return NativeFlowButton;
    })();

    proto.NativeFlowMessage = (function() {

        /**
         * Properties of a NativeFlowMessage.
         * @memberof proto
         * @interface INativeFlowMessage
         * @property {Array.<proto.INativeFlowButton>|null} [buttons] NativeFlowMessage buttons
         * @property {string|null} [messageParamsJson] NativeFlowMessage messageParamsJson
         * @property {number|null} [messageVersion] NativeFlowMessage messageVersion
         */

        /**
         * Constructs a new NativeFlowMessage.
         * @memberof proto
         * @classdesc Represents a NativeFlowMessage.
         * @implements INativeFlowMessage
         * @constructor
         * @param {proto.INativeFlowMessage=} [properties] Properties to set
         */
        function NativeFlowMessage(properties) {
            this.buttons = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * NativeFlowMessage buttons.
         * @member {Array.<proto.INativeFlowButton>} buttons
         * @memberof proto.NativeFlowMessage
         * @instance
         */
        NativeFlowMessage.prototype.buttons = $util.emptyArray;

        /**
         * NativeFlowMessage messageParamsJson.
         * @member {string} messageParamsJson
         * @memberof proto.NativeFlowMessage
         * @instance
         */
        NativeFlowMessage.prototype.messageParamsJson = "";

        /**
         * NativeFlowMessage messageVersion.
         * @member {number} messageVersion
         * @memberof proto.NativeFlowMessage
         * @instance
         */
        NativeFlowMessage.prototype.messageVersion = 0;

        /**
         * Creates a new NativeFlowMessage instance using the specified properties.
         * @function create
         * @memberof proto.NativeFlowMessage
         * @static
         * @param {proto.INativeFlowMessage=} [properties] Properties to set
         * @returns {proto.NativeFlowMessage} NativeFlowMessage instance
         */
        NativeFlowMessage.create = function create(properties) {
            return new NativeFlowMessage(properties);
        };

        /**
         * Encodes the specified NativeFlowMessage message. Does not implicitly {@link proto.NativeFlowMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.NativeFlowMessage
         * @static
         * @param {proto.INativeFlowMessage} message NativeFlowMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        NativeFlowMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.buttons != null && message.buttons.length)
                for (var i = 0; i < message.buttons.length; ++i)
                    $root.proto.NativeFlowButton.encode(message.buttons[i], writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.messageParamsJson != null && Object.hasOwnProperty.call(message, "messageParamsJson"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.messageParamsJson);
            if (message.messageVersion != null && Object.hasOwnProperty.call(message, "messageVersion"))
                writer.uint32(/* id 3, wireType 0 =*/24).int32(message.messageVersion);
            return writer;
        };

        /**
         * Encodes the specified NativeFlowMessage message, length delimited. Does not implicitly {@link proto.NativeFlowMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.NativeFlowMessage
         * @static
         * @param {proto.INativeFlowMessage} message NativeFlowMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        NativeFlowMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a NativeFlowMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.NativeFlowMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.NativeFlowMessage} NativeFlowMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        NativeFlowMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.NativeFlowMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    if (!(message.buttons && message.buttons.length))
                        message.buttons = [];
                    message.buttons.push($root.proto.NativeFlowButton.decode(reader, reader.uint32()));
                    break;
                case 2:
                    message.messageParamsJson = reader.string();
                    break;
                case 3:
                    message.messageVersion = reader.int32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a NativeFlowMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.NativeFlowMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.NativeFlowMessage} NativeFlowMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        NativeFlowMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a NativeFlowMessage message.
         * @function verify
         * @memberof proto.NativeFlowMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        NativeFlowMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.buttons != null && message.hasOwnProperty("buttons")) {
                if (!Array.isArray(message.buttons))
                    return "buttons: array expected";
                for (var i = 0; i < message.buttons.length; ++i) {
                    var error = $root.proto.NativeFlowButton.verify(message.buttons[i]);
                    if (error)
                        return "buttons." + error;
                }
            }
            if (message.messageParamsJson != null && message.hasOwnProperty("messageParamsJson"))
                if (!$util.isString(message.messageParamsJson))
                    return "messageParamsJson: string expected";
            if (message.messageVersion != null && message.hasOwnProperty("messageVersion"))
                if (!$util.isInteger(message.messageVersion))
                    return "messageVersion: integer expected";
            return null;
        };

        /**
         * Creates a NativeFlowMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.NativeFlowMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.NativeFlowMessage} NativeFlowMessage
         */
        NativeFlowMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.NativeFlowMessage)
                return object;
            var message = new $root.proto.NativeFlowMessage();
            if (object.buttons) {
                if (!Array.isArray(object.buttons))
                    throw TypeError(".proto.NativeFlowMessage.buttons: array expected");
                message.buttons = [];
                for (var i = 0; i < object.buttons.length; ++i) {
                    if (typeof object.buttons[i] !== "object")
                        throw TypeError(".proto.NativeFlowMessage.buttons: object expected");
                    message.buttons[i] = $root.proto.NativeFlowButton.fromObject(object.buttons[i]);
                }
            }
            if (object.messageParamsJson != null)
                message.messageParamsJson = String(object.messageParamsJson);
            if (object.messageVersion != null)
                message.messageVersion = object.messageVersion | 0;
            return message;
        };

        /**
         * Creates a plain object from a NativeFlowMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.NativeFlowMessage
         * @static
         * @param {proto.NativeFlowMessage} message NativeFlowMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        NativeFlowMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.buttons = [];
            if (options.defaults) {
                object.messageParamsJson = "";
                object.messageVersion = 0;
            }
            if (message.buttons && message.buttons.length) {
                object.buttons = [];
                for (var j = 0; j < message.buttons.length; ++j)
                    object.buttons[j] = $root.proto.NativeFlowButton.toObject(message.buttons[j], options);
            }
            if (message.messageParamsJson != null && message.hasOwnProperty("messageParamsJson"))
                object.messageParamsJson = message.messageParamsJson;
            if (message.messageVersion != null && message.hasOwnProperty("messageVersion"))
                object.messageVersion = message.messageVersion;
            return object;
        };

        /**
         * Converts this NativeFlowMessage to JSON.
         * @function toJSON
         * @memberof proto.NativeFlowMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        NativeFlowMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return NativeFlowMessage;
    })();

    proto.InteractiveMessage = (function() {

        /**
         * Properties of an InteractiveMessage.
         * @memberof proto
         * @interface IInteractiveMessage
         * @property {proto.IHeader|null} [header] InteractiveMessage header
         * @property {proto.IBody|null} [body] InteractiveMessage body
         * @property {proto.IFooter|null} [footer] InteractiveMessage footer
         * @property {proto.IContextInfo|null} [contextInfo] InteractiveMessage contextInfo
         * @property {proto.IShopMessage|null} [shopStorefrontMessage] InteractiveMessage shopStorefrontMessage
         * @property {proto.ICollectionMessage|null} [collectionMessage] InteractiveMessage collectionMessage
         * @property {proto.INativeFlowMessage|null} [nativeFlowMessage] InteractiveMessage nativeFlowMessage
         */

        /**
         * Constructs a new InteractiveMessage.
         * @memberof proto
         * @classdesc Represents an InteractiveMessage.
         * @implements IInteractiveMessage
         * @constructor
         * @param {proto.IInteractiveMessage=} [properties] Properties to set
         */
        function InteractiveMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * InteractiveMessage header.
         * @member {proto.IHeader|null|undefined} header
         * @memberof proto.InteractiveMessage
         * @instance
         */
        InteractiveMessage.prototype.header = null;

        /**
         * InteractiveMessage body.
         * @member {proto.IBody|null|undefined} body
         * @memberof proto.InteractiveMessage
         * @instance
         */
        InteractiveMessage.prototype.body = null;

        /**
         * InteractiveMessage footer.
         * @member {proto.IFooter|null|undefined} footer
         * @memberof proto.InteractiveMessage
         * @instance
         */
        InteractiveMessage.prototype.footer = null;

        /**
         * InteractiveMessage contextInfo.
         * @member {proto.IContextInfo|null|undefined} contextInfo
         * @memberof proto.InteractiveMessage
         * @instance
         */
        InteractiveMessage.prototype.contextInfo = null;

        /**
         * InteractiveMessage shopStorefrontMessage.
         * @member {proto.IShopMessage|null|undefined} shopStorefrontMessage
         * @memberof proto.InteractiveMessage
         * @instance
         */
        InteractiveMessage.prototype.shopStorefrontMessage = null;

        /**
         * InteractiveMessage collectionMessage.
         * @member {proto.ICollectionMessage|null|undefined} collectionMessage
         * @memberof proto.InteractiveMessage
         * @instance
         */
        InteractiveMessage.prototype.collectionMessage = null;

        /**
         * InteractiveMessage nativeFlowMessage.
         * @member {proto.INativeFlowMessage|null|undefined} nativeFlowMessage
         * @memberof proto.InteractiveMessage
         * @instance
         */
        InteractiveMessage.prototype.nativeFlowMessage = null;

        // OneOf field names bound to virtual getters and setters
        var $oneOfFields;

        /**
         * InteractiveMessage interactiveMessage.
         * @member {"shopStorefrontMessage"|"collectionMessage"|"nativeFlowMessage"|undefined} interactiveMessage
         * @memberof proto.InteractiveMessage
         * @instance
         */
        Object.defineProperty(InteractiveMessage.prototype, "interactiveMessage", {
            get: $util.oneOfGetter($oneOfFields = ["shopStorefrontMessage", "collectionMessage", "nativeFlowMessage"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new InteractiveMessage instance using the specified properties.
         * @function create
         * @memberof proto.InteractiveMessage
         * @static
         * @param {proto.IInteractiveMessage=} [properties] Properties to set
         * @returns {proto.InteractiveMessage} InteractiveMessage instance
         */
        InteractiveMessage.create = function create(properties) {
            return new InteractiveMessage(properties);
        };

        /**
         * Encodes the specified InteractiveMessage message. Does not implicitly {@link proto.InteractiveMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.InteractiveMessage
         * @static
         * @param {proto.IInteractiveMessage} message InteractiveMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        InteractiveMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.header != null && Object.hasOwnProperty.call(message, "header"))
                $root.proto.Header.encode(message.header, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.body != null && Object.hasOwnProperty.call(message, "body"))
                $root.proto.Body.encode(message.body, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.footer != null && Object.hasOwnProperty.call(message, "footer"))
                $root.proto.Footer.encode(message.footer, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.shopStorefrontMessage != null && Object.hasOwnProperty.call(message, "shopStorefrontMessage"))
                $root.proto.ShopMessage.encode(message.shopStorefrontMessage, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
            if (message.collectionMessage != null && Object.hasOwnProperty.call(message, "collectionMessage"))
                $root.proto.CollectionMessage.encode(message.collectionMessage, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim();
            if (message.nativeFlowMessage != null && Object.hasOwnProperty.call(message, "nativeFlowMessage"))
                $root.proto.NativeFlowMessage.encode(message.nativeFlowMessage, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim();
            if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo"))
                $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 15, wireType 2 =*/122).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified InteractiveMessage message, length delimited. Does not implicitly {@link proto.InteractiveMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.InteractiveMessage
         * @static
         * @param {proto.IInteractiveMessage} message InteractiveMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        InteractiveMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an InteractiveMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.InteractiveMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.InteractiveMessage} InteractiveMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        InteractiveMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.InteractiveMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.header = $root.proto.Header.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.body = $root.proto.Body.decode(reader, reader.uint32());
                    break;
                case 3:
                    message.footer = $root.proto.Footer.decode(reader, reader.uint32());
                    break;
                case 15:
                    message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32());
                    break;
                case 4:
                    message.shopStorefrontMessage = $root.proto.ShopMessage.decode(reader, reader.uint32());
                    break;
                case 5:
                    message.collectionMessage = $root.proto.CollectionMessage.decode(reader, reader.uint32());
                    break;
                case 6:
                    message.nativeFlowMessage = $root.proto.NativeFlowMessage.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an InteractiveMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.InteractiveMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.InteractiveMessage} InteractiveMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        InteractiveMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an InteractiveMessage message.
         * @function verify
         * @memberof proto.InteractiveMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        InteractiveMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            var properties = {};
            if (message.header != null && message.hasOwnProperty("header")) {
                var error = $root.proto.Header.verify(message.header);
                if (error)
                    return "header." + error;
            }
            if (message.body != null && message.hasOwnProperty("body")) {
                var error = $root.proto.Body.verify(message.body);
                if (error)
                    return "body." + error;
            }
            if (message.footer != null && message.hasOwnProperty("footer")) {
                var error = $root.proto.Footer.verify(message.footer);
                if (error)
                    return "footer." + error;
            }
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) {
                var error = $root.proto.ContextInfo.verify(message.contextInfo);
                if (error)
                    return "contextInfo." + error;
            }
            if (message.shopStorefrontMessage != null && message.hasOwnProperty("shopStorefrontMessage")) {
                properties.interactiveMessage = 1;
                {
                    var error = $root.proto.ShopMessage.verify(message.shopStorefrontMessage);
                    if (error)
                        return "shopStorefrontMessage." + error;
                }
            }
            if (message.collectionMessage != null && message.hasOwnProperty("collectionMessage")) {
                if (properties.interactiveMessage === 1)
                    return "interactiveMessage: multiple values";
                properties.interactiveMessage = 1;
                {
                    var error = $root.proto.CollectionMessage.verify(message.collectionMessage);
                    if (error)
                        return "collectionMessage." + error;
                }
            }
            if (message.nativeFlowMessage != null && message.hasOwnProperty("nativeFlowMessage")) {
                if (properties.interactiveMessage === 1)
                    return "interactiveMessage: multiple values";
                properties.interactiveMessage = 1;
                {
                    var error = $root.proto.NativeFlowMessage.verify(message.nativeFlowMessage);
                    if (error)
                        return "nativeFlowMessage." + error;
                }
            }
            return null;
        };

        /**
         * Creates an InteractiveMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.InteractiveMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.InteractiveMessage} InteractiveMessage
         */
        InteractiveMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.InteractiveMessage)
                return object;
            var message = new $root.proto.InteractiveMessage();
            if (object.header != null) {
                if (typeof object.header !== "object")
                    throw TypeError(".proto.InteractiveMessage.header: object expected");
                message.header = $root.proto.Header.fromObject(object.header);
            }
            if (object.body != null) {
                if (typeof object.body !== "object")
                    throw TypeError(".proto.InteractiveMessage.body: object expected");
                message.body = $root.proto.Body.fromObject(object.body);
            }
            if (object.footer != null) {
                if (typeof object.footer !== "object")
                    throw TypeError(".proto.InteractiveMessage.footer: object expected");
                message.footer = $root.proto.Footer.fromObject(object.footer);
            }
            if (object.contextInfo != null) {
                if (typeof object.contextInfo !== "object")
                    throw TypeError(".proto.InteractiveMessage.contextInfo: object expected");
                message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo);
            }
            if (object.shopStorefrontMessage != null) {
                if (typeof object.shopStorefrontMessage !== "object")
                    throw TypeError(".proto.InteractiveMessage.shopStorefrontMessage: object expected");
                message.shopStorefrontMessage = $root.proto.ShopMessage.fromObject(object.shopStorefrontMessage);
            }
            if (object.collectionMessage != null) {
                if (typeof object.collectionMessage !== "object")
                    throw TypeError(".proto.InteractiveMessage.collectionMessage: object expected");
                message.collectionMessage = $root.proto.CollectionMessage.fromObject(object.collectionMessage);
            }
            if (object.nativeFlowMessage != null) {
                if (typeof object.nativeFlowMessage !== "object")
                    throw TypeError(".proto.InteractiveMessage.nativeFlowMessage: object expected");
                message.nativeFlowMessage = $root.proto.NativeFlowMessage.fromObject(object.nativeFlowMessage);
            }
            return message;
        };

        /**
         * Creates a plain object from an InteractiveMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.InteractiveMessage
         * @static
         * @param {proto.InteractiveMessage} message InteractiveMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        InteractiveMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.header = null;
                object.body = null;
                object.footer = null;
                object.contextInfo = null;
            }
            if (message.header != null && message.hasOwnProperty("header"))
                object.header = $root.proto.Header.toObject(message.header, options);
            if (message.body != null && message.hasOwnProperty("body"))
                object.body = $root.proto.Body.toObject(message.body, options);
            if (message.footer != null && message.hasOwnProperty("footer"))
                object.footer = $root.proto.Footer.toObject(message.footer, options);
            if (message.shopStorefrontMessage != null && message.hasOwnProperty("shopStorefrontMessage")) {
                object.shopStorefrontMessage = $root.proto.ShopMessage.toObject(message.shopStorefrontMessage, options);
                if (options.oneofs)
                    object.interactiveMessage = "shopStorefrontMessage";
            }
            if (message.collectionMessage != null && message.hasOwnProperty("collectionMessage")) {
                object.collectionMessage = $root.proto.CollectionMessage.toObject(message.collectionMessage, options);
                if (options.oneofs)
                    object.interactiveMessage = "collectionMessage";
            }
            if (message.nativeFlowMessage != null && message.hasOwnProperty("nativeFlowMessage")) {
                object.nativeFlowMessage = $root.proto.NativeFlowMessage.toObject(message.nativeFlowMessage, options);
                if (options.oneofs)
                    object.interactiveMessage = "nativeFlowMessage";
            }
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo"))
                object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options);
            return object;
        };

        /**
         * Converts this InteractiveMessage to JSON.
         * @function toJSON
         * @memberof proto.InteractiveMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        InteractiveMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return InteractiveMessage;
    })();

    proto.GroupInviteMessage = (function() {

        /**
         * Properties of a GroupInviteMessage.
         * @memberof proto
         * @interface IGroupInviteMessage
         * @property {string|null} [groupJid] GroupInviteMessage groupJid
         * @property {string|null} [inviteCode] GroupInviteMessage inviteCode
         * @property {number|Long|null} [inviteExpiration] GroupInviteMessage inviteExpiration
         * @property {string|null} [groupName] GroupInviteMessage groupName
         * @property {Uint8Array|null} [jpegThumbnail] GroupInviteMessage jpegThumbnail
         * @property {string|null} [caption] GroupInviteMessage caption
         * @property {proto.IContextInfo|null} [contextInfo] GroupInviteMessage contextInfo
         * @property {proto.GroupInviteMessage.GroupInviteMessageGroupType|null} [groupType] GroupInviteMessage groupType
         */

        /**
         * Constructs a new GroupInviteMessage.
         * @memberof proto
         * @classdesc Represents a GroupInviteMessage.
         * @implements IGroupInviteMessage
         * @constructor
         * @param {proto.IGroupInviteMessage=} [properties] Properties to set
         */
        function GroupInviteMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * GroupInviteMessage groupJid.
         * @member {string} groupJid
         * @memberof proto.GroupInviteMessage
         * @instance
         */
        GroupInviteMessage.prototype.groupJid = "";

        /**
         * GroupInviteMessage inviteCode.
         * @member {string} inviteCode
         * @memberof proto.GroupInviteMessage
         * @instance
         */
        GroupInviteMessage.prototype.inviteCode = "";

        /**
         * GroupInviteMessage inviteExpiration.
         * @member {number|Long} inviteExpiration
         * @memberof proto.GroupInviteMessage
         * @instance
         */
        GroupInviteMessage.prototype.inviteExpiration = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * GroupInviteMessage groupName.
         * @member {string} groupName
         * @memberof proto.GroupInviteMessage
         * @instance
         */
        GroupInviteMessage.prototype.groupName = "";

        /**
         * GroupInviteMessage jpegThumbnail.
         * @member {Uint8Array} jpegThumbnail
         * @memberof proto.GroupInviteMessage
         * @instance
         */
        GroupInviteMessage.prototype.jpegThumbnail = $util.newBuffer([]);

        /**
         * GroupInviteMessage caption.
         * @member {string} caption
         * @memberof proto.GroupInviteMessage
         * @instance
         */
        GroupInviteMessage.prototype.caption = "";

        /**
         * GroupInviteMessage contextInfo.
         * @member {proto.IContextInfo|null|undefined} contextInfo
         * @memberof proto.GroupInviteMessage
         * @instance
         */
        GroupInviteMessage.prototype.contextInfo = null;

        /**
         * GroupInviteMessage groupType.
         * @member {proto.GroupInviteMessage.GroupInviteMessageGroupType} groupType
         * @memberof proto.GroupInviteMessage
         * @instance
         */
        GroupInviteMessage.prototype.groupType = 0;

        /**
         * Creates a new GroupInviteMessage instance using the specified properties.
         * @function create
         * @memberof proto.GroupInviteMessage
         * @static
         * @param {proto.IGroupInviteMessage=} [properties] Properties to set
         * @returns {proto.GroupInviteMessage} GroupInviteMessage instance
         */
        GroupInviteMessage.create = function create(properties) {
            return new GroupInviteMessage(properties);
        };

        /**
         * Encodes the specified GroupInviteMessage message. Does not implicitly {@link proto.GroupInviteMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.GroupInviteMessage
         * @static
         * @param {proto.IGroupInviteMessage} message GroupInviteMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        GroupInviteMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.groupJid != null && Object.hasOwnProperty.call(message, "groupJid"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.groupJid);
            if (message.inviteCode != null && Object.hasOwnProperty.call(message, "inviteCode"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.inviteCode);
            if (message.inviteExpiration != null && Object.hasOwnProperty.call(message, "inviteExpiration"))
                writer.uint32(/* id 3, wireType 0 =*/24).int64(message.inviteExpiration);
            if (message.groupName != null && Object.hasOwnProperty.call(message, "groupName"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.groupName);
            if (message.jpegThumbnail != null && Object.hasOwnProperty.call(message, "jpegThumbnail"))
                writer.uint32(/* id 5, wireType 2 =*/42).bytes(message.jpegThumbnail);
            if (message.caption != null && Object.hasOwnProperty.call(message, "caption"))
                writer.uint32(/* id 6, wireType 2 =*/50).string(message.caption);
            if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo"))
                $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim();
            if (message.groupType != null && Object.hasOwnProperty.call(message, "groupType"))
                writer.uint32(/* id 8, wireType 0 =*/64).int32(message.groupType);
            return writer;
        };

        /**
         * Encodes the specified GroupInviteMessage message, length delimited. Does not implicitly {@link proto.GroupInviteMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.GroupInviteMessage
         * @static
         * @param {proto.IGroupInviteMessage} message GroupInviteMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        GroupInviteMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a GroupInviteMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.GroupInviteMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.GroupInviteMessage} GroupInviteMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        GroupInviteMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.GroupInviteMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.groupJid = reader.string();
                    break;
                case 2:
                    message.inviteCode = reader.string();
                    break;
                case 3:
                    message.inviteExpiration = reader.int64();
                    break;
                case 4:
                    message.groupName = reader.string();
                    break;
                case 5:
                    message.jpegThumbnail = reader.bytes();
                    break;
                case 6:
                    message.caption = reader.string();
                    break;
                case 7:
                    message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32());
                    break;
                case 8:
                    message.groupType = reader.int32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a GroupInviteMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.GroupInviteMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.GroupInviteMessage} GroupInviteMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        GroupInviteMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a GroupInviteMessage message.
         * @function verify
         * @memberof proto.GroupInviteMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        GroupInviteMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.groupJid != null && message.hasOwnProperty("groupJid"))
                if (!$util.isString(message.groupJid))
                    return "groupJid: string expected";
            if (message.inviteCode != null && message.hasOwnProperty("inviteCode"))
                if (!$util.isString(message.inviteCode))
                    return "inviteCode: string expected";
            if (message.inviteExpiration != null && message.hasOwnProperty("inviteExpiration"))
                if (!$util.isInteger(message.inviteExpiration) && !(message.inviteExpiration && $util.isInteger(message.inviteExpiration.low) && $util.isInteger(message.inviteExpiration.high)))
                    return "inviteExpiration: integer|Long expected";
            if (message.groupName != null && message.hasOwnProperty("groupName"))
                if (!$util.isString(message.groupName))
                    return "groupName: string expected";
            if (message.jpegThumbnail != null && message.hasOwnProperty("jpegThumbnail"))
                if (!(message.jpegThumbnail && typeof message.jpegThumbnail.length === "number" || $util.isString(message.jpegThumbnail)))
                    return "jpegThumbnail: buffer expected";
            if (message.caption != null && message.hasOwnProperty("caption"))
                if (!$util.isString(message.caption))
                    return "caption: string expected";
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) {
                var error = $root.proto.ContextInfo.verify(message.contextInfo);
                if (error)
                    return "contextInfo." + error;
            }
            if (message.groupType != null && message.hasOwnProperty("groupType"))
                switch (message.groupType) {
                default:
                    return "groupType: enum value expected";
                case 0:
                case 1:
                    break;
                }
            return null;
        };

        /**
         * Creates a GroupInviteMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.GroupInviteMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.GroupInviteMessage} GroupInviteMessage
         */
        GroupInviteMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.GroupInviteMessage)
                return object;
            var message = new $root.proto.GroupInviteMessage();
            if (object.groupJid != null)
                message.groupJid = String(object.groupJid);
            if (object.inviteCode != null)
                message.inviteCode = String(object.inviteCode);
            if (object.inviteExpiration != null)
                if ($util.Long)
                    (message.inviteExpiration = $util.Long.fromValue(object.inviteExpiration)).unsigned = false;
                else if (typeof object.inviteExpiration === "string")
                    message.inviteExpiration = parseInt(object.inviteExpiration, 10);
                else if (typeof object.inviteExpiration === "number")
                    message.inviteExpiration = object.inviteExpiration;
                else if (typeof object.inviteExpiration === "object")
                    message.inviteExpiration = new $util.LongBits(object.inviteExpiration.low >>> 0, object.inviteExpiration.high >>> 0).toNumber();
            if (object.groupName != null)
                message.groupName = String(object.groupName);
            if (object.jpegThumbnail != null)
                if (typeof object.jpegThumbnail === "string")
                    $util.base64.decode(object.jpegThumbnail, message.jpegThumbnail = $util.newBuffer($util.base64.length(object.jpegThumbnail)), 0);
                else if (object.jpegThumbnail.length)
                    message.jpegThumbnail = object.jpegThumbnail;
            if (object.caption != null)
                message.caption = String(object.caption);
            if (object.contextInfo != null) {
                if (typeof object.contextInfo !== "object")
                    throw TypeError(".proto.GroupInviteMessage.contextInfo: object expected");
                message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo);
            }
            switch (object.groupType) {
            case "DEFAULT":
            case 0:
                message.groupType = 0;
                break;
            case "PARENT":
            case 1:
                message.groupType = 1;
                break;
            }
            return message;
        };

        /**
         * Creates a plain object from a GroupInviteMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.GroupInviteMessage
         * @static
         * @param {proto.GroupInviteMessage} message GroupInviteMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        GroupInviteMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.groupJid = "";
                object.inviteCode = "";
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.inviteExpiration = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.inviteExpiration = options.longs === String ? "0" : 0;
                object.groupName = "";
                if (options.bytes === String)
                    object.jpegThumbnail = "";
                else {
                    object.jpegThumbnail = [];
                    if (options.bytes !== Array)
                        object.jpegThumbnail = $util.newBuffer(object.jpegThumbnail);
                }
                object.caption = "";
                object.contextInfo = null;
                object.groupType = options.enums === String ? "DEFAULT" : 0;
            }
            if (message.groupJid != null && message.hasOwnProperty("groupJid"))
                object.groupJid = message.groupJid;
            if (message.inviteCode != null && message.hasOwnProperty("inviteCode"))
                object.inviteCode = message.inviteCode;
            if (message.inviteExpiration != null && message.hasOwnProperty("inviteExpiration"))
                if (typeof message.inviteExpiration === "number")
                    object.inviteExpiration = options.longs === String ? String(message.inviteExpiration) : message.inviteExpiration;
                else
                    object.inviteExpiration = options.longs === String ? $util.Long.prototype.toString.call(message.inviteExpiration) : options.longs === Number ? new $util.LongBits(message.inviteExpiration.low >>> 0, message.inviteExpiration.high >>> 0).toNumber() : message.inviteExpiration;
            if (message.groupName != null && message.hasOwnProperty("groupName"))
                object.groupName = message.groupName;
            if (message.jpegThumbnail != null && message.hasOwnProperty("jpegThumbnail"))
                object.jpegThumbnail = options.bytes === String ? $util.base64.encode(message.jpegThumbnail, 0, message.jpegThumbnail.length) : options.bytes === Array ? Array.prototype.slice.call(message.jpegThumbnail) : message.jpegThumbnail;
            if (message.caption != null && message.hasOwnProperty("caption"))
                object.caption = message.caption;
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo"))
                object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options);
            if (message.groupType != null && message.hasOwnProperty("groupType"))
                object.groupType = options.enums === String ? $root.proto.GroupInviteMessage.GroupInviteMessageGroupType[message.groupType] : message.groupType;
            return object;
        };

        /**
         * Converts this GroupInviteMessage to JSON.
         * @function toJSON
         * @memberof proto.GroupInviteMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        GroupInviteMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * GroupInviteMessageGroupType enum.
         * @name proto.GroupInviteMessage.GroupInviteMessageGroupType
         * @enum {number}
         * @property {number} DEFAULT=0 DEFAULT value
         * @property {number} PARENT=1 PARENT value
         */
        GroupInviteMessage.GroupInviteMessageGroupType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "DEFAULT"] = 0;
            values[valuesById[1] = "PARENT"] = 1;
            return values;
        })();

        return GroupInviteMessage;
    })();

    proto.DeviceSentMessage = (function() {

        /**
         * Properties of a DeviceSentMessage.
         * @memberof proto
         * @interface IDeviceSentMessage
         * @property {string|null} [destinationJid] DeviceSentMessage destinationJid
         * @property {proto.IMessage|null} [message] DeviceSentMessage message
         * @property {string|null} [phash] DeviceSentMessage phash
         */

        /**
         * Constructs a new DeviceSentMessage.
         * @memberof proto
         * @classdesc Represents a DeviceSentMessage.
         * @implements IDeviceSentMessage
         * @constructor
         * @param {proto.IDeviceSentMessage=} [properties] Properties to set
         */
        function DeviceSentMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * DeviceSentMessage destinationJid.
         * @member {string} destinationJid
         * @memberof proto.DeviceSentMessage
         * @instance
         */
        DeviceSentMessage.prototype.destinationJid = "";

        /**
         * DeviceSentMessage message.
         * @member {proto.IMessage|null|undefined} message
         * @memberof proto.DeviceSentMessage
         * @instance
         */
        DeviceSentMessage.prototype.message = null;

        /**
         * DeviceSentMessage phash.
         * @member {string} phash
         * @memberof proto.DeviceSentMessage
         * @instance
         */
        DeviceSentMessage.prototype.phash = "";

        /**
         * Creates a new DeviceSentMessage instance using the specified properties.
         * @function create
         * @memberof proto.DeviceSentMessage
         * @static
         * @param {proto.IDeviceSentMessage=} [properties] Properties to set
         * @returns {proto.DeviceSentMessage} DeviceSentMessage instance
         */
        DeviceSentMessage.create = function create(properties) {
            return new DeviceSentMessage(properties);
        };

        /**
         * Encodes the specified DeviceSentMessage message. Does not implicitly {@link proto.DeviceSentMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.DeviceSentMessage
         * @static
         * @param {proto.IDeviceSentMessage} message DeviceSentMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        DeviceSentMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.destinationJid != null && Object.hasOwnProperty.call(message, "destinationJid"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.destinationJid);
            if (message.message != null && Object.hasOwnProperty.call(message, "message"))
                $root.proto.Message.encode(message.message, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.phash != null && Object.hasOwnProperty.call(message, "phash"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.phash);
            return writer;
        };

        /**
         * Encodes the specified DeviceSentMessage message, length delimited. Does not implicitly {@link proto.DeviceSentMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.DeviceSentMessage
         * @static
         * @param {proto.IDeviceSentMessage} message DeviceSentMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        DeviceSentMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a DeviceSentMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.DeviceSentMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.DeviceSentMessage} DeviceSentMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        DeviceSentMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.DeviceSentMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.destinationJid = reader.string();
                    break;
                case 2:
                    message.message = $root.proto.Message.decode(reader, reader.uint32());
                    break;
                case 3:
                    message.phash = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a DeviceSentMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.DeviceSentMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.DeviceSentMessage} DeviceSentMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        DeviceSentMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a DeviceSentMessage message.
         * @function verify
         * @memberof proto.DeviceSentMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        DeviceSentMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.destinationJid != null && message.hasOwnProperty("destinationJid"))
                if (!$util.isString(message.destinationJid))
                    return "destinationJid: string expected";
            if (message.message != null && message.hasOwnProperty("message")) {
                var error = $root.proto.Message.verify(message.message);
                if (error)
                    return "message." + error;
            }
            if (message.phash != null && message.hasOwnProperty("phash"))
                if (!$util.isString(message.phash))
                    return "phash: string expected";
            return null;
        };

        /**
         * Creates a DeviceSentMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.DeviceSentMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.DeviceSentMessage} DeviceSentMessage
         */
        DeviceSentMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.DeviceSentMessage)
                return object;
            var message = new $root.proto.DeviceSentMessage();
            if (object.destinationJid != null)
                message.destinationJid = String(object.destinationJid);
            if (object.message != null) {
                if (typeof object.message !== "object")
                    throw TypeError(".proto.DeviceSentMessage.message: object expected");
                message.message = $root.proto.Message.fromObject(object.message);
            }
            if (object.phash != null)
                message.phash = String(object.phash);
            return message;
        };

        /**
         * Creates a plain object from a DeviceSentMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.DeviceSentMessage
         * @static
         * @param {proto.DeviceSentMessage} message DeviceSentMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        DeviceSentMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.destinationJid = "";
                object.message = null;
                object.phash = "";
            }
            if (message.destinationJid != null && message.hasOwnProperty("destinationJid"))
                object.destinationJid = message.destinationJid;
            if (message.message != null && message.hasOwnProperty("message"))
                object.message = $root.proto.Message.toObject(message.message, options);
            if (message.phash != null && message.hasOwnProperty("phash"))
                object.phash = message.phash;
            return object;
        };

        /**
         * Converts this DeviceSentMessage to JSON.
         * @function toJSON
         * @memberof proto.DeviceSentMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        DeviceSentMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return DeviceSentMessage;
    })();

    proto.FutureProofMessage = (function() {

        /**
         * Properties of a FutureProofMessage.
         * @memberof proto
         * @interface IFutureProofMessage
         * @property {proto.IMessage|null} [message] FutureProofMessage message
         */

        /**
         * Constructs a new FutureProofMessage.
         * @memberof proto
         * @classdesc Represents a FutureProofMessage.
         * @implements IFutureProofMessage
         * @constructor
         * @param {proto.IFutureProofMessage=} [properties] Properties to set
         */
        function FutureProofMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * FutureProofMessage message.
         * @member {proto.IMessage|null|undefined} message
         * @memberof proto.FutureProofMessage
         * @instance
         */
        FutureProofMessage.prototype.message = null;

        /**
         * Creates a new FutureProofMessage instance using the specified properties.
         * @function create
         * @memberof proto.FutureProofMessage
         * @static
         * @param {proto.IFutureProofMessage=} [properties] Properties to set
         * @returns {proto.FutureProofMessage} FutureProofMessage instance
         */
        FutureProofMessage.create = function create(properties) {
            return new FutureProofMessage(properties);
        };

        /**
         * Encodes the specified FutureProofMessage message. Does not implicitly {@link proto.FutureProofMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.FutureProofMessage
         * @static
         * @param {proto.IFutureProofMessage} message FutureProofMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FutureProofMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.message != null && Object.hasOwnProperty.call(message, "message"))
                $root.proto.Message.encode(message.message, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified FutureProofMessage message, length delimited. Does not implicitly {@link proto.FutureProofMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.FutureProofMessage
         * @static
         * @param {proto.IFutureProofMessage} message FutureProofMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        FutureProofMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a FutureProofMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.FutureProofMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.FutureProofMessage} FutureProofMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FutureProofMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.FutureProofMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.message = $root.proto.Message.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a FutureProofMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.FutureProofMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.FutureProofMessage} FutureProofMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        FutureProofMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a FutureProofMessage message.
         * @function verify
         * @memberof proto.FutureProofMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        FutureProofMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.message != null && message.hasOwnProperty("message")) {
                var error = $root.proto.Message.verify(message.message);
                if (error)
                    return "message." + error;
            }
            return null;
        };

        /**
         * Creates a FutureProofMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.FutureProofMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.FutureProofMessage} FutureProofMessage
         */
        FutureProofMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.FutureProofMessage)
                return object;
            var message = new $root.proto.FutureProofMessage();
            if (object.message != null) {
                if (typeof object.message !== "object")
                    throw TypeError(".proto.FutureProofMessage.message: object expected");
                message.message = $root.proto.Message.fromObject(object.message);
            }
            return message;
        };

        /**
         * Creates a plain object from a FutureProofMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.FutureProofMessage
         * @static
         * @param {proto.FutureProofMessage} message FutureProofMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        FutureProofMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                object.message = null;
            if (message.message != null && message.hasOwnProperty("message"))
                object.message = $root.proto.Message.toObject(message.message, options);
            return object;
        };

        /**
         * Converts this FutureProofMessage to JSON.
         * @function toJSON
         * @memberof proto.FutureProofMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        FutureProofMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return FutureProofMessage;
    })();

    proto.ButtonText = (function() {

        /**
         * Properties of a ButtonText.
         * @memberof proto
         * @interface IButtonText
         * @property {string|null} [displayText] ButtonText displayText
         */

        /**
         * Constructs a new ButtonText.
         * @memberof proto
         * @classdesc Represents a ButtonText.
         * @implements IButtonText
         * @constructor
         * @param {proto.IButtonText=} [properties] Properties to set
         */
        function ButtonText(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ButtonText displayText.
         * @member {string} displayText
         * @memberof proto.ButtonText
         * @instance
         */
        ButtonText.prototype.displayText = "";

        /**
         * Creates a new ButtonText instance using the specified properties.
         * @function create
         * @memberof proto.ButtonText
         * @static
         * @param {proto.IButtonText=} [properties] Properties to set
         * @returns {proto.ButtonText} ButtonText instance
         */
        ButtonText.create = function create(properties) {
            return new ButtonText(properties);
        };

        /**
         * Encodes the specified ButtonText message. Does not implicitly {@link proto.ButtonText.verify|verify} messages.
         * @function encode
         * @memberof proto.ButtonText
         * @static
         * @param {proto.IButtonText} message ButtonText message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ButtonText.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayText);
            return writer;
        };

        /**
         * Encodes the specified ButtonText message, length delimited. Does not implicitly {@link proto.ButtonText.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ButtonText
         * @static
         * @param {proto.IButtonText} message ButtonText message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ButtonText.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ButtonText message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ButtonText
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ButtonText} ButtonText
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ButtonText.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ButtonText();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.displayText = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ButtonText message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ButtonText
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ButtonText} ButtonText
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ButtonText.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ButtonText message.
         * @function verify
         * @memberof proto.ButtonText
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ButtonText.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.displayText != null && message.hasOwnProperty("displayText"))
                if (!$util.isString(message.displayText))
                    return "displayText: string expected";
            return null;
        };

        /**
         * Creates a ButtonText message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ButtonText
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ButtonText} ButtonText
         */
        ButtonText.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ButtonText)
                return object;
            var message = new $root.proto.ButtonText();
            if (object.displayText != null)
                message.displayText = String(object.displayText);
            return message;
        };

        /**
         * Creates a plain object from a ButtonText message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ButtonText
         * @static
         * @param {proto.ButtonText} message ButtonText
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ButtonText.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                object.displayText = "";
            if (message.displayText != null && message.hasOwnProperty("displayText"))
                object.displayText = message.displayText;
            return object;
        };

        /**
         * Converts this ButtonText to JSON.
         * @function toJSON
         * @memberof proto.ButtonText
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ButtonText.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ButtonText;
    })();

    proto.NativeFlowInfo = (function() {

        /**
         * Properties of a NativeFlowInfo.
         * @memberof proto
         * @interface INativeFlowInfo
         * @property {string|null} [name] NativeFlowInfo name
         * @property {string|null} [paramsJson] NativeFlowInfo paramsJson
         */

        /**
         * Constructs a new NativeFlowInfo.
         * @memberof proto
         * @classdesc Represents a NativeFlowInfo.
         * @implements INativeFlowInfo
         * @constructor
         * @param {proto.INativeFlowInfo=} [properties] Properties to set
         */
        function NativeFlowInfo(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * NativeFlowInfo name.
         * @member {string} name
         * @memberof proto.NativeFlowInfo
         * @instance
         */
        NativeFlowInfo.prototype.name = "";

        /**
         * NativeFlowInfo paramsJson.
         * @member {string} paramsJson
         * @memberof proto.NativeFlowInfo
         * @instance
         */
        NativeFlowInfo.prototype.paramsJson = "";

        /**
         * Creates a new NativeFlowInfo instance using the specified properties.
         * @function create
         * @memberof proto.NativeFlowInfo
         * @static
         * @param {proto.INativeFlowInfo=} [properties] Properties to set
         * @returns {proto.NativeFlowInfo} NativeFlowInfo instance
         */
        NativeFlowInfo.create = function create(properties) {
            return new NativeFlowInfo(properties);
        };

        /**
         * Encodes the specified NativeFlowInfo message. Does not implicitly {@link proto.NativeFlowInfo.verify|verify} messages.
         * @function encode
         * @memberof proto.NativeFlowInfo
         * @static
         * @param {proto.INativeFlowInfo} message NativeFlowInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        NativeFlowInfo.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.name != null && Object.hasOwnProperty.call(message, "name"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.name);
            if (message.paramsJson != null && Object.hasOwnProperty.call(message, "paramsJson"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.paramsJson);
            return writer;
        };

        /**
         * Encodes the specified NativeFlowInfo message, length delimited. Does not implicitly {@link proto.NativeFlowInfo.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.NativeFlowInfo
         * @static
         * @param {proto.INativeFlowInfo} message NativeFlowInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        NativeFlowInfo.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a NativeFlowInfo message from the specified reader or buffer.
         * @function decode
         * @memberof proto.NativeFlowInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.NativeFlowInfo} NativeFlowInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        NativeFlowInfo.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.NativeFlowInfo();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.name = reader.string();
                    break;
                case 2:
                    message.paramsJson = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a NativeFlowInfo message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.NativeFlowInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.NativeFlowInfo} NativeFlowInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        NativeFlowInfo.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a NativeFlowInfo message.
         * @function verify
         * @memberof proto.NativeFlowInfo
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        NativeFlowInfo.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.name != null && message.hasOwnProperty("name"))
                if (!$util.isString(message.name))
                    return "name: string expected";
            if (message.paramsJson != null && message.hasOwnProperty("paramsJson"))
                if (!$util.isString(message.paramsJson))
                    return "paramsJson: string expected";
            return null;
        };

        /**
         * Creates a NativeFlowInfo message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.NativeFlowInfo
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.NativeFlowInfo} NativeFlowInfo
         */
        NativeFlowInfo.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.NativeFlowInfo)
                return object;
            var message = new $root.proto.NativeFlowInfo();
            if (object.name != null)
                message.name = String(object.name);
            if (object.paramsJson != null)
                message.paramsJson = String(object.paramsJson);
            return message;
        };

        /**
         * Creates a plain object from a NativeFlowInfo message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.NativeFlowInfo
         * @static
         * @param {proto.NativeFlowInfo} message NativeFlowInfo
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        NativeFlowInfo.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.name = "";
                object.paramsJson = "";
            }
            if (message.name != null && message.hasOwnProperty("name"))
                object.name = message.name;
            if (message.paramsJson != null && message.hasOwnProperty("paramsJson"))
                object.paramsJson = message.paramsJson;
            return object;
        };

        /**
         * Converts this NativeFlowInfo to JSON.
         * @function toJSON
         * @memberof proto.NativeFlowInfo
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        NativeFlowInfo.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return NativeFlowInfo;
    })();

    proto.Button = (function() {

        /**
         * Properties of a Button.
         * @memberof proto
         * @interface IButton
         * @property {string|null} [buttonId] Button buttonId
         * @property {proto.IButtonText|null} [buttonText] Button buttonText
         * @property {proto.Button.ButtonType|null} [type] Button type
         * @property {proto.INativeFlowInfo|null} [nativeFlowInfo] Button nativeFlowInfo
         */

        /**
         * Constructs a new Button.
         * @memberof proto
         * @classdesc Represents a Button.
         * @implements IButton
         * @constructor
         * @param {proto.IButton=} [properties] Properties to set
         */
        function Button(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Button buttonId.
         * @member {string} buttonId
         * @memberof proto.Button
         * @instance
         */
        Button.prototype.buttonId = "";

        /**
         * Button buttonText.
         * @member {proto.IButtonText|null|undefined} buttonText
         * @memberof proto.Button
         * @instance
         */
        Button.prototype.buttonText = null;

        /**
         * Button type.
         * @member {proto.Button.ButtonType} type
         * @memberof proto.Button
         * @instance
         */
        Button.prototype.type = 0;

        /**
         * Button nativeFlowInfo.
         * @member {proto.INativeFlowInfo|null|undefined} nativeFlowInfo
         * @memberof proto.Button
         * @instance
         */
        Button.prototype.nativeFlowInfo = null;

        /**
         * Creates a new Button instance using the specified properties.
         * @function create
         * @memberof proto.Button
         * @static
         * @param {proto.IButton=} [properties] Properties to set
         * @returns {proto.Button} Button instance
         */
        Button.create = function create(properties) {
            return new Button(properties);
        };

        /**
         * Encodes the specified Button message. Does not implicitly {@link proto.Button.verify|verify} messages.
         * @function encode
         * @memberof proto.Button
         * @static
         * @param {proto.IButton} message Button message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Button.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.buttonId != null && Object.hasOwnProperty.call(message, "buttonId"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.buttonId);
            if (message.buttonText != null && Object.hasOwnProperty.call(message, "buttonText"))
                $root.proto.ButtonText.encode(message.buttonText, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.type != null && Object.hasOwnProperty.call(message, "type"))
                writer.uint32(/* id 3, wireType 0 =*/24).int32(message.type);
            if (message.nativeFlowInfo != null && Object.hasOwnProperty.call(message, "nativeFlowInfo"))
                $root.proto.NativeFlowInfo.encode(message.nativeFlowInfo, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified Button message, length delimited. Does not implicitly {@link proto.Button.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.Button
         * @static
         * @param {proto.IButton} message Button message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Button.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a Button message from the specified reader or buffer.
         * @function decode
         * @memberof proto.Button
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.Button} Button
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Button.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Button();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.buttonId = reader.string();
                    break;
                case 2:
                    message.buttonText = $root.proto.ButtonText.decode(reader, reader.uint32());
                    break;
                case 3:
                    message.type = reader.int32();
                    break;
                case 4:
                    message.nativeFlowInfo = $root.proto.NativeFlowInfo.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a Button message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.Button
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.Button} Button
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Button.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a Button message.
         * @function verify
         * @memberof proto.Button
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        Button.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.buttonId != null && message.hasOwnProperty("buttonId"))
                if (!$util.isString(message.buttonId))
                    return "buttonId: string expected";
            if (message.buttonText != null && message.hasOwnProperty("buttonText")) {
                var error = $root.proto.ButtonText.verify(message.buttonText);
                if (error)
                    return "buttonText." + error;
            }
            if (message.type != null && message.hasOwnProperty("type"))
                switch (message.type) {
                default:
                    return "type: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            if (message.nativeFlowInfo != null && message.hasOwnProperty("nativeFlowInfo")) {
                var error = $root.proto.NativeFlowInfo.verify(message.nativeFlowInfo);
                if (error)
                    return "nativeFlowInfo." + error;
            }
            return null;
        };

        /**
         * Creates a Button message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.Button
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.Button} Button
         */
        Button.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.Button)
                return object;
            var message = new $root.proto.Button();
            if (object.buttonId != null)
                message.buttonId = String(object.buttonId);
            if (object.buttonText != null) {
                if (typeof object.buttonText !== "object")
                    throw TypeError(".proto.Button.buttonText: object expected");
                message.buttonText = $root.proto.ButtonText.fromObject(object.buttonText);
            }
            switch (object.type) {
            case "UNKNOWN":
            case 0:
                message.type = 0;
                break;
            case "RESPONSE":
            case 1:
                message.type = 1;
                break;
            case "NATIVE_FLOW":
            case 2:
                message.type = 2;
                break;
            }
            if (object.nativeFlowInfo != null) {
                if (typeof object.nativeFlowInfo !== "object")
                    throw TypeError(".proto.Button.nativeFlowInfo: object expected");
                message.nativeFlowInfo = $root.proto.NativeFlowInfo.fromObject(object.nativeFlowInfo);
            }
            return message;
        };

        /**
         * Creates a plain object from a Button message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.Button
         * @static
         * @param {proto.Button} message Button
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        Button.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.buttonId = "";
                object.buttonText = null;
                object.type = options.enums === String ? "UNKNOWN" : 0;
                object.nativeFlowInfo = null;
            }
            if (message.buttonId != null && message.hasOwnProperty("buttonId"))
                object.buttonId = message.buttonId;
            if (message.buttonText != null && message.hasOwnProperty("buttonText"))
                object.buttonText = $root.proto.ButtonText.toObject(message.buttonText, options);
            if (message.type != null && message.hasOwnProperty("type"))
                object.type = options.enums === String ? $root.proto.Button.ButtonType[message.type] : message.type;
            if (message.nativeFlowInfo != null && message.hasOwnProperty("nativeFlowInfo"))
                object.nativeFlowInfo = $root.proto.NativeFlowInfo.toObject(message.nativeFlowInfo, options);
            return object;
        };

        /**
         * Converts this Button to JSON.
         * @function toJSON
         * @memberof proto.Button
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        Button.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * ButtonType enum.
         * @name proto.Button.ButtonType
         * @enum {number}
         * @property {number} UNKNOWN=0 UNKNOWN value
         * @property {number} RESPONSE=1 RESPONSE value
         * @property {number} NATIVE_FLOW=2 NATIVE_FLOW value
         */
        Button.ButtonType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "UNKNOWN"] = 0;
            values[valuesById[1] = "RESPONSE"] = 1;
            values[valuesById[2] = "NATIVE_FLOW"] = 2;
            return values;
        })();

        return Button;
    })();

    proto.ButtonsMessage = (function() {

        /**
         * Properties of a ButtonsMessage.
         * @memberof proto
         * @interface IButtonsMessage
         * @property {string|null} [contentText] ButtonsMessage contentText
         * @property {string|null} [footerText] ButtonsMessage footerText
         * @property {proto.IContextInfo|null} [contextInfo] ButtonsMessage contextInfo
         * @property {Array.<proto.IButton>|null} [buttons] ButtonsMessage buttons
         * @property {proto.ButtonsMessage.ButtonsMessageHeaderType|null} [headerType] ButtonsMessage headerType
         * @property {string|null} [text] ButtonsMessage text
         * @property {proto.IDocumentMessage|null} [documentMessage] ButtonsMessage documentMessage
         * @property {proto.IImageMessage|null} [imageMessage] ButtonsMessage imageMessage
         * @property {proto.IVideoMessage|null} [videoMessage] ButtonsMessage videoMessage
         * @property {proto.ILocationMessage|null} [locationMessage] ButtonsMessage locationMessage
         */

        /**
         * Constructs a new ButtonsMessage.
         * @memberof proto
         * @classdesc Represents a ButtonsMessage.
         * @implements IButtonsMessage
         * @constructor
         * @param {proto.IButtonsMessage=} [properties] Properties to set
         */
        function ButtonsMessage(properties) {
            this.buttons = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ButtonsMessage contentText.
         * @member {string} contentText
         * @memberof proto.ButtonsMessage
         * @instance
         */
        ButtonsMessage.prototype.contentText = "";

        /**
         * ButtonsMessage footerText.
         * @member {string} footerText
         * @memberof proto.ButtonsMessage
         * @instance
         */
        ButtonsMessage.prototype.footerText = "";

        /**
         * ButtonsMessage contextInfo.
         * @member {proto.IContextInfo|null|undefined} contextInfo
         * @memberof proto.ButtonsMessage
         * @instance
         */
        ButtonsMessage.prototype.contextInfo = null;

        /**
         * ButtonsMessage buttons.
         * @member {Array.<proto.IButton>} buttons
         * @memberof proto.ButtonsMessage
         * @instance
         */
        ButtonsMessage.prototype.buttons = $util.emptyArray;

        /**
         * ButtonsMessage headerType.
         * @member {proto.ButtonsMessage.ButtonsMessageHeaderType} headerType
         * @memberof proto.ButtonsMessage
         * @instance
         */
        ButtonsMessage.prototype.headerType = 0;

        /**
         * ButtonsMessage text.
         * @member {string|null|undefined} text
         * @memberof proto.ButtonsMessage
         * @instance
         */
        ButtonsMessage.prototype.text = null;

        /**
         * ButtonsMessage documentMessage.
         * @member {proto.IDocumentMessage|null|undefined} documentMessage
         * @memberof proto.ButtonsMessage
         * @instance
         */
        ButtonsMessage.prototype.documentMessage = null;

        /**
         * ButtonsMessage imageMessage.
         * @member {proto.IImageMessage|null|undefined} imageMessage
         * @memberof proto.ButtonsMessage
         * @instance
         */
        ButtonsMessage.prototype.imageMessage = null;

        /**
         * ButtonsMessage videoMessage.
         * @member {proto.IVideoMessage|null|undefined} videoMessage
         * @memberof proto.ButtonsMessage
         * @instance
         */
        ButtonsMessage.prototype.videoMessage = null;

        /**
         * ButtonsMessage locationMessage.
         * @member {proto.ILocationMessage|null|undefined} locationMessage
         * @memberof proto.ButtonsMessage
         * @instance
         */
        ButtonsMessage.prototype.locationMessage = null;

        // OneOf field names bound to virtual getters and setters
        var $oneOfFields;

        /**
         * ButtonsMessage header.
         * @member {"text"|"documentMessage"|"imageMessage"|"videoMessage"|"locationMessage"|undefined} header
         * @memberof proto.ButtonsMessage
         * @instance
         */
        Object.defineProperty(ButtonsMessage.prototype, "header", {
            get: $util.oneOfGetter($oneOfFields = ["text", "documentMessage", "imageMessage", "videoMessage", "locationMessage"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new ButtonsMessage instance using the specified properties.
         * @function create
         * @memberof proto.ButtonsMessage
         * @static
         * @param {proto.IButtonsMessage=} [properties] Properties to set
         * @returns {proto.ButtonsMessage} ButtonsMessage instance
         */
        ButtonsMessage.create = function create(properties) {
            return new ButtonsMessage(properties);
        };

        /**
         * Encodes the specified ButtonsMessage message. Does not implicitly {@link proto.ButtonsMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.ButtonsMessage
         * @static
         * @param {proto.IButtonsMessage} message ButtonsMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ButtonsMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.text != null && Object.hasOwnProperty.call(message, "text"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.text);
            if (message.documentMessage != null && Object.hasOwnProperty.call(message, "documentMessage"))
                $root.proto.DocumentMessage.encode(message.documentMessage, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.imageMessage != null && Object.hasOwnProperty.call(message, "imageMessage"))
                $root.proto.ImageMessage.encode(message.imageMessage, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.videoMessage != null && Object.hasOwnProperty.call(message, "videoMessage"))
                $root.proto.VideoMessage.encode(message.videoMessage, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
            if (message.locationMessage != null && Object.hasOwnProperty.call(message, "locationMessage"))
                $root.proto.LocationMessage.encode(message.locationMessage, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim();
            if (message.contentText != null && Object.hasOwnProperty.call(message, "contentText"))
                writer.uint32(/* id 6, wireType 2 =*/50).string(message.contentText);
            if (message.footerText != null && Object.hasOwnProperty.call(message, "footerText"))
                writer.uint32(/* id 7, wireType 2 =*/58).string(message.footerText);
            if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo"))
                $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim();
            if (message.buttons != null && message.buttons.length)
                for (var i = 0; i < message.buttons.length; ++i)
                    $root.proto.Button.encode(message.buttons[i], writer.uint32(/* id 9, wireType 2 =*/74).fork()).ldelim();
            if (message.headerType != null && Object.hasOwnProperty.call(message, "headerType"))
                writer.uint32(/* id 10, wireType 0 =*/80).int32(message.headerType);
            return writer;
        };

        /**
         * Encodes the specified ButtonsMessage message, length delimited. Does not implicitly {@link proto.ButtonsMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ButtonsMessage
         * @static
         * @param {proto.IButtonsMessage} message ButtonsMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ButtonsMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ButtonsMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ButtonsMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ButtonsMessage} ButtonsMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ButtonsMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ButtonsMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 6:
                    message.contentText = reader.string();
                    break;
                case 7:
                    message.footerText = reader.string();
                    break;
                case 8:
                    message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32());
                    break;
                case 9:
                    if (!(message.buttons && message.buttons.length))
                        message.buttons = [];
                    message.buttons.push($root.proto.Button.decode(reader, reader.uint32()));
                    break;
                case 10:
                    message.headerType = reader.int32();
                    break;
                case 1:
                    message.text = reader.string();
                    break;
                case 2:
                    message.documentMessage = $root.proto.DocumentMessage.decode(reader, reader.uint32());
                    break;
                case 3:
                    message.imageMessage = $root.proto.ImageMessage.decode(reader, reader.uint32());
                    break;
                case 4:
                    message.videoMessage = $root.proto.VideoMessage.decode(reader, reader.uint32());
                    break;
                case 5:
                    message.locationMessage = $root.proto.LocationMessage.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ButtonsMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ButtonsMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ButtonsMessage} ButtonsMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ButtonsMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ButtonsMessage message.
         * @function verify
         * @memberof proto.ButtonsMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ButtonsMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            var properties = {};
            if (message.contentText != null && message.hasOwnProperty("contentText"))
                if (!$util.isString(message.contentText))
                    return "contentText: string expected";
            if (message.footerText != null && message.hasOwnProperty("footerText"))
                if (!$util.isString(message.footerText))
                    return "footerText: string expected";
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) {
                var error = $root.proto.ContextInfo.verify(message.contextInfo);
                if (error)
                    return "contextInfo." + error;
            }
            if (message.buttons != null && message.hasOwnProperty("buttons")) {
                if (!Array.isArray(message.buttons))
                    return "buttons: array expected";
                for (var i = 0; i < message.buttons.length; ++i) {
                    var error = $root.proto.Button.verify(message.buttons[i]);
                    if (error)
                        return "buttons." + error;
                }
            }
            if (message.headerType != null && message.hasOwnProperty("headerType"))
                switch (message.headerType) {
                default:
                    return "headerType: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                    break;
                }
            if (message.text != null && message.hasOwnProperty("text")) {
                properties.header = 1;
                if (!$util.isString(message.text))
                    return "text: string expected";
            }
            if (message.documentMessage != null && message.hasOwnProperty("documentMessage")) {
                if (properties.header === 1)
                    return "header: multiple values";
                properties.header = 1;
                {
                    var error = $root.proto.DocumentMessage.verify(message.documentMessage);
                    if (error)
                        return "documentMessage." + error;
                }
            }
            if (message.imageMessage != null && message.hasOwnProperty("imageMessage")) {
                if (properties.header === 1)
                    return "header: multiple values";
                properties.header = 1;
                {
                    var error = $root.proto.ImageMessage.verify(message.imageMessage);
                    if (error)
                        return "imageMessage." + error;
                }
            }
            if (message.videoMessage != null && message.hasOwnProperty("videoMessage")) {
                if (properties.header === 1)
                    return "header: multiple values";
                properties.header = 1;
                {
                    var error = $root.proto.VideoMessage.verify(message.videoMessage);
                    if (error)
                        return "videoMessage." + error;
                }
            }
            if (message.locationMessage != null && message.hasOwnProperty("locationMessage")) {
                if (properties.header === 1)
                    return "header: multiple values";
                properties.header = 1;
                {
                    var error = $root.proto.LocationMessage.verify(message.locationMessage);
                    if (error)
                        return "locationMessage." + error;
                }
            }
            return null;
        };

        /**
         * Creates a ButtonsMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ButtonsMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ButtonsMessage} ButtonsMessage
         */
        ButtonsMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ButtonsMessage)
                return object;
            var message = new $root.proto.ButtonsMessage();
            if (object.contentText != null)
                message.contentText = String(object.contentText);
            if (object.footerText != null)
                message.footerText = String(object.footerText);
            if (object.contextInfo != null) {
                if (typeof object.contextInfo !== "object")
                    throw TypeError(".proto.ButtonsMessage.contextInfo: object expected");
                message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo);
            }
            if (object.buttons) {
                if (!Array.isArray(object.buttons))
                    throw TypeError(".proto.ButtonsMessage.buttons: array expected");
                message.buttons = [];
                for (var i = 0; i < object.buttons.length; ++i) {
                    if (typeof object.buttons[i] !== "object")
                        throw TypeError(".proto.ButtonsMessage.buttons: object expected");
                    message.buttons[i] = $root.proto.Button.fromObject(object.buttons[i]);
                }
            }
            switch (object.headerType) {
            case "UNKNOWN":
            case 0:
                message.headerType = 0;
                break;
            case "EMPTY":
            case 1:
                message.headerType = 1;
                break;
            case "TEXT":
            case 2:
                message.headerType = 2;
                break;
            case "DOCUMENT":
            case 3:
                message.headerType = 3;
                break;
            case "IMAGE":
            case 4:
                message.headerType = 4;
                break;
            case "VIDEO":
            case 5:
                message.headerType = 5;
                break;
            case "LOCATION":
            case 6:
                message.headerType = 6;
                break;
            }
            if (object.text != null)
                message.text = String(object.text);
            if (object.documentMessage != null) {
                if (typeof object.documentMessage !== "object")
                    throw TypeError(".proto.ButtonsMessage.documentMessage: object expected");
                message.documentMessage = $root.proto.DocumentMessage.fromObject(object.documentMessage);
            }
            if (object.imageMessage != null) {
                if (typeof object.imageMessage !== "object")
                    throw TypeError(".proto.ButtonsMessage.imageMessage: object expected");
                message.imageMessage = $root.proto.ImageMessage.fromObject(object.imageMessage);
            }
            if (object.videoMessage != null) {
                if (typeof object.videoMessage !== "object")
                    throw TypeError(".proto.ButtonsMessage.videoMessage: object expected");
                message.videoMessage = $root.proto.VideoMessage.fromObject(object.videoMessage);
            }
            if (object.locationMessage != null) {
                if (typeof object.locationMessage !== "object")
                    throw TypeError(".proto.ButtonsMessage.locationMessage: object expected");
                message.locationMessage = $root.proto.LocationMessage.fromObject(object.locationMessage);
            }
            return message;
        };

        /**
         * Creates a plain object from a ButtonsMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ButtonsMessage
         * @static
         * @param {proto.ButtonsMessage} message ButtonsMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ButtonsMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.buttons = [];
            if (options.defaults) {
                object.contentText = "";
                object.footerText = "";
                object.contextInfo = null;
                object.headerType = options.enums === String ? "UNKNOWN" : 0;
            }
            if (message.text != null && message.hasOwnProperty("text")) {
                object.text = message.text;
                if (options.oneofs)
                    object.header = "text";
            }
            if (message.documentMessage != null && message.hasOwnProperty("documentMessage")) {
                object.documentMessage = $root.proto.DocumentMessage.toObject(message.documentMessage, options);
                if (options.oneofs)
                    object.header = "documentMessage";
            }
            if (message.imageMessage != null && message.hasOwnProperty("imageMessage")) {
                object.imageMessage = $root.proto.ImageMessage.toObject(message.imageMessage, options);
                if (options.oneofs)
                    object.header = "imageMessage";
            }
            if (message.videoMessage != null && message.hasOwnProperty("videoMessage")) {
                object.videoMessage = $root.proto.VideoMessage.toObject(message.videoMessage, options);
                if (options.oneofs)
                    object.header = "videoMessage";
            }
            if (message.locationMessage != null && message.hasOwnProperty("locationMessage")) {
                object.locationMessage = $root.proto.LocationMessage.toObject(message.locationMessage, options);
                if (options.oneofs)
                    object.header = "locationMessage";
            }
            if (message.contentText != null && message.hasOwnProperty("contentText"))
                object.contentText = message.contentText;
            if (message.footerText != null && message.hasOwnProperty("footerText"))
                object.footerText = message.footerText;
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo"))
                object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options);
            if (message.buttons && message.buttons.length) {
                object.buttons = [];
                for (var j = 0; j < message.buttons.length; ++j)
                    object.buttons[j] = $root.proto.Button.toObject(message.buttons[j], options);
            }
            if (message.headerType != null && message.hasOwnProperty("headerType"))
                object.headerType = options.enums === String ? $root.proto.ButtonsMessage.ButtonsMessageHeaderType[message.headerType] : message.headerType;
            return object;
        };

        /**
         * Converts this ButtonsMessage to JSON.
         * @function toJSON
         * @memberof proto.ButtonsMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ButtonsMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * ButtonsMessageHeaderType enum.
         * @name proto.ButtonsMessage.ButtonsMessageHeaderType
         * @enum {number}
         * @property {number} UNKNOWN=0 UNKNOWN value
         * @property {number} EMPTY=1 EMPTY value
         * @property {number} TEXT=2 TEXT value
         * @property {number} DOCUMENT=3 DOCUMENT value
         * @property {number} IMAGE=4 IMAGE value
         * @property {number} VIDEO=5 VIDEO value
         * @property {number} LOCATION=6 LOCATION value
         */
        ButtonsMessage.ButtonsMessageHeaderType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "UNKNOWN"] = 0;
            values[valuesById[1] = "EMPTY"] = 1;
            values[valuesById[2] = "TEXT"] = 2;
            values[valuesById[3] = "DOCUMENT"] = 3;
            values[valuesById[4] = "IMAGE"] = 4;
            values[valuesById[5] = "VIDEO"] = 5;
            values[valuesById[6] = "LOCATION"] = 6;
            return values;
        })();

        return ButtonsMessage;
    })();

    proto.ButtonsResponseMessage = (function() {

        /**
         * Properties of a ButtonsResponseMessage.
         * @memberof proto
         * @interface IButtonsResponseMessage
         * @property {string|null} [selectedButtonId] ButtonsResponseMessage selectedButtonId
         * @property {proto.IContextInfo|null} [contextInfo] ButtonsResponseMessage contextInfo
         * @property {proto.ButtonsResponseMessage.ButtonsResponseMessageType|null} [type] ButtonsResponseMessage type
         * @property {string|null} [selectedDisplayText] ButtonsResponseMessage selectedDisplayText
         */

        /**
         * Constructs a new ButtonsResponseMessage.
         * @memberof proto
         * @classdesc Represents a ButtonsResponseMessage.
         * @implements IButtonsResponseMessage
         * @constructor
         * @param {proto.IButtonsResponseMessage=} [properties] Properties to set
         */
        function ButtonsResponseMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ButtonsResponseMessage selectedButtonId.
         * @member {string} selectedButtonId
         * @memberof proto.ButtonsResponseMessage
         * @instance
         */
        ButtonsResponseMessage.prototype.selectedButtonId = "";

        /**
         * ButtonsResponseMessage contextInfo.
         * @member {proto.IContextInfo|null|undefined} contextInfo
         * @memberof proto.ButtonsResponseMessage
         * @instance
         */
        ButtonsResponseMessage.prototype.contextInfo = null;

        /**
         * ButtonsResponseMessage type.
         * @member {proto.ButtonsResponseMessage.ButtonsResponseMessageType} type
         * @memberof proto.ButtonsResponseMessage
         * @instance
         */
        ButtonsResponseMessage.prototype.type = 0;

        /**
         * ButtonsResponseMessage selectedDisplayText.
         * @member {string|null|undefined} selectedDisplayText
         * @memberof proto.ButtonsResponseMessage
         * @instance
         */
        ButtonsResponseMessage.prototype.selectedDisplayText = null;

        // OneOf field names bound to virtual getters and setters
        var $oneOfFields;

        /**
         * ButtonsResponseMessage response.
         * @member {"selectedDisplayText"|undefined} response
         * @memberof proto.ButtonsResponseMessage
         * @instance
         */
        Object.defineProperty(ButtonsResponseMessage.prototype, "response", {
            get: $util.oneOfGetter($oneOfFields = ["selectedDisplayText"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new ButtonsResponseMessage instance using the specified properties.
         * @function create
         * @memberof proto.ButtonsResponseMessage
         * @static
         * @param {proto.IButtonsResponseMessage=} [properties] Properties to set
         * @returns {proto.ButtonsResponseMessage} ButtonsResponseMessage instance
         */
        ButtonsResponseMessage.create = function create(properties) {
            return new ButtonsResponseMessage(properties);
        };

        /**
         * Encodes the specified ButtonsResponseMessage message. Does not implicitly {@link proto.ButtonsResponseMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.ButtonsResponseMessage
         * @static
         * @param {proto.IButtonsResponseMessage} message ButtonsResponseMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ButtonsResponseMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.selectedButtonId != null && Object.hasOwnProperty.call(message, "selectedButtonId"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.selectedButtonId);
            if (message.selectedDisplayText != null && Object.hasOwnProperty.call(message, "selectedDisplayText"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.selectedDisplayText);
            if (message.contextInfo != null && Object.hasOwnProperty.call(message, "contextInfo"))
                $root.proto.ContextInfo.encode(message.contextInfo, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.type != null && Object.hasOwnProperty.call(message, "type"))
                writer.uint32(/* id 4, wireType 0 =*/32).int32(message.type);
            return writer;
        };

        /**
         * Encodes the specified ButtonsResponseMessage message, length delimited. Does not implicitly {@link proto.ButtonsResponseMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ButtonsResponseMessage
         * @static
         * @param {proto.IButtonsResponseMessage} message ButtonsResponseMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ButtonsResponseMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ButtonsResponseMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ButtonsResponseMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ButtonsResponseMessage} ButtonsResponseMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ButtonsResponseMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ButtonsResponseMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.selectedButtonId = reader.string();
                    break;
                case 3:
                    message.contextInfo = $root.proto.ContextInfo.decode(reader, reader.uint32());
                    break;
                case 4:
                    message.type = reader.int32();
                    break;
                case 2:
                    message.selectedDisplayText = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ButtonsResponseMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ButtonsResponseMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ButtonsResponseMessage} ButtonsResponseMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ButtonsResponseMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ButtonsResponseMessage message.
         * @function verify
         * @memberof proto.ButtonsResponseMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ButtonsResponseMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            var properties = {};
            if (message.selectedButtonId != null && message.hasOwnProperty("selectedButtonId"))
                if (!$util.isString(message.selectedButtonId))
                    return "selectedButtonId: string expected";
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo")) {
                var error = $root.proto.ContextInfo.verify(message.contextInfo);
                if (error)
                    return "contextInfo." + error;
            }
            if (message.type != null && message.hasOwnProperty("type"))
                switch (message.type) {
                default:
                    return "type: enum value expected";
                case 0:
                case 1:
                    break;
                }
            if (message.selectedDisplayText != null && message.hasOwnProperty("selectedDisplayText")) {
                properties.response = 1;
                if (!$util.isString(message.selectedDisplayText))
                    return "selectedDisplayText: string expected";
            }
            return null;
        };

        /**
         * Creates a ButtonsResponseMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ButtonsResponseMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ButtonsResponseMessage} ButtonsResponseMessage
         */
        ButtonsResponseMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ButtonsResponseMessage)
                return object;
            var message = new $root.proto.ButtonsResponseMessage();
            if (object.selectedButtonId != null)
                message.selectedButtonId = String(object.selectedButtonId);
            if (object.contextInfo != null) {
                if (typeof object.contextInfo !== "object")
                    throw TypeError(".proto.ButtonsResponseMessage.contextInfo: object expected");
                message.contextInfo = $root.proto.ContextInfo.fromObject(object.contextInfo);
            }
            switch (object.type) {
            case "UNKNOWN":
            case 0:
                message.type = 0;
                break;
            case "DISPLAY_TEXT":
            case 1:
                message.type = 1;
                break;
            }
            if (object.selectedDisplayText != null)
                message.selectedDisplayText = String(object.selectedDisplayText);
            return message;
        };

        /**
         * Creates a plain object from a ButtonsResponseMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ButtonsResponseMessage
         * @static
         * @param {proto.ButtonsResponseMessage} message ButtonsResponseMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ButtonsResponseMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.selectedButtonId = "";
                object.contextInfo = null;
                object.type = options.enums === String ? "UNKNOWN" : 0;
            }
            if (message.selectedButtonId != null && message.hasOwnProperty("selectedButtonId"))
                object.selectedButtonId = message.selectedButtonId;
            if (message.selectedDisplayText != null && message.hasOwnProperty("selectedDisplayText")) {
                object.selectedDisplayText = message.selectedDisplayText;
                if (options.oneofs)
                    object.response = "selectedDisplayText";
            }
            if (message.contextInfo != null && message.hasOwnProperty("contextInfo"))
                object.contextInfo = $root.proto.ContextInfo.toObject(message.contextInfo, options);
            if (message.type != null && message.hasOwnProperty("type"))
                object.type = options.enums === String ? $root.proto.ButtonsResponseMessage.ButtonsResponseMessageType[message.type] : message.type;
            return object;
        };

        /**
         * Converts this ButtonsResponseMessage to JSON.
         * @function toJSON
         * @memberof proto.ButtonsResponseMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ButtonsResponseMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * ButtonsResponseMessageType enum.
         * @name proto.ButtonsResponseMessage.ButtonsResponseMessageType
         * @enum {number}
         * @property {number} UNKNOWN=0 UNKNOWN value
         * @property {number} DISPLAY_TEXT=1 DISPLAY_TEXT value
         */
        ButtonsResponseMessage.ButtonsResponseMessageType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "UNKNOWN"] = 0;
            values[valuesById[1] = "DISPLAY_TEXT"] = 1;
            return values;
        })();

        return ButtonsResponseMessage;
    })();

    proto.ReactionMessage = (function() {

        /**
         * Properties of a ReactionMessage.
         * @memberof proto
         * @interface IReactionMessage
         * @property {proto.IMessageKey|null} [key] ReactionMessage key
         * @property {string|null} [text] ReactionMessage text
         * @property {string|null} [groupingKey] ReactionMessage groupingKey
         * @property {number|Long|null} [senderTimestampMs] ReactionMessage senderTimestampMs
         */

        /**
         * Constructs a new ReactionMessage.
         * @memberof proto
         * @classdesc Represents a ReactionMessage.
         * @implements IReactionMessage
         * @constructor
         * @param {proto.IReactionMessage=} [properties] Properties to set
         */
        function ReactionMessage(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ReactionMessage key.
         * @member {proto.IMessageKey|null|undefined} key
         * @memberof proto.ReactionMessage
         * @instance
         */
        ReactionMessage.prototype.key = null;

        /**
         * ReactionMessage text.
         * @member {string} text
         * @memberof proto.ReactionMessage
         * @instance
         */
        ReactionMessage.prototype.text = "";

        /**
         * ReactionMessage groupingKey.
         * @member {string} groupingKey
         * @memberof proto.ReactionMessage
         * @instance
         */
        ReactionMessage.prototype.groupingKey = "";

        /**
         * ReactionMessage senderTimestampMs.
         * @member {number|Long} senderTimestampMs
         * @memberof proto.ReactionMessage
         * @instance
         */
        ReactionMessage.prototype.senderTimestampMs = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * Creates a new ReactionMessage instance using the specified properties.
         * @function create
         * @memberof proto.ReactionMessage
         * @static
         * @param {proto.IReactionMessage=} [properties] Properties to set
         * @returns {proto.ReactionMessage} ReactionMessage instance
         */
        ReactionMessage.create = function create(properties) {
            return new ReactionMessage(properties);
        };

        /**
         * Encodes the specified ReactionMessage message. Does not implicitly {@link proto.ReactionMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.ReactionMessage
         * @static
         * @param {proto.IReactionMessage} message ReactionMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ReactionMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.key != null && Object.hasOwnProperty.call(message, "key"))
                $root.proto.MessageKey.encode(message.key, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.text != null && Object.hasOwnProperty.call(message, "text"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.text);
            if (message.groupingKey != null && Object.hasOwnProperty.call(message, "groupingKey"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.groupingKey);
            if (message.senderTimestampMs != null && Object.hasOwnProperty.call(message, "senderTimestampMs"))
                writer.uint32(/* id 4, wireType 0 =*/32).int64(message.senderTimestampMs);
            return writer;
        };

        /**
         * Encodes the specified ReactionMessage message, length delimited. Does not implicitly {@link proto.ReactionMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ReactionMessage
         * @static
         * @param {proto.IReactionMessage} message ReactionMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ReactionMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ReactionMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ReactionMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ReactionMessage} ReactionMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ReactionMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ReactionMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.key = $root.proto.MessageKey.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.text = reader.string();
                    break;
                case 3:
                    message.groupingKey = reader.string();
                    break;
                case 4:
                    message.senderTimestampMs = reader.int64();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ReactionMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ReactionMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ReactionMessage} ReactionMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ReactionMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ReactionMessage message.
         * @function verify
         * @memberof proto.ReactionMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ReactionMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.key != null && message.hasOwnProperty("key")) {
                var error = $root.proto.MessageKey.verify(message.key);
                if (error)
                    return "key." + error;
            }
            if (message.text != null && message.hasOwnProperty("text"))
                if (!$util.isString(message.text))
                    return "text: string expected";
            if (message.groupingKey != null && message.hasOwnProperty("groupingKey"))
                if (!$util.isString(message.groupingKey))
                    return "groupingKey: string expected";
            if (message.senderTimestampMs != null && message.hasOwnProperty("senderTimestampMs"))
                if (!$util.isInteger(message.senderTimestampMs) && !(message.senderTimestampMs && $util.isInteger(message.senderTimestampMs.low) && $util.isInteger(message.senderTimestampMs.high)))
                    return "senderTimestampMs: integer|Long expected";
            return null;
        };

        /**
         * Creates a ReactionMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ReactionMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ReactionMessage} ReactionMessage
         */
        ReactionMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ReactionMessage)
                return object;
            var message = new $root.proto.ReactionMessage();
            if (object.key != null) {
                if (typeof object.key !== "object")
                    throw TypeError(".proto.ReactionMessage.key: object expected");
                message.key = $root.proto.MessageKey.fromObject(object.key);
            }
            if (object.text != null)
                message.text = String(object.text);
            if (object.groupingKey != null)
                message.groupingKey = String(object.groupingKey);
            if (object.senderTimestampMs != null)
                if ($util.Long)
                    (message.senderTimestampMs = $util.Long.fromValue(object.senderTimestampMs)).unsigned = false;
                else if (typeof object.senderTimestampMs === "string")
                    message.senderTimestampMs = parseInt(object.senderTimestampMs, 10);
                else if (typeof object.senderTimestampMs === "number")
                    message.senderTimestampMs = object.senderTimestampMs;
                else if (typeof object.senderTimestampMs === "object")
                    message.senderTimestampMs = new $util.LongBits(object.senderTimestampMs.low >>> 0, object.senderTimestampMs.high >>> 0).toNumber();
            return message;
        };

        /**
         * Creates a plain object from a ReactionMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ReactionMessage
         * @static
         * @param {proto.ReactionMessage} message ReactionMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ReactionMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.key = null;
                object.text = "";
                object.groupingKey = "";
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.senderTimestampMs = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.senderTimestampMs = options.longs === String ? "0" : 0;
            }
            if (message.key != null && message.hasOwnProperty("key"))
                object.key = $root.proto.MessageKey.toObject(message.key, options);
            if (message.text != null && message.hasOwnProperty("text"))
                object.text = message.text;
            if (message.groupingKey != null && message.hasOwnProperty("groupingKey"))
                object.groupingKey = message.groupingKey;
            if (message.senderTimestampMs != null && message.hasOwnProperty("senderTimestampMs"))
                if (typeof message.senderTimestampMs === "number")
                    object.senderTimestampMs = options.longs === String ? String(message.senderTimestampMs) : message.senderTimestampMs;
                else
                    object.senderTimestampMs = options.longs === String ? $util.Long.prototype.toString.call(message.senderTimestampMs) : options.longs === Number ? new $util.LongBits(message.senderTimestampMs.low >>> 0, message.senderTimestampMs.high >>> 0).toNumber() : message.senderTimestampMs;
            return object;
        };

        /**
         * Converts this ReactionMessage to JSON.
         * @function toJSON
         * @memberof proto.ReactionMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ReactionMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ReactionMessage;
    })();

    proto.StickerSyncRMRMessage = (function() {

        /**
         * Properties of a StickerSyncRMRMessage.
         * @memberof proto
         * @interface IStickerSyncRMRMessage
         * @property {Array.<string>|null} [filehash] StickerSyncRMRMessage filehash
         * @property {string|null} [rmrSource] StickerSyncRMRMessage rmrSource
         * @property {number|Long|null} [requestTimestamp] StickerSyncRMRMessage requestTimestamp
         */

        /**
         * Constructs a new StickerSyncRMRMessage.
         * @memberof proto
         * @classdesc Represents a StickerSyncRMRMessage.
         * @implements IStickerSyncRMRMessage
         * @constructor
         * @param {proto.IStickerSyncRMRMessage=} [properties] Properties to set
         */
        function StickerSyncRMRMessage(properties) {
            this.filehash = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * StickerSyncRMRMessage filehash.
         * @member {Array.<string>} filehash
         * @memberof proto.StickerSyncRMRMessage
         * @instance
         */
        StickerSyncRMRMessage.prototype.filehash = $util.emptyArray;

        /**
         * StickerSyncRMRMessage rmrSource.
         * @member {string} rmrSource
         * @memberof proto.StickerSyncRMRMessage
         * @instance
         */
        StickerSyncRMRMessage.prototype.rmrSource = "";

        /**
         * StickerSyncRMRMessage requestTimestamp.
         * @member {number|Long} requestTimestamp
         * @memberof proto.StickerSyncRMRMessage
         * @instance
         */
        StickerSyncRMRMessage.prototype.requestTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * Creates a new StickerSyncRMRMessage instance using the specified properties.
         * @function create
         * @memberof proto.StickerSyncRMRMessage
         * @static
         * @param {proto.IStickerSyncRMRMessage=} [properties] Properties to set
         * @returns {proto.StickerSyncRMRMessage} StickerSyncRMRMessage instance
         */
        StickerSyncRMRMessage.create = function create(properties) {
            return new StickerSyncRMRMessage(properties);
        };

        /**
         * Encodes the specified StickerSyncRMRMessage message. Does not implicitly {@link proto.StickerSyncRMRMessage.verify|verify} messages.
         * @function encode
         * @memberof proto.StickerSyncRMRMessage
         * @static
         * @param {proto.IStickerSyncRMRMessage} message StickerSyncRMRMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        StickerSyncRMRMessage.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.filehash != null && message.filehash.length)
                for (var i = 0; i < message.filehash.length; ++i)
                    writer.uint32(/* id 1, wireType 2 =*/10).string(message.filehash[i]);
            if (message.rmrSource != null && Object.hasOwnProperty.call(message, "rmrSource"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.rmrSource);
            if (message.requestTimestamp != null && Object.hasOwnProperty.call(message, "requestTimestamp"))
                writer.uint32(/* id 3, wireType 0 =*/24).int64(message.requestTimestamp);
            return writer;
        };

        /**
         * Encodes the specified StickerSyncRMRMessage message, length delimited. Does not implicitly {@link proto.StickerSyncRMRMessage.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.StickerSyncRMRMessage
         * @static
         * @param {proto.IStickerSyncRMRMessage} message StickerSyncRMRMessage message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        StickerSyncRMRMessage.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a StickerSyncRMRMessage message from the specified reader or buffer.
         * @function decode
         * @memberof proto.StickerSyncRMRMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.StickerSyncRMRMessage} StickerSyncRMRMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        StickerSyncRMRMessage.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.StickerSyncRMRMessage();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    if (!(message.filehash && message.filehash.length))
                        message.filehash = [];
                    message.filehash.push(reader.string());
                    break;
                case 2:
                    message.rmrSource = reader.string();
                    break;
                case 3:
                    message.requestTimestamp = reader.int64();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a StickerSyncRMRMessage message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.StickerSyncRMRMessage
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.StickerSyncRMRMessage} StickerSyncRMRMessage
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        StickerSyncRMRMessage.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a StickerSyncRMRMessage message.
         * @function verify
         * @memberof proto.StickerSyncRMRMessage
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        StickerSyncRMRMessage.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.filehash != null && message.hasOwnProperty("filehash")) {
                if (!Array.isArray(message.filehash))
                    return "filehash: array expected";
                for (var i = 0; i < message.filehash.length; ++i)
                    if (!$util.isString(message.filehash[i]))
                        return "filehash: string[] expected";
            }
            if (message.rmrSource != null && message.hasOwnProperty("rmrSource"))
                if (!$util.isString(message.rmrSource))
                    return "rmrSource: string expected";
            if (message.requestTimestamp != null && message.hasOwnProperty("requestTimestamp"))
                if (!$util.isInteger(message.requestTimestamp) && !(message.requestTimestamp && $util.isInteger(message.requestTimestamp.low) && $util.isInteger(message.requestTimestamp.high)))
                    return "requestTimestamp: integer|Long expected";
            return null;
        };

        /**
         * Creates a StickerSyncRMRMessage message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.StickerSyncRMRMessage
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.StickerSyncRMRMessage} StickerSyncRMRMessage
         */
        StickerSyncRMRMessage.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.StickerSyncRMRMessage)
                return object;
            var message = new $root.proto.StickerSyncRMRMessage();
            if (object.filehash) {
                if (!Array.isArray(object.filehash))
                    throw TypeError(".proto.StickerSyncRMRMessage.filehash: array expected");
                message.filehash = [];
                for (var i = 0; i < object.filehash.length; ++i)
                    message.filehash[i] = String(object.filehash[i]);
            }
            if (object.rmrSource != null)
                message.rmrSource = String(object.rmrSource);
            if (object.requestTimestamp != null)
                if ($util.Long)
                    (message.requestTimestamp = $util.Long.fromValue(object.requestTimestamp)).unsigned = false;
                else if (typeof object.requestTimestamp === "string")
                    message.requestTimestamp = parseInt(object.requestTimestamp, 10);
                else if (typeof object.requestTimestamp === "number")
                    message.requestTimestamp = object.requestTimestamp;
                else if (typeof object.requestTimestamp === "object")
                    message.requestTimestamp = new $util.LongBits(object.requestTimestamp.low >>> 0, object.requestTimestamp.high >>> 0).toNumber();
            return message;
        };

        /**
         * Creates a plain object from a StickerSyncRMRMessage message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.StickerSyncRMRMessage
         * @static
         * @param {proto.StickerSyncRMRMessage} message StickerSyncRMRMessage
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        StickerSyncRMRMessage.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.filehash = [];
            if (options.defaults) {
                object.rmrSource = "";
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.requestTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.requestTimestamp = options.longs === String ? "0" : 0;
            }
            if (message.filehash && message.filehash.length) {
                object.filehash = [];
                for (var j = 0; j < message.filehash.length; ++j)
                    object.filehash[j] = message.filehash[j];
            }
            if (message.rmrSource != null && message.hasOwnProperty("rmrSource"))
                object.rmrSource = message.rmrSource;
            if (message.requestTimestamp != null && message.hasOwnProperty("requestTimestamp"))
                if (typeof message.requestTimestamp === "number")
                    object.requestTimestamp = options.longs === String ? String(message.requestTimestamp) : message.requestTimestamp;
                else
                    object.requestTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.requestTimestamp) : options.longs === Number ? new $util.LongBits(message.requestTimestamp.low >>> 0, message.requestTimestamp.high >>> 0).toNumber() : message.requestTimestamp;
            return object;
        };

        /**
         * Converts this StickerSyncRMRMessage to JSON.
         * @function toJSON
         * @memberof proto.StickerSyncRMRMessage
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        StickerSyncRMRMessage.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return StickerSyncRMRMessage;
    })();

    proto.Message = (function() {

        /**
         * Properties of a Message.
         * @memberof proto
         * @interface IMessage
         * @property {string|null} [conversation] Message conversation
         * @property {proto.ISenderKeyDistributionMessage|null} [senderKeyDistributionMessage] Message senderKeyDistributionMessage
         * @property {proto.IImageMessage|null} [imageMessage] Message imageMessage
         * @property {proto.IContactMessage|null} [contactMessage] Message contactMessage
         * @property {proto.ILocationMessage|null} [locationMessage] Message locationMessage
         * @property {proto.IExtendedTextMessage|null} [extendedTextMessage] Message extendedTextMessage
         * @property {proto.IDocumentMessage|null} [documentMessage] Message documentMessage
         * @property {proto.IAudioMessage|null} [audioMessage] Message audioMessage
         * @property {proto.IVideoMessage|null} [videoMessage] Message videoMessage
         * @property {proto.ICall|null} [call] Message call
         * @property {proto.IChat|null} [chat] Message chat
         * @property {proto.IProtocolMessage|null} [protocolMessage] Message protocolMessage
         * @property {proto.IContactsArrayMessage|null} [contactsArrayMessage] Message contactsArrayMessage
         * @property {proto.IHighlyStructuredMessage|null} [highlyStructuredMessage] Message highlyStructuredMessage
         * @property {proto.ISenderKeyDistributionMessage|null} [fastRatchetKeySenderKeyDistributionMessage] Message fastRatchetKeySenderKeyDistributionMessage
         * @property {proto.ISendPaymentMessage|null} [sendPaymentMessage] Message sendPaymentMessage
         * @property {proto.ILiveLocationMessage|null} [liveLocationMessage] Message liveLocationMessage
         * @property {proto.IRequestPaymentMessage|null} [requestPaymentMessage] Message requestPaymentMessage
         * @property {proto.IDeclinePaymentRequestMessage|null} [declinePaymentRequestMessage] Message declinePaymentRequestMessage
         * @property {proto.ICancelPaymentRequestMessage|null} [cancelPaymentRequestMessage] Message cancelPaymentRequestMessage
         * @property {proto.ITemplateMessage|null} [templateMessage] Message templateMessage
         * @property {proto.IStickerMessage|null} [stickerMessage] Message stickerMessage
         * @property {proto.IGroupInviteMessage|null} [groupInviteMessage] Message groupInviteMessage
         * @property {proto.ITemplateButtonReplyMessage|null} [templateButtonReplyMessage] Message templateButtonReplyMessage
         * @property {proto.IProductMessage|null} [productMessage] Message productMessage
         * @property {proto.IDeviceSentMessage|null} [deviceSentMessage] Message deviceSentMessage
         * @property {proto.IMessageContextInfo|null} [messageContextInfo] Message messageContextInfo
         * @property {proto.IListMessage|null} [listMessage] Message listMessage
         * @property {proto.IFutureProofMessage|null} [viewOnceMessage] Message viewOnceMessage
         * @property {proto.IOrderMessage|null} [orderMessage] Message orderMessage
         * @property {proto.IListResponseMessage|null} [listResponseMessage] Message listResponseMessage
         * @property {proto.IFutureProofMessage|null} [ephemeralMessage] Message ephemeralMessage
         * @property {proto.IInvoiceMessage|null} [invoiceMessage] Message invoiceMessage
         * @property {proto.IButtonsMessage|null} [buttonsMessage] Message buttonsMessage
         * @property {proto.IButtonsResponseMessage|null} [buttonsResponseMessage] Message buttonsResponseMessage
         * @property {proto.IPaymentInviteMessage|null} [paymentInviteMessage] Message paymentInviteMessage
         * @property {proto.IInteractiveMessage|null} [interactiveMessage] Message interactiveMessage
         * @property {proto.IReactionMessage|null} [reactionMessage] Message reactionMessage
         * @property {proto.IStickerSyncRMRMessage|null} [stickerSyncRmrMessage] Message stickerSyncRmrMessage
         */

        /**
         * Constructs a new Message.
         * @memberof proto
         * @classdesc Represents a Message.
         * @implements IMessage
         * @constructor
         * @param {proto.IMessage=} [properties] Properties to set
         */
        function Message(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Message conversation.
         * @member {string} conversation
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.conversation = "";

        /**
         * Message senderKeyDistributionMessage.
         * @member {proto.ISenderKeyDistributionMessage|null|undefined} senderKeyDistributionMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.senderKeyDistributionMessage = null;

        /**
         * Message imageMessage.
         * @member {proto.IImageMessage|null|undefined} imageMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.imageMessage = null;

        /**
         * Message contactMessage.
         * @member {proto.IContactMessage|null|undefined} contactMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.contactMessage = null;

        /**
         * Message locationMessage.
         * @member {proto.ILocationMessage|null|undefined} locationMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.locationMessage = null;

        /**
         * Message extendedTextMessage.
         * @member {proto.IExtendedTextMessage|null|undefined} extendedTextMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.extendedTextMessage = null;

        /**
         * Message documentMessage.
         * @member {proto.IDocumentMessage|null|undefined} documentMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.documentMessage = null;

        /**
         * Message audioMessage.
         * @member {proto.IAudioMessage|null|undefined} audioMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.audioMessage = null;

        /**
         * Message videoMessage.
         * @member {proto.IVideoMessage|null|undefined} videoMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.videoMessage = null;

        /**
         * Message call.
         * @member {proto.ICall|null|undefined} call
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.call = null;

        /**
         * Message chat.
         * @member {proto.IChat|null|undefined} chat
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.chat = null;

        /**
         * Message protocolMessage.
         * @member {proto.IProtocolMessage|null|undefined} protocolMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.protocolMessage = null;

        /**
         * Message contactsArrayMessage.
         * @member {proto.IContactsArrayMessage|null|undefined} contactsArrayMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.contactsArrayMessage = null;

        /**
         * Message highlyStructuredMessage.
         * @member {proto.IHighlyStructuredMessage|null|undefined} highlyStructuredMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.highlyStructuredMessage = null;

        /**
         * Message fastRatchetKeySenderKeyDistributionMessage.
         * @member {proto.ISenderKeyDistributionMessage|null|undefined} fastRatchetKeySenderKeyDistributionMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.fastRatchetKeySenderKeyDistributionMessage = null;

        /**
         * Message sendPaymentMessage.
         * @member {proto.ISendPaymentMessage|null|undefined} sendPaymentMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.sendPaymentMessage = null;

        /**
         * Message liveLocationMessage.
         * @member {proto.ILiveLocationMessage|null|undefined} liveLocationMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.liveLocationMessage = null;

        /**
         * Message requestPaymentMessage.
         * @member {proto.IRequestPaymentMessage|null|undefined} requestPaymentMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.requestPaymentMessage = null;

        /**
         * Message declinePaymentRequestMessage.
         * @member {proto.IDeclinePaymentRequestMessage|null|undefined} declinePaymentRequestMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.declinePaymentRequestMessage = null;

        /**
         * Message cancelPaymentRequestMessage.
         * @member {proto.ICancelPaymentRequestMessage|null|undefined} cancelPaymentRequestMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.cancelPaymentRequestMessage = null;

        /**
         * Message templateMessage.
         * @member {proto.ITemplateMessage|null|undefined} templateMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.templateMessage = null;

        /**
         * Message stickerMessage.
         * @member {proto.IStickerMessage|null|undefined} stickerMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.stickerMessage = null;

        /**
         * Message groupInviteMessage.
         * @member {proto.IGroupInviteMessage|null|undefined} groupInviteMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.groupInviteMessage = null;

        /**
         * Message templateButtonReplyMessage.
         * @member {proto.ITemplateButtonReplyMessage|null|undefined} templateButtonReplyMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.templateButtonReplyMessage = null;

        /**
         * Message productMessage.
         * @member {proto.IProductMessage|null|undefined} productMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.productMessage = null;

        /**
         * Message deviceSentMessage.
         * @member {proto.IDeviceSentMessage|null|undefined} deviceSentMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.deviceSentMessage = null;

        /**
         * Message messageContextInfo.
         * @member {proto.IMessageContextInfo|null|undefined} messageContextInfo
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.messageContextInfo = null;

        /**
         * Message listMessage.
         * @member {proto.IListMessage|null|undefined} listMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.listMessage = null;

        /**
         * Message viewOnceMessage.
         * @member {proto.IFutureProofMessage|null|undefined} viewOnceMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.viewOnceMessage = null;

        /**
         * Message orderMessage.
         * @member {proto.IOrderMessage|null|undefined} orderMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.orderMessage = null;

        /**
         * Message listResponseMessage.
         * @member {proto.IListResponseMessage|null|undefined} listResponseMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.listResponseMessage = null;

        /**
         * Message ephemeralMessage.
         * @member {proto.IFutureProofMessage|null|undefined} ephemeralMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.ephemeralMessage = null;

        /**
         * Message invoiceMessage.
         * @member {proto.IInvoiceMessage|null|undefined} invoiceMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.invoiceMessage = null;

        /**
         * Message buttonsMessage.
         * @member {proto.IButtonsMessage|null|undefined} buttonsMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.buttonsMessage = null;

        /**
         * Message buttonsResponseMessage.
         * @member {proto.IButtonsResponseMessage|null|undefined} buttonsResponseMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.buttonsResponseMessage = null;

        /**
         * Message paymentInviteMessage.
         * @member {proto.IPaymentInviteMessage|null|undefined} paymentInviteMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.paymentInviteMessage = null;

        /**
         * Message interactiveMessage.
         * @member {proto.IInteractiveMessage|null|undefined} interactiveMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.interactiveMessage = null;

        /**
         * Message reactionMessage.
         * @member {proto.IReactionMessage|null|undefined} reactionMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.reactionMessage = null;

        /**
         * Message stickerSyncRmrMessage.
         * @member {proto.IStickerSyncRMRMessage|null|undefined} stickerSyncRmrMessage
         * @memberof proto.Message
         * @instance
         */
        Message.prototype.stickerSyncRmrMessage = null;

        /**
         * Creates a new Message instance using the specified properties.
         * @function create
         * @memberof proto.Message
         * @static
         * @param {proto.IMessage=} [properties] Properties to set
         * @returns {proto.Message} Message instance
         */
        Message.create = function create(properties) {
            return new Message(properties);
        };

        /**
         * Encodes the specified Message message. Does not implicitly {@link proto.Message.verify|verify} messages.
         * @function encode
         * @memberof proto.Message
         * @static
         * @param {proto.IMessage} message Message message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Message.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.conversation != null && Object.hasOwnProperty.call(message, "conversation"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.conversation);
            if (message.senderKeyDistributionMessage != null && Object.hasOwnProperty.call(message, "senderKeyDistributionMessage"))
                $root.proto.SenderKeyDistributionMessage.encode(message.senderKeyDistributionMessage, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.imageMessage != null && Object.hasOwnProperty.call(message, "imageMessage"))
                $root.proto.ImageMessage.encode(message.imageMessage, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.contactMessage != null && Object.hasOwnProperty.call(message, "contactMessage"))
                $root.proto.ContactMessage.encode(message.contactMessage, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
            if (message.locationMessage != null && Object.hasOwnProperty.call(message, "locationMessage"))
                $root.proto.LocationMessage.encode(message.locationMessage, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim();
            if (message.extendedTextMessage != null && Object.hasOwnProperty.call(message, "extendedTextMessage"))
                $root.proto.ExtendedTextMessage.encode(message.extendedTextMessage, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim();
            if (message.documentMessage != null && Object.hasOwnProperty.call(message, "documentMessage"))
                $root.proto.DocumentMessage.encode(message.documentMessage, writer.uint32(/* id 7, wireType 2 =*/58).fork()).ldelim();
            if (message.audioMessage != null && Object.hasOwnProperty.call(message, "audioMessage"))
                $root.proto.AudioMessage.encode(message.audioMessage, writer.uint32(/* id 8, wireType 2 =*/66).fork()).ldelim();
            if (message.videoMessage != null && Object.hasOwnProperty.call(message, "videoMessage"))
                $root.proto.VideoMessage.encode(message.videoMessage, writer.uint32(/* id 9, wireType 2 =*/74).fork()).ldelim();
            if (message.call != null && Object.hasOwnProperty.call(message, "call"))
                $root.proto.Call.encode(message.call, writer.uint32(/* id 10, wireType 2 =*/82).fork()).ldelim();
            if (message.chat != null && Object.hasOwnProperty.call(message, "chat"))
                $root.proto.Chat.encode(message.chat, writer.uint32(/* id 11, wireType 2 =*/90).fork()).ldelim();
            if (message.protocolMessage != null && Object.hasOwnProperty.call(message, "protocolMessage"))
                $root.proto.ProtocolMessage.encode(message.protocolMessage, writer.uint32(/* id 12, wireType 2 =*/98).fork()).ldelim();
            if (message.contactsArrayMessage != null && Object.hasOwnProperty.call(message, "contactsArrayMessage"))
                $root.proto.ContactsArrayMessage.encode(message.contactsArrayMessage, writer.uint32(/* id 13, wireType 2 =*/106).fork()).ldelim();
            if (message.highlyStructuredMessage != null && Object.hasOwnProperty.call(message, "highlyStructuredMessage"))
                $root.proto.HighlyStructuredMessage.encode(message.highlyStructuredMessage, writer.uint32(/* id 14, wireType 2 =*/114).fork()).ldelim();
            if (message.fastRatchetKeySenderKeyDistributionMessage != null && Object.hasOwnProperty.call(message, "fastRatchetKeySenderKeyDistributionMessage"))
                $root.proto.SenderKeyDistributionMessage.encode(message.fastRatchetKeySenderKeyDistributionMessage, writer.uint32(/* id 15, wireType 2 =*/122).fork()).ldelim();
            if (message.sendPaymentMessage != null && Object.hasOwnProperty.call(message, "sendPaymentMessage"))
                $root.proto.SendPaymentMessage.encode(message.sendPaymentMessage, writer.uint32(/* id 16, wireType 2 =*/130).fork()).ldelim();
            if (message.liveLocationMessage != null && Object.hasOwnProperty.call(message, "liveLocationMessage"))
                $root.proto.LiveLocationMessage.encode(message.liveLocationMessage, writer.uint32(/* id 18, wireType 2 =*/146).fork()).ldelim();
            if (message.requestPaymentMessage != null && Object.hasOwnProperty.call(message, "requestPaymentMessage"))
                $root.proto.RequestPaymentMessage.encode(message.requestPaymentMessage, writer.uint32(/* id 22, wireType 2 =*/178).fork()).ldelim();
            if (message.declinePaymentRequestMessage != null && Object.hasOwnProperty.call(message, "declinePaymentRequestMessage"))
                $root.proto.DeclinePaymentRequestMessage.encode(message.declinePaymentRequestMessage, writer.uint32(/* id 23, wireType 2 =*/186).fork()).ldelim();
            if (message.cancelPaymentRequestMessage != null && Object.hasOwnProperty.call(message, "cancelPaymentRequestMessage"))
                $root.proto.CancelPaymentRequestMessage.encode(message.cancelPaymentRequestMessage, writer.uint32(/* id 24, wireType 2 =*/194).fork()).ldelim();
            if (message.templateMessage != null && Object.hasOwnProperty.call(message, "templateMessage"))
                $root.proto.TemplateMessage.encode(message.templateMessage, writer.uint32(/* id 25, wireType 2 =*/202).fork()).ldelim();
            if (message.stickerMessage != null && Object.hasOwnProperty.call(message, "stickerMessage"))
                $root.proto.StickerMessage.encode(message.stickerMessage, writer.uint32(/* id 26, wireType 2 =*/210).fork()).ldelim();
            if (message.groupInviteMessage != null && Object.hasOwnProperty.call(message, "groupInviteMessage"))
                $root.proto.GroupInviteMessage.encode(message.groupInviteMessage, writer.uint32(/* id 28, wireType 2 =*/226).fork()).ldelim();
            if (message.templateButtonReplyMessage != null && Object.hasOwnProperty.call(message, "templateButtonReplyMessage"))
                $root.proto.TemplateButtonReplyMessage.encode(message.templateButtonReplyMessage, writer.uint32(/* id 29, wireType 2 =*/234).fork()).ldelim();
            if (message.productMessage != null && Object.hasOwnProperty.call(message, "productMessage"))
                $root.proto.ProductMessage.encode(message.productMessage, writer.uint32(/* id 30, wireType 2 =*/242).fork()).ldelim();
            if (message.deviceSentMessage != null && Object.hasOwnProperty.call(message, "deviceSentMessage"))
                $root.proto.DeviceSentMessage.encode(message.deviceSentMessage, writer.uint32(/* id 31, wireType 2 =*/250).fork()).ldelim();
            if (message.messageContextInfo != null && Object.hasOwnProperty.call(message, "messageContextInfo"))
                $root.proto.MessageContextInfo.encode(message.messageContextInfo, writer.uint32(/* id 35, wireType 2 =*/282).fork()).ldelim();
            if (message.listMessage != null && Object.hasOwnProperty.call(message, "listMessage"))
                $root.proto.ListMessage.encode(message.listMessage, writer.uint32(/* id 36, wireType 2 =*/290).fork()).ldelim();
            if (message.viewOnceMessage != null && Object.hasOwnProperty.call(message, "viewOnceMessage"))
                $root.proto.FutureProofMessage.encode(message.viewOnceMessage, writer.uint32(/* id 37, wireType 2 =*/298).fork()).ldelim();
            if (message.orderMessage != null && Object.hasOwnProperty.call(message, "orderMessage"))
                $root.proto.OrderMessage.encode(message.orderMessage, writer.uint32(/* id 38, wireType 2 =*/306).fork()).ldelim();
            if (message.listResponseMessage != null && Object.hasOwnProperty.call(message, "listResponseMessage"))
                $root.proto.ListResponseMessage.encode(message.listResponseMessage, writer.uint32(/* id 39, wireType 2 =*/314).fork()).ldelim();
            if (message.ephemeralMessage != null && Object.hasOwnProperty.call(message, "ephemeralMessage"))
                $root.proto.FutureProofMessage.encode(message.ephemeralMessage, writer.uint32(/* id 40, wireType 2 =*/322).fork()).ldelim();
            if (message.invoiceMessage != null && Object.hasOwnProperty.call(message, "invoiceMessage"))
                $root.proto.InvoiceMessage.encode(message.invoiceMessage, writer.uint32(/* id 41, wireType 2 =*/330).fork()).ldelim();
            if (message.buttonsMessage != null && Object.hasOwnProperty.call(message, "buttonsMessage"))
                $root.proto.ButtonsMessage.encode(message.buttonsMessage, writer.uint32(/* id 42, wireType 2 =*/338).fork()).ldelim();
            if (message.buttonsResponseMessage != null && Object.hasOwnProperty.call(message, "buttonsResponseMessage"))
                $root.proto.ButtonsResponseMessage.encode(message.buttonsResponseMessage, writer.uint32(/* id 43, wireType 2 =*/346).fork()).ldelim();
            if (message.paymentInviteMessage != null && Object.hasOwnProperty.call(message, "paymentInviteMessage"))
                $root.proto.PaymentInviteMessage.encode(message.paymentInviteMessage, writer.uint32(/* id 44, wireType 2 =*/354).fork()).ldelim();
            if (message.interactiveMessage != null && Object.hasOwnProperty.call(message, "interactiveMessage"))
                $root.proto.InteractiveMessage.encode(message.interactiveMessage, writer.uint32(/* id 45, wireType 2 =*/362).fork()).ldelim();
            if (message.reactionMessage != null && Object.hasOwnProperty.call(message, "reactionMessage"))
                $root.proto.ReactionMessage.encode(message.reactionMessage, writer.uint32(/* id 46, wireType 2 =*/370).fork()).ldelim();
            if (message.stickerSyncRmrMessage != null && Object.hasOwnProperty.call(message, "stickerSyncRmrMessage"))
                $root.proto.StickerSyncRMRMessage.encode(message.stickerSyncRmrMessage, writer.uint32(/* id 47, wireType 2 =*/378).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified Message message, length delimited. Does not implicitly {@link proto.Message.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.Message
         * @static
         * @param {proto.IMessage} message Message message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Message.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a Message message from the specified reader or buffer.
         * @function decode
         * @memberof proto.Message
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.Message} Message
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Message.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Message();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.conversation = reader.string();
                    break;
                case 2:
                    message.senderKeyDistributionMessage = $root.proto.SenderKeyDistributionMessage.decode(reader, reader.uint32());
                    break;
                case 3:
                    message.imageMessage = $root.proto.ImageMessage.decode(reader, reader.uint32());
                    break;
                case 4:
                    message.contactMessage = $root.proto.ContactMessage.decode(reader, reader.uint32());
                    break;
                case 5:
                    message.locationMessage = $root.proto.LocationMessage.decode(reader, reader.uint32());
                    break;
                case 6:
                    message.extendedTextMessage = $root.proto.ExtendedTextMessage.decode(reader, reader.uint32());
                    break;
                case 7:
                    message.documentMessage = $root.proto.DocumentMessage.decode(reader, reader.uint32());
                    break;
                case 8:
                    message.audioMessage = $root.proto.AudioMessage.decode(reader, reader.uint32());
                    break;
                case 9:
                    message.videoMessage = $root.proto.VideoMessage.decode(reader, reader.uint32());
                    break;
                case 10:
                    message.call = $root.proto.Call.decode(reader, reader.uint32());
                    break;
                case 11:
                    message.chat = $root.proto.Chat.decode(reader, reader.uint32());
                    break;
                case 12:
                    message.protocolMessage = $root.proto.ProtocolMessage.decode(reader, reader.uint32());
                    break;
                case 13:
                    message.contactsArrayMessage = $root.proto.ContactsArrayMessage.decode(reader, reader.uint32());
                    break;
                case 14:
                    message.highlyStructuredMessage = $root.proto.HighlyStructuredMessage.decode(reader, reader.uint32());
                    break;
                case 15:
                    message.fastRatchetKeySenderKeyDistributionMessage = $root.proto.SenderKeyDistributionMessage.decode(reader, reader.uint32());
                    break;
                case 16:
                    message.sendPaymentMessage = $root.proto.SendPaymentMessage.decode(reader, reader.uint32());
                    break;
                case 18:
                    message.liveLocationMessage = $root.proto.LiveLocationMessage.decode(reader, reader.uint32());
                    break;
                case 22:
                    message.requestPaymentMessage = $root.proto.RequestPaymentMessage.decode(reader, reader.uint32());
                    break;
                case 23:
                    message.declinePaymentRequestMessage = $root.proto.DeclinePaymentRequestMessage.decode(reader, reader.uint32());
                    break;
                case 24:
                    message.cancelPaymentRequestMessage = $root.proto.CancelPaymentRequestMessage.decode(reader, reader.uint32());
                    break;
                case 25:
                    message.templateMessage = $root.proto.TemplateMessage.decode(reader, reader.uint32());
                    break;
                case 26:
                    message.stickerMessage = $root.proto.StickerMessage.decode(reader, reader.uint32());
                    break;
                case 28:
                    message.groupInviteMessage = $root.proto.GroupInviteMessage.decode(reader, reader.uint32());
                    break;
                case 29:
                    message.templateButtonReplyMessage = $root.proto.TemplateButtonReplyMessage.decode(reader, reader.uint32());
                    break;
                case 30:
                    message.productMessage = $root.proto.ProductMessage.decode(reader, reader.uint32());
                    break;
                case 31:
                    message.deviceSentMessage = $root.proto.DeviceSentMessage.decode(reader, reader.uint32());
                    break;
                case 35:
                    message.messageContextInfo = $root.proto.MessageContextInfo.decode(reader, reader.uint32());
                    break;
                case 36:
                    message.listMessage = $root.proto.ListMessage.decode(reader, reader.uint32());
                    break;
                case 37:
                    message.viewOnceMessage = $root.proto.FutureProofMessage.decode(reader, reader.uint32());
                    break;
                case 38:
                    message.orderMessage = $root.proto.OrderMessage.decode(reader, reader.uint32());
                    break;
                case 39:
                    message.listResponseMessage = $root.proto.ListResponseMessage.decode(reader, reader.uint32());
                    break;
                case 40:
                    message.ephemeralMessage = $root.proto.FutureProofMessage.decode(reader, reader.uint32());
                    break;
                case 41:
                    message.invoiceMessage = $root.proto.InvoiceMessage.decode(reader, reader.uint32());
                    break;
                case 42:
                    message.buttonsMessage = $root.proto.ButtonsMessage.decode(reader, reader.uint32());
                    break;
                case 43:
                    message.buttonsResponseMessage = $root.proto.ButtonsResponseMessage.decode(reader, reader.uint32());
                    break;
                case 44:
                    message.paymentInviteMessage = $root.proto.PaymentInviteMessage.decode(reader, reader.uint32());
                    break;
                case 45:
                    message.interactiveMessage = $root.proto.InteractiveMessage.decode(reader, reader.uint32());
                    break;
                case 46:
                    message.reactionMessage = $root.proto.ReactionMessage.decode(reader, reader.uint32());
                    break;
                case 47:
                    message.stickerSyncRmrMessage = $root.proto.StickerSyncRMRMessage.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a Message message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.Message
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.Message} Message
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Message.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a Message message.
         * @function verify
         * @memberof proto.Message
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        Message.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.conversation != null && message.hasOwnProperty("conversation"))
                if (!$util.isString(message.conversation))
                    return "conversation: string expected";
            if (message.senderKeyDistributionMessage != null && message.hasOwnProperty("senderKeyDistributionMessage")) {
                var error = $root.proto.SenderKeyDistributionMessage.verify(message.senderKeyDistributionMessage);
                if (error)
                    return "senderKeyDistributionMessage." + error;
            }
            if (message.imageMessage != null && message.hasOwnProperty("imageMessage")) {
                var error = $root.proto.ImageMessage.verify(message.imageMessage);
                if (error)
                    return "imageMessage." + error;
            }
            if (message.contactMessage != null && message.hasOwnProperty("contactMessage")) {
                var error = $root.proto.ContactMessage.verify(message.contactMessage);
                if (error)
                    return "contactMessage." + error;
            }
            if (message.locationMessage != null && message.hasOwnProperty("locationMessage")) {
                var error = $root.proto.LocationMessage.verify(message.locationMessage);
                if (error)
                    return "locationMessage." + error;
            }
            if (message.extendedTextMessage != null && message.hasOwnProperty("extendedTextMessage")) {
                var error = $root.proto.ExtendedTextMessage.verify(message.extendedTextMessage);
                if (error)
                    return "extendedTextMessage." + error;
            }
            if (message.documentMessage != null && message.hasOwnProperty("documentMessage")) {
                var error = $root.proto.DocumentMessage.verify(message.documentMessage);
                if (error)
                    return "documentMessage." + error;
            }
            if (message.audioMessage != null && message.hasOwnProperty("audioMessage")) {
                var error = $root.proto.AudioMessage.verify(message.audioMessage);
                if (error)
                    return "audioMessage." + error;
            }
            if (message.videoMessage != null && message.hasOwnProperty("videoMessage")) {
                var error = $root.proto.VideoMessage.verify(message.videoMessage);
                if (error)
                    return "videoMessage." + error;
            }
            if (message.call != null && message.hasOwnProperty("call")) {
                var error = $root.proto.Call.verify(message.call);
                if (error)
                    return "call." + error;
            }
            if (message.chat != null && message.hasOwnProperty("chat")) {
                var error = $root.proto.Chat.verify(message.chat);
                if (error)
                    return "chat." + error;
            }
            if (message.protocolMessage != null && message.hasOwnProperty("protocolMessage")) {
                var error = $root.proto.ProtocolMessage.verify(message.protocolMessage);
                if (error)
                    return "protocolMessage." + error;
            }
            if (message.contactsArrayMessage != null && message.hasOwnProperty("contactsArrayMessage")) {
                var error = $root.proto.ContactsArrayMessage.verify(message.contactsArrayMessage);
                if (error)
                    return "contactsArrayMessage." + error;
            }
            if (message.highlyStructuredMessage != null && message.hasOwnProperty("highlyStructuredMessage")) {
                var error = $root.proto.HighlyStructuredMessage.verify(message.highlyStructuredMessage);
                if (error)
                    return "highlyStructuredMessage." + error;
            }
            if (message.fastRatchetKeySenderKeyDistributionMessage != null && message.hasOwnProperty("fastRatchetKeySenderKeyDistributionMessage")) {
                var error = $root.proto.SenderKeyDistributionMessage.verify(message.fastRatchetKeySenderKeyDistributionMessage);
                if (error)
                    return "fastRatchetKeySenderKeyDistributionMessage." + error;
            }
            if (message.sendPaymentMessage != null && message.hasOwnProperty("sendPaymentMessage")) {
                var error = $root.proto.SendPaymentMessage.verify(message.sendPaymentMessage);
                if (error)
                    return "sendPaymentMessage." + error;
            }
            if (message.liveLocationMessage != null && message.hasOwnProperty("liveLocationMessage")) {
                var error = $root.proto.LiveLocationMessage.verify(message.liveLocationMessage);
                if (error)
                    return "liveLocationMessage." + error;
            }
            if (message.requestPaymentMessage != null && message.hasOwnProperty("requestPaymentMessage")) {
                var error = $root.proto.RequestPaymentMessage.verify(message.requestPaymentMessage);
                if (error)
                    return "requestPaymentMessage." + error;
            }
            if (message.declinePaymentRequestMessage != null && message.hasOwnProperty("declinePaymentRequestMessage")) {
                var error = $root.proto.DeclinePaymentRequestMessage.verify(message.declinePaymentRequestMessage);
                if (error)
                    return "declinePaymentRequestMessage." + error;
            }
            if (message.cancelPaymentRequestMessage != null && message.hasOwnProperty("cancelPaymentRequestMessage")) {
                var error = $root.proto.CancelPaymentRequestMessage.verify(message.cancelPaymentRequestMessage);
                if (error)
                    return "cancelPaymentRequestMessage." + error;
            }
            if (message.templateMessage != null && message.hasOwnProperty("templateMessage")) {
                var error = $root.proto.TemplateMessage.verify(message.templateMessage);
                if (error)
                    return "templateMessage." + error;
            }
            if (message.stickerMessage != null && message.hasOwnProperty("stickerMessage")) {
                var error = $root.proto.StickerMessage.verify(message.stickerMessage);
                if (error)
                    return "stickerMessage." + error;
            }
            if (message.groupInviteMessage != null && message.hasOwnProperty("groupInviteMessage")) {
                var error = $root.proto.GroupInviteMessage.verify(message.groupInviteMessage);
                if (error)
                    return "groupInviteMessage." + error;
            }
            if (message.templateButtonReplyMessage != null && message.hasOwnProperty("templateButtonReplyMessage")) {
                var error = $root.proto.TemplateButtonReplyMessage.verify(message.templateButtonReplyMessage);
                if (error)
                    return "templateButtonReplyMessage." + error;
            }
            if (message.productMessage != null && message.hasOwnProperty("productMessage")) {
                var error = $root.proto.ProductMessage.verify(message.productMessage);
                if (error)
                    return "productMessage." + error;
            }
            if (message.deviceSentMessage != null && message.hasOwnProperty("deviceSentMessage")) {
                var error = $root.proto.DeviceSentMessage.verify(message.deviceSentMessage);
                if (error)
                    return "deviceSentMessage." + error;
            }
            if (message.messageContextInfo != null && message.hasOwnProperty("messageContextInfo")) {
                var error = $root.proto.MessageContextInfo.verify(message.messageContextInfo);
                if (error)
                    return "messageContextInfo." + error;
            }
            if (message.listMessage != null && message.hasOwnProperty("listMessage")) {
                var error = $root.proto.ListMessage.verify(message.listMessage);
                if (error)
                    return "listMessage." + error;
            }
            if (message.viewOnceMessage != null && message.hasOwnProperty("viewOnceMessage")) {
                var error = $root.proto.FutureProofMessage.verify(message.viewOnceMessage);
                if (error)
                    return "viewOnceMessage." + error;
            }
            if (message.orderMessage != null && message.hasOwnProperty("orderMessage")) {
                var error = $root.proto.OrderMessage.verify(message.orderMessage);
                if (error)
                    return "orderMessage." + error;
            }
            if (message.listResponseMessage != null && message.hasOwnProperty("listResponseMessage")) {
                var error = $root.proto.ListResponseMessage.verify(message.listResponseMessage);
                if (error)
                    return "listResponseMessage." + error;
            }
            if (message.ephemeralMessage != null && message.hasOwnProperty("ephemeralMessage")) {
                var error = $root.proto.FutureProofMessage.verify(message.ephemeralMessage);
                if (error)
                    return "ephemeralMessage." + error;
            }
            if (message.invoiceMessage != null && message.hasOwnProperty("invoiceMessage")) {
                var error = $root.proto.InvoiceMessage.verify(message.invoiceMessage);
                if (error)
                    return "invoiceMessage." + error;
            }
            if (message.buttonsMessage != null && message.hasOwnProperty("buttonsMessage")) {
                var error = $root.proto.ButtonsMessage.verify(message.buttonsMessage);
                if (error)
                    return "buttonsMessage." + error;
            }
            if (message.buttonsResponseMessage != null && message.hasOwnProperty("buttonsResponseMessage")) {
                var error = $root.proto.ButtonsResponseMessage.verify(message.buttonsResponseMessage);
                if (error)
                    return "buttonsResponseMessage." + error;
            }
            if (message.paymentInviteMessage != null && message.hasOwnProperty("paymentInviteMessage")) {
                var error = $root.proto.PaymentInviteMessage.verify(message.paymentInviteMessage);
                if (error)
                    return "paymentInviteMessage." + error;
            }
            if (message.interactiveMessage != null && message.hasOwnProperty("interactiveMessage")) {
                var error = $root.proto.InteractiveMessage.verify(message.interactiveMessage);
                if (error)
                    return "interactiveMessage." + error;
            }
            if (message.reactionMessage != null && message.hasOwnProperty("reactionMessage")) {
                var error = $root.proto.ReactionMessage.verify(message.reactionMessage);
                if (error)
                    return "reactionMessage." + error;
            }
            if (message.stickerSyncRmrMessage != null && message.hasOwnProperty("stickerSyncRmrMessage")) {
                var error = $root.proto.StickerSyncRMRMessage.verify(message.stickerSyncRmrMessage);
                if (error)
                    return "stickerSyncRmrMessage." + error;
            }
            return null;
        };

        /**
         * Creates a Message message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.Message
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.Message} Message
         */
        Message.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.Message)
                return object;
            var message = new $root.proto.Message();
            if (object.conversation != null)
                message.conversation = String(object.conversation);
            if (object.senderKeyDistributionMessage != null) {
                if (typeof object.senderKeyDistributionMessage !== "object")
                    throw TypeError(".proto.Message.senderKeyDistributionMessage: object expected");
                message.senderKeyDistributionMessage = $root.proto.SenderKeyDistributionMessage.fromObject(object.senderKeyDistributionMessage);
            }
            if (object.imageMessage != null) {
                if (typeof object.imageMessage !== "object")
                    throw TypeError(".proto.Message.imageMessage: object expected");
                message.imageMessage = $root.proto.ImageMessage.fromObject(object.imageMessage);
            }
            if (object.contactMessage != null) {
                if (typeof object.contactMessage !== "object")
                    throw TypeError(".proto.Message.contactMessage: object expected");
                message.contactMessage = $root.proto.ContactMessage.fromObject(object.contactMessage);
            }
            if (object.locationMessage != null) {
                if (typeof object.locationMessage !== "object")
                    throw TypeError(".proto.Message.locationMessage: object expected");
                message.locationMessage = $root.proto.LocationMessage.fromObject(object.locationMessage);
            }
            if (object.extendedTextMessage != null) {
                if (typeof object.extendedTextMessage !== "object")
                    throw TypeError(".proto.Message.extendedTextMessage: object expected");
                message.extendedTextMessage = $root.proto.ExtendedTextMessage.fromObject(object.extendedTextMessage);
            }
            if (object.documentMessage != null) {
                if (typeof object.documentMessage !== "object")
                    throw TypeError(".proto.Message.documentMessage: object expected");
                message.documentMessage = $root.proto.DocumentMessage.fromObject(object.documentMessage);
            }
            if (object.audioMessage != null) {
                if (typeof object.audioMessage !== "object")
                    throw TypeError(".proto.Message.audioMessage: object expected");
                message.audioMessage = $root.proto.AudioMessage.fromObject(object.audioMessage);
            }
            if (object.videoMessage != null) {
                if (typeof object.videoMessage !== "object")
                    throw TypeError(".proto.Message.videoMessage: object expected");
                message.videoMessage = $root.proto.VideoMessage.fromObject(object.videoMessage);
            }
            if (object.call != null) {
                if (typeof object.call !== "object")
                    throw TypeError(".proto.Message.call: object expected");
                message.call = $root.proto.Call.fromObject(object.call);
            }
            if (object.chat != null) {
                if (typeof object.chat !== "object")
                    throw TypeError(".proto.Message.chat: object expected");
                message.chat = $root.proto.Chat.fromObject(object.chat);
            }
            if (object.protocolMessage != null) {
                if (typeof object.protocolMessage !== "object")
                    throw TypeError(".proto.Message.protocolMessage: object expected");
                message.protocolMessage = $root.proto.ProtocolMessage.fromObject(object.protocolMessage);
            }
            if (object.contactsArrayMessage != null) {
                if (typeof object.contactsArrayMessage !== "object")
                    throw TypeError(".proto.Message.contactsArrayMessage: object expected");
                message.contactsArrayMessage = $root.proto.ContactsArrayMessage.fromObject(object.contactsArrayMessage);
            }
            if (object.highlyStructuredMessage != null) {
                if (typeof object.highlyStructuredMessage !== "object")
                    throw TypeError(".proto.Message.highlyStructuredMessage: object expected");
                message.highlyStructuredMessage = $root.proto.HighlyStructuredMessage.fromObject(object.highlyStructuredMessage);
            }
            if (object.fastRatchetKeySenderKeyDistributionMessage != null) {
                if (typeof object.fastRatchetKeySenderKeyDistributionMessage !== "object")
                    throw TypeError(".proto.Message.fastRatchetKeySenderKeyDistributionMessage: object expected");
                message.fastRatchetKeySenderKeyDistributionMessage = $root.proto.SenderKeyDistributionMessage.fromObject(object.fastRatchetKeySenderKeyDistributionMessage);
            }
            if (object.sendPaymentMessage != null) {
                if (typeof object.sendPaymentMessage !== "object")
                    throw TypeError(".proto.Message.sendPaymentMessage: object expected");
                message.sendPaymentMessage = $root.proto.SendPaymentMessage.fromObject(object.sendPaymentMessage);
            }
            if (object.liveLocationMessage != null) {
                if (typeof object.liveLocationMessage !== "object")
                    throw TypeError(".proto.Message.liveLocationMessage: object expected");
                message.liveLocationMessage = $root.proto.LiveLocationMessage.fromObject(object.liveLocationMessage);
            }
            if (object.requestPaymentMessage != null) {
                if (typeof object.requestPaymentMessage !== "object")
                    throw TypeError(".proto.Message.requestPaymentMessage: object expected");
                message.requestPaymentMessage = $root.proto.RequestPaymentMessage.fromObject(object.requestPaymentMessage);
            }
            if (object.declinePaymentRequestMessage != null) {
                if (typeof object.declinePaymentRequestMessage !== "object")
                    throw TypeError(".proto.Message.declinePaymentRequestMessage: object expected");
                message.declinePaymentRequestMessage = $root.proto.DeclinePaymentRequestMessage.fromObject(object.declinePaymentRequestMessage);
            }
            if (object.cancelPaymentRequestMessage != null) {
                if (typeof object.cancelPaymentRequestMessage !== "object")
                    throw TypeError(".proto.Message.cancelPaymentRequestMessage: object expected");
                message.cancelPaymentRequestMessage = $root.proto.CancelPaymentRequestMessage.fromObject(object.cancelPaymentRequestMessage);
            }
            if (object.templateMessage != null) {
                if (typeof object.templateMessage !== "object")
                    throw TypeError(".proto.Message.templateMessage: object expected");
                message.templateMessage = $root.proto.TemplateMessage.fromObject(object.templateMessage);
            }
            if (object.stickerMessage != null) {
                if (typeof object.stickerMessage !== "object")
                    throw TypeError(".proto.Message.stickerMessage: object expected");
                message.stickerMessage = $root.proto.StickerMessage.fromObject(object.stickerMessage);
            }
            if (object.groupInviteMessage != null) {
                if (typeof object.groupInviteMessage !== "object")
                    throw TypeError(".proto.Message.groupInviteMessage: object expected");
                message.groupInviteMessage = $root.proto.GroupInviteMessage.fromObject(object.groupInviteMessage);
            }
            if (object.templateButtonReplyMessage != null) {
                if (typeof object.templateButtonReplyMessage !== "object")
                    throw TypeError(".proto.Message.templateButtonReplyMessage: object expected");
                message.templateButtonReplyMessage = $root.proto.TemplateButtonReplyMessage.fromObject(object.templateButtonReplyMessage);
            }
            if (object.productMessage != null) {
                if (typeof object.productMessage !== "object")
                    throw TypeError(".proto.Message.productMessage: object expected");
                message.productMessage = $root.proto.ProductMessage.fromObject(object.productMessage);
            }
            if (object.deviceSentMessage != null) {
                if (typeof object.deviceSentMessage !== "object")
                    throw TypeError(".proto.Message.deviceSentMessage: object expected");
                message.deviceSentMessage = $root.proto.DeviceSentMessage.fromObject(object.deviceSentMessage);
            }
            if (object.messageContextInfo != null) {
                if (typeof object.messageContextInfo !== "object")
                    throw TypeError(".proto.Message.messageContextInfo: object expected");
                message.messageContextInfo = $root.proto.MessageContextInfo.fromObject(object.messageContextInfo);
            }
            if (object.listMessage != null) {
                if (typeof object.listMessage !== "object")
                    throw TypeError(".proto.Message.listMessage: object expected");
                message.listMessage = $root.proto.ListMessage.fromObject(object.listMessage);
            }
            if (object.viewOnceMessage != null) {
                if (typeof object.viewOnceMessage !== "object")
                    throw TypeError(".proto.Message.viewOnceMessage: object expected");
                message.viewOnceMessage = $root.proto.FutureProofMessage.fromObject(object.viewOnceMessage);
            }
            if (object.orderMessage != null) {
                if (typeof object.orderMessage !== "object")
                    throw TypeError(".proto.Message.orderMessage: object expected");
                message.orderMessage = $root.proto.OrderMessage.fromObject(object.orderMessage);
            }
            if (object.listResponseMessage != null) {
                if (typeof object.listResponseMessage !== "object")
                    throw TypeError(".proto.Message.listResponseMessage: object expected");
                message.listResponseMessage = $root.proto.ListResponseMessage.fromObject(object.listResponseMessage);
            }
            if (object.ephemeralMessage != null) {
                if (typeof object.ephemeralMessage !== "object")
                    throw TypeError(".proto.Message.ephemeralMessage: object expected");
                message.ephemeralMessage = $root.proto.FutureProofMessage.fromObject(object.ephemeralMessage);
            }
            if (object.invoiceMessage != null) {
                if (typeof object.invoiceMessage !== "object")
                    throw TypeError(".proto.Message.invoiceMessage: object expected");
                message.invoiceMessage = $root.proto.InvoiceMessage.fromObject(object.invoiceMessage);
            }
            if (object.buttonsMessage != null) {
                if (typeof object.buttonsMessage !== "object")
                    throw TypeError(".proto.Message.buttonsMessage: object expected");
                message.buttonsMessage = $root.proto.ButtonsMessage.fromObject(object.buttonsMessage);
            }
            if (object.buttonsResponseMessage != null) {
                if (typeof object.buttonsResponseMessage !== "object")
                    throw TypeError(".proto.Message.buttonsResponseMessage: object expected");
                message.buttonsResponseMessage = $root.proto.ButtonsResponseMessage.fromObject(object.buttonsResponseMessage);
            }
            if (object.paymentInviteMessage != null) {
                if (typeof object.paymentInviteMessage !== "object")
                    throw TypeError(".proto.Message.paymentInviteMessage: object expected");
                message.paymentInviteMessage = $root.proto.PaymentInviteMessage.fromObject(object.paymentInviteMessage);
            }
            if (object.interactiveMessage != null) {
                if (typeof object.interactiveMessage !== "object")
                    throw TypeError(".proto.Message.interactiveMessage: object expected");
                message.interactiveMessage = $root.proto.InteractiveMessage.fromObject(object.interactiveMessage);
            }
            if (object.reactionMessage != null) {
                if (typeof object.reactionMessage !== "object")
                    throw TypeError(".proto.Message.reactionMessage: object expected");
                message.reactionMessage = $root.proto.ReactionMessage.fromObject(object.reactionMessage);
            }
            if (object.stickerSyncRmrMessage != null) {
                if (typeof object.stickerSyncRmrMessage !== "object")
                    throw TypeError(".proto.Message.stickerSyncRmrMessage: object expected");
                message.stickerSyncRmrMessage = $root.proto.StickerSyncRMRMessage.fromObject(object.stickerSyncRmrMessage);
            }
            return message;
        };

        /**
         * Creates a plain object from a Message message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.Message
         * @static
         * @param {proto.Message} message Message
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        Message.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.conversation = "";
                object.senderKeyDistributionMessage = null;
                object.imageMessage = null;
                object.contactMessage = null;
                object.locationMessage = null;
                object.extendedTextMessage = null;
                object.documentMessage = null;
                object.audioMessage = null;
                object.videoMessage = null;
                object.call = null;
                object.chat = null;
                object.protocolMessage = null;
                object.contactsArrayMessage = null;
                object.highlyStructuredMessage = null;
                object.fastRatchetKeySenderKeyDistributionMessage = null;
                object.sendPaymentMessage = null;
                object.liveLocationMessage = null;
                object.requestPaymentMessage = null;
                object.declinePaymentRequestMessage = null;
                object.cancelPaymentRequestMessage = null;
                object.templateMessage = null;
                object.stickerMessage = null;
                object.groupInviteMessage = null;
                object.templateButtonReplyMessage = null;
                object.productMessage = null;
                object.deviceSentMessage = null;
                object.messageContextInfo = null;
                object.listMessage = null;
                object.viewOnceMessage = null;
                object.orderMessage = null;
                object.listResponseMessage = null;
                object.ephemeralMessage = null;
                object.invoiceMessage = null;
                object.buttonsMessage = null;
                object.buttonsResponseMessage = null;
                object.paymentInviteMessage = null;
                object.interactiveMessage = null;
                object.reactionMessage = null;
                object.stickerSyncRmrMessage = null;
            }
            if (message.conversation != null && message.hasOwnProperty("conversation"))
                object.conversation = message.conversation;
            if (message.senderKeyDistributionMessage != null && message.hasOwnProperty("senderKeyDistributionMessage"))
                object.senderKeyDistributionMessage = $root.proto.SenderKeyDistributionMessage.toObject(message.senderKeyDistributionMessage, options);
            if (message.imageMessage != null && message.hasOwnProperty("imageMessage"))
                object.imageMessage = $root.proto.ImageMessage.toObject(message.imageMessage, options);
            if (message.contactMessage != null && message.hasOwnProperty("contactMessage"))
                object.contactMessage = $root.proto.ContactMessage.toObject(message.contactMessage, options);
            if (message.locationMessage != null && message.hasOwnProperty("locationMessage"))
                object.locationMessage = $root.proto.LocationMessage.toObject(message.locationMessage, options);
            if (message.extendedTextMessage != null && message.hasOwnProperty("extendedTextMessage"))
                object.extendedTextMessage = $root.proto.ExtendedTextMessage.toObject(message.extendedTextMessage, options);
            if (message.documentMessage != null && message.hasOwnProperty("documentMessage"))
                object.documentMessage = $root.proto.DocumentMessage.toObject(message.documentMessage, options);
            if (message.audioMessage != null && message.hasOwnProperty("audioMessage"))
                object.audioMessage = $root.proto.AudioMessage.toObject(message.audioMessage, options);
            if (message.videoMessage != null && message.hasOwnProperty("videoMessage"))
                object.videoMessage = $root.proto.VideoMessage.toObject(message.videoMessage, options);
            if (message.call != null && message.hasOwnProperty("call"))
                object.call = $root.proto.Call.toObject(message.call, options);
            if (message.chat != null && message.hasOwnProperty("chat"))
                object.chat = $root.proto.Chat.toObject(message.chat, options);
            if (message.protocolMessage != null && message.hasOwnProperty("protocolMessage"))
                object.protocolMessage = $root.proto.ProtocolMessage.toObject(message.protocolMessage, options);
            if (message.contactsArrayMessage != null && message.hasOwnProperty("contactsArrayMessage"))
                object.contactsArrayMessage = $root.proto.ContactsArrayMessage.toObject(message.contactsArrayMessage, options);
            if (message.highlyStructuredMessage != null && message.hasOwnProperty("highlyStructuredMessage"))
                object.highlyStructuredMessage = $root.proto.HighlyStructuredMessage.toObject(message.highlyStructuredMessage, options);
            if (message.fastRatchetKeySenderKeyDistributionMessage != null && message.hasOwnProperty("fastRatchetKeySenderKeyDistributionMessage"))
                object.fastRatchetKeySenderKeyDistributionMessage = $root.proto.SenderKeyDistributionMessage.toObject(message.fastRatchetKeySenderKeyDistributionMessage, options);
            if (message.sendPaymentMessage != null && message.hasOwnProperty("sendPaymentMessage"))
                object.sendPaymentMessage = $root.proto.SendPaymentMessage.toObject(message.sendPaymentMessage, options);
            if (message.liveLocationMessage != null && message.hasOwnProperty("liveLocationMessage"))
                object.liveLocationMessage = $root.proto.LiveLocationMessage.toObject(message.liveLocationMessage, options);
            if (message.requestPaymentMessage != null && message.hasOwnProperty("requestPaymentMessage"))
                object.requestPaymentMessage = $root.proto.RequestPaymentMessage.toObject(message.requestPaymentMessage, options);
            if (message.declinePaymentRequestMessage != null && message.hasOwnProperty("declinePaymentRequestMessage"))
                object.declinePaymentRequestMessage = $root.proto.DeclinePaymentRequestMessage.toObject(message.declinePaymentRequestMessage, options);
            if (message.cancelPaymentRequestMessage != null && message.hasOwnProperty("cancelPaymentRequestMessage"))
                object.cancelPaymentRequestMessage = $root.proto.CancelPaymentRequestMessage.toObject(message.cancelPaymentRequestMessage, options);
            if (message.templateMessage != null && message.hasOwnProperty("templateMessage"))
                object.templateMessage = $root.proto.TemplateMessage.toObject(message.templateMessage, options);
            if (message.stickerMessage != null && message.hasOwnProperty("stickerMessage"))
                object.stickerMessage = $root.proto.StickerMessage.toObject(message.stickerMessage, options);
            if (message.groupInviteMessage != null && message.hasOwnProperty("groupInviteMessage"))
                object.groupInviteMessage = $root.proto.GroupInviteMessage.toObject(message.groupInviteMessage, options);
            if (message.templateButtonReplyMessage != null && message.hasOwnProperty("templateButtonReplyMessage"))
                object.templateButtonReplyMessage = $root.proto.TemplateButtonReplyMessage.toObject(message.templateButtonReplyMessage, options);
            if (message.productMessage != null && message.hasOwnProperty("productMessage"))
                object.productMessage = $root.proto.ProductMessage.toObject(message.productMessage, options);
            if (message.deviceSentMessage != null && message.hasOwnProperty("deviceSentMessage"))
                object.deviceSentMessage = $root.proto.DeviceSentMessage.toObject(message.deviceSentMessage, options);
            if (message.messageContextInfo != null && message.hasOwnProperty("messageContextInfo"))
                object.messageContextInfo = $root.proto.MessageContextInfo.toObject(message.messageContextInfo, options);
            if (message.listMessage != null && message.hasOwnProperty("listMessage"))
                object.listMessage = $root.proto.ListMessage.toObject(message.listMessage, options);
            if (message.viewOnceMessage != null && message.hasOwnProperty("viewOnceMessage"))
                object.viewOnceMessage = $root.proto.FutureProofMessage.toObject(message.viewOnceMessage, options);
            if (message.orderMessage != null && message.hasOwnProperty("orderMessage"))
                object.orderMessage = $root.proto.OrderMessage.toObject(message.orderMessage, options);
            if (message.listResponseMessage != null && message.hasOwnProperty("listResponseMessage"))
                object.listResponseMessage = $root.proto.ListResponseMessage.toObject(message.listResponseMessage, options);
            if (message.ephemeralMessage != null && message.hasOwnProperty("ephemeralMessage"))
                object.ephemeralMessage = $root.proto.FutureProofMessage.toObject(message.ephemeralMessage, options);
            if (message.invoiceMessage != null && message.hasOwnProperty("invoiceMessage"))
                object.invoiceMessage = $root.proto.InvoiceMessage.toObject(message.invoiceMessage, options);
            if (message.buttonsMessage != null && message.hasOwnProperty("buttonsMessage"))
                object.buttonsMessage = $root.proto.ButtonsMessage.toObject(message.buttonsMessage, options);
            if (message.buttonsResponseMessage != null && message.hasOwnProperty("buttonsResponseMessage"))
                object.buttonsResponseMessage = $root.proto.ButtonsResponseMessage.toObject(message.buttonsResponseMessage, options);
            if (message.paymentInviteMessage != null && message.hasOwnProperty("paymentInviteMessage"))
                object.paymentInviteMessage = $root.proto.PaymentInviteMessage.toObject(message.paymentInviteMessage, options);
            if (message.interactiveMessage != null && message.hasOwnProperty("interactiveMessage"))
                object.interactiveMessage = $root.proto.InteractiveMessage.toObject(message.interactiveMessage, options);
            if (message.reactionMessage != null && message.hasOwnProperty("reactionMessage"))
                object.reactionMessage = $root.proto.ReactionMessage.toObject(message.reactionMessage, options);
            if (message.stickerSyncRmrMessage != null && message.hasOwnProperty("stickerSyncRmrMessage"))
                object.stickerSyncRmrMessage = $root.proto.StickerSyncRMRMessage.toObject(message.stickerSyncRmrMessage, options);
            return object;
        };

        /**
         * Converts this Message to JSON.
         * @function toJSON
         * @memberof proto.Message
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        Message.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return Message;
    })();

    proto.ActionLink = (function() {

        /**
         * Properties of an ActionLink.
         * @memberof proto
         * @interface IActionLink
         * @property {string|null} [url] ActionLink url
         * @property {string|null} [buttonTitle] ActionLink buttonTitle
         */

        /**
         * Constructs a new ActionLink.
         * @memberof proto
         * @classdesc Represents an ActionLink.
         * @implements IActionLink
         * @constructor
         * @param {proto.IActionLink=} [properties] Properties to set
         */
        function ActionLink(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ActionLink url.
         * @member {string} url
         * @memberof proto.ActionLink
         * @instance
         */
        ActionLink.prototype.url = "";

        /**
         * ActionLink buttonTitle.
         * @member {string} buttonTitle
         * @memberof proto.ActionLink
         * @instance
         */
        ActionLink.prototype.buttonTitle = "";

        /**
         * Creates a new ActionLink instance using the specified properties.
         * @function create
         * @memberof proto.ActionLink
         * @static
         * @param {proto.IActionLink=} [properties] Properties to set
         * @returns {proto.ActionLink} ActionLink instance
         */
        ActionLink.create = function create(properties) {
            return new ActionLink(properties);
        };

        /**
         * Encodes the specified ActionLink message. Does not implicitly {@link proto.ActionLink.verify|verify} messages.
         * @function encode
         * @memberof proto.ActionLink
         * @static
         * @param {proto.IActionLink} message ActionLink message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ActionLink.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.url != null && Object.hasOwnProperty.call(message, "url"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.url);
            if (message.buttonTitle != null && Object.hasOwnProperty.call(message, "buttonTitle"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.buttonTitle);
            return writer;
        };

        /**
         * Encodes the specified ActionLink message, length delimited. Does not implicitly {@link proto.ActionLink.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ActionLink
         * @static
         * @param {proto.IActionLink} message ActionLink message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ActionLink.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes an ActionLink message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ActionLink
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ActionLink} ActionLink
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ActionLink.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ActionLink();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.url = reader.string();
                    break;
                case 2:
                    message.buttonTitle = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes an ActionLink message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ActionLink
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ActionLink} ActionLink
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ActionLink.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies an ActionLink message.
         * @function verify
         * @memberof proto.ActionLink
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ActionLink.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.url != null && message.hasOwnProperty("url"))
                if (!$util.isString(message.url))
                    return "url: string expected";
            if (message.buttonTitle != null && message.hasOwnProperty("buttonTitle"))
                if (!$util.isString(message.buttonTitle))
                    return "buttonTitle: string expected";
            return null;
        };

        /**
         * Creates an ActionLink message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ActionLink
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ActionLink} ActionLink
         */
        ActionLink.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ActionLink)
                return object;
            var message = new $root.proto.ActionLink();
            if (object.url != null)
                message.url = String(object.url);
            if (object.buttonTitle != null)
                message.buttonTitle = String(object.buttonTitle);
            return message;
        };

        /**
         * Creates a plain object from an ActionLink message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ActionLink
         * @static
         * @param {proto.ActionLink} message ActionLink
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ActionLink.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.url = "";
                object.buttonTitle = "";
            }
            if (message.url != null && message.hasOwnProperty("url"))
                object.url = message.url;
            if (message.buttonTitle != null && message.hasOwnProperty("buttonTitle"))
                object.buttonTitle = message.buttonTitle;
            return object;
        };

        /**
         * Converts this ActionLink to JSON.
         * @function toJSON
         * @memberof proto.ActionLink
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ActionLink.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ActionLink;
    })();

    proto.DisappearingMode = (function() {

        /**
         * Properties of a DisappearingMode.
         * @memberof proto
         * @interface IDisappearingMode
         * @property {proto.DisappearingMode.DisappearingModeInitiator|null} [initiator] DisappearingMode initiator
         */

        /**
         * Constructs a new DisappearingMode.
         * @memberof proto
         * @classdesc Represents a DisappearingMode.
         * @implements IDisappearingMode
         * @constructor
         * @param {proto.IDisappearingMode=} [properties] Properties to set
         */
        function DisappearingMode(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * DisappearingMode initiator.
         * @member {proto.DisappearingMode.DisappearingModeInitiator} initiator
         * @memberof proto.DisappearingMode
         * @instance
         */
        DisappearingMode.prototype.initiator = 0;

        /**
         * Creates a new DisappearingMode instance using the specified properties.
         * @function create
         * @memberof proto.DisappearingMode
         * @static
         * @param {proto.IDisappearingMode=} [properties] Properties to set
         * @returns {proto.DisappearingMode} DisappearingMode instance
         */
        DisappearingMode.create = function create(properties) {
            return new DisappearingMode(properties);
        };

        /**
         * Encodes the specified DisappearingMode message. Does not implicitly {@link proto.DisappearingMode.verify|verify} messages.
         * @function encode
         * @memberof proto.DisappearingMode
         * @static
         * @param {proto.IDisappearingMode} message DisappearingMode message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        DisappearingMode.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.initiator != null && Object.hasOwnProperty.call(message, "initiator"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.initiator);
            return writer;
        };

        /**
         * Encodes the specified DisappearingMode message, length delimited. Does not implicitly {@link proto.DisappearingMode.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.DisappearingMode
         * @static
         * @param {proto.IDisappearingMode} message DisappearingMode message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        DisappearingMode.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a DisappearingMode message from the specified reader or buffer.
         * @function decode
         * @memberof proto.DisappearingMode
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.DisappearingMode} DisappearingMode
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        DisappearingMode.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.DisappearingMode();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.initiator = reader.int32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a DisappearingMode message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.DisappearingMode
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.DisappearingMode} DisappearingMode
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        DisappearingMode.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a DisappearingMode message.
         * @function verify
         * @memberof proto.DisappearingMode
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        DisappearingMode.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.initiator != null && message.hasOwnProperty("initiator"))
                switch (message.initiator) {
                default:
                    return "initiator: enum value expected";
                case 0:
                case 1:
                case 2:
                    break;
                }
            return null;
        };

        /**
         * Creates a DisappearingMode message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.DisappearingMode
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.DisappearingMode} DisappearingMode
         */
        DisappearingMode.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.DisappearingMode)
                return object;
            var message = new $root.proto.DisappearingMode();
            switch (object.initiator) {
            case "CHANGED_IN_CHAT":
            case 0:
                message.initiator = 0;
                break;
            case "INITIATED_BY_ME":
            case 1:
                message.initiator = 1;
                break;
            case "INITIATED_BY_OTHER":
            case 2:
                message.initiator = 2;
                break;
            }
            return message;
        };

        /**
         * Creates a plain object from a DisappearingMode message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.DisappearingMode
         * @static
         * @param {proto.DisappearingMode} message DisappearingMode
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        DisappearingMode.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                object.initiator = options.enums === String ? "CHANGED_IN_CHAT" : 0;
            if (message.initiator != null && message.hasOwnProperty("initiator"))
                object.initiator = options.enums === String ? $root.proto.DisappearingMode.DisappearingModeInitiator[message.initiator] : message.initiator;
            return object;
        };

        /**
         * Converts this DisappearingMode to JSON.
         * @function toJSON
         * @memberof proto.DisappearingMode
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        DisappearingMode.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * DisappearingModeInitiator enum.
         * @name proto.DisappearingMode.DisappearingModeInitiator
         * @enum {number}
         * @property {number} CHANGED_IN_CHAT=0 CHANGED_IN_CHAT value
         * @property {number} INITIATED_BY_ME=1 INITIATED_BY_ME value
         * @property {number} INITIATED_BY_OTHER=2 INITIATED_BY_OTHER value
         */
        DisappearingMode.DisappearingModeInitiator = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "CHANGED_IN_CHAT"] = 0;
            values[valuesById[1] = "INITIATED_BY_ME"] = 1;
            values[valuesById[2] = "INITIATED_BY_OTHER"] = 2;
            return values;
        })();

        return DisappearingMode;
    })();

    proto.MediaData = (function() {

        /**
         * Properties of a MediaData.
         * @memberof proto
         * @interface IMediaData
         * @property {Uint8Array|null} [mediaKey] MediaData mediaKey
         * @property {number|Long|null} [mediaKeyTimestamp] MediaData mediaKeyTimestamp
         * @property {Uint8Array|null} [fileSha256] MediaData fileSha256
         * @property {Uint8Array|null} [fileEncSha256] MediaData fileEncSha256
         * @property {string|null} [directPath] MediaData directPath
         */

        /**
         * Constructs a new MediaData.
         * @memberof proto
         * @classdesc Represents a MediaData.
         * @implements IMediaData
         * @constructor
         * @param {proto.IMediaData=} [properties] Properties to set
         */
        function MediaData(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * MediaData mediaKey.
         * @member {Uint8Array} mediaKey
         * @memberof proto.MediaData
         * @instance
         */
        MediaData.prototype.mediaKey = $util.newBuffer([]);

        /**
         * MediaData mediaKeyTimestamp.
         * @member {number|Long} mediaKeyTimestamp
         * @memberof proto.MediaData
         * @instance
         */
        MediaData.prototype.mediaKeyTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * MediaData fileSha256.
         * @member {Uint8Array} fileSha256
         * @memberof proto.MediaData
         * @instance
         */
        MediaData.prototype.fileSha256 = $util.newBuffer([]);

        /**
         * MediaData fileEncSha256.
         * @member {Uint8Array} fileEncSha256
         * @memberof proto.MediaData
         * @instance
         */
        MediaData.prototype.fileEncSha256 = $util.newBuffer([]);

        /**
         * MediaData directPath.
         * @member {string} directPath
         * @memberof proto.MediaData
         * @instance
         */
        MediaData.prototype.directPath = "";

        /**
         * Creates a new MediaData instance using the specified properties.
         * @function create
         * @memberof proto.MediaData
         * @static
         * @param {proto.IMediaData=} [properties] Properties to set
         * @returns {proto.MediaData} MediaData instance
         */
        MediaData.create = function create(properties) {
            return new MediaData(properties);
        };

        /**
         * Encodes the specified MediaData message. Does not implicitly {@link proto.MediaData.verify|verify} messages.
         * @function encode
         * @memberof proto.MediaData
         * @static
         * @param {proto.IMediaData} message MediaData message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        MediaData.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.mediaKey != null && Object.hasOwnProperty.call(message, "mediaKey"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.mediaKey);
            if (message.mediaKeyTimestamp != null && Object.hasOwnProperty.call(message, "mediaKeyTimestamp"))
                writer.uint32(/* id 2, wireType 0 =*/16).int64(message.mediaKeyTimestamp);
            if (message.fileSha256 != null && Object.hasOwnProperty.call(message, "fileSha256"))
                writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.fileSha256);
            if (message.fileEncSha256 != null && Object.hasOwnProperty.call(message, "fileEncSha256"))
                writer.uint32(/* id 4, wireType 2 =*/34).bytes(message.fileEncSha256);
            if (message.directPath != null && Object.hasOwnProperty.call(message, "directPath"))
                writer.uint32(/* id 5, wireType 2 =*/42).string(message.directPath);
            return writer;
        };

        /**
         * Encodes the specified MediaData message, length delimited. Does not implicitly {@link proto.MediaData.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.MediaData
         * @static
         * @param {proto.IMediaData} message MediaData message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        MediaData.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a MediaData message from the specified reader or buffer.
         * @function decode
         * @memberof proto.MediaData
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.MediaData} MediaData
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        MediaData.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MediaData();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.mediaKey = reader.bytes();
                    break;
                case 2:
                    message.mediaKeyTimestamp = reader.int64();
                    break;
                case 3:
                    message.fileSha256 = reader.bytes();
                    break;
                case 4:
                    message.fileEncSha256 = reader.bytes();
                    break;
                case 5:
                    message.directPath = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a MediaData message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.MediaData
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.MediaData} MediaData
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        MediaData.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a MediaData message.
         * @function verify
         * @memberof proto.MediaData
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        MediaData.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.mediaKey != null && message.hasOwnProperty("mediaKey"))
                if (!(message.mediaKey && typeof message.mediaKey.length === "number" || $util.isString(message.mediaKey)))
                    return "mediaKey: buffer expected";
            if (message.mediaKeyTimestamp != null && message.hasOwnProperty("mediaKeyTimestamp"))
                if (!$util.isInteger(message.mediaKeyTimestamp) && !(message.mediaKeyTimestamp && $util.isInteger(message.mediaKeyTimestamp.low) && $util.isInteger(message.mediaKeyTimestamp.high)))
                    return "mediaKeyTimestamp: integer|Long expected";
            if (message.fileSha256 != null && message.hasOwnProperty("fileSha256"))
                if (!(message.fileSha256 && typeof message.fileSha256.length === "number" || $util.isString(message.fileSha256)))
                    return "fileSha256: buffer expected";
            if (message.fileEncSha256 != null && message.hasOwnProperty("fileEncSha256"))
                if (!(message.fileEncSha256 && typeof message.fileEncSha256.length === "number" || $util.isString(message.fileEncSha256)))
                    return "fileEncSha256: buffer expected";
            if (message.directPath != null && message.hasOwnProperty("directPath"))
                if (!$util.isString(message.directPath))
                    return "directPath: string expected";
            return null;
        };

        /**
         * Creates a MediaData message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.MediaData
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.MediaData} MediaData
         */
        MediaData.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.MediaData)
                return object;
            var message = new $root.proto.MediaData();
            if (object.mediaKey != null)
                if (typeof object.mediaKey === "string")
                    $util.base64.decode(object.mediaKey, message.mediaKey = $util.newBuffer($util.base64.length(object.mediaKey)), 0);
                else if (object.mediaKey.length)
                    message.mediaKey = object.mediaKey;
            if (object.mediaKeyTimestamp != null)
                if ($util.Long)
                    (message.mediaKeyTimestamp = $util.Long.fromValue(object.mediaKeyTimestamp)).unsigned = false;
                else if (typeof object.mediaKeyTimestamp === "string")
                    message.mediaKeyTimestamp = parseInt(object.mediaKeyTimestamp, 10);
                else if (typeof object.mediaKeyTimestamp === "number")
                    message.mediaKeyTimestamp = object.mediaKeyTimestamp;
                else if (typeof object.mediaKeyTimestamp === "object")
                    message.mediaKeyTimestamp = new $util.LongBits(object.mediaKeyTimestamp.low >>> 0, object.mediaKeyTimestamp.high >>> 0).toNumber();
            if (object.fileSha256 != null)
                if (typeof object.fileSha256 === "string")
                    $util.base64.decode(object.fileSha256, message.fileSha256 = $util.newBuffer($util.base64.length(object.fileSha256)), 0);
                else if (object.fileSha256.length)
                    message.fileSha256 = object.fileSha256;
            if (object.fileEncSha256 != null)
                if (typeof object.fileEncSha256 === "string")
                    $util.base64.decode(object.fileEncSha256, message.fileEncSha256 = $util.newBuffer($util.base64.length(object.fileEncSha256)), 0);
                else if (object.fileEncSha256.length)
                    message.fileEncSha256 = object.fileEncSha256;
            if (object.directPath != null)
                message.directPath = String(object.directPath);
            return message;
        };

        /**
         * Creates a plain object from a MediaData message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.MediaData
         * @static
         * @param {proto.MediaData} message MediaData
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        MediaData.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object.mediaKey = "";
                else {
                    object.mediaKey = [];
                    if (options.bytes !== Array)
                        object.mediaKey = $util.newBuffer(object.mediaKey);
                }
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.mediaKeyTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.mediaKeyTimestamp = options.longs === String ? "0" : 0;
                if (options.bytes === String)
                    object.fileSha256 = "";
                else {
                    object.fileSha256 = [];
                    if (options.bytes !== Array)
                        object.fileSha256 = $util.newBuffer(object.fileSha256);
                }
                if (options.bytes === String)
                    object.fileEncSha256 = "";
                else {
                    object.fileEncSha256 = [];
                    if (options.bytes !== Array)
                        object.fileEncSha256 = $util.newBuffer(object.fileEncSha256);
                }
                object.directPath = "";
            }
            if (message.mediaKey != null && message.hasOwnProperty("mediaKey"))
                object.mediaKey = options.bytes === String ? $util.base64.encode(message.mediaKey, 0, message.mediaKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.mediaKey) : message.mediaKey;
            if (message.mediaKeyTimestamp != null && message.hasOwnProperty("mediaKeyTimestamp"))
                if (typeof message.mediaKeyTimestamp === "number")
                    object.mediaKeyTimestamp = options.longs === String ? String(message.mediaKeyTimestamp) : message.mediaKeyTimestamp;
                else
                    object.mediaKeyTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.mediaKeyTimestamp) : options.longs === Number ? new $util.LongBits(message.mediaKeyTimestamp.low >>> 0, message.mediaKeyTimestamp.high >>> 0).toNumber() : message.mediaKeyTimestamp;
            if (message.fileSha256 != null && message.hasOwnProperty("fileSha256"))
                object.fileSha256 = options.bytes === String ? $util.base64.encode(message.fileSha256, 0, message.fileSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.fileSha256) : message.fileSha256;
            if (message.fileEncSha256 != null && message.hasOwnProperty("fileEncSha256"))
                object.fileEncSha256 = options.bytes === String ? $util.base64.encode(message.fileEncSha256, 0, message.fileEncSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.fileEncSha256) : message.fileEncSha256;
            if (message.directPath != null && message.hasOwnProperty("directPath"))
                object.directPath = message.directPath;
            return object;
        };

        /**
         * Converts this MediaData to JSON.
         * @function toJSON
         * @memberof proto.MediaData
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        MediaData.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return MediaData;
    })();

    proto.PaymentBackground = (function() {

        /**
         * Properties of a PaymentBackground.
         * @memberof proto
         * @interface IPaymentBackground
         * @property {string|null} [id] PaymentBackground id
         * @property {number|Long|null} [fileLength] PaymentBackground fileLength
         * @property {number|null} [width] PaymentBackground width
         * @property {number|null} [height] PaymentBackground height
         * @property {string|null} [mimetype] PaymentBackground mimetype
         * @property {number|null} [placeholderArgb] PaymentBackground placeholderArgb
         * @property {number|null} [textArgb] PaymentBackground textArgb
         * @property {number|null} [subtextArgb] PaymentBackground subtextArgb
         * @property {proto.IMediaData|null} [mediaData] PaymentBackground mediaData
         * @property {proto.PaymentBackground.PaymentBackgroundType|null} [type] PaymentBackground type
         */

        /**
         * Constructs a new PaymentBackground.
         * @memberof proto
         * @classdesc Represents a PaymentBackground.
         * @implements IPaymentBackground
         * @constructor
         * @param {proto.IPaymentBackground=} [properties] Properties to set
         */
        function PaymentBackground(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * PaymentBackground id.
         * @member {string} id
         * @memberof proto.PaymentBackground
         * @instance
         */
        PaymentBackground.prototype.id = "";

        /**
         * PaymentBackground fileLength.
         * @member {number|Long} fileLength
         * @memberof proto.PaymentBackground
         * @instance
         */
        PaymentBackground.prototype.fileLength = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * PaymentBackground width.
         * @member {number} width
         * @memberof proto.PaymentBackground
         * @instance
         */
        PaymentBackground.prototype.width = 0;

        /**
         * PaymentBackground height.
         * @member {number} height
         * @memberof proto.PaymentBackground
         * @instance
         */
        PaymentBackground.prototype.height = 0;

        /**
         * PaymentBackground mimetype.
         * @member {string} mimetype
         * @memberof proto.PaymentBackground
         * @instance
         */
        PaymentBackground.prototype.mimetype = "";

        /**
         * PaymentBackground placeholderArgb.
         * @member {number} placeholderArgb
         * @memberof proto.PaymentBackground
         * @instance
         */
        PaymentBackground.prototype.placeholderArgb = 0;

        /**
         * PaymentBackground textArgb.
         * @member {number} textArgb
         * @memberof proto.PaymentBackground
         * @instance
         */
        PaymentBackground.prototype.textArgb = 0;

        /**
         * PaymentBackground subtextArgb.
         * @member {number} subtextArgb
         * @memberof proto.PaymentBackground
         * @instance
         */
        PaymentBackground.prototype.subtextArgb = 0;

        /**
         * PaymentBackground mediaData.
         * @member {proto.IMediaData|null|undefined} mediaData
         * @memberof proto.PaymentBackground
         * @instance
         */
        PaymentBackground.prototype.mediaData = null;

        /**
         * PaymentBackground type.
         * @member {proto.PaymentBackground.PaymentBackgroundType} type
         * @memberof proto.PaymentBackground
         * @instance
         */
        PaymentBackground.prototype.type = 0;

        /**
         * Creates a new PaymentBackground instance using the specified properties.
         * @function create
         * @memberof proto.PaymentBackground
         * @static
         * @param {proto.IPaymentBackground=} [properties] Properties to set
         * @returns {proto.PaymentBackground} PaymentBackground instance
         */
        PaymentBackground.create = function create(properties) {
            return new PaymentBackground(properties);
        };

        /**
         * Encodes the specified PaymentBackground message. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages.
         * @function encode
         * @memberof proto.PaymentBackground
         * @static
         * @param {proto.IPaymentBackground} message PaymentBackground message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PaymentBackground.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.id);
            if (message.fileLength != null && Object.hasOwnProperty.call(message, "fileLength"))
                writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.fileLength);
            if (message.width != null && Object.hasOwnProperty.call(message, "width"))
                writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.width);
            if (message.height != null && Object.hasOwnProperty.call(message, "height"))
                writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.height);
            if (message.mimetype != null && Object.hasOwnProperty.call(message, "mimetype"))
                writer.uint32(/* id 5, wireType 2 =*/42).string(message.mimetype);
            if (message.placeholderArgb != null && Object.hasOwnProperty.call(message, "placeholderArgb"))
                writer.uint32(/* id 6, wireType 5 =*/53).fixed32(message.placeholderArgb);
            if (message.textArgb != null && Object.hasOwnProperty.call(message, "textArgb"))
                writer.uint32(/* id 7, wireType 5 =*/61).fixed32(message.textArgb);
            if (message.subtextArgb != null && Object.hasOwnProperty.call(message, "subtextArgb"))
                writer.uint32(/* id 8, wireType 5 =*/69).fixed32(message.subtextArgb);
            if (message.mediaData != null && Object.hasOwnProperty.call(message, "mediaData"))
                $root.proto.MediaData.encode(message.mediaData, writer.uint32(/* id 9, wireType 2 =*/74).fork()).ldelim();
            if (message.type != null && Object.hasOwnProperty.call(message, "type"))
                writer.uint32(/* id 10, wireType 0 =*/80).int32(message.type);
            return writer;
        };

        /**
         * Encodes the specified PaymentBackground message, length delimited. Does not implicitly {@link proto.PaymentBackground.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.PaymentBackground
         * @static
         * @param {proto.IPaymentBackground} message PaymentBackground message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PaymentBackground.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a PaymentBackground message from the specified reader or buffer.
         * @function decode
         * @memberof proto.PaymentBackground
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.PaymentBackground} PaymentBackground
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PaymentBackground.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.PaymentBackground();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.id = reader.string();
                    break;
                case 2:
                    message.fileLength = reader.uint64();
                    break;
                case 3:
                    message.width = reader.uint32();
                    break;
                case 4:
                    message.height = reader.uint32();
                    break;
                case 5:
                    message.mimetype = reader.string();
                    break;
                case 6:
                    message.placeholderArgb = reader.fixed32();
                    break;
                case 7:
                    message.textArgb = reader.fixed32();
                    break;
                case 8:
                    message.subtextArgb = reader.fixed32();
                    break;
                case 9:
                    message.mediaData = $root.proto.MediaData.decode(reader, reader.uint32());
                    break;
                case 10:
                    message.type = reader.int32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a PaymentBackground message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.PaymentBackground
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.PaymentBackground} PaymentBackground
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PaymentBackground.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a PaymentBackground message.
         * @function verify
         * @memberof proto.PaymentBackground
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        PaymentBackground.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isString(message.id))
                    return "id: string expected";
            if (message.fileLength != null && message.hasOwnProperty("fileLength"))
                if (!$util.isInteger(message.fileLength) && !(message.fileLength && $util.isInteger(message.fileLength.low) && $util.isInteger(message.fileLength.high)))
                    return "fileLength: integer|Long expected";
            if (message.width != null && message.hasOwnProperty("width"))
                if (!$util.isInteger(message.width))
                    return "width: integer expected";
            if (message.height != null && message.hasOwnProperty("height"))
                if (!$util.isInteger(message.height))
                    return "height: integer expected";
            if (message.mimetype != null && message.hasOwnProperty("mimetype"))
                if (!$util.isString(message.mimetype))
                    return "mimetype: string expected";
            if (message.placeholderArgb != null && message.hasOwnProperty("placeholderArgb"))
                if (!$util.isInteger(message.placeholderArgb))
                    return "placeholderArgb: integer expected";
            if (message.textArgb != null && message.hasOwnProperty("textArgb"))
                if (!$util.isInteger(message.textArgb))
                    return "textArgb: integer expected";
            if (message.subtextArgb != null && message.hasOwnProperty("subtextArgb"))
                if (!$util.isInteger(message.subtextArgb))
                    return "subtextArgb: integer expected";
            if (message.mediaData != null && message.hasOwnProperty("mediaData")) {
                var error = $root.proto.MediaData.verify(message.mediaData);
                if (error)
                    return "mediaData." + error;
            }
            if (message.type != null && message.hasOwnProperty("type"))
                switch (message.type) {
                default:
                    return "type: enum value expected";
                case 0:
                case 1:
                    break;
                }
            return null;
        };

        /**
         * Creates a PaymentBackground message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.PaymentBackground
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.PaymentBackground} PaymentBackground
         */
        PaymentBackground.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.PaymentBackground)
                return object;
            var message = new $root.proto.PaymentBackground();
            if (object.id != null)
                message.id = String(object.id);
            if (object.fileLength != null)
                if ($util.Long)
                    (message.fileLength = $util.Long.fromValue(object.fileLength)).unsigned = true;
                else if (typeof object.fileLength === "string")
                    message.fileLength = parseInt(object.fileLength, 10);
                else if (typeof object.fileLength === "number")
                    message.fileLength = object.fileLength;
                else if (typeof object.fileLength === "object")
                    message.fileLength = new $util.LongBits(object.fileLength.low >>> 0, object.fileLength.high >>> 0).toNumber(true);
            if (object.width != null)
                message.width = object.width >>> 0;
            if (object.height != null)
                message.height = object.height >>> 0;
            if (object.mimetype != null)
                message.mimetype = String(object.mimetype);
            if (object.placeholderArgb != null)
                message.placeholderArgb = object.placeholderArgb >>> 0;
            if (object.textArgb != null)
                message.textArgb = object.textArgb >>> 0;
            if (object.subtextArgb != null)
                message.subtextArgb = object.subtextArgb >>> 0;
            if (object.mediaData != null) {
                if (typeof object.mediaData !== "object")
                    throw TypeError(".proto.PaymentBackground.mediaData: object expected");
                message.mediaData = $root.proto.MediaData.fromObject(object.mediaData);
            }
            switch (object.type) {
            case "UNKNOWN":
            case 0:
                message.type = 0;
                break;
            case "DEFAULT":
            case 1:
                message.type = 1;
                break;
            }
            return message;
        };

        /**
         * Creates a plain object from a PaymentBackground message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.PaymentBackground
         * @static
         * @param {proto.PaymentBackground} message PaymentBackground
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        PaymentBackground.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.id = "";
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.fileLength = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.fileLength = options.longs === String ? "0" : 0;
                object.width = 0;
                object.height = 0;
                object.mimetype = "";
                object.placeholderArgb = 0;
                object.textArgb = 0;
                object.subtextArgb = 0;
                object.mediaData = null;
                object.type = options.enums === String ? "UNKNOWN" : 0;
            }
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.fileLength != null && message.hasOwnProperty("fileLength"))
                if (typeof message.fileLength === "number")
                    object.fileLength = options.longs === String ? String(message.fileLength) : message.fileLength;
                else
                    object.fileLength = options.longs === String ? $util.Long.prototype.toString.call(message.fileLength) : options.longs === Number ? new $util.LongBits(message.fileLength.low >>> 0, message.fileLength.high >>> 0).toNumber(true) : message.fileLength;
            if (message.width != null && message.hasOwnProperty("width"))
                object.width = message.width;
            if (message.height != null && message.hasOwnProperty("height"))
                object.height = message.height;
            if (message.mimetype != null && message.hasOwnProperty("mimetype"))
                object.mimetype = message.mimetype;
            if (message.placeholderArgb != null && message.hasOwnProperty("placeholderArgb"))
                object.placeholderArgb = message.placeholderArgb;
            if (message.textArgb != null && message.hasOwnProperty("textArgb"))
                object.textArgb = message.textArgb;
            if (message.subtextArgb != null && message.hasOwnProperty("subtextArgb"))
                object.subtextArgb = message.subtextArgb;
            if (message.mediaData != null && message.hasOwnProperty("mediaData"))
                object.mediaData = $root.proto.MediaData.toObject(message.mediaData, options);
            if (message.type != null && message.hasOwnProperty("type"))
                object.type = options.enums === String ? $root.proto.PaymentBackground.PaymentBackgroundType[message.type] : message.type;
            return object;
        };

        /**
         * Converts this PaymentBackground to JSON.
         * @function toJSON
         * @memberof proto.PaymentBackground
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        PaymentBackground.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * PaymentBackgroundType enum.
         * @name proto.PaymentBackground.PaymentBackgroundType
         * @enum {number}
         * @property {number} UNKNOWN=0 UNKNOWN value
         * @property {number} DEFAULT=1 DEFAULT value
         */
        PaymentBackground.PaymentBackgroundType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "UNKNOWN"] = 0;
            values[valuesById[1] = "DEFAULT"] = 1;
            return values;
        })();

        return PaymentBackground;
    })();

    proto.Money = (function() {

        /**
         * Properties of a Money.
         * @memberof proto
         * @interface IMoney
         * @property {number|Long|null} [value] Money value
         * @property {number|null} [offset] Money offset
         * @property {string|null} [currencyCode] Money currencyCode
         */

        /**
         * Constructs a new Money.
         * @memberof proto
         * @classdesc Represents a Money.
         * @implements IMoney
         * @constructor
         * @param {proto.IMoney=} [properties] Properties to set
         */
        function Money(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Money value.
         * @member {number|Long} value
         * @memberof proto.Money
         * @instance
         */
        Money.prototype.value = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * Money offset.
         * @member {number} offset
         * @memberof proto.Money
         * @instance
         */
        Money.prototype.offset = 0;

        /**
         * Money currencyCode.
         * @member {string} currencyCode
         * @memberof proto.Money
         * @instance
         */
        Money.prototype.currencyCode = "";

        /**
         * Creates a new Money instance using the specified properties.
         * @function create
         * @memberof proto.Money
         * @static
         * @param {proto.IMoney=} [properties] Properties to set
         * @returns {proto.Money} Money instance
         */
        Money.create = function create(properties) {
            return new Money(properties);
        };

        /**
         * Encodes the specified Money message. Does not implicitly {@link proto.Money.verify|verify} messages.
         * @function encode
         * @memberof proto.Money
         * @static
         * @param {proto.IMoney} message Money message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Money.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.value != null && Object.hasOwnProperty.call(message, "value"))
                writer.uint32(/* id 1, wireType 0 =*/8).int64(message.value);
            if (message.offset != null && Object.hasOwnProperty.call(message, "offset"))
                writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.offset);
            if (message.currencyCode != null && Object.hasOwnProperty.call(message, "currencyCode"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.currencyCode);
            return writer;
        };

        /**
         * Encodes the specified Money message, length delimited. Does not implicitly {@link proto.Money.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.Money
         * @static
         * @param {proto.IMoney} message Money message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Money.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a Money message from the specified reader or buffer.
         * @function decode
         * @memberof proto.Money
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.Money} Money
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Money.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Money();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.value = reader.int64();
                    break;
                case 2:
                    message.offset = reader.uint32();
                    break;
                case 3:
                    message.currencyCode = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a Money message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.Money
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.Money} Money
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Money.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a Money message.
         * @function verify
         * @memberof proto.Money
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        Money.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.value != null && message.hasOwnProperty("value"))
                if (!$util.isInteger(message.value) && !(message.value && $util.isInteger(message.value.low) && $util.isInteger(message.value.high)))
                    return "value: integer|Long expected";
            if (message.offset != null && message.hasOwnProperty("offset"))
                if (!$util.isInteger(message.offset))
                    return "offset: integer expected";
            if (message.currencyCode != null && message.hasOwnProperty("currencyCode"))
                if (!$util.isString(message.currencyCode))
                    return "currencyCode: string expected";
            return null;
        };

        /**
         * Creates a Money message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.Money
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.Money} Money
         */
        Money.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.Money)
                return object;
            var message = new $root.proto.Money();
            if (object.value != null)
                if ($util.Long)
                    (message.value = $util.Long.fromValue(object.value)).unsigned = false;
                else if (typeof object.value === "string")
                    message.value = parseInt(object.value, 10);
                else if (typeof object.value === "number")
                    message.value = object.value;
                else if (typeof object.value === "object")
                    message.value = new $util.LongBits(object.value.low >>> 0, object.value.high >>> 0).toNumber();
            if (object.offset != null)
                message.offset = object.offset >>> 0;
            if (object.currencyCode != null)
                message.currencyCode = String(object.currencyCode);
            return message;
        };

        /**
         * Creates a plain object from a Money message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.Money
         * @static
         * @param {proto.Money} message Money
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        Money.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.value = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.value = options.longs === String ? "0" : 0;
                object.offset = 0;
                object.currencyCode = "";
            }
            if (message.value != null && message.hasOwnProperty("value"))
                if (typeof message.value === "number")
                    object.value = options.longs === String ? String(message.value) : message.value;
                else
                    object.value = options.longs === String ? $util.Long.prototype.toString.call(message.value) : options.longs === Number ? new $util.LongBits(message.value.low >>> 0, message.value.high >>> 0).toNumber() : message.value;
            if (message.offset != null && message.hasOwnProperty("offset"))
                object.offset = message.offset;
            if (message.currencyCode != null && message.hasOwnProperty("currencyCode"))
                object.currencyCode = message.currencyCode;
            return object;
        };

        /**
         * Converts this Money to JSON.
         * @function toJSON
         * @memberof proto.Money
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        Money.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return Money;
    })();

    proto.HydratedQuickReplyButton = (function() {

        /**
         * Properties of a HydratedQuickReplyButton.
         * @memberof proto
         * @interface IHydratedQuickReplyButton
         * @property {string|null} [displayText] HydratedQuickReplyButton displayText
         * @property {string|null} [id] HydratedQuickReplyButton id
         */

        /**
         * Constructs a new HydratedQuickReplyButton.
         * @memberof proto
         * @classdesc Represents a HydratedQuickReplyButton.
         * @implements IHydratedQuickReplyButton
         * @constructor
         * @param {proto.IHydratedQuickReplyButton=} [properties] Properties to set
         */
        function HydratedQuickReplyButton(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * HydratedQuickReplyButton displayText.
         * @member {string} displayText
         * @memberof proto.HydratedQuickReplyButton
         * @instance
         */
        HydratedQuickReplyButton.prototype.displayText = "";

        /**
         * HydratedQuickReplyButton id.
         * @member {string} id
         * @memberof proto.HydratedQuickReplyButton
         * @instance
         */
        HydratedQuickReplyButton.prototype.id = "";

        /**
         * Creates a new HydratedQuickReplyButton instance using the specified properties.
         * @function create
         * @memberof proto.HydratedQuickReplyButton
         * @static
         * @param {proto.IHydratedQuickReplyButton=} [properties] Properties to set
         * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton instance
         */
        HydratedQuickReplyButton.create = function create(properties) {
            return new HydratedQuickReplyButton(properties);
        };

        /**
         * Encodes the specified HydratedQuickReplyButton message. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages.
         * @function encode
         * @memberof proto.HydratedQuickReplyButton
         * @static
         * @param {proto.IHydratedQuickReplyButton} message HydratedQuickReplyButton message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HydratedQuickReplyButton.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayText);
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.id);
            return writer;
        };

        /**
         * Encodes the specified HydratedQuickReplyButton message, length delimited. Does not implicitly {@link proto.HydratedQuickReplyButton.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.HydratedQuickReplyButton
         * @static
         * @param {proto.IHydratedQuickReplyButton} message HydratedQuickReplyButton message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HydratedQuickReplyButton.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a HydratedQuickReplyButton message from the specified reader or buffer.
         * @function decode
         * @memberof proto.HydratedQuickReplyButton
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HydratedQuickReplyButton.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedQuickReplyButton();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.displayText = reader.string();
                    break;
                case 2:
                    message.id = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a HydratedQuickReplyButton message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.HydratedQuickReplyButton
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HydratedQuickReplyButton.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a HydratedQuickReplyButton message.
         * @function verify
         * @memberof proto.HydratedQuickReplyButton
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        HydratedQuickReplyButton.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.displayText != null && message.hasOwnProperty("displayText"))
                if (!$util.isString(message.displayText))
                    return "displayText: string expected";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isString(message.id))
                    return "id: string expected";
            return null;
        };

        /**
         * Creates a HydratedQuickReplyButton message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.HydratedQuickReplyButton
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.HydratedQuickReplyButton} HydratedQuickReplyButton
         */
        HydratedQuickReplyButton.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.HydratedQuickReplyButton)
                return object;
            var message = new $root.proto.HydratedQuickReplyButton();
            if (object.displayText != null)
                message.displayText = String(object.displayText);
            if (object.id != null)
                message.id = String(object.id);
            return message;
        };

        /**
         * Creates a plain object from a HydratedQuickReplyButton message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.HydratedQuickReplyButton
         * @static
         * @param {proto.HydratedQuickReplyButton} message HydratedQuickReplyButton
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        HydratedQuickReplyButton.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.displayText = "";
                object.id = "";
            }
            if (message.displayText != null && message.hasOwnProperty("displayText"))
                object.displayText = message.displayText;
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            return object;
        };

        /**
         * Converts this HydratedQuickReplyButton to JSON.
         * @function toJSON
         * @memberof proto.HydratedQuickReplyButton
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        HydratedQuickReplyButton.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return HydratedQuickReplyButton;
    })();

    proto.HydratedURLButton = (function() {

        /**
         * Properties of a HydratedURLButton.
         * @memberof proto
         * @interface IHydratedURLButton
         * @property {string|null} [displayText] HydratedURLButton displayText
         * @property {string|null} [url] HydratedURLButton url
         */

        /**
         * Constructs a new HydratedURLButton.
         * @memberof proto
         * @classdesc Represents a HydratedURLButton.
         * @implements IHydratedURLButton
         * @constructor
         * @param {proto.IHydratedURLButton=} [properties] Properties to set
         */
        function HydratedURLButton(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * HydratedURLButton displayText.
         * @member {string} displayText
         * @memberof proto.HydratedURLButton
         * @instance
         */
        HydratedURLButton.prototype.displayText = "";

        /**
         * HydratedURLButton url.
         * @member {string} url
         * @memberof proto.HydratedURLButton
         * @instance
         */
        HydratedURLButton.prototype.url = "";

        /**
         * Creates a new HydratedURLButton instance using the specified properties.
         * @function create
         * @memberof proto.HydratedURLButton
         * @static
         * @param {proto.IHydratedURLButton=} [properties] Properties to set
         * @returns {proto.HydratedURLButton} HydratedURLButton instance
         */
        HydratedURLButton.create = function create(properties) {
            return new HydratedURLButton(properties);
        };

        /**
         * Encodes the specified HydratedURLButton message. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages.
         * @function encode
         * @memberof proto.HydratedURLButton
         * @static
         * @param {proto.IHydratedURLButton} message HydratedURLButton message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HydratedURLButton.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayText);
            if (message.url != null && Object.hasOwnProperty.call(message, "url"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.url);
            return writer;
        };

        /**
         * Encodes the specified HydratedURLButton message, length delimited. Does not implicitly {@link proto.HydratedURLButton.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.HydratedURLButton
         * @static
         * @param {proto.IHydratedURLButton} message HydratedURLButton message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HydratedURLButton.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a HydratedURLButton message from the specified reader or buffer.
         * @function decode
         * @memberof proto.HydratedURLButton
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.HydratedURLButton} HydratedURLButton
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HydratedURLButton.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedURLButton();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.displayText = reader.string();
                    break;
                case 2:
                    message.url = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a HydratedURLButton message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.HydratedURLButton
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.HydratedURLButton} HydratedURLButton
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HydratedURLButton.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a HydratedURLButton message.
         * @function verify
         * @memberof proto.HydratedURLButton
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        HydratedURLButton.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.displayText != null && message.hasOwnProperty("displayText"))
                if (!$util.isString(message.displayText))
                    return "displayText: string expected";
            if (message.url != null && message.hasOwnProperty("url"))
                if (!$util.isString(message.url))
                    return "url: string expected";
            return null;
        };

        /**
         * Creates a HydratedURLButton message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.HydratedURLButton
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.HydratedURLButton} HydratedURLButton
         */
        HydratedURLButton.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.HydratedURLButton)
                return object;
            var message = new $root.proto.HydratedURLButton();
            if (object.displayText != null)
                message.displayText = String(object.displayText);
            if (object.url != null)
                message.url = String(object.url);
            return message;
        };

        /**
         * Creates a plain object from a HydratedURLButton message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.HydratedURLButton
         * @static
         * @param {proto.HydratedURLButton} message HydratedURLButton
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        HydratedURLButton.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.displayText = "";
                object.url = "";
            }
            if (message.displayText != null && message.hasOwnProperty("displayText"))
                object.displayText = message.displayText;
            if (message.url != null && message.hasOwnProperty("url"))
                object.url = message.url;
            return object;
        };

        /**
         * Converts this HydratedURLButton to JSON.
         * @function toJSON
         * @memberof proto.HydratedURLButton
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        HydratedURLButton.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return HydratedURLButton;
    })();

    proto.HydratedCallButton = (function() {

        /**
         * Properties of a HydratedCallButton.
         * @memberof proto
         * @interface IHydratedCallButton
         * @property {string|null} [displayText] HydratedCallButton displayText
         * @property {string|null} [phoneNumber] HydratedCallButton phoneNumber
         */

        /**
         * Constructs a new HydratedCallButton.
         * @memberof proto
         * @classdesc Represents a HydratedCallButton.
         * @implements IHydratedCallButton
         * @constructor
         * @param {proto.IHydratedCallButton=} [properties] Properties to set
         */
        function HydratedCallButton(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * HydratedCallButton displayText.
         * @member {string} displayText
         * @memberof proto.HydratedCallButton
         * @instance
         */
        HydratedCallButton.prototype.displayText = "";

        /**
         * HydratedCallButton phoneNumber.
         * @member {string} phoneNumber
         * @memberof proto.HydratedCallButton
         * @instance
         */
        HydratedCallButton.prototype.phoneNumber = "";

        /**
         * Creates a new HydratedCallButton instance using the specified properties.
         * @function create
         * @memberof proto.HydratedCallButton
         * @static
         * @param {proto.IHydratedCallButton=} [properties] Properties to set
         * @returns {proto.HydratedCallButton} HydratedCallButton instance
         */
        HydratedCallButton.create = function create(properties) {
            return new HydratedCallButton(properties);
        };

        /**
         * Encodes the specified HydratedCallButton message. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages.
         * @function encode
         * @memberof proto.HydratedCallButton
         * @static
         * @param {proto.IHydratedCallButton} message HydratedCallButton message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HydratedCallButton.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.displayText);
            if (message.phoneNumber != null && Object.hasOwnProperty.call(message, "phoneNumber"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.phoneNumber);
            return writer;
        };

        /**
         * Encodes the specified HydratedCallButton message, length delimited. Does not implicitly {@link proto.HydratedCallButton.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.HydratedCallButton
         * @static
         * @param {proto.IHydratedCallButton} message HydratedCallButton message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HydratedCallButton.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a HydratedCallButton message from the specified reader or buffer.
         * @function decode
         * @memberof proto.HydratedCallButton
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.HydratedCallButton} HydratedCallButton
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HydratedCallButton.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedCallButton();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.displayText = reader.string();
                    break;
                case 2:
                    message.phoneNumber = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a HydratedCallButton message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.HydratedCallButton
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.HydratedCallButton} HydratedCallButton
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HydratedCallButton.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a HydratedCallButton message.
         * @function verify
         * @memberof proto.HydratedCallButton
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        HydratedCallButton.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.displayText != null && message.hasOwnProperty("displayText"))
                if (!$util.isString(message.displayText))
                    return "displayText: string expected";
            if (message.phoneNumber != null && message.hasOwnProperty("phoneNumber"))
                if (!$util.isString(message.phoneNumber))
                    return "phoneNumber: string expected";
            return null;
        };

        /**
         * Creates a HydratedCallButton message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.HydratedCallButton
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.HydratedCallButton} HydratedCallButton
         */
        HydratedCallButton.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.HydratedCallButton)
                return object;
            var message = new $root.proto.HydratedCallButton();
            if (object.displayText != null)
                message.displayText = String(object.displayText);
            if (object.phoneNumber != null)
                message.phoneNumber = String(object.phoneNumber);
            return message;
        };

        /**
         * Creates a plain object from a HydratedCallButton message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.HydratedCallButton
         * @static
         * @param {proto.HydratedCallButton} message HydratedCallButton
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        HydratedCallButton.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.displayText = "";
                object.phoneNumber = "";
            }
            if (message.displayText != null && message.hasOwnProperty("displayText"))
                object.displayText = message.displayText;
            if (message.phoneNumber != null && message.hasOwnProperty("phoneNumber"))
                object.phoneNumber = message.phoneNumber;
            return object;
        };

        /**
         * Converts this HydratedCallButton to JSON.
         * @function toJSON
         * @memberof proto.HydratedCallButton
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        HydratedCallButton.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return HydratedCallButton;
    })();

    proto.HydratedTemplateButton = (function() {

        /**
         * Properties of a HydratedTemplateButton.
         * @memberof proto
         * @interface IHydratedTemplateButton
         * @property {number|null} [index] HydratedTemplateButton index
         * @property {proto.IHydratedQuickReplyButton|null} [quickReplyButton] HydratedTemplateButton quickReplyButton
         * @property {proto.IHydratedURLButton|null} [urlButton] HydratedTemplateButton urlButton
         * @property {proto.IHydratedCallButton|null} [callButton] HydratedTemplateButton callButton
         */

        /**
         * Constructs a new HydratedTemplateButton.
         * @memberof proto
         * @classdesc Represents a HydratedTemplateButton.
         * @implements IHydratedTemplateButton
         * @constructor
         * @param {proto.IHydratedTemplateButton=} [properties] Properties to set
         */
        function HydratedTemplateButton(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * HydratedTemplateButton index.
         * @member {number} index
         * @memberof proto.HydratedTemplateButton
         * @instance
         */
        HydratedTemplateButton.prototype.index = 0;

        /**
         * HydratedTemplateButton quickReplyButton.
         * @member {proto.IHydratedQuickReplyButton|null|undefined} quickReplyButton
         * @memberof proto.HydratedTemplateButton
         * @instance
         */
        HydratedTemplateButton.prototype.quickReplyButton = null;

        /**
         * HydratedTemplateButton urlButton.
         * @member {proto.IHydratedURLButton|null|undefined} urlButton
         * @memberof proto.HydratedTemplateButton
         * @instance
         */
        HydratedTemplateButton.prototype.urlButton = null;

        /**
         * HydratedTemplateButton callButton.
         * @member {proto.IHydratedCallButton|null|undefined} callButton
         * @memberof proto.HydratedTemplateButton
         * @instance
         */
        HydratedTemplateButton.prototype.callButton = null;

        // OneOf field names bound to virtual getters and setters
        var $oneOfFields;

        /**
         * HydratedTemplateButton hydratedButton.
         * @member {"quickReplyButton"|"urlButton"|"callButton"|undefined} hydratedButton
         * @memberof proto.HydratedTemplateButton
         * @instance
         */
        Object.defineProperty(HydratedTemplateButton.prototype, "hydratedButton", {
            get: $util.oneOfGetter($oneOfFields = ["quickReplyButton", "urlButton", "callButton"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new HydratedTemplateButton instance using the specified properties.
         * @function create
         * @memberof proto.HydratedTemplateButton
         * @static
         * @param {proto.IHydratedTemplateButton=} [properties] Properties to set
         * @returns {proto.HydratedTemplateButton} HydratedTemplateButton instance
         */
        HydratedTemplateButton.create = function create(properties) {
            return new HydratedTemplateButton(properties);
        };

        /**
         * Encodes the specified HydratedTemplateButton message. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages.
         * @function encode
         * @memberof proto.HydratedTemplateButton
         * @static
         * @param {proto.IHydratedTemplateButton} message HydratedTemplateButton message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HydratedTemplateButton.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.quickReplyButton != null && Object.hasOwnProperty.call(message, "quickReplyButton"))
                $root.proto.HydratedQuickReplyButton.encode(message.quickReplyButton, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.urlButton != null && Object.hasOwnProperty.call(message, "urlButton"))
                $root.proto.HydratedURLButton.encode(message.urlButton, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.callButton != null && Object.hasOwnProperty.call(message, "callButton"))
                $root.proto.HydratedCallButton.encode(message.callButton, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.index != null && Object.hasOwnProperty.call(message, "index"))
                writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.index);
            return writer;
        };

        /**
         * Encodes the specified HydratedTemplateButton message, length delimited. Does not implicitly {@link proto.HydratedTemplateButton.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.HydratedTemplateButton
         * @static
         * @param {proto.IHydratedTemplateButton} message HydratedTemplateButton message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        HydratedTemplateButton.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a HydratedTemplateButton message from the specified reader or buffer.
         * @function decode
         * @memberof proto.HydratedTemplateButton
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.HydratedTemplateButton} HydratedTemplateButton
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HydratedTemplateButton.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.HydratedTemplateButton();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 4:
                    message.index = reader.uint32();
                    break;
                case 1:
                    message.quickReplyButton = $root.proto.HydratedQuickReplyButton.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.urlButton = $root.proto.HydratedURLButton.decode(reader, reader.uint32());
                    break;
                case 3:
                    message.callButton = $root.proto.HydratedCallButton.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a HydratedTemplateButton message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.HydratedTemplateButton
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.HydratedTemplateButton} HydratedTemplateButton
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        HydratedTemplateButton.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a HydratedTemplateButton message.
         * @function verify
         * @memberof proto.HydratedTemplateButton
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        HydratedTemplateButton.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            var properties = {};
            if (message.index != null && message.hasOwnProperty("index"))
                if (!$util.isInteger(message.index))
                    return "index: integer expected";
            if (message.quickReplyButton != null && message.hasOwnProperty("quickReplyButton")) {
                properties.hydratedButton = 1;
                {
                    var error = $root.proto.HydratedQuickReplyButton.verify(message.quickReplyButton);
                    if (error)
                        return "quickReplyButton." + error;
                }
            }
            if (message.urlButton != null && message.hasOwnProperty("urlButton")) {
                if (properties.hydratedButton === 1)
                    return "hydratedButton: multiple values";
                properties.hydratedButton = 1;
                {
                    var error = $root.proto.HydratedURLButton.verify(message.urlButton);
                    if (error)
                        return "urlButton." + error;
                }
            }
            if (message.callButton != null && message.hasOwnProperty("callButton")) {
                if (properties.hydratedButton === 1)
                    return "hydratedButton: multiple values";
                properties.hydratedButton = 1;
                {
                    var error = $root.proto.HydratedCallButton.verify(message.callButton);
                    if (error)
                        return "callButton." + error;
                }
            }
            return null;
        };

        /**
         * Creates a HydratedTemplateButton message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.HydratedTemplateButton
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.HydratedTemplateButton} HydratedTemplateButton
         */
        HydratedTemplateButton.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.HydratedTemplateButton)
                return object;
            var message = new $root.proto.HydratedTemplateButton();
            if (object.index != null)
                message.index = object.index >>> 0;
            if (object.quickReplyButton != null) {
                if (typeof object.quickReplyButton !== "object")
                    throw TypeError(".proto.HydratedTemplateButton.quickReplyButton: object expected");
                message.quickReplyButton = $root.proto.HydratedQuickReplyButton.fromObject(object.quickReplyButton);
            }
            if (object.urlButton != null) {
                if (typeof object.urlButton !== "object")
                    throw TypeError(".proto.HydratedTemplateButton.urlButton: object expected");
                message.urlButton = $root.proto.HydratedURLButton.fromObject(object.urlButton);
            }
            if (object.callButton != null) {
                if (typeof object.callButton !== "object")
                    throw TypeError(".proto.HydratedTemplateButton.callButton: object expected");
                message.callButton = $root.proto.HydratedCallButton.fromObject(object.callButton);
            }
            return message;
        };

        /**
         * Creates a plain object from a HydratedTemplateButton message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.HydratedTemplateButton
         * @static
         * @param {proto.HydratedTemplateButton} message HydratedTemplateButton
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        HydratedTemplateButton.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                object.index = 0;
            if (message.quickReplyButton != null && message.hasOwnProperty("quickReplyButton")) {
                object.quickReplyButton = $root.proto.HydratedQuickReplyButton.toObject(message.quickReplyButton, options);
                if (options.oneofs)
                    object.hydratedButton = "quickReplyButton";
            }
            if (message.urlButton != null && message.hasOwnProperty("urlButton")) {
                object.urlButton = $root.proto.HydratedURLButton.toObject(message.urlButton, options);
                if (options.oneofs)
                    object.hydratedButton = "urlButton";
            }
            if (message.callButton != null && message.hasOwnProperty("callButton")) {
                object.callButton = $root.proto.HydratedCallButton.toObject(message.callButton, options);
                if (options.oneofs)
                    object.hydratedButton = "callButton";
            }
            if (message.index != null && message.hasOwnProperty("index"))
                object.index = message.index;
            return object;
        };

        /**
         * Converts this HydratedTemplateButton to JSON.
         * @function toJSON
         * @memberof proto.HydratedTemplateButton
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        HydratedTemplateButton.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return HydratedTemplateButton;
    })();

    proto.QuickReplyButton = (function() {

        /**
         * Properties of a QuickReplyButton.
         * @memberof proto
         * @interface IQuickReplyButton
         * @property {proto.IHighlyStructuredMessage|null} [displayText] QuickReplyButton displayText
         * @property {string|null} [id] QuickReplyButton id
         */

        /**
         * Constructs a new QuickReplyButton.
         * @memberof proto
         * @classdesc Represents a QuickReplyButton.
         * @implements IQuickReplyButton
         * @constructor
         * @param {proto.IQuickReplyButton=} [properties] Properties to set
         */
        function QuickReplyButton(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * QuickReplyButton displayText.
         * @member {proto.IHighlyStructuredMessage|null|undefined} displayText
         * @memberof proto.QuickReplyButton
         * @instance
         */
        QuickReplyButton.prototype.displayText = null;

        /**
         * QuickReplyButton id.
         * @member {string} id
         * @memberof proto.QuickReplyButton
         * @instance
         */
        QuickReplyButton.prototype.id = "";

        /**
         * Creates a new QuickReplyButton instance using the specified properties.
         * @function create
         * @memberof proto.QuickReplyButton
         * @static
         * @param {proto.IQuickReplyButton=} [properties] Properties to set
         * @returns {proto.QuickReplyButton} QuickReplyButton instance
         */
        QuickReplyButton.create = function create(properties) {
            return new QuickReplyButton(properties);
        };

        /**
         * Encodes the specified QuickReplyButton message. Does not implicitly {@link proto.QuickReplyButton.verify|verify} messages.
         * @function encode
         * @memberof proto.QuickReplyButton
         * @static
         * @param {proto.IQuickReplyButton} message QuickReplyButton message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        QuickReplyButton.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText"))
                $root.proto.HighlyStructuredMessage.encode(message.displayText, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.id);
            return writer;
        };

        /**
         * Encodes the specified QuickReplyButton message, length delimited. Does not implicitly {@link proto.QuickReplyButton.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.QuickReplyButton
         * @static
         * @param {proto.IQuickReplyButton} message QuickReplyButton message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        QuickReplyButton.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a QuickReplyButton message from the specified reader or buffer.
         * @function decode
         * @memberof proto.QuickReplyButton
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.QuickReplyButton} QuickReplyButton
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        QuickReplyButton.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.QuickReplyButton();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.displayText = $root.proto.HighlyStructuredMessage.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.id = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a QuickReplyButton message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.QuickReplyButton
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.QuickReplyButton} QuickReplyButton
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        QuickReplyButton.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a QuickReplyButton message.
         * @function verify
         * @memberof proto.QuickReplyButton
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        QuickReplyButton.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.displayText != null && message.hasOwnProperty("displayText")) {
                var error = $root.proto.HighlyStructuredMessage.verify(message.displayText);
                if (error)
                    return "displayText." + error;
            }
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isString(message.id))
                    return "id: string expected";
            return null;
        };

        /**
         * Creates a QuickReplyButton message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.QuickReplyButton
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.QuickReplyButton} QuickReplyButton
         */
        QuickReplyButton.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.QuickReplyButton)
                return object;
            var message = new $root.proto.QuickReplyButton();
            if (object.displayText != null) {
                if (typeof object.displayText !== "object")
                    throw TypeError(".proto.QuickReplyButton.displayText: object expected");
                message.displayText = $root.proto.HighlyStructuredMessage.fromObject(object.displayText);
            }
            if (object.id != null)
                message.id = String(object.id);
            return message;
        };

        /**
         * Creates a plain object from a QuickReplyButton message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.QuickReplyButton
         * @static
         * @param {proto.QuickReplyButton} message QuickReplyButton
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        QuickReplyButton.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.displayText = null;
                object.id = "";
            }
            if (message.displayText != null && message.hasOwnProperty("displayText"))
                object.displayText = $root.proto.HighlyStructuredMessage.toObject(message.displayText, options);
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            return object;
        };

        /**
         * Converts this QuickReplyButton to JSON.
         * @function toJSON
         * @memberof proto.QuickReplyButton
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        QuickReplyButton.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return QuickReplyButton;
    })();

    proto.URLButton = (function() {

        /**
         * Properties of a URLButton.
         * @memberof proto
         * @interface IURLButton
         * @property {proto.IHighlyStructuredMessage|null} [displayText] URLButton displayText
         * @property {proto.IHighlyStructuredMessage|null} [url] URLButton url
         */

        /**
         * Constructs a new URLButton.
         * @memberof proto
         * @classdesc Represents a URLButton.
         * @implements IURLButton
         * @constructor
         * @param {proto.IURLButton=} [properties] Properties to set
         */
        function URLButton(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * URLButton displayText.
         * @member {proto.IHighlyStructuredMessage|null|undefined} displayText
         * @memberof proto.URLButton
         * @instance
         */
        URLButton.prototype.displayText = null;

        /**
         * URLButton url.
         * @member {proto.IHighlyStructuredMessage|null|undefined} url
         * @memberof proto.URLButton
         * @instance
         */
        URLButton.prototype.url = null;

        /**
         * Creates a new URLButton instance using the specified properties.
         * @function create
         * @memberof proto.URLButton
         * @static
         * @param {proto.IURLButton=} [properties] Properties to set
         * @returns {proto.URLButton} URLButton instance
         */
        URLButton.create = function create(properties) {
            return new URLButton(properties);
        };

        /**
         * Encodes the specified URLButton message. Does not implicitly {@link proto.URLButton.verify|verify} messages.
         * @function encode
         * @memberof proto.URLButton
         * @static
         * @param {proto.IURLButton} message URLButton message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        URLButton.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText"))
                $root.proto.HighlyStructuredMessage.encode(message.displayText, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.url != null && Object.hasOwnProperty.call(message, "url"))
                $root.proto.HighlyStructuredMessage.encode(message.url, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified URLButton message, length delimited. Does not implicitly {@link proto.URLButton.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.URLButton
         * @static
         * @param {proto.IURLButton} message URLButton message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        URLButton.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a URLButton message from the specified reader or buffer.
         * @function decode
         * @memberof proto.URLButton
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.URLButton} URLButton
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        URLButton.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.URLButton();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.displayText = $root.proto.HighlyStructuredMessage.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.url = $root.proto.HighlyStructuredMessage.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a URLButton message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.URLButton
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.URLButton} URLButton
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        URLButton.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a URLButton message.
         * @function verify
         * @memberof proto.URLButton
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        URLButton.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.displayText != null && message.hasOwnProperty("displayText")) {
                var error = $root.proto.HighlyStructuredMessage.verify(message.displayText);
                if (error)
                    return "displayText." + error;
            }
            if (message.url != null && message.hasOwnProperty("url")) {
                var error = $root.proto.HighlyStructuredMessage.verify(message.url);
                if (error)
                    return "url." + error;
            }
            return null;
        };

        /**
         * Creates a URLButton message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.URLButton
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.URLButton} URLButton
         */
        URLButton.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.URLButton)
                return object;
            var message = new $root.proto.URLButton();
            if (object.displayText != null) {
                if (typeof object.displayText !== "object")
                    throw TypeError(".proto.URLButton.displayText: object expected");
                message.displayText = $root.proto.HighlyStructuredMessage.fromObject(object.displayText);
            }
            if (object.url != null) {
                if (typeof object.url !== "object")
                    throw TypeError(".proto.URLButton.url: object expected");
                message.url = $root.proto.HighlyStructuredMessage.fromObject(object.url);
            }
            return message;
        };

        /**
         * Creates a plain object from a URLButton message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.URLButton
         * @static
         * @param {proto.URLButton} message URLButton
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        URLButton.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.displayText = null;
                object.url = null;
            }
            if (message.displayText != null && message.hasOwnProperty("displayText"))
                object.displayText = $root.proto.HighlyStructuredMessage.toObject(message.displayText, options);
            if (message.url != null && message.hasOwnProperty("url"))
                object.url = $root.proto.HighlyStructuredMessage.toObject(message.url, options);
            return object;
        };

        /**
         * Converts this URLButton to JSON.
         * @function toJSON
         * @memberof proto.URLButton
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        URLButton.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return URLButton;
    })();

    proto.CallButton = (function() {

        /**
         * Properties of a CallButton.
         * @memberof proto
         * @interface ICallButton
         * @property {proto.IHighlyStructuredMessage|null} [displayText] CallButton displayText
         * @property {proto.IHighlyStructuredMessage|null} [phoneNumber] CallButton phoneNumber
         */

        /**
         * Constructs a new CallButton.
         * @memberof proto
         * @classdesc Represents a CallButton.
         * @implements ICallButton
         * @constructor
         * @param {proto.ICallButton=} [properties] Properties to set
         */
        function CallButton(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * CallButton displayText.
         * @member {proto.IHighlyStructuredMessage|null|undefined} displayText
         * @memberof proto.CallButton
         * @instance
         */
        CallButton.prototype.displayText = null;

        /**
         * CallButton phoneNumber.
         * @member {proto.IHighlyStructuredMessage|null|undefined} phoneNumber
         * @memberof proto.CallButton
         * @instance
         */
        CallButton.prototype.phoneNumber = null;

        /**
         * Creates a new CallButton instance using the specified properties.
         * @function create
         * @memberof proto.CallButton
         * @static
         * @param {proto.ICallButton=} [properties] Properties to set
         * @returns {proto.CallButton} CallButton instance
         */
        CallButton.create = function create(properties) {
            return new CallButton(properties);
        };

        /**
         * Encodes the specified CallButton message. Does not implicitly {@link proto.CallButton.verify|verify} messages.
         * @function encode
         * @memberof proto.CallButton
         * @static
         * @param {proto.ICallButton} message CallButton message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CallButton.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.displayText != null && Object.hasOwnProperty.call(message, "displayText"))
                $root.proto.HighlyStructuredMessage.encode(message.displayText, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.phoneNumber != null && Object.hasOwnProperty.call(message, "phoneNumber"))
                $root.proto.HighlyStructuredMessage.encode(message.phoneNumber, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified CallButton message, length delimited. Does not implicitly {@link proto.CallButton.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.CallButton
         * @static
         * @param {proto.ICallButton} message CallButton message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CallButton.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a CallButton message from the specified reader or buffer.
         * @function decode
         * @memberof proto.CallButton
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.CallButton} CallButton
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CallButton.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.CallButton();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.displayText = $root.proto.HighlyStructuredMessage.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.phoneNumber = $root.proto.HighlyStructuredMessage.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a CallButton message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.CallButton
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.CallButton} CallButton
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CallButton.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a CallButton message.
         * @function verify
         * @memberof proto.CallButton
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        CallButton.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.displayText != null && message.hasOwnProperty("displayText")) {
                var error = $root.proto.HighlyStructuredMessage.verify(message.displayText);
                if (error)
                    return "displayText." + error;
            }
            if (message.phoneNumber != null && message.hasOwnProperty("phoneNumber")) {
                var error = $root.proto.HighlyStructuredMessage.verify(message.phoneNumber);
                if (error)
                    return "phoneNumber." + error;
            }
            return null;
        };

        /**
         * Creates a CallButton message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.CallButton
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.CallButton} CallButton
         */
        CallButton.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.CallButton)
                return object;
            var message = new $root.proto.CallButton();
            if (object.displayText != null) {
                if (typeof object.displayText !== "object")
                    throw TypeError(".proto.CallButton.displayText: object expected");
                message.displayText = $root.proto.HighlyStructuredMessage.fromObject(object.displayText);
            }
            if (object.phoneNumber != null) {
                if (typeof object.phoneNumber !== "object")
                    throw TypeError(".proto.CallButton.phoneNumber: object expected");
                message.phoneNumber = $root.proto.HighlyStructuredMessage.fromObject(object.phoneNumber);
            }
            return message;
        };

        /**
         * Creates a plain object from a CallButton message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.CallButton
         * @static
         * @param {proto.CallButton} message CallButton
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        CallButton.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.displayText = null;
                object.phoneNumber = null;
            }
            if (message.displayText != null && message.hasOwnProperty("displayText"))
                object.displayText = $root.proto.HighlyStructuredMessage.toObject(message.displayText, options);
            if (message.phoneNumber != null && message.hasOwnProperty("phoneNumber"))
                object.phoneNumber = $root.proto.HighlyStructuredMessage.toObject(message.phoneNumber, options);
            return object;
        };

        /**
         * Converts this CallButton to JSON.
         * @function toJSON
         * @memberof proto.CallButton
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        CallButton.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return CallButton;
    })();

    proto.TemplateButton = (function() {

        /**
         * Properties of a TemplateButton.
         * @memberof proto
         * @interface ITemplateButton
         * @property {number|null} [index] TemplateButton index
         * @property {proto.IQuickReplyButton|null} [quickReplyButton] TemplateButton quickReplyButton
         * @property {proto.IURLButton|null} [urlButton] TemplateButton urlButton
         * @property {proto.ICallButton|null} [callButton] TemplateButton callButton
         */

        /**
         * Constructs a new TemplateButton.
         * @memberof proto
         * @classdesc Represents a TemplateButton.
         * @implements ITemplateButton
         * @constructor
         * @param {proto.ITemplateButton=} [properties] Properties to set
         */
        function TemplateButton(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * TemplateButton index.
         * @member {number} index
         * @memberof proto.TemplateButton
         * @instance
         */
        TemplateButton.prototype.index = 0;

        /**
         * TemplateButton quickReplyButton.
         * @member {proto.IQuickReplyButton|null|undefined} quickReplyButton
         * @memberof proto.TemplateButton
         * @instance
         */
        TemplateButton.prototype.quickReplyButton = null;

        /**
         * TemplateButton urlButton.
         * @member {proto.IURLButton|null|undefined} urlButton
         * @memberof proto.TemplateButton
         * @instance
         */
        TemplateButton.prototype.urlButton = null;

        /**
         * TemplateButton callButton.
         * @member {proto.ICallButton|null|undefined} callButton
         * @memberof proto.TemplateButton
         * @instance
         */
        TemplateButton.prototype.callButton = null;

        // OneOf field names bound to virtual getters and setters
        var $oneOfFields;

        /**
         * TemplateButton button.
         * @member {"quickReplyButton"|"urlButton"|"callButton"|undefined} button
         * @memberof proto.TemplateButton
         * @instance
         */
        Object.defineProperty(TemplateButton.prototype, "button", {
            get: $util.oneOfGetter($oneOfFields = ["quickReplyButton", "urlButton", "callButton"]),
            set: $util.oneOfSetter($oneOfFields)
        });

        /**
         * Creates a new TemplateButton instance using the specified properties.
         * @function create
         * @memberof proto.TemplateButton
         * @static
         * @param {proto.ITemplateButton=} [properties] Properties to set
         * @returns {proto.TemplateButton} TemplateButton instance
         */
        TemplateButton.create = function create(properties) {
            return new TemplateButton(properties);
        };

        /**
         * Encodes the specified TemplateButton message. Does not implicitly {@link proto.TemplateButton.verify|verify} messages.
         * @function encode
         * @memberof proto.TemplateButton
         * @static
         * @param {proto.ITemplateButton} message TemplateButton message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TemplateButton.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.quickReplyButton != null && Object.hasOwnProperty.call(message, "quickReplyButton"))
                $root.proto.QuickReplyButton.encode(message.quickReplyButton, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.urlButton != null && Object.hasOwnProperty.call(message, "urlButton"))
                $root.proto.URLButton.encode(message.urlButton, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.callButton != null && Object.hasOwnProperty.call(message, "callButton"))
                $root.proto.CallButton.encode(message.callButton, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
            if (message.index != null && Object.hasOwnProperty.call(message, "index"))
                writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.index);
            return writer;
        };

        /**
         * Encodes the specified TemplateButton message, length delimited. Does not implicitly {@link proto.TemplateButton.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.TemplateButton
         * @static
         * @param {proto.ITemplateButton} message TemplateButton message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        TemplateButton.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a TemplateButton message from the specified reader or buffer.
         * @function decode
         * @memberof proto.TemplateButton
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.TemplateButton} TemplateButton
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TemplateButton.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.TemplateButton();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 4:
                    message.index = reader.uint32();
                    break;
                case 1:
                    message.quickReplyButton = $root.proto.QuickReplyButton.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.urlButton = $root.proto.URLButton.decode(reader, reader.uint32());
                    break;
                case 3:
                    message.callButton = $root.proto.CallButton.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a TemplateButton message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.TemplateButton
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.TemplateButton} TemplateButton
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        TemplateButton.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a TemplateButton message.
         * @function verify
         * @memberof proto.TemplateButton
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        TemplateButton.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            var properties = {};
            if (message.index != null && message.hasOwnProperty("index"))
                if (!$util.isInteger(message.index))
                    return "index: integer expected";
            if (message.quickReplyButton != null && message.hasOwnProperty("quickReplyButton")) {
                properties.button = 1;
                {
                    var error = $root.proto.QuickReplyButton.verify(message.quickReplyButton);
                    if (error)
                        return "quickReplyButton." + error;
                }
            }
            if (message.urlButton != null && message.hasOwnProperty("urlButton")) {
                if (properties.button === 1)
                    return "button: multiple values";
                properties.button = 1;
                {
                    var error = $root.proto.URLButton.verify(message.urlButton);
                    if (error)
                        return "urlButton." + error;
                }
            }
            if (message.callButton != null && message.hasOwnProperty("callButton")) {
                if (properties.button === 1)
                    return "button: multiple values";
                properties.button = 1;
                {
                    var error = $root.proto.CallButton.verify(message.callButton);
                    if (error)
                        return "callButton." + error;
                }
            }
            return null;
        };

        /**
         * Creates a TemplateButton message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.TemplateButton
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.TemplateButton} TemplateButton
         */
        TemplateButton.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.TemplateButton)
                return object;
            var message = new $root.proto.TemplateButton();
            if (object.index != null)
                message.index = object.index >>> 0;
            if (object.quickReplyButton != null) {
                if (typeof object.quickReplyButton !== "object")
                    throw TypeError(".proto.TemplateButton.quickReplyButton: object expected");
                message.quickReplyButton = $root.proto.QuickReplyButton.fromObject(object.quickReplyButton);
            }
            if (object.urlButton != null) {
                if (typeof object.urlButton !== "object")
                    throw TypeError(".proto.TemplateButton.urlButton: object expected");
                message.urlButton = $root.proto.URLButton.fromObject(object.urlButton);
            }
            if (object.callButton != null) {
                if (typeof object.callButton !== "object")
                    throw TypeError(".proto.TemplateButton.callButton: object expected");
                message.callButton = $root.proto.CallButton.fromObject(object.callButton);
            }
            return message;
        };

        /**
         * Creates a plain object from a TemplateButton message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.TemplateButton
         * @static
         * @param {proto.TemplateButton} message TemplateButton
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        TemplateButton.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults)
                object.index = 0;
            if (message.quickReplyButton != null && message.hasOwnProperty("quickReplyButton")) {
                object.quickReplyButton = $root.proto.QuickReplyButton.toObject(message.quickReplyButton, options);
                if (options.oneofs)
                    object.button = "quickReplyButton";
            }
            if (message.urlButton != null && message.hasOwnProperty("urlButton")) {
                object.urlButton = $root.proto.URLButton.toObject(message.urlButton, options);
                if (options.oneofs)
                    object.button = "urlButton";
            }
            if (message.callButton != null && message.hasOwnProperty("callButton")) {
                object.callButton = $root.proto.CallButton.toObject(message.callButton, options);
                if (options.oneofs)
                    object.button = "callButton";
            }
            if (message.index != null && message.hasOwnProperty("index"))
                object.index = message.index;
            return object;
        };

        /**
         * Converts this TemplateButton to JSON.
         * @function toJSON
         * @memberof proto.TemplateButton
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        TemplateButton.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return TemplateButton;
    })();

    proto.Location = (function() {

        /**
         * Properties of a Location.
         * @memberof proto
         * @interface ILocation
         * @property {number|null} [degreesLatitude] Location degreesLatitude
         * @property {number|null} [degreesLongitude] Location degreesLongitude
         * @property {string|null} [name] Location name
         */

        /**
         * Constructs a new Location.
         * @memberof proto
         * @classdesc Represents a Location.
         * @implements ILocation
         * @constructor
         * @param {proto.ILocation=} [properties] Properties to set
         */
        function Location(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Location degreesLatitude.
         * @member {number} degreesLatitude
         * @memberof proto.Location
         * @instance
         */
        Location.prototype.degreesLatitude = 0;

        /**
         * Location degreesLongitude.
         * @member {number} degreesLongitude
         * @memberof proto.Location
         * @instance
         */
        Location.prototype.degreesLongitude = 0;

        /**
         * Location name.
         * @member {string} name
         * @memberof proto.Location
         * @instance
         */
        Location.prototype.name = "";

        /**
         * Creates a new Location instance using the specified properties.
         * @function create
         * @memberof proto.Location
         * @static
         * @param {proto.ILocation=} [properties] Properties to set
         * @returns {proto.Location} Location instance
         */
        Location.create = function create(properties) {
            return new Location(properties);
        };

        /**
         * Encodes the specified Location message. Does not implicitly {@link proto.Location.verify|verify} messages.
         * @function encode
         * @memberof proto.Location
         * @static
         * @param {proto.ILocation} message Location message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Location.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.degreesLatitude != null && Object.hasOwnProperty.call(message, "degreesLatitude"))
                writer.uint32(/* id 1, wireType 1 =*/9).double(message.degreesLatitude);
            if (message.degreesLongitude != null && Object.hasOwnProperty.call(message, "degreesLongitude"))
                writer.uint32(/* id 2, wireType 1 =*/17).double(message.degreesLongitude);
            if (message.name != null && Object.hasOwnProperty.call(message, "name"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.name);
            return writer;
        };

        /**
         * Encodes the specified Location message, length delimited. Does not implicitly {@link proto.Location.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.Location
         * @static
         * @param {proto.ILocation} message Location message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Location.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a Location message from the specified reader or buffer.
         * @function decode
         * @memberof proto.Location
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.Location} Location
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Location.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Location();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.degreesLatitude = reader.double();
                    break;
                case 2:
                    message.degreesLongitude = reader.double();
                    break;
                case 3:
                    message.name = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a Location message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.Location
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.Location} Location
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Location.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a Location message.
         * @function verify
         * @memberof proto.Location
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        Location.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.degreesLatitude != null && message.hasOwnProperty("degreesLatitude"))
                if (typeof message.degreesLatitude !== "number")
                    return "degreesLatitude: number expected";
            if (message.degreesLongitude != null && message.hasOwnProperty("degreesLongitude"))
                if (typeof message.degreesLongitude !== "number")
                    return "degreesLongitude: number expected";
            if (message.name != null && message.hasOwnProperty("name"))
                if (!$util.isString(message.name))
                    return "name: string expected";
            return null;
        };

        /**
         * Creates a Location message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.Location
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.Location} Location
         */
        Location.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.Location)
                return object;
            var message = new $root.proto.Location();
            if (object.degreesLatitude != null)
                message.degreesLatitude = Number(object.degreesLatitude);
            if (object.degreesLongitude != null)
                message.degreesLongitude = Number(object.degreesLongitude);
            if (object.name != null)
                message.name = String(object.name);
            return message;
        };

        /**
         * Creates a plain object from a Location message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.Location
         * @static
         * @param {proto.Location} message Location
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        Location.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.degreesLatitude = 0;
                object.degreesLongitude = 0;
                object.name = "";
            }
            if (message.degreesLatitude != null && message.hasOwnProperty("degreesLatitude"))
                object.degreesLatitude = options.json && !isFinite(message.degreesLatitude) ? String(message.degreesLatitude) : message.degreesLatitude;
            if (message.degreesLongitude != null && message.hasOwnProperty("degreesLongitude"))
                object.degreesLongitude = options.json && !isFinite(message.degreesLongitude) ? String(message.degreesLongitude) : message.degreesLongitude;
            if (message.name != null && message.hasOwnProperty("name"))
                object.name = message.name;
            return object;
        };

        /**
         * Converts this Location to JSON.
         * @function toJSON
         * @memberof proto.Location
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        Location.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return Location;
    })();

    proto.Point = (function() {

        /**
         * Properties of a Point.
         * @memberof proto
         * @interface IPoint
         * @property {number|null} [xDeprecated] Point xDeprecated
         * @property {number|null} [yDeprecated] Point yDeprecated
         * @property {number|null} [x] Point x
         * @property {number|null} [y] Point y
         */

        /**
         * Constructs a new Point.
         * @memberof proto
         * @classdesc Represents a Point.
         * @implements IPoint
         * @constructor
         * @param {proto.IPoint=} [properties] Properties to set
         */
        function Point(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Point xDeprecated.
         * @member {number} xDeprecated
         * @memberof proto.Point
         * @instance
         */
        Point.prototype.xDeprecated = 0;

        /**
         * Point yDeprecated.
         * @member {number} yDeprecated
         * @memberof proto.Point
         * @instance
         */
        Point.prototype.yDeprecated = 0;

        /**
         * Point x.
         * @member {number} x
         * @memberof proto.Point
         * @instance
         */
        Point.prototype.x = 0;

        /**
         * Point y.
         * @member {number} y
         * @memberof proto.Point
         * @instance
         */
        Point.prototype.y = 0;

        /**
         * Creates a new Point instance using the specified properties.
         * @function create
         * @memberof proto.Point
         * @static
         * @param {proto.IPoint=} [properties] Properties to set
         * @returns {proto.Point} Point instance
         */
        Point.create = function create(properties) {
            return new Point(properties);
        };

        /**
         * Encodes the specified Point message. Does not implicitly {@link proto.Point.verify|verify} messages.
         * @function encode
         * @memberof proto.Point
         * @static
         * @param {proto.IPoint} message Point message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Point.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.xDeprecated != null && Object.hasOwnProperty.call(message, "xDeprecated"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.xDeprecated);
            if (message.yDeprecated != null && Object.hasOwnProperty.call(message, "yDeprecated"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.yDeprecated);
            if (message.x != null && Object.hasOwnProperty.call(message, "x"))
                writer.uint32(/* id 3, wireType 1 =*/25).double(message.x);
            if (message.y != null && Object.hasOwnProperty.call(message, "y"))
                writer.uint32(/* id 4, wireType 1 =*/33).double(message.y);
            return writer;
        };

        /**
         * Encodes the specified Point message, length delimited. Does not implicitly {@link proto.Point.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.Point
         * @static
         * @param {proto.IPoint} message Point message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Point.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a Point message from the specified reader or buffer.
         * @function decode
         * @memberof proto.Point
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.Point} Point
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Point.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Point();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.xDeprecated = reader.int32();
                    break;
                case 2:
                    message.yDeprecated = reader.int32();
                    break;
                case 3:
                    message.x = reader.double();
                    break;
                case 4:
                    message.y = reader.double();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a Point message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.Point
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.Point} Point
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Point.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a Point message.
         * @function verify
         * @memberof proto.Point
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        Point.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.xDeprecated != null && message.hasOwnProperty("xDeprecated"))
                if (!$util.isInteger(message.xDeprecated))
                    return "xDeprecated: integer expected";
            if (message.yDeprecated != null && message.hasOwnProperty("yDeprecated"))
                if (!$util.isInteger(message.yDeprecated))
                    return "yDeprecated: integer expected";
            if (message.x != null && message.hasOwnProperty("x"))
                if (typeof message.x !== "number")
                    return "x: number expected";
            if (message.y != null && message.hasOwnProperty("y"))
                if (typeof message.y !== "number")
                    return "y: number expected";
            return null;
        };

        /**
         * Creates a Point message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.Point
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.Point} Point
         */
        Point.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.Point)
                return object;
            var message = new $root.proto.Point();
            if (object.xDeprecated != null)
                message.xDeprecated = object.xDeprecated | 0;
            if (object.yDeprecated != null)
                message.yDeprecated = object.yDeprecated | 0;
            if (object.x != null)
                message.x = Number(object.x);
            if (object.y != null)
                message.y = Number(object.y);
            return message;
        };

        /**
         * Creates a plain object from a Point message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.Point
         * @static
         * @param {proto.Point} message Point
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        Point.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.xDeprecated = 0;
                object.yDeprecated = 0;
                object.x = 0;
                object.y = 0;
            }
            if (message.xDeprecated != null && message.hasOwnProperty("xDeprecated"))
                object.xDeprecated = message.xDeprecated;
            if (message.yDeprecated != null && message.hasOwnProperty("yDeprecated"))
                object.yDeprecated = message.yDeprecated;
            if (message.x != null && message.hasOwnProperty("x"))
                object.x = options.json && !isFinite(message.x) ? String(message.x) : message.x;
            if (message.y != null && message.hasOwnProperty("y"))
                object.y = options.json && !isFinite(message.y) ? String(message.y) : message.y;
            return object;
        };

        /**
         * Converts this Point to JSON.
         * @function toJSON
         * @memberof proto.Point
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        Point.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return Point;
    })();

    proto.CompanionProps = (function() {

        /**
         * Properties of a CompanionProps.
         * @memberof proto
         * @interface ICompanionProps
         * @property {string|null} [os] CompanionProps os
         * @property {proto.IAppVersion|null} [version] CompanionProps version
         * @property {proto.CompanionProps.CompanionPropsPlatformType|null} [platformType] CompanionProps platformType
         * @property {boolean|null} [requireFullSync] CompanionProps requireFullSync
         */

        /**
         * Constructs a new CompanionProps.
         * @memberof proto
         * @classdesc Represents a CompanionProps.
         * @implements ICompanionProps
         * @constructor
         * @param {proto.ICompanionProps=} [properties] Properties to set
         */
        function CompanionProps(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * CompanionProps os.
         * @member {string} os
         * @memberof proto.CompanionProps
         * @instance
         */
        CompanionProps.prototype.os = "";

        /**
         * CompanionProps version.
         * @member {proto.IAppVersion|null|undefined} version
         * @memberof proto.CompanionProps
         * @instance
         */
        CompanionProps.prototype.version = null;

        /**
         * CompanionProps platformType.
         * @member {proto.CompanionProps.CompanionPropsPlatformType} platformType
         * @memberof proto.CompanionProps
         * @instance
         */
        CompanionProps.prototype.platformType = 0;

        /**
         * CompanionProps requireFullSync.
         * @member {boolean} requireFullSync
         * @memberof proto.CompanionProps
         * @instance
         */
        CompanionProps.prototype.requireFullSync = false;

        /**
         * Creates a new CompanionProps instance using the specified properties.
         * @function create
         * @memberof proto.CompanionProps
         * @static
         * @param {proto.ICompanionProps=} [properties] Properties to set
         * @returns {proto.CompanionProps} CompanionProps instance
         */
        CompanionProps.create = function create(properties) {
            return new CompanionProps(properties);
        };

        /**
         * Encodes the specified CompanionProps message. Does not implicitly {@link proto.CompanionProps.verify|verify} messages.
         * @function encode
         * @memberof proto.CompanionProps
         * @static
         * @param {proto.ICompanionProps} message CompanionProps message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CompanionProps.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.os != null && Object.hasOwnProperty.call(message, "os"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.os);
            if (message.version != null && Object.hasOwnProperty.call(message, "version"))
                $root.proto.AppVersion.encode(message.version, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.platformType != null && Object.hasOwnProperty.call(message, "platformType"))
                writer.uint32(/* id 3, wireType 0 =*/24).int32(message.platformType);
            if (message.requireFullSync != null && Object.hasOwnProperty.call(message, "requireFullSync"))
                writer.uint32(/* id 4, wireType 0 =*/32).bool(message.requireFullSync);
            return writer;
        };

        /**
         * Encodes the specified CompanionProps message, length delimited. Does not implicitly {@link proto.CompanionProps.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.CompanionProps
         * @static
         * @param {proto.ICompanionProps} message CompanionProps message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        CompanionProps.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a CompanionProps message from the specified reader or buffer.
         * @function decode
         * @memberof proto.CompanionProps
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.CompanionProps} CompanionProps
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CompanionProps.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.CompanionProps();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.os = reader.string();
                    break;
                case 2:
                    message.version = $root.proto.AppVersion.decode(reader, reader.uint32());
                    break;
                case 3:
                    message.platformType = reader.int32();
                    break;
                case 4:
                    message.requireFullSync = reader.bool();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a CompanionProps message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.CompanionProps
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.CompanionProps} CompanionProps
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        CompanionProps.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a CompanionProps message.
         * @function verify
         * @memberof proto.CompanionProps
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        CompanionProps.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.os != null && message.hasOwnProperty("os"))
                if (!$util.isString(message.os))
                    return "os: string expected";
            if (message.version != null && message.hasOwnProperty("version")) {
                var error = $root.proto.AppVersion.verify(message.version);
                if (error)
                    return "version." + error;
            }
            if (message.platformType != null && message.hasOwnProperty("platformType"))
                switch (message.platformType) {
                default:
                    return "platformType: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                case 8:
                case 9:
                case 10:
                case 11:
                case 12:
                    break;
                }
            if (message.requireFullSync != null && message.hasOwnProperty("requireFullSync"))
                if (typeof message.requireFullSync !== "boolean")
                    return "requireFullSync: boolean expected";
            return null;
        };

        /**
         * Creates a CompanionProps message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.CompanionProps
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.CompanionProps} CompanionProps
         */
        CompanionProps.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.CompanionProps)
                return object;
            var message = new $root.proto.CompanionProps();
            if (object.os != null)
                message.os = String(object.os);
            if (object.version != null) {
                if (typeof object.version !== "object")
                    throw TypeError(".proto.CompanionProps.version: object expected");
                message.version = $root.proto.AppVersion.fromObject(object.version);
            }
            switch (object.platformType) {
            case "UNKNOWN":
            case 0:
                message.platformType = 0;
                break;
            case "CHROME":
            case 1:
                message.platformType = 1;
                break;
            case "FIREFOX":
            case 2:
                message.platformType = 2;
                break;
            case "IE":
            case 3:
                message.platformType = 3;
                break;
            case "OPERA":
            case 4:
                message.platformType = 4;
                break;
            case "SAFARI":
            case 5:
                message.platformType = 5;
                break;
            case "EDGE":
            case 6:
                message.platformType = 6;
                break;
            case "DESKTOP":
            case 7:
                message.platformType = 7;
                break;
            case "IPAD":
            case 8:
                message.platformType = 8;
                break;
            case "ANDROID_TABLET":
            case 9:
                message.platformType = 9;
                break;
            case "OHANA":
            case 10:
                message.platformType = 10;
                break;
            case "ALOHA":
            case 11:
                message.platformType = 11;
                break;
            case "CATALINA":
            case 12:
                message.platformType = 12;
                break;
            }
            if (object.requireFullSync != null)
                message.requireFullSync = Boolean(object.requireFullSync);
            return message;
        };

        /**
         * Creates a plain object from a CompanionProps message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.CompanionProps
         * @static
         * @param {proto.CompanionProps} message CompanionProps
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        CompanionProps.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.os = "";
                object.version = null;
                object.platformType = options.enums === String ? "UNKNOWN" : 0;
                object.requireFullSync = false;
            }
            if (message.os != null && message.hasOwnProperty("os"))
                object.os = message.os;
            if (message.version != null && message.hasOwnProperty("version"))
                object.version = $root.proto.AppVersion.toObject(message.version, options);
            if (message.platformType != null && message.hasOwnProperty("platformType"))
                object.platformType = options.enums === String ? $root.proto.CompanionProps.CompanionPropsPlatformType[message.platformType] : message.platformType;
            if (message.requireFullSync != null && message.hasOwnProperty("requireFullSync"))
                object.requireFullSync = message.requireFullSync;
            return object;
        };

        /**
         * Converts this CompanionProps to JSON.
         * @function toJSON
         * @memberof proto.CompanionProps
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        CompanionProps.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * CompanionPropsPlatformType enum.
         * @name proto.CompanionProps.CompanionPropsPlatformType
         * @enum {number}
         * @property {number} UNKNOWN=0 UNKNOWN value
         * @property {number} CHROME=1 CHROME value
         * @property {number} FIREFOX=2 FIREFOX value
         * @property {number} IE=3 IE value
         * @property {number} OPERA=4 OPERA value
         * @property {number} SAFARI=5 SAFARI value
         * @property {number} EDGE=6 EDGE value
         * @property {number} DESKTOP=7 DESKTOP value
         * @property {number} IPAD=8 IPAD value
         * @property {number} ANDROID_TABLET=9 ANDROID_TABLET value
         * @property {number} OHANA=10 OHANA value
         * @property {number} ALOHA=11 ALOHA value
         * @property {number} CATALINA=12 CATALINA value
         */
        CompanionProps.CompanionPropsPlatformType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "UNKNOWN"] = 0;
            values[valuesById[1] = "CHROME"] = 1;
            values[valuesById[2] = "FIREFOX"] = 2;
            values[valuesById[3] = "IE"] = 3;
            values[valuesById[4] = "OPERA"] = 4;
            values[valuesById[5] = "SAFARI"] = 5;
            values[valuesById[6] = "EDGE"] = 6;
            values[valuesById[7] = "DESKTOP"] = 7;
            values[valuesById[8] = "IPAD"] = 8;
            values[valuesById[9] = "ANDROID_TABLET"] = 9;
            values[valuesById[10] = "OHANA"] = 10;
            values[valuesById[11] = "ALOHA"] = 11;
            values[valuesById[12] = "CATALINA"] = 12;
            return values;
        })();

        return CompanionProps;
    })();

    proto.ADVSignedDeviceIdentityHMAC = (function() {

        /**
         * Properties of a ADVSignedDeviceIdentityHMAC.
         * @memberof proto
         * @interface IADVSignedDeviceIdentityHMAC
         * @property {Uint8Array|null} [details] ADVSignedDeviceIdentityHMAC details
         * @property {Uint8Array|null} [hmac] ADVSignedDeviceIdentityHMAC hmac
         */

        /**
         * Constructs a new ADVSignedDeviceIdentityHMAC.
         * @memberof proto
         * @classdesc Represents a ADVSignedDeviceIdentityHMAC.
         * @implements IADVSignedDeviceIdentityHMAC
         * @constructor
         * @param {proto.IADVSignedDeviceIdentityHMAC=} [properties] Properties to set
         */
        function ADVSignedDeviceIdentityHMAC(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ADVSignedDeviceIdentityHMAC details.
         * @member {Uint8Array} details
         * @memberof proto.ADVSignedDeviceIdentityHMAC
         * @instance
         */
        ADVSignedDeviceIdentityHMAC.prototype.details = $util.newBuffer([]);

        /**
         * ADVSignedDeviceIdentityHMAC hmac.
         * @member {Uint8Array} hmac
         * @memberof proto.ADVSignedDeviceIdentityHMAC
         * @instance
         */
        ADVSignedDeviceIdentityHMAC.prototype.hmac = $util.newBuffer([]);

        /**
         * Creates a new ADVSignedDeviceIdentityHMAC instance using the specified properties.
         * @function create
         * @memberof proto.ADVSignedDeviceIdentityHMAC
         * @static
         * @param {proto.IADVSignedDeviceIdentityHMAC=} [properties] Properties to set
         * @returns {proto.ADVSignedDeviceIdentityHMAC} ADVSignedDeviceIdentityHMAC instance
         */
        ADVSignedDeviceIdentityHMAC.create = function create(properties) {
            return new ADVSignedDeviceIdentityHMAC(properties);
        };

        /**
         * Encodes the specified ADVSignedDeviceIdentityHMAC message. Does not implicitly {@link proto.ADVSignedDeviceIdentityHMAC.verify|verify} messages.
         * @function encode
         * @memberof proto.ADVSignedDeviceIdentityHMAC
         * @static
         * @param {proto.IADVSignedDeviceIdentityHMAC} message ADVSignedDeviceIdentityHMAC message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ADVSignedDeviceIdentityHMAC.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.details != null && Object.hasOwnProperty.call(message, "details"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.details);
            if (message.hmac != null && Object.hasOwnProperty.call(message, "hmac"))
                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.hmac);
            return writer;
        };

        /**
         * Encodes the specified ADVSignedDeviceIdentityHMAC message, length delimited. Does not implicitly {@link proto.ADVSignedDeviceIdentityHMAC.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ADVSignedDeviceIdentityHMAC
         * @static
         * @param {proto.IADVSignedDeviceIdentityHMAC} message ADVSignedDeviceIdentityHMAC message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ADVSignedDeviceIdentityHMAC.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ADVSignedDeviceIdentityHMAC message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ADVSignedDeviceIdentityHMAC
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ADVSignedDeviceIdentityHMAC} ADVSignedDeviceIdentityHMAC
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ADVSignedDeviceIdentityHMAC.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ADVSignedDeviceIdentityHMAC();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.details = reader.bytes();
                    break;
                case 2:
                    message.hmac = reader.bytes();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ADVSignedDeviceIdentityHMAC message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ADVSignedDeviceIdentityHMAC
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ADVSignedDeviceIdentityHMAC} ADVSignedDeviceIdentityHMAC
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ADVSignedDeviceIdentityHMAC.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ADVSignedDeviceIdentityHMAC message.
         * @function verify
         * @memberof proto.ADVSignedDeviceIdentityHMAC
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ADVSignedDeviceIdentityHMAC.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.details != null && message.hasOwnProperty("details"))
                if (!(message.details && typeof message.details.length === "number" || $util.isString(message.details)))
                    return "details: buffer expected";
            if (message.hmac != null && message.hasOwnProperty("hmac"))
                if (!(message.hmac && typeof message.hmac.length === "number" || $util.isString(message.hmac)))
                    return "hmac: buffer expected";
            return null;
        };

        /**
         * Creates a ADVSignedDeviceIdentityHMAC message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ADVSignedDeviceIdentityHMAC
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ADVSignedDeviceIdentityHMAC} ADVSignedDeviceIdentityHMAC
         */
        ADVSignedDeviceIdentityHMAC.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ADVSignedDeviceIdentityHMAC)
                return object;
            var message = new $root.proto.ADVSignedDeviceIdentityHMAC();
            if (object.details != null)
                if (typeof object.details === "string")
                    $util.base64.decode(object.details, message.details = $util.newBuffer($util.base64.length(object.details)), 0);
                else if (object.details.length)
                    message.details = object.details;
            if (object.hmac != null)
                if (typeof object.hmac === "string")
                    $util.base64.decode(object.hmac, message.hmac = $util.newBuffer($util.base64.length(object.hmac)), 0);
                else if (object.hmac.length)
                    message.hmac = object.hmac;
            return message;
        };

        /**
         * Creates a plain object from a ADVSignedDeviceIdentityHMAC message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ADVSignedDeviceIdentityHMAC
         * @static
         * @param {proto.ADVSignedDeviceIdentityHMAC} message ADVSignedDeviceIdentityHMAC
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ADVSignedDeviceIdentityHMAC.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object.details = "";
                else {
                    object.details = [];
                    if (options.bytes !== Array)
                        object.details = $util.newBuffer(object.details);
                }
                if (options.bytes === String)
                    object.hmac = "";
                else {
                    object.hmac = [];
                    if (options.bytes !== Array)
                        object.hmac = $util.newBuffer(object.hmac);
                }
            }
            if (message.details != null && message.hasOwnProperty("details"))
                object.details = options.bytes === String ? $util.base64.encode(message.details, 0, message.details.length) : options.bytes === Array ? Array.prototype.slice.call(message.details) : message.details;
            if (message.hmac != null && message.hasOwnProperty("hmac"))
                object.hmac = options.bytes === String ? $util.base64.encode(message.hmac, 0, message.hmac.length) : options.bytes === Array ? Array.prototype.slice.call(message.hmac) : message.hmac;
            return object;
        };

        /**
         * Converts this ADVSignedDeviceIdentityHMAC to JSON.
         * @function toJSON
         * @memberof proto.ADVSignedDeviceIdentityHMAC
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ADVSignedDeviceIdentityHMAC.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ADVSignedDeviceIdentityHMAC;
    })();

    proto.ADVSignedDeviceIdentity = (function() {

        /**
         * Properties of a ADVSignedDeviceIdentity.
         * @memberof proto
         * @interface IADVSignedDeviceIdentity
         * @property {Uint8Array|null} [details] ADVSignedDeviceIdentity details
         * @property {Uint8Array|null} [accountSignatureKey] ADVSignedDeviceIdentity accountSignatureKey
         * @property {Uint8Array|null} [accountSignature] ADVSignedDeviceIdentity accountSignature
         * @property {Uint8Array|null} [deviceSignature] ADVSignedDeviceIdentity deviceSignature
         */

        /**
         * Constructs a new ADVSignedDeviceIdentity.
         * @memberof proto
         * @classdesc Represents a ADVSignedDeviceIdentity.
         * @implements IADVSignedDeviceIdentity
         * @constructor
         * @param {proto.IADVSignedDeviceIdentity=} [properties] Properties to set
         */
        function ADVSignedDeviceIdentity(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ADVSignedDeviceIdentity details.
         * @member {Uint8Array} details
         * @memberof proto.ADVSignedDeviceIdentity
         * @instance
         */
        ADVSignedDeviceIdentity.prototype.details = $util.newBuffer([]);

        /**
         * ADVSignedDeviceIdentity accountSignatureKey.
         * @member {Uint8Array} accountSignatureKey
         * @memberof proto.ADVSignedDeviceIdentity
         * @instance
         */
        ADVSignedDeviceIdentity.prototype.accountSignatureKey = $util.newBuffer([]);

        /**
         * ADVSignedDeviceIdentity accountSignature.
         * @member {Uint8Array} accountSignature
         * @memberof proto.ADVSignedDeviceIdentity
         * @instance
         */
        ADVSignedDeviceIdentity.prototype.accountSignature = $util.newBuffer([]);

        /**
         * ADVSignedDeviceIdentity deviceSignature.
         * @member {Uint8Array} deviceSignature
         * @memberof proto.ADVSignedDeviceIdentity
         * @instance
         */
        ADVSignedDeviceIdentity.prototype.deviceSignature = $util.newBuffer([]);

        /**
         * Creates a new ADVSignedDeviceIdentity instance using the specified properties.
         * @function create
         * @memberof proto.ADVSignedDeviceIdentity
         * @static
         * @param {proto.IADVSignedDeviceIdentity=} [properties] Properties to set
         * @returns {proto.ADVSignedDeviceIdentity} ADVSignedDeviceIdentity instance
         */
        ADVSignedDeviceIdentity.create = function create(properties) {
            return new ADVSignedDeviceIdentity(properties);
        };

        /**
         * Encodes the specified ADVSignedDeviceIdentity message. Does not implicitly {@link proto.ADVSignedDeviceIdentity.verify|verify} messages.
         * @function encode
         * @memberof proto.ADVSignedDeviceIdentity
         * @static
         * @param {proto.IADVSignedDeviceIdentity} message ADVSignedDeviceIdentity message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ADVSignedDeviceIdentity.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.details != null && Object.hasOwnProperty.call(message, "details"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.details);
            if (message.accountSignatureKey != null && Object.hasOwnProperty.call(message, "accountSignatureKey"))
                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.accountSignatureKey);
            if (message.accountSignature != null && Object.hasOwnProperty.call(message, "accountSignature"))
                writer.uint32(/* id 3, wireType 2 =*/26).bytes(message.accountSignature);
            if (message.deviceSignature != null && Object.hasOwnProperty.call(message, "deviceSignature"))
                writer.uint32(/* id 4, wireType 2 =*/34).bytes(message.deviceSignature);
            return writer;
        };

        /**
         * Encodes the specified ADVSignedDeviceIdentity message, length delimited. Does not implicitly {@link proto.ADVSignedDeviceIdentity.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ADVSignedDeviceIdentity
         * @static
         * @param {proto.IADVSignedDeviceIdentity} message ADVSignedDeviceIdentity message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ADVSignedDeviceIdentity.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ADVSignedDeviceIdentity message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ADVSignedDeviceIdentity
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ADVSignedDeviceIdentity} ADVSignedDeviceIdentity
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ADVSignedDeviceIdentity.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ADVSignedDeviceIdentity();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.details = reader.bytes();
                    break;
                case 2:
                    message.accountSignatureKey = reader.bytes();
                    break;
                case 3:
                    message.accountSignature = reader.bytes();
                    break;
                case 4:
                    message.deviceSignature = reader.bytes();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ADVSignedDeviceIdentity message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ADVSignedDeviceIdentity
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ADVSignedDeviceIdentity} ADVSignedDeviceIdentity
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ADVSignedDeviceIdentity.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ADVSignedDeviceIdentity message.
         * @function verify
         * @memberof proto.ADVSignedDeviceIdentity
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ADVSignedDeviceIdentity.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.details != null && message.hasOwnProperty("details"))
                if (!(message.details && typeof message.details.length === "number" || $util.isString(message.details)))
                    return "details: buffer expected";
            if (message.accountSignatureKey != null && message.hasOwnProperty("accountSignatureKey"))
                if (!(message.accountSignatureKey && typeof message.accountSignatureKey.length === "number" || $util.isString(message.accountSignatureKey)))
                    return "accountSignatureKey: buffer expected";
            if (message.accountSignature != null && message.hasOwnProperty("accountSignature"))
                if (!(message.accountSignature && typeof message.accountSignature.length === "number" || $util.isString(message.accountSignature)))
                    return "accountSignature: buffer expected";
            if (message.deviceSignature != null && message.hasOwnProperty("deviceSignature"))
                if (!(message.deviceSignature && typeof message.deviceSignature.length === "number" || $util.isString(message.deviceSignature)))
                    return "deviceSignature: buffer expected";
            return null;
        };

        /**
         * Creates a ADVSignedDeviceIdentity message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ADVSignedDeviceIdentity
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ADVSignedDeviceIdentity} ADVSignedDeviceIdentity
         */
        ADVSignedDeviceIdentity.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ADVSignedDeviceIdentity)
                return object;
            var message = new $root.proto.ADVSignedDeviceIdentity();
            if (object.details != null)
                if (typeof object.details === "string")
                    $util.base64.decode(object.details, message.details = $util.newBuffer($util.base64.length(object.details)), 0);
                else if (object.details.length)
                    message.details = object.details;
            if (object.accountSignatureKey != null)
                if (typeof object.accountSignatureKey === "string")
                    $util.base64.decode(object.accountSignatureKey, message.accountSignatureKey = $util.newBuffer($util.base64.length(object.accountSignatureKey)), 0);
                else if (object.accountSignatureKey.length)
                    message.accountSignatureKey = object.accountSignatureKey;
            if (object.accountSignature != null)
                if (typeof object.accountSignature === "string")
                    $util.base64.decode(object.accountSignature, message.accountSignature = $util.newBuffer($util.base64.length(object.accountSignature)), 0);
                else if (object.accountSignature.length)
                    message.accountSignature = object.accountSignature;
            if (object.deviceSignature != null)
                if (typeof object.deviceSignature === "string")
                    $util.base64.decode(object.deviceSignature, message.deviceSignature = $util.newBuffer($util.base64.length(object.deviceSignature)), 0);
                else if (object.deviceSignature.length)
                    message.deviceSignature = object.deviceSignature;
            return message;
        };

        /**
         * Creates a plain object from a ADVSignedDeviceIdentity message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ADVSignedDeviceIdentity
         * @static
         * @param {proto.ADVSignedDeviceIdentity} message ADVSignedDeviceIdentity
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ADVSignedDeviceIdentity.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object.details = "";
                else {
                    object.details = [];
                    if (options.bytes !== Array)
                        object.details = $util.newBuffer(object.details);
                }
                if (options.bytes === String)
                    object.accountSignatureKey = "";
                else {
                    object.accountSignatureKey = [];
                    if (options.bytes !== Array)
                        object.accountSignatureKey = $util.newBuffer(object.accountSignatureKey);
                }
                if (options.bytes === String)
                    object.accountSignature = "";
                else {
                    object.accountSignature = [];
                    if (options.bytes !== Array)
                        object.accountSignature = $util.newBuffer(object.accountSignature);
                }
                if (options.bytes === String)
                    object.deviceSignature = "";
                else {
                    object.deviceSignature = [];
                    if (options.bytes !== Array)
                        object.deviceSignature = $util.newBuffer(object.deviceSignature);
                }
            }
            if (message.details != null && message.hasOwnProperty("details"))
                object.details = options.bytes === String ? $util.base64.encode(message.details, 0, message.details.length) : options.bytes === Array ? Array.prototype.slice.call(message.details) : message.details;
            if (message.accountSignatureKey != null && message.hasOwnProperty("accountSignatureKey"))
                object.accountSignatureKey = options.bytes === String ? $util.base64.encode(message.accountSignatureKey, 0, message.accountSignatureKey.length) : options.bytes === Array ? Array.prototype.slice.call(message.accountSignatureKey) : message.accountSignatureKey;
            if (message.accountSignature != null && message.hasOwnProperty("accountSignature"))
                object.accountSignature = options.bytes === String ? $util.base64.encode(message.accountSignature, 0, message.accountSignature.length) : options.bytes === Array ? Array.prototype.slice.call(message.accountSignature) : message.accountSignature;
            if (message.deviceSignature != null && message.hasOwnProperty("deviceSignature"))
                object.deviceSignature = options.bytes === String ? $util.base64.encode(message.deviceSignature, 0, message.deviceSignature.length) : options.bytes === Array ? Array.prototype.slice.call(message.deviceSignature) : message.deviceSignature;
            return object;
        };

        /**
         * Converts this ADVSignedDeviceIdentity to JSON.
         * @function toJSON
         * @memberof proto.ADVSignedDeviceIdentity
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ADVSignedDeviceIdentity.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ADVSignedDeviceIdentity;
    })();

    proto.ADVDeviceIdentity = (function() {

        /**
         * Properties of a ADVDeviceIdentity.
         * @memberof proto
         * @interface IADVDeviceIdentity
         * @property {number|null} [rawId] ADVDeviceIdentity rawId
         * @property {number|Long|null} [timestamp] ADVDeviceIdentity timestamp
         * @property {number|null} [keyIndex] ADVDeviceIdentity keyIndex
         */

        /**
         * Constructs a new ADVDeviceIdentity.
         * @memberof proto
         * @classdesc Represents a ADVDeviceIdentity.
         * @implements IADVDeviceIdentity
         * @constructor
         * @param {proto.IADVDeviceIdentity=} [properties] Properties to set
         */
        function ADVDeviceIdentity(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ADVDeviceIdentity rawId.
         * @member {number} rawId
         * @memberof proto.ADVDeviceIdentity
         * @instance
         */
        ADVDeviceIdentity.prototype.rawId = 0;

        /**
         * ADVDeviceIdentity timestamp.
         * @member {number|Long} timestamp
         * @memberof proto.ADVDeviceIdentity
         * @instance
         */
        ADVDeviceIdentity.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * ADVDeviceIdentity keyIndex.
         * @member {number} keyIndex
         * @memberof proto.ADVDeviceIdentity
         * @instance
         */
        ADVDeviceIdentity.prototype.keyIndex = 0;

        /**
         * Creates a new ADVDeviceIdentity instance using the specified properties.
         * @function create
         * @memberof proto.ADVDeviceIdentity
         * @static
         * @param {proto.IADVDeviceIdentity=} [properties] Properties to set
         * @returns {proto.ADVDeviceIdentity} ADVDeviceIdentity instance
         */
        ADVDeviceIdentity.create = function create(properties) {
            return new ADVDeviceIdentity(properties);
        };

        /**
         * Encodes the specified ADVDeviceIdentity message. Does not implicitly {@link proto.ADVDeviceIdentity.verify|verify} messages.
         * @function encode
         * @memberof proto.ADVDeviceIdentity
         * @static
         * @param {proto.IADVDeviceIdentity} message ADVDeviceIdentity message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ADVDeviceIdentity.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.rawId != null && Object.hasOwnProperty.call(message, "rawId"))
                writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.rawId);
            if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp"))
                writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.timestamp);
            if (message.keyIndex != null && Object.hasOwnProperty.call(message, "keyIndex"))
                writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.keyIndex);
            return writer;
        };

        /**
         * Encodes the specified ADVDeviceIdentity message, length delimited. Does not implicitly {@link proto.ADVDeviceIdentity.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ADVDeviceIdentity
         * @static
         * @param {proto.IADVDeviceIdentity} message ADVDeviceIdentity message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ADVDeviceIdentity.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ADVDeviceIdentity message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ADVDeviceIdentity
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ADVDeviceIdentity} ADVDeviceIdentity
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ADVDeviceIdentity.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ADVDeviceIdentity();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.rawId = reader.uint32();
                    break;
                case 2:
                    message.timestamp = reader.uint64();
                    break;
                case 3:
                    message.keyIndex = reader.uint32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ADVDeviceIdentity message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ADVDeviceIdentity
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ADVDeviceIdentity} ADVDeviceIdentity
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ADVDeviceIdentity.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ADVDeviceIdentity message.
         * @function verify
         * @memberof proto.ADVDeviceIdentity
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ADVDeviceIdentity.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.rawId != null && message.hasOwnProperty("rawId"))
                if (!$util.isInteger(message.rawId))
                    return "rawId: integer expected";
            if (message.timestamp != null && message.hasOwnProperty("timestamp"))
                if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high)))
                    return "timestamp: integer|Long expected";
            if (message.keyIndex != null && message.hasOwnProperty("keyIndex"))
                if (!$util.isInteger(message.keyIndex))
                    return "keyIndex: integer expected";
            return null;
        };

        /**
         * Creates a ADVDeviceIdentity message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ADVDeviceIdentity
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ADVDeviceIdentity} ADVDeviceIdentity
         */
        ADVDeviceIdentity.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ADVDeviceIdentity)
                return object;
            var message = new $root.proto.ADVDeviceIdentity();
            if (object.rawId != null)
                message.rawId = object.rawId >>> 0;
            if (object.timestamp != null)
                if ($util.Long)
                    (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = true;
                else if (typeof object.timestamp === "string")
                    message.timestamp = parseInt(object.timestamp, 10);
                else if (typeof object.timestamp === "number")
                    message.timestamp = object.timestamp;
                else if (typeof object.timestamp === "object")
                    message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber(true);
            if (object.keyIndex != null)
                message.keyIndex = object.keyIndex >>> 0;
            return message;
        };

        /**
         * Creates a plain object from a ADVDeviceIdentity message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ADVDeviceIdentity
         * @static
         * @param {proto.ADVDeviceIdentity} message ADVDeviceIdentity
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ADVDeviceIdentity.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.rawId = 0;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.timestamp = options.longs === String ? "0" : 0;
                object.keyIndex = 0;
            }
            if (message.rawId != null && message.hasOwnProperty("rawId"))
                object.rawId = message.rawId;
            if (message.timestamp != null && message.hasOwnProperty("timestamp"))
                if (typeof message.timestamp === "number")
                    object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp;
                else
                    object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber(true) : message.timestamp;
            if (message.keyIndex != null && message.hasOwnProperty("keyIndex"))
                object.keyIndex = message.keyIndex;
            return object;
        };

        /**
         * Converts this ADVDeviceIdentity to JSON.
         * @function toJSON
         * @memberof proto.ADVDeviceIdentity
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ADVDeviceIdentity.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ADVDeviceIdentity;
    })();

    proto.ADVSignedKeyIndexList = (function() {

        /**
         * Properties of a ADVSignedKeyIndexList.
         * @memberof proto
         * @interface IADVSignedKeyIndexList
         * @property {Uint8Array|null} [details] ADVSignedKeyIndexList details
         * @property {Uint8Array|null} [accountSignature] ADVSignedKeyIndexList accountSignature
         */

        /**
         * Constructs a new ADVSignedKeyIndexList.
         * @memberof proto
         * @classdesc Represents a ADVSignedKeyIndexList.
         * @implements IADVSignedKeyIndexList
         * @constructor
         * @param {proto.IADVSignedKeyIndexList=} [properties] Properties to set
         */
        function ADVSignedKeyIndexList(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ADVSignedKeyIndexList details.
         * @member {Uint8Array} details
         * @memberof proto.ADVSignedKeyIndexList
         * @instance
         */
        ADVSignedKeyIndexList.prototype.details = $util.newBuffer([]);

        /**
         * ADVSignedKeyIndexList accountSignature.
         * @member {Uint8Array} accountSignature
         * @memberof proto.ADVSignedKeyIndexList
         * @instance
         */
        ADVSignedKeyIndexList.prototype.accountSignature = $util.newBuffer([]);

        /**
         * Creates a new ADVSignedKeyIndexList instance using the specified properties.
         * @function create
         * @memberof proto.ADVSignedKeyIndexList
         * @static
         * @param {proto.IADVSignedKeyIndexList=} [properties] Properties to set
         * @returns {proto.ADVSignedKeyIndexList} ADVSignedKeyIndexList instance
         */
        ADVSignedKeyIndexList.create = function create(properties) {
            return new ADVSignedKeyIndexList(properties);
        };

        /**
         * Encodes the specified ADVSignedKeyIndexList message. Does not implicitly {@link proto.ADVSignedKeyIndexList.verify|verify} messages.
         * @function encode
         * @memberof proto.ADVSignedKeyIndexList
         * @static
         * @param {proto.IADVSignedKeyIndexList} message ADVSignedKeyIndexList message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ADVSignedKeyIndexList.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.details != null && Object.hasOwnProperty.call(message, "details"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.details);
            if (message.accountSignature != null && Object.hasOwnProperty.call(message, "accountSignature"))
                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.accountSignature);
            return writer;
        };

        /**
         * Encodes the specified ADVSignedKeyIndexList message, length delimited. Does not implicitly {@link proto.ADVSignedKeyIndexList.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ADVSignedKeyIndexList
         * @static
         * @param {proto.IADVSignedKeyIndexList} message ADVSignedKeyIndexList message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ADVSignedKeyIndexList.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ADVSignedKeyIndexList message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ADVSignedKeyIndexList
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ADVSignedKeyIndexList} ADVSignedKeyIndexList
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ADVSignedKeyIndexList.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ADVSignedKeyIndexList();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.details = reader.bytes();
                    break;
                case 2:
                    message.accountSignature = reader.bytes();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ADVSignedKeyIndexList message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ADVSignedKeyIndexList
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ADVSignedKeyIndexList} ADVSignedKeyIndexList
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ADVSignedKeyIndexList.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ADVSignedKeyIndexList message.
         * @function verify
         * @memberof proto.ADVSignedKeyIndexList
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ADVSignedKeyIndexList.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.details != null && message.hasOwnProperty("details"))
                if (!(message.details && typeof message.details.length === "number" || $util.isString(message.details)))
                    return "details: buffer expected";
            if (message.accountSignature != null && message.hasOwnProperty("accountSignature"))
                if (!(message.accountSignature && typeof message.accountSignature.length === "number" || $util.isString(message.accountSignature)))
                    return "accountSignature: buffer expected";
            return null;
        };

        /**
         * Creates a ADVSignedKeyIndexList message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ADVSignedKeyIndexList
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ADVSignedKeyIndexList} ADVSignedKeyIndexList
         */
        ADVSignedKeyIndexList.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ADVSignedKeyIndexList)
                return object;
            var message = new $root.proto.ADVSignedKeyIndexList();
            if (object.details != null)
                if (typeof object.details === "string")
                    $util.base64.decode(object.details, message.details = $util.newBuffer($util.base64.length(object.details)), 0);
                else if (object.details.length)
                    message.details = object.details;
            if (object.accountSignature != null)
                if (typeof object.accountSignature === "string")
                    $util.base64.decode(object.accountSignature, message.accountSignature = $util.newBuffer($util.base64.length(object.accountSignature)), 0);
                else if (object.accountSignature.length)
                    message.accountSignature = object.accountSignature;
            return message;
        };

        /**
         * Creates a plain object from a ADVSignedKeyIndexList message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ADVSignedKeyIndexList
         * @static
         * @param {proto.ADVSignedKeyIndexList} message ADVSignedKeyIndexList
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ADVSignedKeyIndexList.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object.details = "";
                else {
                    object.details = [];
                    if (options.bytes !== Array)
                        object.details = $util.newBuffer(object.details);
                }
                if (options.bytes === String)
                    object.accountSignature = "";
                else {
                    object.accountSignature = [];
                    if (options.bytes !== Array)
                        object.accountSignature = $util.newBuffer(object.accountSignature);
                }
            }
            if (message.details != null && message.hasOwnProperty("details"))
                object.details = options.bytes === String ? $util.base64.encode(message.details, 0, message.details.length) : options.bytes === Array ? Array.prototype.slice.call(message.details) : message.details;
            if (message.accountSignature != null && message.hasOwnProperty("accountSignature"))
                object.accountSignature = options.bytes === String ? $util.base64.encode(message.accountSignature, 0, message.accountSignature.length) : options.bytes === Array ? Array.prototype.slice.call(message.accountSignature) : message.accountSignature;
            return object;
        };

        /**
         * Converts this ADVSignedKeyIndexList to JSON.
         * @function toJSON
         * @memberof proto.ADVSignedKeyIndexList
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ADVSignedKeyIndexList.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ADVSignedKeyIndexList;
    })();

    proto.ADVKeyIndexList = (function() {

        /**
         * Properties of a ADVKeyIndexList.
         * @memberof proto
         * @interface IADVKeyIndexList
         * @property {number|null} [rawId] ADVKeyIndexList rawId
         * @property {number|Long|null} [timestamp] ADVKeyIndexList timestamp
         * @property {number|null} [currentIndex] ADVKeyIndexList currentIndex
         * @property {Array.<number>|null} [validIndexes] ADVKeyIndexList validIndexes
         */

        /**
         * Constructs a new ADVKeyIndexList.
         * @memberof proto
         * @classdesc Represents a ADVKeyIndexList.
         * @implements IADVKeyIndexList
         * @constructor
         * @param {proto.IADVKeyIndexList=} [properties] Properties to set
         */
        function ADVKeyIndexList(properties) {
            this.validIndexes = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * ADVKeyIndexList rawId.
         * @member {number} rawId
         * @memberof proto.ADVKeyIndexList
         * @instance
         */
        ADVKeyIndexList.prototype.rawId = 0;

        /**
         * ADVKeyIndexList timestamp.
         * @member {number|Long} timestamp
         * @memberof proto.ADVKeyIndexList
         * @instance
         */
        ADVKeyIndexList.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * ADVKeyIndexList currentIndex.
         * @member {number} currentIndex
         * @memberof proto.ADVKeyIndexList
         * @instance
         */
        ADVKeyIndexList.prototype.currentIndex = 0;

        /**
         * ADVKeyIndexList validIndexes.
         * @member {Array.<number>} validIndexes
         * @memberof proto.ADVKeyIndexList
         * @instance
         */
        ADVKeyIndexList.prototype.validIndexes = $util.emptyArray;

        /**
         * Creates a new ADVKeyIndexList instance using the specified properties.
         * @function create
         * @memberof proto.ADVKeyIndexList
         * @static
         * @param {proto.IADVKeyIndexList=} [properties] Properties to set
         * @returns {proto.ADVKeyIndexList} ADVKeyIndexList instance
         */
        ADVKeyIndexList.create = function create(properties) {
            return new ADVKeyIndexList(properties);
        };

        /**
         * Encodes the specified ADVKeyIndexList message. Does not implicitly {@link proto.ADVKeyIndexList.verify|verify} messages.
         * @function encode
         * @memberof proto.ADVKeyIndexList
         * @static
         * @param {proto.IADVKeyIndexList} message ADVKeyIndexList message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ADVKeyIndexList.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.rawId != null && Object.hasOwnProperty.call(message, "rawId"))
                writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.rawId);
            if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp"))
                writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.timestamp);
            if (message.currentIndex != null && Object.hasOwnProperty.call(message, "currentIndex"))
                writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.currentIndex);
            if (message.validIndexes != null && message.validIndexes.length) {
                writer.uint32(/* id 4, wireType 2 =*/34).fork();
                for (var i = 0; i < message.validIndexes.length; ++i)
                    writer.uint32(message.validIndexes[i]);
                writer.ldelim();
            }
            return writer;
        };

        /**
         * Encodes the specified ADVKeyIndexList message, length delimited. Does not implicitly {@link proto.ADVKeyIndexList.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.ADVKeyIndexList
         * @static
         * @param {proto.IADVKeyIndexList} message ADVKeyIndexList message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        ADVKeyIndexList.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a ADVKeyIndexList message from the specified reader or buffer.
         * @function decode
         * @memberof proto.ADVKeyIndexList
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.ADVKeyIndexList} ADVKeyIndexList
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ADVKeyIndexList.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.ADVKeyIndexList();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.rawId = reader.uint32();
                    break;
                case 2:
                    message.timestamp = reader.uint64();
                    break;
                case 3:
                    message.currentIndex = reader.uint32();
                    break;
                case 4:
                    if (!(message.validIndexes && message.validIndexes.length))
                        message.validIndexes = [];
                    if ((tag & 7) === 2) {
                        var end2 = reader.uint32() + reader.pos;
                        while (reader.pos < end2)
                            message.validIndexes.push(reader.uint32());
                    } else
                        message.validIndexes.push(reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a ADVKeyIndexList message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.ADVKeyIndexList
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.ADVKeyIndexList} ADVKeyIndexList
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        ADVKeyIndexList.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a ADVKeyIndexList message.
         * @function verify
         * @memberof proto.ADVKeyIndexList
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        ADVKeyIndexList.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.rawId != null && message.hasOwnProperty("rawId"))
                if (!$util.isInteger(message.rawId))
                    return "rawId: integer expected";
            if (message.timestamp != null && message.hasOwnProperty("timestamp"))
                if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high)))
                    return "timestamp: integer|Long expected";
            if (message.currentIndex != null && message.hasOwnProperty("currentIndex"))
                if (!$util.isInteger(message.currentIndex))
                    return "currentIndex: integer expected";
            if (message.validIndexes != null && message.hasOwnProperty("validIndexes")) {
                if (!Array.isArray(message.validIndexes))
                    return "validIndexes: array expected";
                for (var i = 0; i < message.validIndexes.length; ++i)
                    if (!$util.isInteger(message.validIndexes[i]))
                        return "validIndexes: integer[] expected";
            }
            return null;
        };

        /**
         * Creates a ADVKeyIndexList message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.ADVKeyIndexList
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.ADVKeyIndexList} ADVKeyIndexList
         */
        ADVKeyIndexList.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.ADVKeyIndexList)
                return object;
            var message = new $root.proto.ADVKeyIndexList();
            if (object.rawId != null)
                message.rawId = object.rawId >>> 0;
            if (object.timestamp != null)
                if ($util.Long)
                    (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = true;
                else if (typeof object.timestamp === "string")
                    message.timestamp = parseInt(object.timestamp, 10);
                else if (typeof object.timestamp === "number")
                    message.timestamp = object.timestamp;
                else if (typeof object.timestamp === "object")
                    message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber(true);
            if (object.currentIndex != null)
                message.currentIndex = object.currentIndex >>> 0;
            if (object.validIndexes) {
                if (!Array.isArray(object.validIndexes))
                    throw TypeError(".proto.ADVKeyIndexList.validIndexes: array expected");
                message.validIndexes = [];
                for (var i = 0; i < object.validIndexes.length; ++i)
                    message.validIndexes[i] = object.validIndexes[i] >>> 0;
            }
            return message;
        };

        /**
         * Creates a plain object from a ADVKeyIndexList message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.ADVKeyIndexList
         * @static
         * @param {proto.ADVKeyIndexList} message ADVKeyIndexList
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        ADVKeyIndexList.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.validIndexes = [];
            if (options.defaults) {
                object.rawId = 0;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.timestamp = options.longs === String ? "0" : 0;
                object.currentIndex = 0;
            }
            if (message.rawId != null && message.hasOwnProperty("rawId"))
                object.rawId = message.rawId;
            if (message.timestamp != null && message.hasOwnProperty("timestamp"))
                if (typeof message.timestamp === "number")
                    object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp;
                else
                    object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber(true) : message.timestamp;
            if (message.currentIndex != null && message.hasOwnProperty("currentIndex"))
                object.currentIndex = message.currentIndex;
            if (message.validIndexes && message.validIndexes.length) {
                object.validIndexes = [];
                for (var j = 0; j < message.validIndexes.length; ++j)
                    object.validIndexes[j] = message.validIndexes[j];
            }
            return object;
        };

        /**
         * Converts this ADVKeyIndexList to JSON.
         * @function toJSON
         * @memberof proto.ADVKeyIndexList
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        ADVKeyIndexList.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return ADVKeyIndexList;
    })();

    proto.MessageKey = (function() {

        /**
         * Properties of a MessageKey.
         * @memberof proto
         * @interface IMessageKey
         * @property {string|null} [remoteJid] MessageKey remoteJid
         * @property {boolean|null} [fromMe] MessageKey fromMe
         * @property {string|null} [id] MessageKey id
         * @property {string|null} [participant] MessageKey participant
         */

        /**
         * Constructs a new MessageKey.
         * @memberof proto
         * @classdesc Represents a MessageKey.
         * @implements IMessageKey
         * @constructor
         * @param {proto.IMessageKey=} [properties] Properties to set
         */
        function MessageKey(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * MessageKey remoteJid.
         * @member {string} remoteJid
         * @memberof proto.MessageKey
         * @instance
         */
        MessageKey.prototype.remoteJid = "";

        /**
         * MessageKey fromMe.
         * @member {boolean} fromMe
         * @memberof proto.MessageKey
         * @instance
         */
        MessageKey.prototype.fromMe = false;

        /**
         * MessageKey id.
         * @member {string} id
         * @memberof proto.MessageKey
         * @instance
         */
        MessageKey.prototype.id = "";

        /**
         * MessageKey participant.
         * @member {string} participant
         * @memberof proto.MessageKey
         * @instance
         */
        MessageKey.prototype.participant = "";

        /**
         * Creates a new MessageKey instance using the specified properties.
         * @function create
         * @memberof proto.MessageKey
         * @static
         * @param {proto.IMessageKey=} [properties] Properties to set
         * @returns {proto.MessageKey} MessageKey instance
         */
        MessageKey.create = function create(properties) {
            return new MessageKey(properties);
        };

        /**
         * Encodes the specified MessageKey message. Does not implicitly {@link proto.MessageKey.verify|verify} messages.
         * @function encode
         * @memberof proto.MessageKey
         * @static
         * @param {proto.IMessageKey} message MessageKey message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        MessageKey.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.remoteJid != null && Object.hasOwnProperty.call(message, "remoteJid"))
                writer.uint32(/* id 1, wireType 2 =*/10).string(message.remoteJid);
            if (message.fromMe != null && Object.hasOwnProperty.call(message, "fromMe"))
                writer.uint32(/* id 2, wireType 0 =*/16).bool(message.fromMe);
            if (message.id != null && Object.hasOwnProperty.call(message, "id"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.id);
            if (message.participant != null && Object.hasOwnProperty.call(message, "participant"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.participant);
            return writer;
        };

        /**
         * Encodes the specified MessageKey message, length delimited. Does not implicitly {@link proto.MessageKey.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.MessageKey
         * @static
         * @param {proto.IMessageKey} message MessageKey message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        MessageKey.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a MessageKey message from the specified reader or buffer.
         * @function decode
         * @memberof proto.MessageKey
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.MessageKey} MessageKey
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        MessageKey.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.MessageKey();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.remoteJid = reader.string();
                    break;
                case 2:
                    message.fromMe = reader.bool();
                    break;
                case 3:
                    message.id = reader.string();
                    break;
                case 4:
                    message.participant = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a MessageKey message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.MessageKey
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.MessageKey} MessageKey
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        MessageKey.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a MessageKey message.
         * @function verify
         * @memberof proto.MessageKey
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        MessageKey.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.remoteJid != null && message.hasOwnProperty("remoteJid"))
                if (!$util.isString(message.remoteJid))
                    return "remoteJid: string expected";
            if (message.fromMe != null && message.hasOwnProperty("fromMe"))
                if (typeof message.fromMe !== "boolean")
                    return "fromMe: boolean expected";
            if (message.id != null && message.hasOwnProperty("id"))
                if (!$util.isString(message.id))
                    return "id: string expected";
            if (message.participant != null && message.hasOwnProperty("participant"))
                if (!$util.isString(message.participant))
                    return "participant: string expected";
            return null;
        };

        /**
         * Creates a MessageKey message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.MessageKey
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.MessageKey} MessageKey
         */
        MessageKey.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.MessageKey)
                return object;
            var message = new $root.proto.MessageKey();
            if (object.remoteJid != null)
                message.remoteJid = String(object.remoteJid);
            if (object.fromMe != null)
                message.fromMe = Boolean(object.fromMe);
            if (object.id != null)
                message.id = String(object.id);
            if (object.participant != null)
                message.participant = String(object.participant);
            return message;
        };

        /**
         * Creates a plain object from a MessageKey message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.MessageKey
         * @static
         * @param {proto.MessageKey} message MessageKey
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        MessageKey.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.remoteJid = "";
                object.fromMe = false;
                object.id = "";
                object.participant = "";
            }
            if (message.remoteJid != null && message.hasOwnProperty("remoteJid"))
                object.remoteJid = message.remoteJid;
            if (message.fromMe != null && message.hasOwnProperty("fromMe"))
                object.fromMe = message.fromMe;
            if (message.id != null && message.hasOwnProperty("id"))
                object.id = message.id;
            if (message.participant != null && message.hasOwnProperty("participant"))
                object.participant = message.participant;
            return object;
        };

        /**
         * Converts this MessageKey to JSON.
         * @function toJSON
         * @memberof proto.MessageKey
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        MessageKey.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return MessageKey;
    })();

    proto.Reaction = (function() {

        /**
         * Properties of a Reaction.
         * @memberof proto
         * @interface IReaction
         * @property {proto.IMessageKey|null} [key] Reaction key
         * @property {string|null} [text] Reaction text
         * @property {string|null} [groupingKey] Reaction groupingKey
         * @property {number|Long|null} [senderTimestampMs] Reaction senderTimestampMs
         * @property {boolean|null} [unread] Reaction unread
         */

        /**
         * Constructs a new Reaction.
         * @memberof proto
         * @classdesc Represents a Reaction.
         * @implements IReaction
         * @constructor
         * @param {proto.IReaction=} [properties] Properties to set
         */
        function Reaction(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * Reaction key.
         * @member {proto.IMessageKey|null|undefined} key
         * @memberof proto.Reaction
         * @instance
         */
        Reaction.prototype.key = null;

        /**
         * Reaction text.
         * @member {string} text
         * @memberof proto.Reaction
         * @instance
         */
        Reaction.prototype.text = "";

        /**
         * Reaction groupingKey.
         * @member {string} groupingKey
         * @memberof proto.Reaction
         * @instance
         */
        Reaction.prototype.groupingKey = "";

        /**
         * Reaction senderTimestampMs.
         * @member {number|Long} senderTimestampMs
         * @memberof proto.Reaction
         * @instance
         */
        Reaction.prototype.senderTimestampMs = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * Reaction unread.
         * @member {boolean} unread
         * @memberof proto.Reaction
         * @instance
         */
        Reaction.prototype.unread = false;

        /**
         * Creates a new Reaction instance using the specified properties.
         * @function create
         * @memberof proto.Reaction
         * @static
         * @param {proto.IReaction=} [properties] Properties to set
         * @returns {proto.Reaction} Reaction instance
         */
        Reaction.create = function create(properties) {
            return new Reaction(properties);
        };

        /**
         * Encodes the specified Reaction message. Does not implicitly {@link proto.Reaction.verify|verify} messages.
         * @function encode
         * @memberof proto.Reaction
         * @static
         * @param {proto.IReaction} message Reaction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Reaction.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.key != null && Object.hasOwnProperty.call(message, "key"))
                $root.proto.MessageKey.encode(message.key, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.text != null && Object.hasOwnProperty.call(message, "text"))
                writer.uint32(/* id 2, wireType 2 =*/18).string(message.text);
            if (message.groupingKey != null && Object.hasOwnProperty.call(message, "groupingKey"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.groupingKey);
            if (message.senderTimestampMs != null && Object.hasOwnProperty.call(message, "senderTimestampMs"))
                writer.uint32(/* id 4, wireType 0 =*/32).int64(message.senderTimestampMs);
            if (message.unread != null && Object.hasOwnProperty.call(message, "unread"))
                writer.uint32(/* id 5, wireType 0 =*/40).bool(message.unread);
            return writer;
        };

        /**
         * Encodes the specified Reaction message, length delimited. Does not implicitly {@link proto.Reaction.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.Reaction
         * @static
         * @param {proto.IReaction} message Reaction message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        Reaction.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a Reaction message from the specified reader or buffer.
         * @function decode
         * @memberof proto.Reaction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.Reaction} Reaction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Reaction.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.Reaction();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.key = $root.proto.MessageKey.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.text = reader.string();
                    break;
                case 3:
                    message.groupingKey = reader.string();
                    break;
                case 4:
                    message.senderTimestampMs = reader.int64();
                    break;
                case 5:
                    message.unread = reader.bool();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a Reaction message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.Reaction
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.Reaction} Reaction
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        Reaction.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a Reaction message.
         * @function verify
         * @memberof proto.Reaction
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        Reaction.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.key != null && message.hasOwnProperty("key")) {
                var error = $root.proto.MessageKey.verify(message.key);
                if (error)
                    return "key." + error;
            }
            if (message.text != null && message.hasOwnProperty("text"))
                if (!$util.isString(message.text))
                    return "text: string expected";
            if (message.groupingKey != null && message.hasOwnProperty("groupingKey"))
                if (!$util.isString(message.groupingKey))
                    return "groupingKey: string expected";
            if (message.senderTimestampMs != null && message.hasOwnProperty("senderTimestampMs"))
                if (!$util.isInteger(message.senderTimestampMs) && !(message.senderTimestampMs && $util.isInteger(message.senderTimestampMs.low) && $util.isInteger(message.senderTimestampMs.high)))
                    return "senderTimestampMs: integer|Long expected";
            if (message.unread != null && message.hasOwnProperty("unread"))
                if (typeof message.unread !== "boolean")
                    return "unread: boolean expected";
            return null;
        };

        /**
         * Creates a Reaction message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.Reaction
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.Reaction} Reaction
         */
        Reaction.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.Reaction)
                return object;
            var message = new $root.proto.Reaction();
            if (object.key != null) {
                if (typeof object.key !== "object")
                    throw TypeError(".proto.Reaction.key: object expected");
                message.key = $root.proto.MessageKey.fromObject(object.key);
            }
            if (object.text != null)
                message.text = String(object.text);
            if (object.groupingKey != null)
                message.groupingKey = String(object.groupingKey);
            if (object.senderTimestampMs != null)
                if ($util.Long)
                    (message.senderTimestampMs = $util.Long.fromValue(object.senderTimestampMs)).unsigned = false;
                else if (typeof object.senderTimestampMs === "string")
                    message.senderTimestampMs = parseInt(object.senderTimestampMs, 10);
                else if (typeof object.senderTimestampMs === "number")
                    message.senderTimestampMs = object.senderTimestampMs;
                else if (typeof object.senderTimestampMs === "object")
                    message.senderTimestampMs = new $util.LongBits(object.senderTimestampMs.low >>> 0, object.senderTimestampMs.high >>> 0).toNumber();
            if (object.unread != null)
                message.unread = Boolean(object.unread);
            return message;
        };

        /**
         * Creates a plain object from a Reaction message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.Reaction
         * @static
         * @param {proto.Reaction} message Reaction
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        Reaction.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.key = null;
                object.text = "";
                object.groupingKey = "";
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.senderTimestampMs = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.senderTimestampMs = options.longs === String ? "0" : 0;
                object.unread = false;
            }
            if (message.key != null && message.hasOwnProperty("key"))
                object.key = $root.proto.MessageKey.toObject(message.key, options);
            if (message.text != null && message.hasOwnProperty("text"))
                object.text = message.text;
            if (message.groupingKey != null && message.hasOwnProperty("groupingKey"))
                object.groupingKey = message.groupingKey;
            if (message.senderTimestampMs != null && message.hasOwnProperty("senderTimestampMs"))
                if (typeof message.senderTimestampMs === "number")
                    object.senderTimestampMs = options.longs === String ? String(message.senderTimestampMs) : message.senderTimestampMs;
                else
                    object.senderTimestampMs = options.longs === String ? $util.Long.prototype.toString.call(message.senderTimestampMs) : options.longs === Number ? new $util.LongBits(message.senderTimestampMs.low >>> 0, message.senderTimestampMs.high >>> 0).toNumber() : message.senderTimestampMs;
            if (message.unread != null && message.hasOwnProperty("unread"))
                object.unread = message.unread;
            return object;
        };

        /**
         * Converts this Reaction to JSON.
         * @function toJSON
         * @memberof proto.Reaction
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        Reaction.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return Reaction;
    })();

    proto.UserReceipt = (function() {

        /**
         * Properties of a UserReceipt.
         * @memberof proto
         * @interface IUserReceipt
         * @property {string} userJid UserReceipt userJid
         * @property {number|Long|null} [receiptTimestamp] UserReceipt receiptTimestamp
         * @property {number|Long|null} [readTimestamp] UserReceipt readTimestamp
         * @property {number|Long|null} [playedTimestamp] UserReceipt playedTimestamp
         * @property {Array.<string>|null} [pendingDeviceJid] UserReceipt pendingDeviceJid
         * @property {Array.<string>|null} [deliveredDeviceJid] UserReceipt deliveredDeviceJid
         */

        /**
         * Constructs a new UserReceipt.
         * @memberof proto
         * @classdesc Represents a UserReceipt.
         * @implements IUserReceipt
         * @constructor
         * @param {proto.IUserReceipt=} [properties] Properties to set
         */
        function UserReceipt(properties) {
            this.pendingDeviceJid = [];
            this.deliveredDeviceJid = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * UserReceipt userJid.
         * @member {string} userJid
         * @memberof proto.UserReceipt
         * @instance
         */
        UserReceipt.prototype.userJid = "";

        /**
         * UserReceipt receiptTimestamp.
         * @member {number|Long} receiptTimestamp
         * @memberof proto.UserReceipt
         * @instance
         */
        UserReceipt.prototype.receiptTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * UserReceipt readTimestamp.
         * @member {number|Long} readTimestamp
         * @memberof proto.UserReceipt
         * @instance
         */
        UserReceipt.prototype.readTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * UserReceipt playedTimestamp.
         * @member {number|Long} playedTimestamp
         * @memberof proto.UserReceipt
         * @instance
         */
        UserReceipt.prototype.playedTimestamp = $util.Long ? $util.Long.fromBits(0,0,false) : 0;

        /**
         * UserReceipt pendingDeviceJid.
         * @member {Array.<string>} pendingDeviceJid
         * @memberof proto.UserReceipt
         * @instance
         */
        UserReceipt.prototype.pendingDeviceJid = $util.emptyArray;

        /**
         * UserReceipt deliveredDeviceJid.
         * @member {Array.<string>} deliveredDeviceJid
         * @memberof proto.UserReceipt
         * @instance
         */
        UserReceipt.prototype.deliveredDeviceJid = $util.emptyArray;

        /**
         * Creates a new UserReceipt instance using the specified properties.
         * @function create
         * @memberof proto.UserReceipt
         * @static
         * @param {proto.IUserReceipt=} [properties] Properties to set
         * @returns {proto.UserReceipt} UserReceipt instance
         */
        UserReceipt.create = function create(properties) {
            return new UserReceipt(properties);
        };

        /**
         * Encodes the specified UserReceipt message. Does not implicitly {@link proto.UserReceipt.verify|verify} messages.
         * @function encode
         * @memberof proto.UserReceipt
         * @static
         * @param {proto.IUserReceipt} message UserReceipt message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        UserReceipt.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            writer.uint32(/* id 1, wireType 2 =*/10).string(message.userJid);
            if (message.receiptTimestamp != null && Object.hasOwnProperty.call(message, "receiptTimestamp"))
                writer.uint32(/* id 2, wireType 0 =*/16).int64(message.receiptTimestamp);
            if (message.readTimestamp != null && Object.hasOwnProperty.call(message, "readTimestamp"))
                writer.uint32(/* id 3, wireType 0 =*/24).int64(message.readTimestamp);
            if (message.playedTimestamp != null && Object.hasOwnProperty.call(message, "playedTimestamp"))
                writer.uint32(/* id 4, wireType 0 =*/32).int64(message.playedTimestamp);
            if (message.pendingDeviceJid != null && message.pendingDeviceJid.length)
                for (var i = 0; i < message.pendingDeviceJid.length; ++i)
                    writer.uint32(/* id 5, wireType 2 =*/42).string(message.pendingDeviceJid[i]);
            if (message.deliveredDeviceJid != null && message.deliveredDeviceJid.length)
                for (var i = 0; i < message.deliveredDeviceJid.length; ++i)
                    writer.uint32(/* id 6, wireType 2 =*/50).string(message.deliveredDeviceJid[i]);
            return writer;
        };

        /**
         * Encodes the specified UserReceipt message, length delimited. Does not implicitly {@link proto.UserReceipt.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.UserReceipt
         * @static
         * @param {proto.IUserReceipt} message UserReceipt message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        UserReceipt.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a UserReceipt message from the specified reader or buffer.
         * @function decode
         * @memberof proto.UserReceipt
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.UserReceipt} UserReceipt
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        UserReceipt.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.UserReceipt();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.userJid = reader.string();
                    break;
                case 2:
                    message.receiptTimestamp = reader.int64();
                    break;
                case 3:
                    message.readTimestamp = reader.int64();
                    break;
                case 4:
                    message.playedTimestamp = reader.int64();
                    break;
                case 5:
                    if (!(message.pendingDeviceJid && message.pendingDeviceJid.length))
                        message.pendingDeviceJid = [];
                    message.pendingDeviceJid.push(reader.string());
                    break;
                case 6:
                    if (!(message.deliveredDeviceJid && message.deliveredDeviceJid.length))
                        message.deliveredDeviceJid = [];
                    message.deliveredDeviceJid.push(reader.string());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            if (!message.hasOwnProperty("userJid"))
                throw $util.ProtocolError("missing required 'userJid'", { instance: message });
            return message;
        };

        /**
         * Decodes a UserReceipt message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.UserReceipt
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.UserReceipt} UserReceipt
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        UserReceipt.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a UserReceipt message.
         * @function verify
         * @memberof proto.UserReceipt
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        UserReceipt.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (!$util.isString(message.userJid))
                return "userJid: string expected";
            if (message.receiptTimestamp != null && message.hasOwnProperty("receiptTimestamp"))
                if (!$util.isInteger(message.receiptTimestamp) && !(message.receiptTimestamp && $util.isInteger(message.receiptTimestamp.low) && $util.isInteger(message.receiptTimestamp.high)))
                    return "receiptTimestamp: integer|Long expected";
            if (message.readTimestamp != null && message.hasOwnProperty("readTimestamp"))
                if (!$util.isInteger(message.readTimestamp) && !(message.readTimestamp && $util.isInteger(message.readTimestamp.low) && $util.isInteger(message.readTimestamp.high)))
                    return "readTimestamp: integer|Long expected";
            if (message.playedTimestamp != null && message.hasOwnProperty("playedTimestamp"))
                if (!$util.isInteger(message.playedTimestamp) && !(message.playedTimestamp && $util.isInteger(message.playedTimestamp.low) && $util.isInteger(message.playedTimestamp.high)))
                    return "playedTimestamp: integer|Long expected";
            if (message.pendingDeviceJid != null && message.hasOwnProperty("pendingDeviceJid")) {
                if (!Array.isArray(message.pendingDeviceJid))
                    return "pendingDeviceJid: array expected";
                for (var i = 0; i < message.pendingDeviceJid.length; ++i)
                    if (!$util.isString(message.pendingDeviceJid[i]))
                        return "pendingDeviceJid: string[] expected";
            }
            if (message.deliveredDeviceJid != null && message.hasOwnProperty("deliveredDeviceJid")) {
                if (!Array.isArray(message.deliveredDeviceJid))
                    return "deliveredDeviceJid: array expected";
                for (var i = 0; i < message.deliveredDeviceJid.length; ++i)
                    if (!$util.isString(message.deliveredDeviceJid[i]))
                        return "deliveredDeviceJid: string[] expected";
            }
            return null;
        };

        /**
         * Creates a UserReceipt message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.UserReceipt
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.UserReceipt} UserReceipt
         */
        UserReceipt.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.UserReceipt)
                return object;
            var message = new $root.proto.UserReceipt();
            if (object.userJid != null)
                message.userJid = String(object.userJid);
            if (object.receiptTimestamp != null)
                if ($util.Long)
                    (message.receiptTimestamp = $util.Long.fromValue(object.receiptTimestamp)).unsigned = false;
                else if (typeof object.receiptTimestamp === "string")
                    message.receiptTimestamp = parseInt(object.receiptTimestamp, 10);
                else if (typeof object.receiptTimestamp === "number")
                    message.receiptTimestamp = object.receiptTimestamp;
                else if (typeof object.receiptTimestamp === "object")
                    message.receiptTimestamp = new $util.LongBits(object.receiptTimestamp.low >>> 0, object.receiptTimestamp.high >>> 0).toNumber();
            if (object.readTimestamp != null)
                if ($util.Long)
                    (message.readTimestamp = $util.Long.fromValue(object.readTimestamp)).unsigned = false;
                else if (typeof object.readTimestamp === "string")
                    message.readTimestamp = parseInt(object.readTimestamp, 10);
                else if (typeof object.readTimestamp === "number")
                    message.readTimestamp = object.readTimestamp;
                else if (typeof object.readTimestamp === "object")
                    message.readTimestamp = new $util.LongBits(object.readTimestamp.low >>> 0, object.readTimestamp.high >>> 0).toNumber();
            if (object.playedTimestamp != null)
                if ($util.Long)
                    (message.playedTimestamp = $util.Long.fromValue(object.playedTimestamp)).unsigned = false;
                else if (typeof object.playedTimestamp === "string")
                    message.playedTimestamp = parseInt(object.playedTimestamp, 10);
                else if (typeof object.playedTimestamp === "number")
                    message.playedTimestamp = object.playedTimestamp;
                else if (typeof object.playedTimestamp === "object")
                    message.playedTimestamp = new $util.LongBits(object.playedTimestamp.low >>> 0, object.playedTimestamp.high >>> 0).toNumber();
            if (object.pendingDeviceJid) {
                if (!Array.isArray(object.pendingDeviceJid))
                    throw TypeError(".proto.UserReceipt.pendingDeviceJid: array expected");
                message.pendingDeviceJid = [];
                for (var i = 0; i < object.pendingDeviceJid.length; ++i)
                    message.pendingDeviceJid[i] = String(object.pendingDeviceJid[i]);
            }
            if (object.deliveredDeviceJid) {
                if (!Array.isArray(object.deliveredDeviceJid))
                    throw TypeError(".proto.UserReceipt.deliveredDeviceJid: array expected");
                message.deliveredDeviceJid = [];
                for (var i = 0; i < object.deliveredDeviceJid.length; ++i)
                    message.deliveredDeviceJid[i] = String(object.deliveredDeviceJid[i]);
            }
            return message;
        };

        /**
         * Creates a plain object from a UserReceipt message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.UserReceipt
         * @static
         * @param {proto.UserReceipt} message UserReceipt
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        UserReceipt.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults) {
                object.pendingDeviceJid = [];
                object.deliveredDeviceJid = [];
            }
            if (options.defaults) {
                object.userJid = "";
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.receiptTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.receiptTimestamp = options.longs === String ? "0" : 0;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.readTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.readTimestamp = options.longs === String ? "0" : 0;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, false);
                    object.playedTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.playedTimestamp = options.longs === String ? "0" : 0;
            }
            if (message.userJid != null && message.hasOwnProperty("userJid"))
                object.userJid = message.userJid;
            if (message.receiptTimestamp != null && message.hasOwnProperty("receiptTimestamp"))
                if (typeof message.receiptTimestamp === "number")
                    object.receiptTimestamp = options.longs === String ? String(message.receiptTimestamp) : message.receiptTimestamp;
                else
                    object.receiptTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.receiptTimestamp) : options.longs === Number ? new $util.LongBits(message.receiptTimestamp.low >>> 0, message.receiptTimestamp.high >>> 0).toNumber() : message.receiptTimestamp;
            if (message.readTimestamp != null && message.hasOwnProperty("readTimestamp"))
                if (typeof message.readTimestamp === "number")
                    object.readTimestamp = options.longs === String ? String(message.readTimestamp) : message.readTimestamp;
                else
                    object.readTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.readTimestamp) : options.longs === Number ? new $util.LongBits(message.readTimestamp.low >>> 0, message.readTimestamp.high >>> 0).toNumber() : message.readTimestamp;
            if (message.playedTimestamp != null && message.hasOwnProperty("playedTimestamp"))
                if (typeof message.playedTimestamp === "number")
                    object.playedTimestamp = options.longs === String ? String(message.playedTimestamp) : message.playedTimestamp;
                else
                    object.playedTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.playedTimestamp) : options.longs === Number ? new $util.LongBits(message.playedTimestamp.low >>> 0, message.playedTimestamp.high >>> 0).toNumber() : message.playedTimestamp;
            if (message.pendingDeviceJid && message.pendingDeviceJid.length) {
                object.pendingDeviceJid = [];
                for (var j = 0; j < message.pendingDeviceJid.length; ++j)
                    object.pendingDeviceJid[j] = message.pendingDeviceJid[j];
            }
            if (message.deliveredDeviceJid && message.deliveredDeviceJid.length) {
                object.deliveredDeviceJid = [];
                for (var j = 0; j < message.deliveredDeviceJid.length; ++j)
                    object.deliveredDeviceJid[j] = message.deliveredDeviceJid[j];
            }
            return object;
        };

        /**
         * Converts this UserReceipt to JSON.
         * @function toJSON
         * @memberof proto.UserReceipt
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        UserReceipt.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return UserReceipt;
    })();

    proto.PhotoChange = (function() {

        /**
         * Properties of a PhotoChange.
         * @memberof proto
         * @interface IPhotoChange
         * @property {Uint8Array|null} [oldPhoto] PhotoChange oldPhoto
         * @property {Uint8Array|null} [newPhoto] PhotoChange newPhoto
         * @property {number|null} [newPhotoId] PhotoChange newPhotoId
         */

        /**
         * Constructs a new PhotoChange.
         * @memberof proto
         * @classdesc Represents a PhotoChange.
         * @implements IPhotoChange
         * @constructor
         * @param {proto.IPhotoChange=} [properties] Properties to set
         */
        function PhotoChange(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * PhotoChange oldPhoto.
         * @member {Uint8Array} oldPhoto
         * @memberof proto.PhotoChange
         * @instance
         */
        PhotoChange.prototype.oldPhoto = $util.newBuffer([]);

        /**
         * PhotoChange newPhoto.
         * @member {Uint8Array} newPhoto
         * @memberof proto.PhotoChange
         * @instance
         */
        PhotoChange.prototype.newPhoto = $util.newBuffer([]);

        /**
         * PhotoChange newPhotoId.
         * @member {number} newPhotoId
         * @memberof proto.PhotoChange
         * @instance
         */
        PhotoChange.prototype.newPhotoId = 0;

        /**
         * Creates a new PhotoChange instance using the specified properties.
         * @function create
         * @memberof proto.PhotoChange
         * @static
         * @param {proto.IPhotoChange=} [properties] Properties to set
         * @returns {proto.PhotoChange} PhotoChange instance
         */
        PhotoChange.create = function create(properties) {
            return new PhotoChange(properties);
        };

        /**
         * Encodes the specified PhotoChange message. Does not implicitly {@link proto.PhotoChange.verify|verify} messages.
         * @function encode
         * @memberof proto.PhotoChange
         * @static
         * @param {proto.IPhotoChange} message PhotoChange message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PhotoChange.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.oldPhoto != null && Object.hasOwnProperty.call(message, "oldPhoto"))
                writer.uint32(/* id 1, wireType 2 =*/10).bytes(message.oldPhoto);
            if (message.newPhoto != null && Object.hasOwnProperty.call(message, "newPhoto"))
                writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.newPhoto);
            if (message.newPhotoId != null && Object.hasOwnProperty.call(message, "newPhotoId"))
                writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.newPhotoId);
            return writer;
        };

        /**
         * Encodes the specified PhotoChange message, length delimited. Does not implicitly {@link proto.PhotoChange.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.PhotoChange
         * @static
         * @param {proto.IPhotoChange} message PhotoChange message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PhotoChange.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a PhotoChange message from the specified reader or buffer.
         * @function decode
         * @memberof proto.PhotoChange
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.PhotoChange} PhotoChange
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PhotoChange.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.PhotoChange();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.oldPhoto = reader.bytes();
                    break;
                case 2:
                    message.newPhoto = reader.bytes();
                    break;
                case 3:
                    message.newPhotoId = reader.uint32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a PhotoChange message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.PhotoChange
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.PhotoChange} PhotoChange
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PhotoChange.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a PhotoChange message.
         * @function verify
         * @memberof proto.PhotoChange
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        PhotoChange.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.oldPhoto != null && message.hasOwnProperty("oldPhoto"))
                if (!(message.oldPhoto && typeof message.oldPhoto.length === "number" || $util.isString(message.oldPhoto)))
                    return "oldPhoto: buffer expected";
            if (message.newPhoto != null && message.hasOwnProperty("newPhoto"))
                if (!(message.newPhoto && typeof message.newPhoto.length === "number" || $util.isString(message.newPhoto)))
                    return "newPhoto: buffer expected";
            if (message.newPhotoId != null && message.hasOwnProperty("newPhotoId"))
                if (!$util.isInteger(message.newPhotoId))
                    return "newPhotoId: integer expected";
            return null;
        };

        /**
         * Creates a PhotoChange message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.PhotoChange
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.PhotoChange} PhotoChange
         */
        PhotoChange.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.PhotoChange)
                return object;
            var message = new $root.proto.PhotoChange();
            if (object.oldPhoto != null)
                if (typeof object.oldPhoto === "string")
                    $util.base64.decode(object.oldPhoto, message.oldPhoto = $util.newBuffer($util.base64.length(object.oldPhoto)), 0);
                else if (object.oldPhoto.length)
                    message.oldPhoto = object.oldPhoto;
            if (object.newPhoto != null)
                if (typeof object.newPhoto === "string")
                    $util.base64.decode(object.newPhoto, message.newPhoto = $util.newBuffer($util.base64.length(object.newPhoto)), 0);
                else if (object.newPhoto.length)
                    message.newPhoto = object.newPhoto;
            if (object.newPhotoId != null)
                message.newPhotoId = object.newPhotoId >>> 0;
            return message;
        };

        /**
         * Creates a plain object from a PhotoChange message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.PhotoChange
         * @static
         * @param {proto.PhotoChange} message PhotoChange
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        PhotoChange.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                if (options.bytes === String)
                    object.oldPhoto = "";
                else {
                    object.oldPhoto = [];
                    if (options.bytes !== Array)
                        object.oldPhoto = $util.newBuffer(object.oldPhoto);
                }
                if (options.bytes === String)
                    object.newPhoto = "";
                else {
                    object.newPhoto = [];
                    if (options.bytes !== Array)
                        object.newPhoto = $util.newBuffer(object.newPhoto);
                }
                object.newPhotoId = 0;
            }
            if (message.oldPhoto != null && message.hasOwnProperty("oldPhoto"))
                object.oldPhoto = options.bytes === String ? $util.base64.encode(message.oldPhoto, 0, message.oldPhoto.length) : options.bytes === Array ? Array.prototype.slice.call(message.oldPhoto) : message.oldPhoto;
            if (message.newPhoto != null && message.hasOwnProperty("newPhoto"))
                object.newPhoto = options.bytes === String ? $util.base64.encode(message.newPhoto, 0, message.newPhoto.length) : options.bytes === Array ? Array.prototype.slice.call(message.newPhoto) : message.newPhoto;
            if (message.newPhotoId != null && message.hasOwnProperty("newPhotoId"))
                object.newPhotoId = message.newPhotoId;
            return object;
        };

        /**
         * Converts this PhotoChange to JSON.
         * @function toJSON
         * @memberof proto.PhotoChange
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        PhotoChange.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return PhotoChange;
    })();

    proto.WebFeatures = (function() {

        /**
         * Properties of a WebFeatures.
         * @memberof proto
         * @interface IWebFeatures
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [labelsDisplay] WebFeatures labelsDisplay
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [voipIndividualOutgoing] WebFeatures voipIndividualOutgoing
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [groupsV3] WebFeatures groupsV3
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [groupsV3Create] WebFeatures groupsV3Create
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [changeNumberV2] WebFeatures changeNumberV2
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [queryStatusV3Thumbnail] WebFeatures queryStatusV3Thumbnail
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [liveLocations] WebFeatures liveLocations
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [queryVname] WebFeatures queryVname
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [voipIndividualIncoming] WebFeatures voipIndividualIncoming
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [quickRepliesQuery] WebFeatures quickRepliesQuery
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [payments] WebFeatures payments
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [stickerPackQuery] WebFeatures stickerPackQuery
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [liveLocationsFinal] WebFeatures liveLocationsFinal
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [labelsEdit] WebFeatures labelsEdit
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [mediaUpload] WebFeatures mediaUpload
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [mediaUploadRichQuickReplies] WebFeatures mediaUploadRichQuickReplies
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [vnameV2] WebFeatures vnameV2
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [videoPlaybackUrl] WebFeatures videoPlaybackUrl
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [statusRanking] WebFeatures statusRanking
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [voipIndividualVideo] WebFeatures voipIndividualVideo
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [thirdPartyStickers] WebFeatures thirdPartyStickers
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [frequentlyForwardedSetting] WebFeatures frequentlyForwardedSetting
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [groupsV4JoinPermission] WebFeatures groupsV4JoinPermission
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [recentStickers] WebFeatures recentStickers
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [catalog] WebFeatures catalog
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [starredStickers] WebFeatures starredStickers
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [voipGroupCall] WebFeatures voipGroupCall
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [templateMessage] WebFeatures templateMessage
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [templateMessageInteractivity] WebFeatures templateMessageInteractivity
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [ephemeralMessages] WebFeatures ephemeralMessages
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [e2ENotificationSync] WebFeatures e2ENotificationSync
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [recentStickersV2] WebFeatures recentStickersV2
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [recentStickersV3] WebFeatures recentStickersV3
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [userNotice] WebFeatures userNotice
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [support] WebFeatures support
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [groupUiiCleanup] WebFeatures groupUiiCleanup
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [groupDogfoodingInternalOnly] WebFeatures groupDogfoodingInternalOnly
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [settingsSync] WebFeatures settingsSync
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [archiveV2] WebFeatures archiveV2
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [ephemeralAllowGroupMembers] WebFeatures ephemeralAllowGroupMembers
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [ephemeral24HDuration] WebFeatures ephemeral24HDuration
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [mdForceUpgrade] WebFeatures mdForceUpgrade
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [disappearingMode] WebFeatures disappearingMode
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [externalMdOptInAvailable] WebFeatures externalMdOptInAvailable
         * @property {proto.WebFeatures.WebFeaturesFlag|null} [noDeleteMessageTimeLimit] WebFeatures noDeleteMessageTimeLimit
         */

        /**
         * Constructs a new WebFeatures.
         * @memberof proto
         * @classdesc Represents a WebFeatures.
         * @implements IWebFeatures
         * @constructor
         * @param {proto.IWebFeatures=} [properties] Properties to set
         */
        function WebFeatures(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * WebFeatures labelsDisplay.
         * @member {proto.WebFeatures.WebFeaturesFlag} labelsDisplay
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.labelsDisplay = 0;

        /**
         * WebFeatures voipIndividualOutgoing.
         * @member {proto.WebFeatures.WebFeaturesFlag} voipIndividualOutgoing
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.voipIndividualOutgoing = 0;

        /**
         * WebFeatures groupsV3.
         * @member {proto.WebFeatures.WebFeaturesFlag} groupsV3
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.groupsV3 = 0;

        /**
         * WebFeatures groupsV3Create.
         * @member {proto.WebFeatures.WebFeaturesFlag} groupsV3Create
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.groupsV3Create = 0;

        /**
         * WebFeatures changeNumberV2.
         * @member {proto.WebFeatures.WebFeaturesFlag} changeNumberV2
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.changeNumberV2 = 0;

        /**
         * WebFeatures queryStatusV3Thumbnail.
         * @member {proto.WebFeatures.WebFeaturesFlag} queryStatusV3Thumbnail
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.queryStatusV3Thumbnail = 0;

        /**
         * WebFeatures liveLocations.
         * @member {proto.WebFeatures.WebFeaturesFlag} liveLocations
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.liveLocations = 0;

        /**
         * WebFeatures queryVname.
         * @member {proto.WebFeatures.WebFeaturesFlag} queryVname
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.queryVname = 0;

        /**
         * WebFeatures voipIndividualIncoming.
         * @member {proto.WebFeatures.WebFeaturesFlag} voipIndividualIncoming
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.voipIndividualIncoming = 0;

        /**
         * WebFeatures quickRepliesQuery.
         * @member {proto.WebFeatures.WebFeaturesFlag} quickRepliesQuery
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.quickRepliesQuery = 0;

        /**
         * WebFeatures payments.
         * @member {proto.WebFeatures.WebFeaturesFlag} payments
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.payments = 0;

        /**
         * WebFeatures stickerPackQuery.
         * @member {proto.WebFeatures.WebFeaturesFlag} stickerPackQuery
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.stickerPackQuery = 0;

        /**
         * WebFeatures liveLocationsFinal.
         * @member {proto.WebFeatures.WebFeaturesFlag} liveLocationsFinal
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.liveLocationsFinal = 0;

        /**
         * WebFeatures labelsEdit.
         * @member {proto.WebFeatures.WebFeaturesFlag} labelsEdit
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.labelsEdit = 0;

        /**
         * WebFeatures mediaUpload.
         * @member {proto.WebFeatures.WebFeaturesFlag} mediaUpload
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.mediaUpload = 0;

        /**
         * WebFeatures mediaUploadRichQuickReplies.
         * @member {proto.WebFeatures.WebFeaturesFlag} mediaUploadRichQuickReplies
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.mediaUploadRichQuickReplies = 0;

        /**
         * WebFeatures vnameV2.
         * @member {proto.WebFeatures.WebFeaturesFlag} vnameV2
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.vnameV2 = 0;

        /**
         * WebFeatures videoPlaybackUrl.
         * @member {proto.WebFeatures.WebFeaturesFlag} videoPlaybackUrl
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.videoPlaybackUrl = 0;

        /**
         * WebFeatures statusRanking.
         * @member {proto.WebFeatures.WebFeaturesFlag} statusRanking
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.statusRanking = 0;

        /**
         * WebFeatures voipIndividualVideo.
         * @member {proto.WebFeatures.WebFeaturesFlag} voipIndividualVideo
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.voipIndividualVideo = 0;

        /**
         * WebFeatures thirdPartyStickers.
         * @member {proto.WebFeatures.WebFeaturesFlag} thirdPartyStickers
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.thirdPartyStickers = 0;

        /**
         * WebFeatures frequentlyForwardedSetting.
         * @member {proto.WebFeatures.WebFeaturesFlag} frequentlyForwardedSetting
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.frequentlyForwardedSetting = 0;

        /**
         * WebFeatures groupsV4JoinPermission.
         * @member {proto.WebFeatures.WebFeaturesFlag} groupsV4JoinPermission
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.groupsV4JoinPermission = 0;

        /**
         * WebFeatures recentStickers.
         * @member {proto.WebFeatures.WebFeaturesFlag} recentStickers
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.recentStickers = 0;

        /**
         * WebFeatures catalog.
         * @member {proto.WebFeatures.WebFeaturesFlag} catalog
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.catalog = 0;

        /**
         * WebFeatures starredStickers.
         * @member {proto.WebFeatures.WebFeaturesFlag} starredStickers
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.starredStickers = 0;

        /**
         * WebFeatures voipGroupCall.
         * @member {proto.WebFeatures.WebFeaturesFlag} voipGroupCall
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.voipGroupCall = 0;

        /**
         * WebFeatures templateMessage.
         * @member {proto.WebFeatures.WebFeaturesFlag} templateMessage
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.templateMessage = 0;

        /**
         * WebFeatures templateMessageInteractivity.
         * @member {proto.WebFeatures.WebFeaturesFlag} templateMessageInteractivity
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.templateMessageInteractivity = 0;

        /**
         * WebFeatures ephemeralMessages.
         * @member {proto.WebFeatures.WebFeaturesFlag} ephemeralMessages
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.ephemeralMessages = 0;

        /**
         * WebFeatures e2ENotificationSync.
         * @member {proto.WebFeatures.WebFeaturesFlag} e2ENotificationSync
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.e2ENotificationSync = 0;

        /**
         * WebFeatures recentStickersV2.
         * @member {proto.WebFeatures.WebFeaturesFlag} recentStickersV2
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.recentStickersV2 = 0;

        /**
         * WebFeatures recentStickersV3.
         * @member {proto.WebFeatures.WebFeaturesFlag} recentStickersV3
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.recentStickersV3 = 0;

        /**
         * WebFeatures userNotice.
         * @member {proto.WebFeatures.WebFeaturesFlag} userNotice
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.userNotice = 0;

        /**
         * WebFeatures support.
         * @member {proto.WebFeatures.WebFeaturesFlag} support
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.support = 0;

        /**
         * WebFeatures groupUiiCleanup.
         * @member {proto.WebFeatures.WebFeaturesFlag} groupUiiCleanup
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.groupUiiCleanup = 0;

        /**
         * WebFeatures groupDogfoodingInternalOnly.
         * @member {proto.WebFeatures.WebFeaturesFlag} groupDogfoodingInternalOnly
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.groupDogfoodingInternalOnly = 0;

        /**
         * WebFeatures settingsSync.
         * @member {proto.WebFeatures.WebFeaturesFlag} settingsSync
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.settingsSync = 0;

        /**
         * WebFeatures archiveV2.
         * @member {proto.WebFeatures.WebFeaturesFlag} archiveV2
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.archiveV2 = 0;

        /**
         * WebFeatures ephemeralAllowGroupMembers.
         * @member {proto.WebFeatures.WebFeaturesFlag} ephemeralAllowGroupMembers
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.ephemeralAllowGroupMembers = 0;

        /**
         * WebFeatures ephemeral24HDuration.
         * @member {proto.WebFeatures.WebFeaturesFlag} ephemeral24HDuration
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.ephemeral24HDuration = 0;

        /**
         * WebFeatures mdForceUpgrade.
         * @member {proto.WebFeatures.WebFeaturesFlag} mdForceUpgrade
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.mdForceUpgrade = 0;

        /**
         * WebFeatures disappearingMode.
         * @member {proto.WebFeatures.WebFeaturesFlag} disappearingMode
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.disappearingMode = 0;

        /**
         * WebFeatures externalMdOptInAvailable.
         * @member {proto.WebFeatures.WebFeaturesFlag} externalMdOptInAvailable
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.externalMdOptInAvailable = 0;

        /**
         * WebFeatures noDeleteMessageTimeLimit.
         * @member {proto.WebFeatures.WebFeaturesFlag} noDeleteMessageTimeLimit
         * @memberof proto.WebFeatures
         * @instance
         */
        WebFeatures.prototype.noDeleteMessageTimeLimit = 0;

        /**
         * Creates a new WebFeatures instance using the specified properties.
         * @function create
         * @memberof proto.WebFeatures
         * @static
         * @param {proto.IWebFeatures=} [properties] Properties to set
         * @returns {proto.WebFeatures} WebFeatures instance
         */
        WebFeatures.create = function create(properties) {
            return new WebFeatures(properties);
        };

        /**
         * Encodes the specified WebFeatures message. Does not implicitly {@link proto.WebFeatures.verify|verify} messages.
         * @function encode
         * @memberof proto.WebFeatures
         * @static
         * @param {proto.IWebFeatures} message WebFeatures message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        WebFeatures.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.labelsDisplay != null && Object.hasOwnProperty.call(message, "labelsDisplay"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.labelsDisplay);
            if (message.voipIndividualOutgoing != null && Object.hasOwnProperty.call(message, "voipIndividualOutgoing"))
                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.voipIndividualOutgoing);
            if (message.groupsV3 != null && Object.hasOwnProperty.call(message, "groupsV3"))
                writer.uint32(/* id 3, wireType 0 =*/24).int32(message.groupsV3);
            if (message.groupsV3Create != null && Object.hasOwnProperty.call(message, "groupsV3Create"))
                writer.uint32(/* id 4, wireType 0 =*/32).int32(message.groupsV3Create);
            if (message.changeNumberV2 != null && Object.hasOwnProperty.call(message, "changeNumberV2"))
                writer.uint32(/* id 5, wireType 0 =*/40).int32(message.changeNumberV2);
            if (message.queryStatusV3Thumbnail != null && Object.hasOwnProperty.call(message, "queryStatusV3Thumbnail"))
                writer.uint32(/* id 6, wireType 0 =*/48).int32(message.queryStatusV3Thumbnail);
            if (message.liveLocations != null && Object.hasOwnProperty.call(message, "liveLocations"))
                writer.uint32(/* id 7, wireType 0 =*/56).int32(message.liveLocations);
            if (message.queryVname != null && Object.hasOwnProperty.call(message, "queryVname"))
                writer.uint32(/* id 8, wireType 0 =*/64).int32(message.queryVname);
            if (message.voipIndividualIncoming != null && Object.hasOwnProperty.call(message, "voipIndividualIncoming"))
                writer.uint32(/* id 9, wireType 0 =*/72).int32(message.voipIndividualIncoming);
            if (message.quickRepliesQuery != null && Object.hasOwnProperty.call(message, "quickRepliesQuery"))
                writer.uint32(/* id 10, wireType 0 =*/80).int32(message.quickRepliesQuery);
            if (message.payments != null && Object.hasOwnProperty.call(message, "payments"))
                writer.uint32(/* id 11, wireType 0 =*/88).int32(message.payments);
            if (message.stickerPackQuery != null && Object.hasOwnProperty.call(message, "stickerPackQuery"))
                writer.uint32(/* id 12, wireType 0 =*/96).int32(message.stickerPackQuery);
            if (message.liveLocationsFinal != null && Object.hasOwnProperty.call(message, "liveLocationsFinal"))
                writer.uint32(/* id 13, wireType 0 =*/104).int32(message.liveLocationsFinal);
            if (message.labelsEdit != null && Object.hasOwnProperty.call(message, "labelsEdit"))
                writer.uint32(/* id 14, wireType 0 =*/112).int32(message.labelsEdit);
            if (message.mediaUpload != null && Object.hasOwnProperty.call(message, "mediaUpload"))
                writer.uint32(/* id 15, wireType 0 =*/120).int32(message.mediaUpload);
            if (message.mediaUploadRichQuickReplies != null && Object.hasOwnProperty.call(message, "mediaUploadRichQuickReplies"))
                writer.uint32(/* id 18, wireType 0 =*/144).int32(message.mediaUploadRichQuickReplies);
            if (message.vnameV2 != null && Object.hasOwnProperty.call(message, "vnameV2"))
                writer.uint32(/* id 19, wireType 0 =*/152).int32(message.vnameV2);
            if (message.videoPlaybackUrl != null && Object.hasOwnProperty.call(message, "videoPlaybackUrl"))
                writer.uint32(/* id 20, wireType 0 =*/160).int32(message.videoPlaybackUrl);
            if (message.statusRanking != null && Object.hasOwnProperty.call(message, "statusRanking"))
                writer.uint32(/* id 21, wireType 0 =*/168).int32(message.statusRanking);
            if (message.voipIndividualVideo != null && Object.hasOwnProperty.call(message, "voipIndividualVideo"))
                writer.uint32(/* id 22, wireType 0 =*/176).int32(message.voipIndividualVideo);
            if (message.thirdPartyStickers != null && Object.hasOwnProperty.call(message, "thirdPartyStickers"))
                writer.uint32(/* id 23, wireType 0 =*/184).int32(message.thirdPartyStickers);
            if (message.frequentlyForwardedSetting != null && Object.hasOwnProperty.call(message, "frequentlyForwardedSetting"))
                writer.uint32(/* id 24, wireType 0 =*/192).int32(message.frequentlyForwardedSetting);
            if (message.groupsV4JoinPermission != null && Object.hasOwnProperty.call(message, "groupsV4JoinPermission"))
                writer.uint32(/* id 25, wireType 0 =*/200).int32(message.groupsV4JoinPermission);
            if (message.recentStickers != null && Object.hasOwnProperty.call(message, "recentStickers"))
                writer.uint32(/* id 26, wireType 0 =*/208).int32(message.recentStickers);
            if (message.catalog != null && Object.hasOwnProperty.call(message, "catalog"))
                writer.uint32(/* id 27, wireType 0 =*/216).int32(message.catalog);
            if (message.starredStickers != null && Object.hasOwnProperty.call(message, "starredStickers"))
                writer.uint32(/* id 28, wireType 0 =*/224).int32(message.starredStickers);
            if (message.voipGroupCall != null && Object.hasOwnProperty.call(message, "voipGroupCall"))
                writer.uint32(/* id 29, wireType 0 =*/232).int32(message.voipGroupCall);
            if (message.templateMessage != null && Object.hasOwnProperty.call(message, "templateMessage"))
                writer.uint32(/* id 30, wireType 0 =*/240).int32(message.templateMessage);
            if (message.templateMessageInteractivity != null && Object.hasOwnProperty.call(message, "templateMessageInteractivity"))
                writer.uint32(/* id 31, wireType 0 =*/248).int32(message.templateMessageInteractivity);
            if (message.ephemeralMessages != null && Object.hasOwnProperty.call(message, "ephemeralMessages"))
                writer.uint32(/* id 32, wireType 0 =*/256).int32(message.ephemeralMessages);
            if (message.e2ENotificationSync != null && Object.hasOwnProperty.call(message, "e2ENotificationSync"))
                writer.uint32(/* id 33, wireType 0 =*/264).int32(message.e2ENotificationSync);
            if (message.recentStickersV2 != null && Object.hasOwnProperty.call(message, "recentStickersV2"))
                writer.uint32(/* id 34, wireType 0 =*/272).int32(message.recentStickersV2);
            if (message.recentStickersV3 != null && Object.hasOwnProperty.call(message, "recentStickersV3"))
                writer.uint32(/* id 36, wireType 0 =*/288).int32(message.recentStickersV3);
            if (message.userNotice != null && Object.hasOwnProperty.call(message, "userNotice"))
                writer.uint32(/* id 37, wireType 0 =*/296).int32(message.userNotice);
            if (message.support != null && Object.hasOwnProperty.call(message, "support"))
                writer.uint32(/* id 39, wireType 0 =*/312).int32(message.support);
            if (message.groupUiiCleanup != null && Object.hasOwnProperty.call(message, "groupUiiCleanup"))
                writer.uint32(/* id 40, wireType 0 =*/320).int32(message.groupUiiCleanup);
            if (message.groupDogfoodingInternalOnly != null && Object.hasOwnProperty.call(message, "groupDogfoodingInternalOnly"))
                writer.uint32(/* id 41, wireType 0 =*/328).int32(message.groupDogfoodingInternalOnly);
            if (message.settingsSync != null && Object.hasOwnProperty.call(message, "settingsSync"))
                writer.uint32(/* id 42, wireType 0 =*/336).int32(message.settingsSync);
            if (message.archiveV2 != null && Object.hasOwnProperty.call(message, "archiveV2"))
                writer.uint32(/* id 43, wireType 0 =*/344).int32(message.archiveV2);
            if (message.ephemeralAllowGroupMembers != null && Object.hasOwnProperty.call(message, "ephemeralAllowGroupMembers"))
                writer.uint32(/* id 44, wireType 0 =*/352).int32(message.ephemeralAllowGroupMembers);
            if (message.ephemeral24HDuration != null && Object.hasOwnProperty.call(message, "ephemeral24HDuration"))
                writer.uint32(/* id 45, wireType 0 =*/360).int32(message.ephemeral24HDuration);
            if (message.mdForceUpgrade != null && Object.hasOwnProperty.call(message, "mdForceUpgrade"))
                writer.uint32(/* id 46, wireType 0 =*/368).int32(message.mdForceUpgrade);
            if (message.disappearingMode != null && Object.hasOwnProperty.call(message, "disappearingMode"))
                writer.uint32(/* id 47, wireType 0 =*/376).int32(message.disappearingMode);
            if (message.externalMdOptInAvailable != null && Object.hasOwnProperty.call(message, "externalMdOptInAvailable"))
                writer.uint32(/* id 48, wireType 0 =*/384).int32(message.externalMdOptInAvailable);
            if (message.noDeleteMessageTimeLimit != null && Object.hasOwnProperty.call(message, "noDeleteMessageTimeLimit"))
                writer.uint32(/* id 49, wireType 0 =*/392).int32(message.noDeleteMessageTimeLimit);
            return writer;
        };

        /**
         * Encodes the specified WebFeatures message, length delimited. Does not implicitly {@link proto.WebFeatures.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.WebFeatures
         * @static
         * @param {proto.IWebFeatures} message WebFeatures message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        WebFeatures.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a WebFeatures message from the specified reader or buffer.
         * @function decode
         * @memberof proto.WebFeatures
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.WebFeatures} WebFeatures
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        WebFeatures.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.WebFeatures();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.labelsDisplay = reader.int32();
                    break;
                case 2:
                    message.voipIndividualOutgoing = reader.int32();
                    break;
                case 3:
                    message.groupsV3 = reader.int32();
                    break;
                case 4:
                    message.groupsV3Create = reader.int32();
                    break;
                case 5:
                    message.changeNumberV2 = reader.int32();
                    break;
                case 6:
                    message.queryStatusV3Thumbnail = reader.int32();
                    break;
                case 7:
                    message.liveLocations = reader.int32();
                    break;
                case 8:
                    message.queryVname = reader.int32();
                    break;
                case 9:
                    message.voipIndividualIncoming = reader.int32();
                    break;
                case 10:
                    message.quickRepliesQuery = reader.int32();
                    break;
                case 11:
                    message.payments = reader.int32();
                    break;
                case 12:
                    message.stickerPackQuery = reader.int32();
                    break;
                case 13:
                    message.liveLocationsFinal = reader.int32();
                    break;
                case 14:
                    message.labelsEdit = reader.int32();
                    break;
                case 15:
                    message.mediaUpload = reader.int32();
                    break;
                case 18:
                    message.mediaUploadRichQuickReplies = reader.int32();
                    break;
                case 19:
                    message.vnameV2 = reader.int32();
                    break;
                case 20:
                    message.videoPlaybackUrl = reader.int32();
                    break;
                case 21:
                    message.statusRanking = reader.int32();
                    break;
                case 22:
                    message.voipIndividualVideo = reader.int32();
                    break;
                case 23:
                    message.thirdPartyStickers = reader.int32();
                    break;
                case 24:
                    message.frequentlyForwardedSetting = reader.int32();
                    break;
                case 25:
                    message.groupsV4JoinPermission = reader.int32();
                    break;
                case 26:
                    message.recentStickers = reader.int32();
                    break;
                case 27:
                    message.catalog = reader.int32();
                    break;
                case 28:
                    message.starredStickers = reader.int32();
                    break;
                case 29:
                    message.voipGroupCall = reader.int32();
                    break;
                case 30:
                    message.templateMessage = reader.int32();
                    break;
                case 31:
                    message.templateMessageInteractivity = reader.int32();
                    break;
                case 32:
                    message.ephemeralMessages = reader.int32();
                    break;
                case 33:
                    message.e2ENotificationSync = reader.int32();
                    break;
                case 34:
                    message.recentStickersV2 = reader.int32();
                    break;
                case 36:
                    message.recentStickersV3 = reader.int32();
                    break;
                case 37:
                    message.userNotice = reader.int32();
                    break;
                case 39:
                    message.support = reader.int32();
                    break;
                case 40:
                    message.groupUiiCleanup = reader.int32();
                    break;
                case 41:
                    message.groupDogfoodingInternalOnly = reader.int32();
                    break;
                case 42:
                    message.settingsSync = reader.int32();
                    break;
                case 43:
                    message.archiveV2 = reader.int32();
                    break;
                case 44:
                    message.ephemeralAllowGroupMembers = reader.int32();
                    break;
                case 45:
                    message.ephemeral24HDuration = reader.int32();
                    break;
                case 46:
                    message.mdForceUpgrade = reader.int32();
                    break;
                case 47:
                    message.disappearingMode = reader.int32();
                    break;
                case 48:
                    message.externalMdOptInAvailable = reader.int32();
                    break;
                case 49:
                    message.noDeleteMessageTimeLimit = reader.int32();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a WebFeatures message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.WebFeatures
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.WebFeatures} WebFeatures
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        WebFeatures.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a WebFeatures message.
         * @function verify
         * @memberof proto.WebFeatures
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        WebFeatures.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.labelsDisplay != null && message.hasOwnProperty("labelsDisplay"))
                switch (message.labelsDisplay) {
                default:
                    return "labelsDisplay: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.voipIndividualOutgoing != null && message.hasOwnProperty("voipIndividualOutgoing"))
                switch (message.voipIndividualOutgoing) {
                default:
                    return "voipIndividualOutgoing: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.groupsV3 != null && message.hasOwnProperty("groupsV3"))
                switch (message.groupsV3) {
                default:
                    return "groupsV3: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.groupsV3Create != null && message.hasOwnProperty("groupsV3Create"))
                switch (message.groupsV3Create) {
                default:
                    return "groupsV3Create: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.changeNumberV2 != null && message.hasOwnProperty("changeNumberV2"))
                switch (message.changeNumberV2) {
                default:
                    return "changeNumberV2: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.queryStatusV3Thumbnail != null && message.hasOwnProperty("queryStatusV3Thumbnail"))
                switch (message.queryStatusV3Thumbnail) {
                default:
                    return "queryStatusV3Thumbnail: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.liveLocations != null && message.hasOwnProperty("liveLocations"))
                switch (message.liveLocations) {
                default:
                    return "liveLocations: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.queryVname != null && message.hasOwnProperty("queryVname"))
                switch (message.queryVname) {
                default:
                    return "queryVname: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.voipIndividualIncoming != null && message.hasOwnProperty("voipIndividualIncoming"))
                switch (message.voipIndividualIncoming) {
                default:
                    return "voipIndividualIncoming: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.quickRepliesQuery != null && message.hasOwnProperty("quickRepliesQuery"))
                switch (message.quickRepliesQuery) {
                default:
                    return "quickRepliesQuery: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.payments != null && message.hasOwnProperty("payments"))
                switch (message.payments) {
                default:
                    return "payments: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.stickerPackQuery != null && message.hasOwnProperty("stickerPackQuery"))
                switch (message.stickerPackQuery) {
                default:
                    return "stickerPackQuery: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.liveLocationsFinal != null && message.hasOwnProperty("liveLocationsFinal"))
                switch (message.liveLocationsFinal) {
                default:
                    return "liveLocationsFinal: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.labelsEdit != null && message.hasOwnProperty("labelsEdit"))
                switch (message.labelsEdit) {
                default:
                    return "labelsEdit: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.mediaUpload != null && message.hasOwnProperty("mediaUpload"))
                switch (message.mediaUpload) {
                default:
                    return "mediaUpload: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.mediaUploadRichQuickReplies != null && message.hasOwnProperty("mediaUploadRichQuickReplies"))
                switch (message.mediaUploadRichQuickReplies) {
                default:
                    return "mediaUploadRichQuickReplies: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.vnameV2 != null && message.hasOwnProperty("vnameV2"))
                switch (message.vnameV2) {
                default:
                    return "vnameV2: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.videoPlaybackUrl != null && message.hasOwnProperty("videoPlaybackUrl"))
                switch (message.videoPlaybackUrl) {
                default:
                    return "videoPlaybackUrl: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.statusRanking != null && message.hasOwnProperty("statusRanking"))
                switch (message.statusRanking) {
                default:
                    return "statusRanking: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.voipIndividualVideo != null && message.hasOwnProperty("voipIndividualVideo"))
                switch (message.voipIndividualVideo) {
                default:
                    return "voipIndividualVideo: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.thirdPartyStickers != null && message.hasOwnProperty("thirdPartyStickers"))
                switch (message.thirdPartyStickers) {
                default:
                    return "thirdPartyStickers: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.frequentlyForwardedSetting != null && message.hasOwnProperty("frequentlyForwardedSetting"))
                switch (message.frequentlyForwardedSetting) {
                default:
                    return "frequentlyForwardedSetting: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.groupsV4JoinPermission != null && message.hasOwnProperty("groupsV4JoinPermission"))
                switch (message.groupsV4JoinPermission) {
                default:
                    return "groupsV4JoinPermission: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.recentStickers != null && message.hasOwnProperty("recentStickers"))
                switch (message.recentStickers) {
                default:
                    return "recentStickers: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.catalog != null && message.hasOwnProperty("catalog"))
                switch (message.catalog) {
                default:
                    return "catalog: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.starredStickers != null && message.hasOwnProperty("starredStickers"))
                switch (message.starredStickers) {
                default:
                    return "starredStickers: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.voipGroupCall != null && message.hasOwnProperty("voipGroupCall"))
                switch (message.voipGroupCall) {
                default:
                    return "voipGroupCall: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.templateMessage != null && message.hasOwnProperty("templateMessage"))
                switch (message.templateMessage) {
                default:
                    return "templateMessage: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.templateMessageInteractivity != null && message.hasOwnProperty("templateMessageInteractivity"))
                switch (message.templateMessageInteractivity) {
                default:
                    return "templateMessageInteractivity: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.ephemeralMessages != null && message.hasOwnProperty("ephemeralMessages"))
                switch (message.ephemeralMessages) {
                default:
                    return "ephemeralMessages: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.e2ENotificationSync != null && message.hasOwnProperty("e2ENotificationSync"))
                switch (message.e2ENotificationSync) {
                default:
                    return "e2ENotificationSync: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.recentStickersV2 != null && message.hasOwnProperty("recentStickersV2"))
                switch (message.recentStickersV2) {
                default:
                    return "recentStickersV2: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.recentStickersV3 != null && message.hasOwnProperty("recentStickersV3"))
                switch (message.recentStickersV3) {
                default:
                    return "recentStickersV3: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.userNotice != null && message.hasOwnProperty("userNotice"))
                switch (message.userNotice) {
                default:
                    return "userNotice: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.support != null && message.hasOwnProperty("support"))
                switch (message.support) {
                default:
                    return "support: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.groupUiiCleanup != null && message.hasOwnProperty("groupUiiCleanup"))
                switch (message.groupUiiCleanup) {
                default:
                    return "groupUiiCleanup: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.groupDogfoodingInternalOnly != null && message.hasOwnProperty("groupDogfoodingInternalOnly"))
                switch (message.groupDogfoodingInternalOnly) {
                default:
                    return "groupDogfoodingInternalOnly: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.settingsSync != null && message.hasOwnProperty("settingsSync"))
                switch (message.settingsSync) {
                default:
                    return "settingsSync: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.archiveV2 != null && message.hasOwnProperty("archiveV2"))
                switch (message.archiveV2) {
                default:
                    return "archiveV2: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.ephemeralAllowGroupMembers != null && message.hasOwnProperty("ephemeralAllowGroupMembers"))
                switch (message.ephemeralAllowGroupMembers) {
                default:
                    return "ephemeralAllowGroupMembers: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.ephemeral24HDuration != null && message.hasOwnProperty("ephemeral24HDuration"))
                switch (message.ephemeral24HDuration) {
                default:
                    return "ephemeral24HDuration: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.mdForceUpgrade != null && message.hasOwnProperty("mdForceUpgrade"))
                switch (message.mdForceUpgrade) {
                default:
                    return "mdForceUpgrade: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode"))
                switch (message.disappearingMode) {
                default:
                    return "disappearingMode: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.externalMdOptInAvailable != null && message.hasOwnProperty("externalMdOptInAvailable"))
                switch (message.externalMdOptInAvailable) {
                default:
                    return "externalMdOptInAvailable: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            if (message.noDeleteMessageTimeLimit != null && message.hasOwnProperty("noDeleteMessageTimeLimit"))
                switch (message.noDeleteMessageTimeLimit) {
                default:
                    return "noDeleteMessageTimeLimit: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                    break;
                }
            return null;
        };

        /**
         * Creates a WebFeatures message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.WebFeatures
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.WebFeatures} WebFeatures
         */
        WebFeatures.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.WebFeatures)
                return object;
            var message = new $root.proto.WebFeatures();
            switch (object.labelsDisplay) {
            case "NOT_STARTED":
            case 0:
                message.labelsDisplay = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.labelsDisplay = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.labelsDisplay = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.labelsDisplay = 3;
                break;
            }
            switch (object.voipIndividualOutgoing) {
            case "NOT_STARTED":
            case 0:
                message.voipIndividualOutgoing = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.voipIndividualOutgoing = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.voipIndividualOutgoing = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.voipIndividualOutgoing = 3;
                break;
            }
            switch (object.groupsV3) {
            case "NOT_STARTED":
            case 0:
                message.groupsV3 = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.groupsV3 = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.groupsV3 = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.groupsV3 = 3;
                break;
            }
            switch (object.groupsV3Create) {
            case "NOT_STARTED":
            case 0:
                message.groupsV3Create = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.groupsV3Create = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.groupsV3Create = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.groupsV3Create = 3;
                break;
            }
            switch (object.changeNumberV2) {
            case "NOT_STARTED":
            case 0:
                message.changeNumberV2 = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.changeNumberV2 = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.changeNumberV2 = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.changeNumberV2 = 3;
                break;
            }
            switch (object.queryStatusV3Thumbnail) {
            case "NOT_STARTED":
            case 0:
                message.queryStatusV3Thumbnail = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.queryStatusV3Thumbnail = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.queryStatusV3Thumbnail = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.queryStatusV3Thumbnail = 3;
                break;
            }
            switch (object.liveLocations) {
            case "NOT_STARTED":
            case 0:
                message.liveLocations = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.liveLocations = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.liveLocations = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.liveLocations = 3;
                break;
            }
            switch (object.queryVname) {
            case "NOT_STARTED":
            case 0:
                message.queryVname = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.queryVname = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.queryVname = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.queryVname = 3;
                break;
            }
            switch (object.voipIndividualIncoming) {
            case "NOT_STARTED":
            case 0:
                message.voipIndividualIncoming = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.voipIndividualIncoming = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.voipIndividualIncoming = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.voipIndividualIncoming = 3;
                break;
            }
            switch (object.quickRepliesQuery) {
            case "NOT_STARTED":
            case 0:
                message.quickRepliesQuery = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.quickRepliesQuery = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.quickRepliesQuery = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.quickRepliesQuery = 3;
                break;
            }
            switch (object.payments) {
            case "NOT_STARTED":
            case 0:
                message.payments = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.payments = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.payments = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.payments = 3;
                break;
            }
            switch (object.stickerPackQuery) {
            case "NOT_STARTED":
            case 0:
                message.stickerPackQuery = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.stickerPackQuery = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.stickerPackQuery = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.stickerPackQuery = 3;
                break;
            }
            switch (object.liveLocationsFinal) {
            case "NOT_STARTED":
            case 0:
                message.liveLocationsFinal = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.liveLocationsFinal = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.liveLocationsFinal = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.liveLocationsFinal = 3;
                break;
            }
            switch (object.labelsEdit) {
            case "NOT_STARTED":
            case 0:
                message.labelsEdit = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.labelsEdit = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.labelsEdit = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.labelsEdit = 3;
                break;
            }
            switch (object.mediaUpload) {
            case "NOT_STARTED":
            case 0:
                message.mediaUpload = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.mediaUpload = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.mediaUpload = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.mediaUpload = 3;
                break;
            }
            switch (object.mediaUploadRichQuickReplies) {
            case "NOT_STARTED":
            case 0:
                message.mediaUploadRichQuickReplies = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.mediaUploadRichQuickReplies = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.mediaUploadRichQuickReplies = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.mediaUploadRichQuickReplies = 3;
                break;
            }
            switch (object.vnameV2) {
            case "NOT_STARTED":
            case 0:
                message.vnameV2 = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.vnameV2 = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.vnameV2 = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.vnameV2 = 3;
                break;
            }
            switch (object.videoPlaybackUrl) {
            case "NOT_STARTED":
            case 0:
                message.videoPlaybackUrl = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.videoPlaybackUrl = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.videoPlaybackUrl = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.videoPlaybackUrl = 3;
                break;
            }
            switch (object.statusRanking) {
            case "NOT_STARTED":
            case 0:
                message.statusRanking = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.statusRanking = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.statusRanking = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.statusRanking = 3;
                break;
            }
            switch (object.voipIndividualVideo) {
            case "NOT_STARTED":
            case 0:
                message.voipIndividualVideo = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.voipIndividualVideo = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.voipIndividualVideo = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.voipIndividualVideo = 3;
                break;
            }
            switch (object.thirdPartyStickers) {
            case "NOT_STARTED":
            case 0:
                message.thirdPartyStickers = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.thirdPartyStickers = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.thirdPartyStickers = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.thirdPartyStickers = 3;
                break;
            }
            switch (object.frequentlyForwardedSetting) {
            case "NOT_STARTED":
            case 0:
                message.frequentlyForwardedSetting = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.frequentlyForwardedSetting = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.frequentlyForwardedSetting = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.frequentlyForwardedSetting = 3;
                break;
            }
            switch (object.groupsV4JoinPermission) {
            case "NOT_STARTED":
            case 0:
                message.groupsV4JoinPermission = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.groupsV4JoinPermission = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.groupsV4JoinPermission = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.groupsV4JoinPermission = 3;
                break;
            }
            switch (object.recentStickers) {
            case "NOT_STARTED":
            case 0:
                message.recentStickers = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.recentStickers = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.recentStickers = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.recentStickers = 3;
                break;
            }
            switch (object.catalog) {
            case "NOT_STARTED":
            case 0:
                message.catalog = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.catalog = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.catalog = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.catalog = 3;
                break;
            }
            switch (object.starredStickers) {
            case "NOT_STARTED":
            case 0:
                message.starredStickers = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.starredStickers = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.starredStickers = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.starredStickers = 3;
                break;
            }
            switch (object.voipGroupCall) {
            case "NOT_STARTED":
            case 0:
                message.voipGroupCall = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.voipGroupCall = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.voipGroupCall = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.voipGroupCall = 3;
                break;
            }
            switch (object.templateMessage) {
            case "NOT_STARTED":
            case 0:
                message.templateMessage = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.templateMessage = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.templateMessage = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.templateMessage = 3;
                break;
            }
            switch (object.templateMessageInteractivity) {
            case "NOT_STARTED":
            case 0:
                message.templateMessageInteractivity = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.templateMessageInteractivity = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.templateMessageInteractivity = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.templateMessageInteractivity = 3;
                break;
            }
            switch (object.ephemeralMessages) {
            case "NOT_STARTED":
            case 0:
                message.ephemeralMessages = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.ephemeralMessages = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.ephemeralMessages = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.ephemeralMessages = 3;
                break;
            }
            switch (object.e2ENotificationSync) {
            case "NOT_STARTED":
            case 0:
                message.e2ENotificationSync = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.e2ENotificationSync = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.e2ENotificationSync = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.e2ENotificationSync = 3;
                break;
            }
            switch (object.recentStickersV2) {
            case "NOT_STARTED":
            case 0:
                message.recentStickersV2 = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.recentStickersV2 = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.recentStickersV2 = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.recentStickersV2 = 3;
                break;
            }
            switch (object.recentStickersV3) {
            case "NOT_STARTED":
            case 0:
                message.recentStickersV3 = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.recentStickersV3 = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.recentStickersV3 = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.recentStickersV3 = 3;
                break;
            }
            switch (object.userNotice) {
            case "NOT_STARTED":
            case 0:
                message.userNotice = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.userNotice = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.userNotice = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.userNotice = 3;
                break;
            }
            switch (object.support) {
            case "NOT_STARTED":
            case 0:
                message.support = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.support = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.support = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.support = 3;
                break;
            }
            switch (object.groupUiiCleanup) {
            case "NOT_STARTED":
            case 0:
                message.groupUiiCleanup = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.groupUiiCleanup = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.groupUiiCleanup = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.groupUiiCleanup = 3;
                break;
            }
            switch (object.groupDogfoodingInternalOnly) {
            case "NOT_STARTED":
            case 0:
                message.groupDogfoodingInternalOnly = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.groupDogfoodingInternalOnly = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.groupDogfoodingInternalOnly = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.groupDogfoodingInternalOnly = 3;
                break;
            }
            switch (object.settingsSync) {
            case "NOT_STARTED":
            case 0:
                message.settingsSync = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.settingsSync = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.settingsSync = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.settingsSync = 3;
                break;
            }
            switch (object.archiveV2) {
            case "NOT_STARTED":
            case 0:
                message.archiveV2 = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.archiveV2 = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.archiveV2 = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.archiveV2 = 3;
                break;
            }
            switch (object.ephemeralAllowGroupMembers) {
            case "NOT_STARTED":
            case 0:
                message.ephemeralAllowGroupMembers = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.ephemeralAllowGroupMembers = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.ephemeralAllowGroupMembers = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.ephemeralAllowGroupMembers = 3;
                break;
            }
            switch (object.ephemeral24HDuration) {
            case "NOT_STARTED":
            case 0:
                message.ephemeral24HDuration = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.ephemeral24HDuration = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.ephemeral24HDuration = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.ephemeral24HDuration = 3;
                break;
            }
            switch (object.mdForceUpgrade) {
            case "NOT_STARTED":
            case 0:
                message.mdForceUpgrade = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.mdForceUpgrade = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.mdForceUpgrade = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.mdForceUpgrade = 3;
                break;
            }
            switch (object.disappearingMode) {
            case "NOT_STARTED":
            case 0:
                message.disappearingMode = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.disappearingMode = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.disappearingMode = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.disappearingMode = 3;
                break;
            }
            switch (object.externalMdOptInAvailable) {
            case "NOT_STARTED":
            case 0:
                message.externalMdOptInAvailable = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.externalMdOptInAvailable = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.externalMdOptInAvailable = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.externalMdOptInAvailable = 3;
                break;
            }
            switch (object.noDeleteMessageTimeLimit) {
            case "NOT_STARTED":
            case 0:
                message.noDeleteMessageTimeLimit = 0;
                break;
            case "FORCE_UPGRADE":
            case 1:
                message.noDeleteMessageTimeLimit = 1;
                break;
            case "DEVELOPMENT":
            case 2:
                message.noDeleteMessageTimeLimit = 2;
                break;
            case "PRODUCTION":
            case 3:
                message.noDeleteMessageTimeLimit = 3;
                break;
            }
            return message;
        };

        /**
         * Creates a plain object from a WebFeatures message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.WebFeatures
         * @static
         * @param {proto.WebFeatures} message WebFeatures
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        WebFeatures.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.labelsDisplay = options.enums === String ? "NOT_STARTED" : 0;
                object.voipIndividualOutgoing = options.enums === String ? "NOT_STARTED" : 0;
                object.groupsV3 = options.enums === String ? "NOT_STARTED" : 0;
                object.groupsV3Create = options.enums === String ? "NOT_STARTED" : 0;
                object.changeNumberV2 = options.enums === String ? "NOT_STARTED" : 0;
                object.queryStatusV3Thumbnail = options.enums === String ? "NOT_STARTED" : 0;
                object.liveLocations = options.enums === String ? "NOT_STARTED" : 0;
                object.queryVname = options.enums === String ? "NOT_STARTED" : 0;
                object.voipIndividualIncoming = options.enums === String ? "NOT_STARTED" : 0;
                object.quickRepliesQuery = options.enums === String ? "NOT_STARTED" : 0;
                object.payments = options.enums === String ? "NOT_STARTED" : 0;
                object.stickerPackQuery = options.enums === String ? "NOT_STARTED" : 0;
                object.liveLocationsFinal = options.enums === String ? "NOT_STARTED" : 0;
                object.labelsEdit = options.enums === String ? "NOT_STARTED" : 0;
                object.mediaUpload = options.enums === String ? "NOT_STARTED" : 0;
                object.mediaUploadRichQuickReplies = options.enums === String ? "NOT_STARTED" : 0;
                object.vnameV2 = options.enums === String ? "NOT_STARTED" : 0;
                object.videoPlaybackUrl = options.enums === String ? "NOT_STARTED" : 0;
                object.statusRanking = options.enums === String ? "NOT_STARTED" : 0;
                object.voipIndividualVideo = options.enums === String ? "NOT_STARTED" : 0;
                object.thirdPartyStickers = options.enums === String ? "NOT_STARTED" : 0;
                object.frequentlyForwardedSetting = options.enums === String ? "NOT_STARTED" : 0;
                object.groupsV4JoinPermission = options.enums === String ? "NOT_STARTED" : 0;
                object.recentStickers = options.enums === String ? "NOT_STARTED" : 0;
                object.catalog = options.enums === String ? "NOT_STARTED" : 0;
                object.starredStickers = options.enums === String ? "NOT_STARTED" : 0;
                object.voipGroupCall = options.enums === String ? "NOT_STARTED" : 0;
                object.templateMessage = options.enums === String ? "NOT_STARTED" : 0;
                object.templateMessageInteractivity = options.enums === String ? "NOT_STARTED" : 0;
                object.ephemeralMessages = options.enums === String ? "NOT_STARTED" : 0;
                object.e2ENotificationSync = options.enums === String ? "NOT_STARTED" : 0;
                object.recentStickersV2 = options.enums === String ? "NOT_STARTED" : 0;
                object.recentStickersV3 = options.enums === String ? "NOT_STARTED" : 0;
                object.userNotice = options.enums === String ? "NOT_STARTED" : 0;
                object.support = options.enums === String ? "NOT_STARTED" : 0;
                object.groupUiiCleanup = options.enums === String ? "NOT_STARTED" : 0;
                object.groupDogfoodingInternalOnly = options.enums === String ? "NOT_STARTED" : 0;
                object.settingsSync = options.enums === String ? "NOT_STARTED" : 0;
                object.archiveV2 = options.enums === String ? "NOT_STARTED" : 0;
                object.ephemeralAllowGroupMembers = options.enums === String ? "NOT_STARTED" : 0;
                object.ephemeral24HDuration = options.enums === String ? "NOT_STARTED" : 0;
                object.mdForceUpgrade = options.enums === String ? "NOT_STARTED" : 0;
                object.disappearingMode = options.enums === String ? "NOT_STARTED" : 0;
                object.externalMdOptInAvailable = options.enums === String ? "NOT_STARTED" : 0;
                object.noDeleteMessageTimeLimit = options.enums === String ? "NOT_STARTED" : 0;
            }
            if (message.labelsDisplay != null && message.hasOwnProperty("labelsDisplay"))
                object.labelsDisplay = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.labelsDisplay] : message.labelsDisplay;
            if (message.voipIndividualOutgoing != null && message.hasOwnProperty("voipIndividualOutgoing"))
                object.voipIndividualOutgoing = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.voipIndividualOutgoing] : message.voipIndividualOutgoing;
            if (message.groupsV3 != null && message.hasOwnProperty("groupsV3"))
                object.groupsV3 = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.groupsV3] : message.groupsV3;
            if (message.groupsV3Create != null && message.hasOwnProperty("groupsV3Create"))
                object.groupsV3Create = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.groupsV3Create] : message.groupsV3Create;
            if (message.changeNumberV2 != null && message.hasOwnProperty("changeNumberV2"))
                object.changeNumberV2 = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.changeNumberV2] : message.changeNumberV2;
            if (message.queryStatusV3Thumbnail != null && message.hasOwnProperty("queryStatusV3Thumbnail"))
                object.queryStatusV3Thumbnail = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.queryStatusV3Thumbnail] : message.queryStatusV3Thumbnail;
            if (message.liveLocations != null && message.hasOwnProperty("liveLocations"))
                object.liveLocations = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.liveLocations] : message.liveLocations;
            if (message.queryVname != null && message.hasOwnProperty("queryVname"))
                object.queryVname = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.queryVname] : message.queryVname;
            if (message.voipIndividualIncoming != null && message.hasOwnProperty("voipIndividualIncoming"))
                object.voipIndividualIncoming = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.voipIndividualIncoming] : message.voipIndividualIncoming;
            if (message.quickRepliesQuery != null && message.hasOwnProperty("quickRepliesQuery"))
                object.quickRepliesQuery = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.quickRepliesQuery] : message.quickRepliesQuery;
            if (message.payments != null && message.hasOwnProperty("payments"))
                object.payments = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.payments] : message.payments;
            if (message.stickerPackQuery != null && message.hasOwnProperty("stickerPackQuery"))
                object.stickerPackQuery = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.stickerPackQuery] : message.stickerPackQuery;
            if (message.liveLocationsFinal != null && message.hasOwnProperty("liveLocationsFinal"))
                object.liveLocationsFinal = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.liveLocationsFinal] : message.liveLocationsFinal;
            if (message.labelsEdit != null && message.hasOwnProperty("labelsEdit"))
                object.labelsEdit = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.labelsEdit] : message.labelsEdit;
            if (message.mediaUpload != null && message.hasOwnProperty("mediaUpload"))
                object.mediaUpload = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.mediaUpload] : message.mediaUpload;
            if (message.mediaUploadRichQuickReplies != null && message.hasOwnProperty("mediaUploadRichQuickReplies"))
                object.mediaUploadRichQuickReplies = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.mediaUploadRichQuickReplies] : message.mediaUploadRichQuickReplies;
            if (message.vnameV2 != null && message.hasOwnProperty("vnameV2"))
                object.vnameV2 = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.vnameV2] : message.vnameV2;
            if (message.videoPlaybackUrl != null && message.hasOwnProperty("videoPlaybackUrl"))
                object.videoPlaybackUrl = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.videoPlaybackUrl] : message.videoPlaybackUrl;
            if (message.statusRanking != null && message.hasOwnProperty("statusRanking"))
                object.statusRanking = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.statusRanking] : message.statusRanking;
            if (message.voipIndividualVideo != null && message.hasOwnProperty("voipIndividualVideo"))
                object.voipIndividualVideo = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.voipIndividualVideo] : message.voipIndividualVideo;
            if (message.thirdPartyStickers != null && message.hasOwnProperty("thirdPartyStickers"))
                object.thirdPartyStickers = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.thirdPartyStickers] : message.thirdPartyStickers;
            if (message.frequentlyForwardedSetting != null && message.hasOwnProperty("frequentlyForwardedSetting"))
                object.frequentlyForwardedSetting = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.frequentlyForwardedSetting] : message.frequentlyForwardedSetting;
            if (message.groupsV4JoinPermission != null && message.hasOwnProperty("groupsV4JoinPermission"))
                object.groupsV4JoinPermission = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.groupsV4JoinPermission] : message.groupsV4JoinPermission;
            if (message.recentStickers != null && message.hasOwnProperty("recentStickers"))
                object.recentStickers = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.recentStickers] : message.recentStickers;
            if (message.catalog != null && message.hasOwnProperty("catalog"))
                object.catalog = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.catalog] : message.catalog;
            if (message.starredStickers != null && message.hasOwnProperty("starredStickers"))
                object.starredStickers = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.starredStickers] : message.starredStickers;
            if (message.voipGroupCall != null && message.hasOwnProperty("voipGroupCall"))
                object.voipGroupCall = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.voipGroupCall] : message.voipGroupCall;
            if (message.templateMessage != null && message.hasOwnProperty("templateMessage"))
                object.templateMessage = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.templateMessage] : message.templateMessage;
            if (message.templateMessageInteractivity != null && message.hasOwnProperty("templateMessageInteractivity"))
                object.templateMessageInteractivity = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.templateMessageInteractivity] : message.templateMessageInteractivity;
            if (message.ephemeralMessages != null && message.hasOwnProperty("ephemeralMessages"))
                object.ephemeralMessages = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.ephemeralMessages] : message.ephemeralMessages;
            if (message.e2ENotificationSync != null && message.hasOwnProperty("e2ENotificationSync"))
                object.e2ENotificationSync = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.e2ENotificationSync] : message.e2ENotificationSync;
            if (message.recentStickersV2 != null && message.hasOwnProperty("recentStickersV2"))
                object.recentStickersV2 = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.recentStickersV2] : message.recentStickersV2;
            if (message.recentStickersV3 != null && message.hasOwnProperty("recentStickersV3"))
                object.recentStickersV3 = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.recentStickersV3] : message.recentStickersV3;
            if (message.userNotice != null && message.hasOwnProperty("userNotice"))
                object.userNotice = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.userNotice] : message.userNotice;
            if (message.support != null && message.hasOwnProperty("support"))
                object.support = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.support] : message.support;
            if (message.groupUiiCleanup != null && message.hasOwnProperty("groupUiiCleanup"))
                object.groupUiiCleanup = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.groupUiiCleanup] : message.groupUiiCleanup;
            if (message.groupDogfoodingInternalOnly != null && message.hasOwnProperty("groupDogfoodingInternalOnly"))
                object.groupDogfoodingInternalOnly = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.groupDogfoodingInternalOnly] : message.groupDogfoodingInternalOnly;
            if (message.settingsSync != null && message.hasOwnProperty("settingsSync"))
                object.settingsSync = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.settingsSync] : message.settingsSync;
            if (message.archiveV2 != null && message.hasOwnProperty("archiveV2"))
                object.archiveV2 = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.archiveV2] : message.archiveV2;
            if (message.ephemeralAllowGroupMembers != null && message.hasOwnProperty("ephemeralAllowGroupMembers"))
                object.ephemeralAllowGroupMembers = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.ephemeralAllowGroupMembers] : message.ephemeralAllowGroupMembers;
            if (message.ephemeral24HDuration != null && message.hasOwnProperty("ephemeral24HDuration"))
                object.ephemeral24HDuration = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.ephemeral24HDuration] : message.ephemeral24HDuration;
            if (message.mdForceUpgrade != null && message.hasOwnProperty("mdForceUpgrade"))
                object.mdForceUpgrade = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.mdForceUpgrade] : message.mdForceUpgrade;
            if (message.disappearingMode != null && message.hasOwnProperty("disappearingMode"))
                object.disappearingMode = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.disappearingMode] : message.disappearingMode;
            if (message.externalMdOptInAvailable != null && message.hasOwnProperty("externalMdOptInAvailable"))
                object.externalMdOptInAvailable = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.externalMdOptInAvailable] : message.externalMdOptInAvailable;
            if (message.noDeleteMessageTimeLimit != null && message.hasOwnProperty("noDeleteMessageTimeLimit"))
                object.noDeleteMessageTimeLimit = options.enums === String ? $root.proto.WebFeatures.WebFeaturesFlag[message.noDeleteMessageTimeLimit] : message.noDeleteMessageTimeLimit;
            return object;
        };

        /**
         * Converts this WebFeatures to JSON.
         * @function toJSON
         * @memberof proto.WebFeatures
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        WebFeatures.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * WebFeaturesFlag enum.
         * @name proto.WebFeatures.WebFeaturesFlag
         * @enum {number}
         * @property {number} NOT_STARTED=0 NOT_STARTED value
         * @property {number} FORCE_UPGRADE=1 FORCE_UPGRADE value
         * @property {number} DEVELOPMENT=2 DEVELOPMENT value
         * @property {number} PRODUCTION=3 PRODUCTION value
         */
        WebFeatures.WebFeaturesFlag = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "NOT_STARTED"] = 0;
            values[valuesById[1] = "FORCE_UPGRADE"] = 1;
            values[valuesById[2] = "DEVELOPMENT"] = 2;
            values[valuesById[3] = "PRODUCTION"] = 3;
            return values;
        })();

        return WebFeatures;
    })();

    proto.NotificationMessageInfo = (function() {

        /**
         * Properties of a NotificationMessageInfo.
         * @memberof proto
         * @interface INotificationMessageInfo
         * @property {proto.IMessageKey|null} [key] NotificationMessageInfo key
         * @property {proto.IMessage|null} [message] NotificationMessageInfo message
         * @property {number|Long|null} [messageTimestamp] NotificationMessageInfo messageTimestamp
         * @property {string|null} [participant] NotificationMessageInfo participant
         */

        /**
         * Constructs a new NotificationMessageInfo.
         * @memberof proto
         * @classdesc Represents a NotificationMessageInfo.
         * @implements INotificationMessageInfo
         * @constructor
         * @param {proto.INotificationMessageInfo=} [properties] Properties to set
         */
        function NotificationMessageInfo(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * NotificationMessageInfo key.
         * @member {proto.IMessageKey|null|undefined} key
         * @memberof proto.NotificationMessageInfo
         * @instance
         */
        NotificationMessageInfo.prototype.key = null;

        /**
         * NotificationMessageInfo message.
         * @member {proto.IMessage|null|undefined} message
         * @memberof proto.NotificationMessageInfo
         * @instance
         */
        NotificationMessageInfo.prototype.message = null;

        /**
         * NotificationMessageInfo messageTimestamp.
         * @member {number|Long} messageTimestamp
         * @memberof proto.NotificationMessageInfo
         * @instance
         */
        NotificationMessageInfo.prototype.messageTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * NotificationMessageInfo participant.
         * @member {string} participant
         * @memberof proto.NotificationMessageInfo
         * @instance
         */
        NotificationMessageInfo.prototype.participant = "";

        /**
         * Creates a new NotificationMessageInfo instance using the specified properties.
         * @function create
         * @memberof proto.NotificationMessageInfo
         * @static
         * @param {proto.INotificationMessageInfo=} [properties] Properties to set
         * @returns {proto.NotificationMessageInfo} NotificationMessageInfo instance
         */
        NotificationMessageInfo.create = function create(properties) {
            return new NotificationMessageInfo(properties);
        };

        /**
         * Encodes the specified NotificationMessageInfo message. Does not implicitly {@link proto.NotificationMessageInfo.verify|verify} messages.
         * @function encode
         * @memberof proto.NotificationMessageInfo
         * @static
         * @param {proto.INotificationMessageInfo} message NotificationMessageInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        NotificationMessageInfo.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.key != null && Object.hasOwnProperty.call(message, "key"))
                $root.proto.MessageKey.encode(message.key, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.message != null && Object.hasOwnProperty.call(message, "message"))
                $root.proto.Message.encode(message.message, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.messageTimestamp != null && Object.hasOwnProperty.call(message, "messageTimestamp"))
                writer.uint32(/* id 3, wireType 0 =*/24).uint64(message.messageTimestamp);
            if (message.participant != null && Object.hasOwnProperty.call(message, "participant"))
                writer.uint32(/* id 4, wireType 2 =*/34).string(message.participant);
            return writer;
        };

        /**
         * Encodes the specified NotificationMessageInfo message, length delimited. Does not implicitly {@link proto.NotificationMessageInfo.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.NotificationMessageInfo
         * @static
         * @param {proto.INotificationMessageInfo} message NotificationMessageInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        NotificationMessageInfo.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a NotificationMessageInfo message from the specified reader or buffer.
         * @function decode
         * @memberof proto.NotificationMessageInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.NotificationMessageInfo} NotificationMessageInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        NotificationMessageInfo.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.NotificationMessageInfo();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.key = $root.proto.MessageKey.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.message = $root.proto.Message.decode(reader, reader.uint32());
                    break;
                case 3:
                    message.messageTimestamp = reader.uint64();
                    break;
                case 4:
                    message.participant = reader.string();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a NotificationMessageInfo message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.NotificationMessageInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.NotificationMessageInfo} NotificationMessageInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        NotificationMessageInfo.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a NotificationMessageInfo message.
         * @function verify
         * @memberof proto.NotificationMessageInfo
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        NotificationMessageInfo.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.key != null && message.hasOwnProperty("key")) {
                var error = $root.proto.MessageKey.verify(message.key);
                if (error)
                    return "key." + error;
            }
            if (message.message != null && message.hasOwnProperty("message")) {
                var error = $root.proto.Message.verify(message.message);
                if (error)
                    return "message." + error;
            }
            if (message.messageTimestamp != null && message.hasOwnProperty("messageTimestamp"))
                if (!$util.isInteger(message.messageTimestamp) && !(message.messageTimestamp && $util.isInteger(message.messageTimestamp.low) && $util.isInteger(message.messageTimestamp.high)))
                    return "messageTimestamp: integer|Long expected";
            if (message.participant != null && message.hasOwnProperty("participant"))
                if (!$util.isString(message.participant))
                    return "participant: string expected";
            return null;
        };

        /**
         * Creates a NotificationMessageInfo message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.NotificationMessageInfo
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.NotificationMessageInfo} NotificationMessageInfo
         */
        NotificationMessageInfo.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.NotificationMessageInfo)
                return object;
            var message = new $root.proto.NotificationMessageInfo();
            if (object.key != null) {
                if (typeof object.key !== "object")
                    throw TypeError(".proto.NotificationMessageInfo.key: object expected");
                message.key = $root.proto.MessageKey.fromObject(object.key);
            }
            if (object.message != null) {
                if (typeof object.message !== "object")
                    throw TypeError(".proto.NotificationMessageInfo.message: object expected");
                message.message = $root.proto.Message.fromObject(object.message);
            }
            if (object.messageTimestamp != null)
                if ($util.Long)
                    (message.messageTimestamp = $util.Long.fromValue(object.messageTimestamp)).unsigned = true;
                else if (typeof object.messageTimestamp === "string")
                    message.messageTimestamp = parseInt(object.messageTimestamp, 10);
                else if (typeof object.messageTimestamp === "number")
                    message.messageTimestamp = object.messageTimestamp;
                else if (typeof object.messageTimestamp === "object")
                    message.messageTimestamp = new $util.LongBits(object.messageTimestamp.low >>> 0, object.messageTimestamp.high >>> 0).toNumber(true);
            if (object.participant != null)
                message.participant = String(object.participant);
            return message;
        };

        /**
         * Creates a plain object from a NotificationMessageInfo message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.NotificationMessageInfo
         * @static
         * @param {proto.NotificationMessageInfo} message NotificationMessageInfo
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        NotificationMessageInfo.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.key = null;
                object.message = null;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.messageTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.messageTimestamp = options.longs === String ? "0" : 0;
                object.participant = "";
            }
            if (message.key != null && message.hasOwnProperty("key"))
                object.key = $root.proto.MessageKey.toObject(message.key, options);
            if (message.message != null && message.hasOwnProperty("message"))
                object.message = $root.proto.Message.toObject(message.message, options);
            if (message.messageTimestamp != null && message.hasOwnProperty("messageTimestamp"))
                if (typeof message.messageTimestamp === "number")
                    object.messageTimestamp = options.longs === String ? String(message.messageTimestamp) : message.messageTimestamp;
                else
                    object.messageTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.messageTimestamp) : options.longs === Number ? new $util.LongBits(message.messageTimestamp.low >>> 0, message.messageTimestamp.high >>> 0).toNumber(true) : message.messageTimestamp;
            if (message.participant != null && message.hasOwnProperty("participant"))
                object.participant = message.participant;
            return object;
        };

        /**
         * Converts this NotificationMessageInfo to JSON.
         * @function toJSON
         * @memberof proto.NotificationMessageInfo
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        NotificationMessageInfo.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return NotificationMessageInfo;
    })();

    proto.WebNotificationsInfo = (function() {

        /**
         * Properties of a WebNotificationsInfo.
         * @memberof proto
         * @interface IWebNotificationsInfo
         * @property {number|Long|null} [timestamp] WebNotificationsInfo timestamp
         * @property {number|null} [unreadChats] WebNotificationsInfo unreadChats
         * @property {number|null} [notifyMessageCount] WebNotificationsInfo notifyMessageCount
         * @property {Array.<proto.IWebMessageInfo>|null} [notifyMessages] WebNotificationsInfo notifyMessages
         */

        /**
         * Constructs a new WebNotificationsInfo.
         * @memberof proto
         * @classdesc Represents a WebNotificationsInfo.
         * @implements IWebNotificationsInfo
         * @constructor
         * @param {proto.IWebNotificationsInfo=} [properties] Properties to set
         */
        function WebNotificationsInfo(properties) {
            this.notifyMessages = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * WebNotificationsInfo timestamp.
         * @member {number|Long} timestamp
         * @memberof proto.WebNotificationsInfo
         * @instance
         */
        WebNotificationsInfo.prototype.timestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * WebNotificationsInfo unreadChats.
         * @member {number} unreadChats
         * @memberof proto.WebNotificationsInfo
         * @instance
         */
        WebNotificationsInfo.prototype.unreadChats = 0;

        /**
         * WebNotificationsInfo notifyMessageCount.
         * @member {number} notifyMessageCount
         * @memberof proto.WebNotificationsInfo
         * @instance
         */
        WebNotificationsInfo.prototype.notifyMessageCount = 0;

        /**
         * WebNotificationsInfo notifyMessages.
         * @member {Array.<proto.IWebMessageInfo>} notifyMessages
         * @memberof proto.WebNotificationsInfo
         * @instance
         */
        WebNotificationsInfo.prototype.notifyMessages = $util.emptyArray;

        /**
         * Creates a new WebNotificationsInfo instance using the specified properties.
         * @function create
         * @memberof proto.WebNotificationsInfo
         * @static
         * @param {proto.IWebNotificationsInfo=} [properties] Properties to set
         * @returns {proto.WebNotificationsInfo} WebNotificationsInfo instance
         */
        WebNotificationsInfo.create = function create(properties) {
            return new WebNotificationsInfo(properties);
        };

        /**
         * Encodes the specified WebNotificationsInfo message. Does not implicitly {@link proto.WebNotificationsInfo.verify|verify} messages.
         * @function encode
         * @memberof proto.WebNotificationsInfo
         * @static
         * @param {proto.IWebNotificationsInfo} message WebNotificationsInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        WebNotificationsInfo.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.timestamp != null && Object.hasOwnProperty.call(message, "timestamp"))
                writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.timestamp);
            if (message.unreadChats != null && Object.hasOwnProperty.call(message, "unreadChats"))
                writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.unreadChats);
            if (message.notifyMessageCount != null && Object.hasOwnProperty.call(message, "notifyMessageCount"))
                writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.notifyMessageCount);
            if (message.notifyMessages != null && message.notifyMessages.length)
                for (var i = 0; i < message.notifyMessages.length; ++i)
                    $root.proto.WebMessageInfo.encode(message.notifyMessages[i], writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified WebNotificationsInfo message, length delimited. Does not implicitly {@link proto.WebNotificationsInfo.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.WebNotificationsInfo
         * @static
         * @param {proto.IWebNotificationsInfo} message WebNotificationsInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        WebNotificationsInfo.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a WebNotificationsInfo message from the specified reader or buffer.
         * @function decode
         * @memberof proto.WebNotificationsInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.WebNotificationsInfo} WebNotificationsInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        WebNotificationsInfo.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.WebNotificationsInfo();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 2:
                    message.timestamp = reader.uint64();
                    break;
                case 3:
                    message.unreadChats = reader.uint32();
                    break;
                case 4:
                    message.notifyMessageCount = reader.uint32();
                    break;
                case 5:
                    if (!(message.notifyMessages && message.notifyMessages.length))
                        message.notifyMessages = [];
                    message.notifyMessages.push($root.proto.WebMessageInfo.decode(reader, reader.uint32()));
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a WebNotificationsInfo message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.WebNotificationsInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.WebNotificationsInfo} WebNotificationsInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        WebNotificationsInfo.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a WebNotificationsInfo message.
         * @function verify
         * @memberof proto.WebNotificationsInfo
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        WebNotificationsInfo.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.timestamp != null && message.hasOwnProperty("timestamp"))
                if (!$util.isInteger(message.timestamp) && !(message.timestamp && $util.isInteger(message.timestamp.low) && $util.isInteger(message.timestamp.high)))
                    return "timestamp: integer|Long expected";
            if (message.unreadChats != null && message.hasOwnProperty("unreadChats"))
                if (!$util.isInteger(message.unreadChats))
                    return "unreadChats: integer expected";
            if (message.notifyMessageCount != null && message.hasOwnProperty("notifyMessageCount"))
                if (!$util.isInteger(message.notifyMessageCount))
                    return "notifyMessageCount: integer expected";
            if (message.notifyMessages != null && message.hasOwnProperty("notifyMessages")) {
                if (!Array.isArray(message.notifyMessages))
                    return "notifyMessages: array expected";
                for (var i = 0; i < message.notifyMessages.length; ++i) {
                    var error = $root.proto.WebMessageInfo.verify(message.notifyMessages[i]);
                    if (error)
                        return "notifyMessages." + error;
                }
            }
            return null;
        };

        /**
         * Creates a WebNotificationsInfo message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.WebNotificationsInfo
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.WebNotificationsInfo} WebNotificationsInfo
         */
        WebNotificationsInfo.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.WebNotificationsInfo)
                return object;
            var message = new $root.proto.WebNotificationsInfo();
            if (object.timestamp != null)
                if ($util.Long)
                    (message.timestamp = $util.Long.fromValue(object.timestamp)).unsigned = true;
                else if (typeof object.timestamp === "string")
                    message.timestamp = parseInt(object.timestamp, 10);
                else if (typeof object.timestamp === "number")
                    message.timestamp = object.timestamp;
                else if (typeof object.timestamp === "object")
                    message.timestamp = new $util.LongBits(object.timestamp.low >>> 0, object.timestamp.high >>> 0).toNumber(true);
            if (object.unreadChats != null)
                message.unreadChats = object.unreadChats >>> 0;
            if (object.notifyMessageCount != null)
                message.notifyMessageCount = object.notifyMessageCount >>> 0;
            if (object.notifyMessages) {
                if (!Array.isArray(object.notifyMessages))
                    throw TypeError(".proto.WebNotificationsInfo.notifyMessages: array expected");
                message.notifyMessages = [];
                for (var i = 0; i < object.notifyMessages.length; ++i) {
                    if (typeof object.notifyMessages[i] !== "object")
                        throw TypeError(".proto.WebNotificationsInfo.notifyMessages: object expected");
                    message.notifyMessages[i] = $root.proto.WebMessageInfo.fromObject(object.notifyMessages[i]);
                }
            }
            return message;
        };

        /**
         * Creates a plain object from a WebNotificationsInfo message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.WebNotificationsInfo
         * @static
         * @param {proto.WebNotificationsInfo} message WebNotificationsInfo
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        WebNotificationsInfo.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults)
                object.notifyMessages = [];
            if (options.defaults) {
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.timestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.timestamp = options.longs === String ? "0" : 0;
                object.unreadChats = 0;
                object.notifyMessageCount = 0;
            }
            if (message.timestamp != null && message.hasOwnProperty("timestamp"))
                if (typeof message.timestamp === "number")
                    object.timestamp = options.longs === String ? String(message.timestamp) : message.timestamp;
                else
                    object.timestamp = options.longs === String ? $util.Long.prototype.toString.call(message.timestamp) : options.longs === Number ? new $util.LongBits(message.timestamp.low >>> 0, message.timestamp.high >>> 0).toNumber(true) : message.timestamp;
            if (message.unreadChats != null && message.hasOwnProperty("unreadChats"))
                object.unreadChats = message.unreadChats;
            if (message.notifyMessageCount != null && message.hasOwnProperty("notifyMessageCount"))
                object.notifyMessageCount = message.notifyMessageCount;
            if (message.notifyMessages && message.notifyMessages.length) {
                object.notifyMessages = [];
                for (var j = 0; j < message.notifyMessages.length; ++j)
                    object.notifyMessages[j] = $root.proto.WebMessageInfo.toObject(message.notifyMessages[j], options);
            }
            return object;
        };

        /**
         * Converts this WebNotificationsInfo to JSON.
         * @function toJSON
         * @memberof proto.WebNotificationsInfo
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        WebNotificationsInfo.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        return WebNotificationsInfo;
    })();

    proto.PaymentInfo = (function() {

        /**
         * Properties of a PaymentInfo.
         * @memberof proto
         * @interface IPaymentInfo
         * @property {proto.PaymentInfo.PaymentInfoCurrency|null} [currencyDeprecated] PaymentInfo currencyDeprecated
         * @property {number|Long|null} [amount1000] PaymentInfo amount1000
         * @property {string|null} [receiverJid] PaymentInfo receiverJid
         * @property {proto.PaymentInfo.PaymentInfoStatus|null} [status] PaymentInfo status
         * @property {number|Long|null} [transactionTimestamp] PaymentInfo transactionTimestamp
         * @property {proto.IMessageKey|null} [requestMessageKey] PaymentInfo requestMessageKey
         * @property {number|Long|null} [expiryTimestamp] PaymentInfo expiryTimestamp
         * @property {boolean|null} [futureproofed] PaymentInfo futureproofed
         * @property {string|null} [currency] PaymentInfo currency
         * @property {proto.PaymentInfo.PaymentInfoTxnStatus|null} [txnStatus] PaymentInfo txnStatus
         * @property {boolean|null} [useNoviFiatFormat] PaymentInfo useNoviFiatFormat
         * @property {proto.IMoney|null} [primaryAmount] PaymentInfo primaryAmount
         * @property {proto.IMoney|null} [exchangeAmount] PaymentInfo exchangeAmount
         */

        /**
         * Constructs a new PaymentInfo.
         * @memberof proto
         * @classdesc Represents a PaymentInfo.
         * @implements IPaymentInfo
         * @constructor
         * @param {proto.IPaymentInfo=} [properties] Properties to set
         */
        function PaymentInfo(properties) {
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * PaymentInfo currencyDeprecated.
         * @member {proto.PaymentInfo.PaymentInfoCurrency} currencyDeprecated
         * @memberof proto.PaymentInfo
         * @instance
         */
        PaymentInfo.prototype.currencyDeprecated = 0;

        /**
         * PaymentInfo amount1000.
         * @member {number|Long} amount1000
         * @memberof proto.PaymentInfo
         * @instance
         */
        PaymentInfo.prototype.amount1000 = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * PaymentInfo receiverJid.
         * @member {string} receiverJid
         * @memberof proto.PaymentInfo
         * @instance
         */
        PaymentInfo.prototype.receiverJid = "";

        /**
         * PaymentInfo status.
         * @member {proto.PaymentInfo.PaymentInfoStatus} status
         * @memberof proto.PaymentInfo
         * @instance
         */
        PaymentInfo.prototype.status = 0;

        /**
         * PaymentInfo transactionTimestamp.
         * @member {number|Long} transactionTimestamp
         * @memberof proto.PaymentInfo
         * @instance
         */
        PaymentInfo.prototype.transactionTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * PaymentInfo requestMessageKey.
         * @member {proto.IMessageKey|null|undefined} requestMessageKey
         * @memberof proto.PaymentInfo
         * @instance
         */
        PaymentInfo.prototype.requestMessageKey = null;

        /**
         * PaymentInfo expiryTimestamp.
         * @member {number|Long} expiryTimestamp
         * @memberof proto.PaymentInfo
         * @instance
         */
        PaymentInfo.prototype.expiryTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * PaymentInfo futureproofed.
         * @member {boolean} futureproofed
         * @memberof proto.PaymentInfo
         * @instance
         */
        PaymentInfo.prototype.futureproofed = false;

        /**
         * PaymentInfo currency.
         * @member {string} currency
         * @memberof proto.PaymentInfo
         * @instance
         */
        PaymentInfo.prototype.currency = "";

        /**
         * PaymentInfo txnStatus.
         * @member {proto.PaymentInfo.PaymentInfoTxnStatus} txnStatus
         * @memberof proto.PaymentInfo
         * @instance
         */
        PaymentInfo.prototype.txnStatus = 0;

        /**
         * PaymentInfo useNoviFiatFormat.
         * @member {boolean} useNoviFiatFormat
         * @memberof proto.PaymentInfo
         * @instance
         */
        PaymentInfo.prototype.useNoviFiatFormat = false;

        /**
         * PaymentInfo primaryAmount.
         * @member {proto.IMoney|null|undefined} primaryAmount
         * @memberof proto.PaymentInfo
         * @instance
         */
        PaymentInfo.prototype.primaryAmount = null;

        /**
         * PaymentInfo exchangeAmount.
         * @member {proto.IMoney|null|undefined} exchangeAmount
         * @memberof proto.PaymentInfo
         * @instance
         */
        PaymentInfo.prototype.exchangeAmount = null;

        /**
         * Creates a new PaymentInfo instance using the specified properties.
         * @function create
         * @memberof proto.PaymentInfo
         * @static
         * @param {proto.IPaymentInfo=} [properties] Properties to set
         * @returns {proto.PaymentInfo} PaymentInfo instance
         */
        PaymentInfo.create = function create(properties) {
            return new PaymentInfo(properties);
        };

        /**
         * Encodes the specified PaymentInfo message. Does not implicitly {@link proto.PaymentInfo.verify|verify} messages.
         * @function encode
         * @memberof proto.PaymentInfo
         * @static
         * @param {proto.IPaymentInfo} message PaymentInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PaymentInfo.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            if (message.currencyDeprecated != null && Object.hasOwnProperty.call(message, "currencyDeprecated"))
                writer.uint32(/* id 1, wireType 0 =*/8).int32(message.currencyDeprecated);
            if (message.amount1000 != null && Object.hasOwnProperty.call(message, "amount1000"))
                writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.amount1000);
            if (message.receiverJid != null && Object.hasOwnProperty.call(message, "receiverJid"))
                writer.uint32(/* id 3, wireType 2 =*/26).string(message.receiverJid);
            if (message.status != null && Object.hasOwnProperty.call(message, "status"))
                writer.uint32(/* id 4, wireType 0 =*/32).int32(message.status);
            if (message.transactionTimestamp != null && Object.hasOwnProperty.call(message, "transactionTimestamp"))
                writer.uint32(/* id 5, wireType 0 =*/40).uint64(message.transactionTimestamp);
            if (message.requestMessageKey != null && Object.hasOwnProperty.call(message, "requestMessageKey"))
                $root.proto.MessageKey.encode(message.requestMessageKey, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim();
            if (message.expiryTimestamp != null && Object.hasOwnProperty.call(message, "expiryTimestamp"))
                writer.uint32(/* id 7, wireType 0 =*/56).uint64(message.expiryTimestamp);
            if (message.futureproofed != null && Object.hasOwnProperty.call(message, "futureproofed"))
                writer.uint32(/* id 8, wireType 0 =*/64).bool(message.futureproofed);
            if (message.currency != null && Object.hasOwnProperty.call(message, "currency"))
                writer.uint32(/* id 9, wireType 2 =*/74).string(message.currency);
            if (message.txnStatus != null && Object.hasOwnProperty.call(message, "txnStatus"))
                writer.uint32(/* id 10, wireType 0 =*/80).int32(message.txnStatus);
            if (message.useNoviFiatFormat != null && Object.hasOwnProperty.call(message, "useNoviFiatFormat"))
                writer.uint32(/* id 11, wireType 0 =*/88).bool(message.useNoviFiatFormat);
            if (message.primaryAmount != null && Object.hasOwnProperty.call(message, "primaryAmount"))
                $root.proto.Money.encode(message.primaryAmount, writer.uint32(/* id 12, wireType 2 =*/98).fork()).ldelim();
            if (message.exchangeAmount != null && Object.hasOwnProperty.call(message, "exchangeAmount"))
                $root.proto.Money.encode(message.exchangeAmount, writer.uint32(/* id 13, wireType 2 =*/106).fork()).ldelim();
            return writer;
        };

        /**
         * Encodes the specified PaymentInfo message, length delimited. Does not implicitly {@link proto.PaymentInfo.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.PaymentInfo
         * @static
         * @param {proto.IPaymentInfo} message PaymentInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        PaymentInfo.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a PaymentInfo message from the specified reader or buffer.
         * @function decode
         * @memberof proto.PaymentInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.PaymentInfo} PaymentInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PaymentInfo.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.PaymentInfo();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.currencyDeprecated = reader.int32();
                    break;
                case 2:
                    message.amount1000 = reader.uint64();
                    break;
                case 3:
                    message.receiverJid = reader.string();
                    break;
                case 4:
                    message.status = reader.int32();
                    break;
                case 5:
                    message.transactionTimestamp = reader.uint64();
                    break;
                case 6:
                    message.requestMessageKey = $root.proto.MessageKey.decode(reader, reader.uint32());
                    break;
                case 7:
                    message.expiryTimestamp = reader.uint64();
                    break;
                case 8:
                    message.futureproofed = reader.bool();
                    break;
                case 9:
                    message.currency = reader.string();
                    break;
                case 10:
                    message.txnStatus = reader.int32();
                    break;
                case 11:
                    message.useNoviFiatFormat = reader.bool();
                    break;
                case 12:
                    message.primaryAmount = $root.proto.Money.decode(reader, reader.uint32());
                    break;
                case 13:
                    message.exchangeAmount = $root.proto.Money.decode(reader, reader.uint32());
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            return message;
        };

        /**
         * Decodes a PaymentInfo message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.PaymentInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.PaymentInfo} PaymentInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        PaymentInfo.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a PaymentInfo message.
         * @function verify
         * @memberof proto.PaymentInfo
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        PaymentInfo.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            if (message.currencyDeprecated != null && message.hasOwnProperty("currencyDeprecated"))
                switch (message.currencyDeprecated) {
                default:
                    return "currencyDeprecated: enum value expected";
                case 0:
                case 1:
                    break;
                }
            if (message.amount1000 != null && message.hasOwnProperty("amount1000"))
                if (!$util.isInteger(message.amount1000) && !(message.amount1000 && $util.isInteger(message.amount1000.low) && $util.isInteger(message.amount1000.high)))
                    return "amount1000: integer|Long expected";
            if (message.receiverJid != null && message.hasOwnProperty("receiverJid"))
                if (!$util.isString(message.receiverJid))
                    return "receiverJid: string expected";
            if (message.status != null && message.hasOwnProperty("status"))
                switch (message.status) {
                default:
                    return "status: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                case 8:
                case 9:
                case 10:
                case 11:
                    break;
                }
            if (message.transactionTimestamp != null && message.hasOwnProperty("transactionTimestamp"))
                if (!$util.isInteger(message.transactionTimestamp) && !(message.transactionTimestamp && $util.isInteger(message.transactionTimestamp.low) && $util.isInteger(message.transactionTimestamp.high)))
                    return "transactionTimestamp: integer|Long expected";
            if (message.requestMessageKey != null && message.hasOwnProperty("requestMessageKey")) {
                var error = $root.proto.MessageKey.verify(message.requestMessageKey);
                if (error)
                    return "requestMessageKey." + error;
            }
            if (message.expiryTimestamp != null && message.hasOwnProperty("expiryTimestamp"))
                if (!$util.isInteger(message.expiryTimestamp) && !(message.expiryTimestamp && $util.isInteger(message.expiryTimestamp.low) && $util.isInteger(message.expiryTimestamp.high)))
                    return "expiryTimestamp: integer|Long expected";
            if (message.futureproofed != null && message.hasOwnProperty("futureproofed"))
                if (typeof message.futureproofed !== "boolean")
                    return "futureproofed: boolean expected";
            if (message.currency != null && message.hasOwnProperty("currency"))
                if (!$util.isString(message.currency))
                    return "currency: string expected";
            if (message.txnStatus != null && message.hasOwnProperty("txnStatus"))
                switch (message.txnStatus) {
                default:
                    return "txnStatus: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                case 8:
                case 9:
                case 10:
                case 11:
                case 12:
                case 13:
                case 14:
                case 15:
                case 16:
                case 17:
                case 18:
                case 19:
                case 20:
                case 21:
                case 22:
                case 23:
                case 24:
                case 25:
                case 26:
                case 27:
                case 28:
                    break;
                }
            if (message.useNoviFiatFormat != null && message.hasOwnProperty("useNoviFiatFormat"))
                if (typeof message.useNoviFiatFormat !== "boolean")
                    return "useNoviFiatFormat: boolean expected";
            if (message.primaryAmount != null && message.hasOwnProperty("primaryAmount")) {
                var error = $root.proto.Money.verify(message.primaryAmount);
                if (error)
                    return "primaryAmount." + error;
            }
            if (message.exchangeAmount != null && message.hasOwnProperty("exchangeAmount")) {
                var error = $root.proto.Money.verify(message.exchangeAmount);
                if (error)
                    return "exchangeAmount." + error;
            }
            return null;
        };

        /**
         * Creates a PaymentInfo message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.PaymentInfo
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.PaymentInfo} PaymentInfo
         */
        PaymentInfo.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.PaymentInfo)
                return object;
            var message = new $root.proto.PaymentInfo();
            switch (object.currencyDeprecated) {
            case "UNKNOWN_CURRENCY":
            case 0:
                message.currencyDeprecated = 0;
                break;
            case "INR":
            case 1:
                message.currencyDeprecated = 1;
                break;
            }
            if (object.amount1000 != null)
                if ($util.Long)
                    (message.amount1000 = $util.Long.fromValue(object.amount1000)).unsigned = true;
                else if (typeof object.amount1000 === "string")
                    message.amount1000 = parseInt(object.amount1000, 10);
                else if (typeof object.amount1000 === "number")
                    message.amount1000 = object.amount1000;
                else if (typeof object.amount1000 === "object")
                    message.amount1000 = new $util.LongBits(object.amount1000.low >>> 0, object.amount1000.high >>> 0).toNumber(true);
            if (object.receiverJid != null)
                message.receiverJid = String(object.receiverJid);
            switch (object.status) {
            case "UNKNOWN_STATUS":
            case 0:
                message.status = 0;
                break;
            case "PROCESSING":
            case 1:
                message.status = 1;
                break;
            case "SENT":
            case 2:
                message.status = 2;
                break;
            case "NEED_TO_ACCEPT":
            case 3:
                message.status = 3;
                break;
            case "COMPLETE":
            case 4:
                message.status = 4;
                break;
            case "COULD_NOT_COMPLETE":
            case 5:
                message.status = 5;
                break;
            case "REFUNDED":
            case 6:
                message.status = 6;
                break;
            case "EXPIRED":
            case 7:
                message.status = 7;
                break;
            case "REJECTED":
            case 8:
                message.status = 8;
                break;
            case "CANCELLED":
            case 9:
                message.status = 9;
                break;
            case "WAITING_FOR_PAYER":
            case 10:
                message.status = 10;
                break;
            case "WAITING":
            case 11:
                message.status = 11;
                break;
            }
            if (object.transactionTimestamp != null)
                if ($util.Long)
                    (message.transactionTimestamp = $util.Long.fromValue(object.transactionTimestamp)).unsigned = true;
                else if (typeof object.transactionTimestamp === "string")
                    message.transactionTimestamp = parseInt(object.transactionTimestamp, 10);
                else if (typeof object.transactionTimestamp === "number")
                    message.transactionTimestamp = object.transactionTimestamp;
                else if (typeof object.transactionTimestamp === "object")
                    message.transactionTimestamp = new $util.LongBits(object.transactionTimestamp.low >>> 0, object.transactionTimestamp.high >>> 0).toNumber(true);
            if (object.requestMessageKey != null) {
                if (typeof object.requestMessageKey !== "object")
                    throw TypeError(".proto.PaymentInfo.requestMessageKey: object expected");
                message.requestMessageKey = $root.proto.MessageKey.fromObject(object.requestMessageKey);
            }
            if (object.expiryTimestamp != null)
                if ($util.Long)
                    (message.expiryTimestamp = $util.Long.fromValue(object.expiryTimestamp)).unsigned = true;
                else if (typeof object.expiryTimestamp === "string")
                    message.expiryTimestamp = parseInt(object.expiryTimestamp, 10);
                else if (typeof object.expiryTimestamp === "number")
                    message.expiryTimestamp = object.expiryTimestamp;
                else if (typeof object.expiryTimestamp === "object")
                    message.expiryTimestamp = new $util.LongBits(object.expiryTimestamp.low >>> 0, object.expiryTimestamp.high >>> 0).toNumber(true);
            if (object.futureproofed != null)
                message.futureproofed = Boolean(object.futureproofed);
            if (object.currency != null)
                message.currency = String(object.currency);
            switch (object.txnStatus) {
            case "UNKNOWN":
            case 0:
                message.txnStatus = 0;
                break;
            case "PENDING_SETUP":
            case 1:
                message.txnStatus = 1;
                break;
            case "PENDING_RECEIVER_SETUP":
            case 2:
                message.txnStatus = 2;
                break;
            case "INIT":
            case 3:
                message.txnStatus = 3;
                break;
            case "SUCCESS":
            case 4:
                message.txnStatus = 4;
                break;
            case "COMPLETED":
            case 5:
                message.txnStatus = 5;
                break;
            case "FAILED":
            case 6:
                message.txnStatus = 6;
                break;
            case "FAILED_RISK":
            case 7:
                message.txnStatus = 7;
                break;
            case "FAILED_PROCESSING":
            case 8:
                message.txnStatus = 8;
                break;
            case "FAILED_RECEIVER_PROCESSING":
            case 9:
                message.txnStatus = 9;
                break;
            case "FAILED_DA":
            case 10:
                message.txnStatus = 10;
                break;
            case "FAILED_DA_FINAL":
            case 11:
                message.txnStatus = 11;
                break;
            case "REFUNDED_TXN":
            case 12:
                message.txnStatus = 12;
                break;
            case "REFUND_FAILED":
            case 13:
                message.txnStatus = 13;
                break;
            case "REFUND_FAILED_PROCESSING":
            case 14:
                message.txnStatus = 14;
                break;
            case "REFUND_FAILED_DA":
            case 15:
                message.txnStatus = 15;
                break;
            case "EXPIRED_TXN":
            case 16:
                message.txnStatus = 16;
                break;
            case "AUTH_CANCELED":
            case 17:
                message.txnStatus = 17;
                break;
            case "AUTH_CANCEL_FAILED_PROCESSING":
            case 18:
                message.txnStatus = 18;
                break;
            case "AUTH_CANCEL_FAILED":
            case 19:
                message.txnStatus = 19;
                break;
            case "COLLECT_INIT":
            case 20:
                message.txnStatus = 20;
                break;
            case "COLLECT_SUCCESS":
            case 21:
                message.txnStatus = 21;
                break;
            case "COLLECT_FAILED":
            case 22:
                message.txnStatus = 22;
                break;
            case "COLLECT_FAILED_RISK":
            case 23:
                message.txnStatus = 23;
                break;
            case "COLLECT_REJECTED":
            case 24:
                message.txnStatus = 24;
                break;
            case "COLLECT_EXPIRED":
            case 25:
                message.txnStatus = 25;
                break;
            case "COLLECT_CANCELED":
            case 26:
                message.txnStatus = 26;
                break;
            case "COLLECT_CANCELLING":
            case 27:
                message.txnStatus = 27;
                break;
            case "IN_REVIEW":
            case 28:
                message.txnStatus = 28;
                break;
            }
            if (object.useNoviFiatFormat != null)
                message.useNoviFiatFormat = Boolean(object.useNoviFiatFormat);
            if (object.primaryAmount != null) {
                if (typeof object.primaryAmount !== "object")
                    throw TypeError(".proto.PaymentInfo.primaryAmount: object expected");
                message.primaryAmount = $root.proto.Money.fromObject(object.primaryAmount);
            }
            if (object.exchangeAmount != null) {
                if (typeof object.exchangeAmount !== "object")
                    throw TypeError(".proto.PaymentInfo.exchangeAmount: object expected");
                message.exchangeAmount = $root.proto.Money.fromObject(object.exchangeAmount);
            }
            return message;
        };

        /**
         * Creates a plain object from a PaymentInfo message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.PaymentInfo
         * @static
         * @param {proto.PaymentInfo} message PaymentInfo
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        PaymentInfo.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.defaults) {
                object.currencyDeprecated = options.enums === String ? "UNKNOWN_CURRENCY" : 0;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.amount1000 = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.amount1000 = options.longs === String ? "0" : 0;
                object.receiverJid = "";
                object.status = options.enums === String ? "UNKNOWN_STATUS" : 0;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.transactionTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.transactionTimestamp = options.longs === String ? "0" : 0;
                object.requestMessageKey = null;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.expiryTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.expiryTimestamp = options.longs === String ? "0" : 0;
                object.futureproofed = false;
                object.currency = "";
                object.txnStatus = options.enums === String ? "UNKNOWN" : 0;
                object.useNoviFiatFormat = false;
                object.primaryAmount = null;
                object.exchangeAmount = null;
            }
            if (message.currencyDeprecated != null && message.hasOwnProperty("currencyDeprecated"))
                object.currencyDeprecated = options.enums === String ? $root.proto.PaymentInfo.PaymentInfoCurrency[message.currencyDeprecated] : message.currencyDeprecated;
            if (message.amount1000 != null && message.hasOwnProperty("amount1000"))
                if (typeof message.amount1000 === "number")
                    object.amount1000 = options.longs === String ? String(message.amount1000) : message.amount1000;
                else
                    object.amount1000 = options.longs === String ? $util.Long.prototype.toString.call(message.amount1000) : options.longs === Number ? new $util.LongBits(message.amount1000.low >>> 0, message.amount1000.high >>> 0).toNumber(true) : message.amount1000;
            if (message.receiverJid != null && message.hasOwnProperty("receiverJid"))
                object.receiverJid = message.receiverJid;
            if (message.status != null && message.hasOwnProperty("status"))
                object.status = options.enums === String ? $root.proto.PaymentInfo.PaymentInfoStatus[message.status] : message.status;
            if (message.transactionTimestamp != null && message.hasOwnProperty("transactionTimestamp"))
                if (typeof message.transactionTimestamp === "number")
                    object.transactionTimestamp = options.longs === String ? String(message.transactionTimestamp) : message.transactionTimestamp;
                else
                    object.transactionTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.transactionTimestamp) : options.longs === Number ? new $util.LongBits(message.transactionTimestamp.low >>> 0, message.transactionTimestamp.high >>> 0).toNumber(true) : message.transactionTimestamp;
            if (message.requestMessageKey != null && message.hasOwnProperty("requestMessageKey"))
                object.requestMessageKey = $root.proto.MessageKey.toObject(message.requestMessageKey, options);
            if (message.expiryTimestamp != null && message.hasOwnProperty("expiryTimestamp"))
                if (typeof message.expiryTimestamp === "number")
                    object.expiryTimestamp = options.longs === String ? String(message.expiryTimestamp) : message.expiryTimestamp;
                else
                    object.expiryTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.expiryTimestamp) : options.longs === Number ? new $util.LongBits(message.expiryTimestamp.low >>> 0, message.expiryTimestamp.high >>> 0).toNumber(true) : message.expiryTimestamp;
            if (message.futureproofed != null && message.hasOwnProperty("futureproofed"))
                object.futureproofed = message.futureproofed;
            if (message.currency != null && message.hasOwnProperty("currency"))
                object.currency = message.currency;
            if (message.txnStatus != null && message.hasOwnProperty("txnStatus"))
                object.txnStatus = options.enums === String ? $root.proto.PaymentInfo.PaymentInfoTxnStatus[message.txnStatus] : message.txnStatus;
            if (message.useNoviFiatFormat != null && message.hasOwnProperty("useNoviFiatFormat"))
                object.useNoviFiatFormat = message.useNoviFiatFormat;
            if (message.primaryAmount != null && message.hasOwnProperty("primaryAmount"))
                object.primaryAmount = $root.proto.Money.toObject(message.primaryAmount, options);
            if (message.exchangeAmount != null && message.hasOwnProperty("exchangeAmount"))
                object.exchangeAmount = $root.proto.Money.toObject(message.exchangeAmount, options);
            return object;
        };

        /**
         * Converts this PaymentInfo to JSON.
         * @function toJSON
         * @memberof proto.PaymentInfo
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        PaymentInfo.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * PaymentInfoCurrency enum.
         * @name proto.PaymentInfo.PaymentInfoCurrency
         * @enum {number}
         * @property {number} UNKNOWN_CURRENCY=0 UNKNOWN_CURRENCY value
         * @property {number} INR=1 INR value
         */
        PaymentInfo.PaymentInfoCurrency = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "UNKNOWN_CURRENCY"] = 0;
            values[valuesById[1] = "INR"] = 1;
            return values;
        })();

        /**
         * PaymentInfoStatus enum.
         * @name proto.PaymentInfo.PaymentInfoStatus
         * @enum {number}
         * @property {number} UNKNOWN_STATUS=0 UNKNOWN_STATUS value
         * @property {number} PROCESSING=1 PROCESSING value
         * @property {number} SENT=2 SENT value
         * @property {number} NEED_TO_ACCEPT=3 NEED_TO_ACCEPT value
         * @property {number} COMPLETE=4 COMPLETE value
         * @property {number} COULD_NOT_COMPLETE=5 COULD_NOT_COMPLETE value
         * @property {number} REFUNDED=6 REFUNDED value
         * @property {number} EXPIRED=7 EXPIRED value
         * @property {number} REJECTED=8 REJECTED value
         * @property {number} CANCELLED=9 CANCELLED value
         * @property {number} WAITING_FOR_PAYER=10 WAITING_FOR_PAYER value
         * @property {number} WAITING=11 WAITING value
         */
        PaymentInfo.PaymentInfoStatus = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "UNKNOWN_STATUS"] = 0;
            values[valuesById[1] = "PROCESSING"] = 1;
            values[valuesById[2] = "SENT"] = 2;
            values[valuesById[3] = "NEED_TO_ACCEPT"] = 3;
            values[valuesById[4] = "COMPLETE"] = 4;
            values[valuesById[5] = "COULD_NOT_COMPLETE"] = 5;
            values[valuesById[6] = "REFUNDED"] = 6;
            values[valuesById[7] = "EXPIRED"] = 7;
            values[valuesById[8] = "REJECTED"] = 8;
            values[valuesById[9] = "CANCELLED"] = 9;
            values[valuesById[10] = "WAITING_FOR_PAYER"] = 10;
            values[valuesById[11] = "WAITING"] = 11;
            return values;
        })();

        /**
         * PaymentInfoTxnStatus enum.
         * @name proto.PaymentInfo.PaymentInfoTxnStatus
         * @enum {number}
         * @property {number} UNKNOWN=0 UNKNOWN value
         * @property {number} PENDING_SETUP=1 PENDING_SETUP value
         * @property {number} PENDING_RECEIVER_SETUP=2 PENDING_RECEIVER_SETUP value
         * @property {number} INIT=3 INIT value
         * @property {number} SUCCESS=4 SUCCESS value
         * @property {number} COMPLETED=5 COMPLETED value
         * @property {number} FAILED=6 FAILED value
         * @property {number} FAILED_RISK=7 FAILED_RISK value
         * @property {number} FAILED_PROCESSING=8 FAILED_PROCESSING value
         * @property {number} FAILED_RECEIVER_PROCESSING=9 FAILED_RECEIVER_PROCESSING value
         * @property {number} FAILED_DA=10 FAILED_DA value
         * @property {number} FAILED_DA_FINAL=11 FAILED_DA_FINAL value
         * @property {number} REFUNDED_TXN=12 REFUNDED_TXN value
         * @property {number} REFUND_FAILED=13 REFUND_FAILED value
         * @property {number} REFUND_FAILED_PROCESSING=14 REFUND_FAILED_PROCESSING value
         * @property {number} REFUND_FAILED_DA=15 REFUND_FAILED_DA value
         * @property {number} EXPIRED_TXN=16 EXPIRED_TXN value
         * @property {number} AUTH_CANCELED=17 AUTH_CANCELED value
         * @property {number} AUTH_CANCEL_FAILED_PROCESSING=18 AUTH_CANCEL_FAILED_PROCESSING value
         * @property {number} AUTH_CANCEL_FAILED=19 AUTH_CANCEL_FAILED value
         * @property {number} COLLECT_INIT=20 COLLECT_INIT value
         * @property {number} COLLECT_SUCCESS=21 COLLECT_SUCCESS value
         * @property {number} COLLECT_FAILED=22 COLLECT_FAILED value
         * @property {number} COLLECT_FAILED_RISK=23 COLLECT_FAILED_RISK value
         * @property {number} COLLECT_REJECTED=24 COLLECT_REJECTED value
         * @property {number} COLLECT_EXPIRED=25 COLLECT_EXPIRED value
         * @property {number} COLLECT_CANCELED=26 COLLECT_CANCELED value
         * @property {number} COLLECT_CANCELLING=27 COLLECT_CANCELLING value
         * @property {number} IN_REVIEW=28 IN_REVIEW value
         */
        PaymentInfo.PaymentInfoTxnStatus = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "UNKNOWN"] = 0;
            values[valuesById[1] = "PENDING_SETUP"] = 1;
            values[valuesById[2] = "PENDING_RECEIVER_SETUP"] = 2;
            values[valuesById[3] = "INIT"] = 3;
            values[valuesById[4] = "SUCCESS"] = 4;
            values[valuesById[5] = "COMPLETED"] = 5;
            values[valuesById[6] = "FAILED"] = 6;
            values[valuesById[7] = "FAILED_RISK"] = 7;
            values[valuesById[8] = "FAILED_PROCESSING"] = 8;
            values[valuesById[9] = "FAILED_RECEIVER_PROCESSING"] = 9;
            values[valuesById[10] = "FAILED_DA"] = 10;
            values[valuesById[11] = "FAILED_DA_FINAL"] = 11;
            values[valuesById[12] = "REFUNDED_TXN"] = 12;
            values[valuesById[13] = "REFUND_FAILED"] = 13;
            values[valuesById[14] = "REFUND_FAILED_PROCESSING"] = 14;
            values[valuesById[15] = "REFUND_FAILED_DA"] = 15;
            values[valuesById[16] = "EXPIRED_TXN"] = 16;
            values[valuesById[17] = "AUTH_CANCELED"] = 17;
            values[valuesById[18] = "AUTH_CANCEL_FAILED_PROCESSING"] = 18;
            values[valuesById[19] = "AUTH_CANCEL_FAILED"] = 19;
            values[valuesById[20] = "COLLECT_INIT"] = 20;
            values[valuesById[21] = "COLLECT_SUCCESS"] = 21;
            values[valuesById[22] = "COLLECT_FAILED"] = 22;
            values[valuesById[23] = "COLLECT_FAILED_RISK"] = 23;
            values[valuesById[24] = "COLLECT_REJECTED"] = 24;
            values[valuesById[25] = "COLLECT_EXPIRED"] = 25;
            values[valuesById[26] = "COLLECT_CANCELED"] = 26;
            values[valuesById[27] = "COLLECT_CANCELLING"] = 27;
            values[valuesById[28] = "IN_REVIEW"] = 28;
            return values;
        })();

        return PaymentInfo;
    })();

    proto.WebMessageInfo = (function() {

        /**
         * Properties of a WebMessageInfo.
         * @memberof proto
         * @interface IWebMessageInfo
         * @property {proto.IMessageKey} key WebMessageInfo key
         * @property {proto.IMessage|null} [message] WebMessageInfo message
         * @property {number|Long|null} [messageTimestamp] WebMessageInfo messageTimestamp
         * @property {proto.WebMessageInfo.WebMessageInfoStatus|null} [status] WebMessageInfo status
         * @property {string|null} [participant] WebMessageInfo participant
         * @property {number|Long|null} [messageC2STimestamp] WebMessageInfo messageC2STimestamp
         * @property {boolean|null} [ignore] WebMessageInfo ignore
         * @property {boolean|null} [starred] WebMessageInfo starred
         * @property {boolean|null} [broadcast] WebMessageInfo broadcast
         * @property {string|null} [pushName] WebMessageInfo pushName
         * @property {Uint8Array|null} [mediaCiphertextSha256] WebMessageInfo mediaCiphertextSha256
         * @property {boolean|null} [multicast] WebMessageInfo multicast
         * @property {boolean|null} [urlText] WebMessageInfo urlText
         * @property {boolean|null} [urlNumber] WebMessageInfo urlNumber
         * @property {proto.WebMessageInfo.WebMessageInfoStubType|null} [messageStubType] WebMessageInfo messageStubType
         * @property {boolean|null} [clearMedia] WebMessageInfo clearMedia
         * @property {Array.<string>|null} [messageStubParameters] WebMessageInfo messageStubParameters
         * @property {number|null} [duration] WebMessageInfo duration
         * @property {Array.<string>|null} [labels] WebMessageInfo labels
         * @property {proto.IPaymentInfo|null} [paymentInfo] WebMessageInfo paymentInfo
         * @property {proto.ILiveLocationMessage|null} [finalLiveLocation] WebMessageInfo finalLiveLocation
         * @property {proto.IPaymentInfo|null} [quotedPaymentInfo] WebMessageInfo quotedPaymentInfo
         * @property {number|Long|null} [ephemeralStartTimestamp] WebMessageInfo ephemeralStartTimestamp
         * @property {number|null} [ephemeralDuration] WebMessageInfo ephemeralDuration
         * @property {boolean|null} [ephemeralOffToOn] WebMessageInfo ephemeralOffToOn
         * @property {boolean|null} [ephemeralOutOfSync] WebMessageInfo ephemeralOutOfSync
         * @property {proto.WebMessageInfo.WebMessageInfoBizPrivacyStatus|null} [bizPrivacyStatus] WebMessageInfo bizPrivacyStatus
         * @property {string|null} [verifiedBizName] WebMessageInfo verifiedBizName
         * @property {proto.IMediaData|null} [mediaData] WebMessageInfo mediaData
         * @property {proto.IPhotoChange|null} [photoChange] WebMessageInfo photoChange
         * @property {Array.<proto.IUserReceipt>|null} [userReceipt] WebMessageInfo userReceipt
         * @property {Array.<proto.IReaction>|null} [reactions] WebMessageInfo reactions
         * @property {proto.IMediaData|null} [quotedStickerData] WebMessageInfo quotedStickerData
         * @property {Uint8Array|null} [futureproofData] WebMessageInfo futureproofData
         * @property {string|null} [statusPsaCampaignId] WebMessageInfo statusPsaCampaignId
         * @property {number|null} [statusPsaCampaignDuration] WebMessageInfo statusPsaCampaignDuration
         * @property {number|Long|null} [statusPsaCampaignReadTimestamp] WebMessageInfo statusPsaCampaignReadTimestamp
         */

        /**
         * Constructs a new WebMessageInfo.
         * @memberof proto
         * @classdesc Represents a WebMessageInfo.
         * @implements IWebMessageInfo
         * @constructor
         * @param {proto.IWebMessageInfo=} [properties] Properties to set
         */
        function WebMessageInfo(properties) {
            this.messageStubParameters = [];
            this.labels = [];
            this.userReceipt = [];
            this.reactions = [];
            if (properties)
                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                    if (properties[keys[i]] != null)
                        this[keys[i]] = properties[keys[i]];
        }

        /**
         * WebMessageInfo key.
         * @member {proto.IMessageKey} key
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.key = null;

        /**
         * WebMessageInfo message.
         * @member {proto.IMessage|null|undefined} message
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.message = null;

        /**
         * WebMessageInfo messageTimestamp.
         * @member {number|Long} messageTimestamp
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.messageTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * WebMessageInfo status.
         * @member {proto.WebMessageInfo.WebMessageInfoStatus} status
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.status = 0;

        /**
         * WebMessageInfo participant.
         * @member {string} participant
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.participant = "";

        /**
         * WebMessageInfo messageC2STimestamp.
         * @member {number|Long} messageC2STimestamp
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.messageC2STimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * WebMessageInfo ignore.
         * @member {boolean} ignore
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.ignore = false;

        /**
         * WebMessageInfo starred.
         * @member {boolean} starred
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.starred = false;

        /**
         * WebMessageInfo broadcast.
         * @member {boolean} broadcast
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.broadcast = false;

        /**
         * WebMessageInfo pushName.
         * @member {string} pushName
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.pushName = "";

        /**
         * WebMessageInfo mediaCiphertextSha256.
         * @member {Uint8Array} mediaCiphertextSha256
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.mediaCiphertextSha256 = $util.newBuffer([]);

        /**
         * WebMessageInfo multicast.
         * @member {boolean} multicast
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.multicast = false;

        /**
         * WebMessageInfo urlText.
         * @member {boolean} urlText
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.urlText = false;

        /**
         * WebMessageInfo urlNumber.
         * @member {boolean} urlNumber
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.urlNumber = false;

        /**
         * WebMessageInfo messageStubType.
         * @member {proto.WebMessageInfo.WebMessageInfoStubType} messageStubType
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.messageStubType = 0;

        /**
         * WebMessageInfo clearMedia.
         * @member {boolean} clearMedia
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.clearMedia = false;

        /**
         * WebMessageInfo messageStubParameters.
         * @member {Array.<string>} messageStubParameters
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.messageStubParameters = $util.emptyArray;

        /**
         * WebMessageInfo duration.
         * @member {number} duration
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.duration = 0;

        /**
         * WebMessageInfo labels.
         * @member {Array.<string>} labels
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.labels = $util.emptyArray;

        /**
         * WebMessageInfo paymentInfo.
         * @member {proto.IPaymentInfo|null|undefined} paymentInfo
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.paymentInfo = null;

        /**
         * WebMessageInfo finalLiveLocation.
         * @member {proto.ILiveLocationMessage|null|undefined} finalLiveLocation
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.finalLiveLocation = null;

        /**
         * WebMessageInfo quotedPaymentInfo.
         * @member {proto.IPaymentInfo|null|undefined} quotedPaymentInfo
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.quotedPaymentInfo = null;

        /**
         * WebMessageInfo ephemeralStartTimestamp.
         * @member {number|Long} ephemeralStartTimestamp
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.ephemeralStartTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * WebMessageInfo ephemeralDuration.
         * @member {number} ephemeralDuration
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.ephemeralDuration = 0;

        /**
         * WebMessageInfo ephemeralOffToOn.
         * @member {boolean} ephemeralOffToOn
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.ephemeralOffToOn = false;

        /**
         * WebMessageInfo ephemeralOutOfSync.
         * @member {boolean} ephemeralOutOfSync
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.ephemeralOutOfSync = false;

        /**
         * WebMessageInfo bizPrivacyStatus.
         * @member {proto.WebMessageInfo.WebMessageInfoBizPrivacyStatus} bizPrivacyStatus
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.bizPrivacyStatus = 0;

        /**
         * WebMessageInfo verifiedBizName.
         * @member {string} verifiedBizName
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.verifiedBizName = "";

        /**
         * WebMessageInfo mediaData.
         * @member {proto.IMediaData|null|undefined} mediaData
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.mediaData = null;

        /**
         * WebMessageInfo photoChange.
         * @member {proto.IPhotoChange|null|undefined} photoChange
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.photoChange = null;

        /**
         * WebMessageInfo userReceipt.
         * @member {Array.<proto.IUserReceipt>} userReceipt
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.userReceipt = $util.emptyArray;

        /**
         * WebMessageInfo reactions.
         * @member {Array.<proto.IReaction>} reactions
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.reactions = $util.emptyArray;

        /**
         * WebMessageInfo quotedStickerData.
         * @member {proto.IMediaData|null|undefined} quotedStickerData
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.quotedStickerData = null;

        /**
         * WebMessageInfo futureproofData.
         * @member {Uint8Array} futureproofData
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.futureproofData = $util.newBuffer([]);

        /**
         * WebMessageInfo statusPsaCampaignId.
         * @member {string} statusPsaCampaignId
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.statusPsaCampaignId = "";

        /**
         * WebMessageInfo statusPsaCampaignDuration.
         * @member {number} statusPsaCampaignDuration
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.statusPsaCampaignDuration = 0;

        /**
         * WebMessageInfo statusPsaCampaignReadTimestamp.
         * @member {number|Long} statusPsaCampaignReadTimestamp
         * @memberof proto.WebMessageInfo
         * @instance
         */
        WebMessageInfo.prototype.statusPsaCampaignReadTimestamp = $util.Long ? $util.Long.fromBits(0,0,true) : 0;

        /**
         * Creates a new WebMessageInfo instance using the specified properties.
         * @function create
         * @memberof proto.WebMessageInfo
         * @static
         * @param {proto.IWebMessageInfo=} [properties] Properties to set
         * @returns {proto.WebMessageInfo} WebMessageInfo instance
         */
        WebMessageInfo.create = function create(properties) {
            return new WebMessageInfo(properties);
        };

        /**
         * Encodes the specified WebMessageInfo message. Does not implicitly {@link proto.WebMessageInfo.verify|verify} messages.
         * @function encode
         * @memberof proto.WebMessageInfo
         * @static
         * @param {proto.IWebMessageInfo} message WebMessageInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        WebMessageInfo.encode = function encode(message, writer) {
            if (!writer)
                writer = $Writer.create();
            $root.proto.MessageKey.encode(message.key, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
            if (message.message != null && Object.hasOwnProperty.call(message, "message"))
                $root.proto.Message.encode(message.message, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
            if (message.messageTimestamp != null && Object.hasOwnProperty.call(message, "messageTimestamp"))
                writer.uint32(/* id 3, wireType 0 =*/24).uint64(message.messageTimestamp);
            if (message.status != null && Object.hasOwnProperty.call(message, "status"))
                writer.uint32(/* id 4, wireType 0 =*/32).int32(message.status);
            if (message.participant != null && Object.hasOwnProperty.call(message, "participant"))
                writer.uint32(/* id 5, wireType 2 =*/42).string(message.participant);
            if (message.messageC2STimestamp != null && Object.hasOwnProperty.call(message, "messageC2STimestamp"))
                writer.uint32(/* id 6, wireType 0 =*/48).uint64(message.messageC2STimestamp);
            if (message.ignore != null && Object.hasOwnProperty.call(message, "ignore"))
                writer.uint32(/* id 16, wireType 0 =*/128).bool(message.ignore);
            if (message.starred != null && Object.hasOwnProperty.call(message, "starred"))
                writer.uint32(/* id 17, wireType 0 =*/136).bool(message.starred);
            if (message.broadcast != null && Object.hasOwnProperty.call(message, "broadcast"))
                writer.uint32(/* id 18, wireType 0 =*/144).bool(message.broadcast);
            if (message.pushName != null && Object.hasOwnProperty.call(message, "pushName"))
                writer.uint32(/* id 19, wireType 2 =*/154).string(message.pushName);
            if (message.mediaCiphertextSha256 != null && Object.hasOwnProperty.call(message, "mediaCiphertextSha256"))
                writer.uint32(/* id 20, wireType 2 =*/162).bytes(message.mediaCiphertextSha256);
            if (message.multicast != null && Object.hasOwnProperty.call(message, "multicast"))
                writer.uint32(/* id 21, wireType 0 =*/168).bool(message.multicast);
            if (message.urlText != null && Object.hasOwnProperty.call(message, "urlText"))
                writer.uint32(/* id 22, wireType 0 =*/176).bool(message.urlText);
            if (message.urlNumber != null && Object.hasOwnProperty.call(message, "urlNumber"))
                writer.uint32(/* id 23, wireType 0 =*/184).bool(message.urlNumber);
            if (message.messageStubType != null && Object.hasOwnProperty.call(message, "messageStubType"))
                writer.uint32(/* id 24, wireType 0 =*/192).int32(message.messageStubType);
            if (message.clearMedia != null && Object.hasOwnProperty.call(message, "clearMedia"))
                writer.uint32(/* id 25, wireType 0 =*/200).bool(message.clearMedia);
            if (message.messageStubParameters != null && message.messageStubParameters.length)
                for (var i = 0; i < message.messageStubParameters.length; ++i)
                    writer.uint32(/* id 26, wireType 2 =*/210).string(message.messageStubParameters[i]);
            if (message.duration != null && Object.hasOwnProperty.call(message, "duration"))
                writer.uint32(/* id 27, wireType 0 =*/216).uint32(message.duration);
            if (message.labels != null && message.labels.length)
                for (var i = 0; i < message.labels.length; ++i)
                    writer.uint32(/* id 28, wireType 2 =*/226).string(message.labels[i]);
            if (message.paymentInfo != null && Object.hasOwnProperty.call(message, "paymentInfo"))
                $root.proto.PaymentInfo.encode(message.paymentInfo, writer.uint32(/* id 29, wireType 2 =*/234).fork()).ldelim();
            if (message.finalLiveLocation != null && Object.hasOwnProperty.call(message, "finalLiveLocation"))
                $root.proto.LiveLocationMessage.encode(message.finalLiveLocation, writer.uint32(/* id 30, wireType 2 =*/242).fork()).ldelim();
            if (message.quotedPaymentInfo != null && Object.hasOwnProperty.call(message, "quotedPaymentInfo"))
                $root.proto.PaymentInfo.encode(message.quotedPaymentInfo, writer.uint32(/* id 31, wireType 2 =*/250).fork()).ldelim();
            if (message.ephemeralStartTimestamp != null && Object.hasOwnProperty.call(message, "ephemeralStartTimestamp"))
                writer.uint32(/* id 32, wireType 0 =*/256).uint64(message.ephemeralStartTimestamp);
            if (message.ephemeralDuration != null && Object.hasOwnProperty.call(message, "ephemeralDuration"))
                writer.uint32(/* id 33, wireType 0 =*/264).uint32(message.ephemeralDuration);
            if (message.ephemeralOffToOn != null && Object.hasOwnProperty.call(message, "ephemeralOffToOn"))
                writer.uint32(/* id 34, wireType 0 =*/272).bool(message.ephemeralOffToOn);
            if (message.ephemeralOutOfSync != null && Object.hasOwnProperty.call(message, "ephemeralOutOfSync"))
                writer.uint32(/* id 35, wireType 0 =*/280).bool(message.ephemeralOutOfSync);
            if (message.bizPrivacyStatus != null && Object.hasOwnProperty.call(message, "bizPrivacyStatus"))
                writer.uint32(/* id 36, wireType 0 =*/288).int32(message.bizPrivacyStatus);
            if (message.verifiedBizName != null && Object.hasOwnProperty.call(message, "verifiedBizName"))
                writer.uint32(/* id 37, wireType 2 =*/298).string(message.verifiedBizName);
            if (message.mediaData != null && Object.hasOwnProperty.call(message, "mediaData"))
                $root.proto.MediaData.encode(message.mediaData, writer.uint32(/* id 38, wireType 2 =*/306).fork()).ldelim();
            if (message.photoChange != null && Object.hasOwnProperty.call(message, "photoChange"))
                $root.proto.PhotoChange.encode(message.photoChange, writer.uint32(/* id 39, wireType 2 =*/314).fork()).ldelim();
            if (message.userReceipt != null && message.userReceipt.length)
                for (var i = 0; i < message.userReceipt.length; ++i)
                    $root.proto.UserReceipt.encode(message.userReceipt[i], writer.uint32(/* id 40, wireType 2 =*/322).fork()).ldelim();
            if (message.reactions != null && message.reactions.length)
                for (var i = 0; i < message.reactions.length; ++i)
                    $root.proto.Reaction.encode(message.reactions[i], writer.uint32(/* id 41, wireType 2 =*/330).fork()).ldelim();
            if (message.quotedStickerData != null && Object.hasOwnProperty.call(message, "quotedStickerData"))
                $root.proto.MediaData.encode(message.quotedStickerData, writer.uint32(/* id 42, wireType 2 =*/338).fork()).ldelim();
            if (message.futureproofData != null && Object.hasOwnProperty.call(message, "futureproofData"))
                writer.uint32(/* id 43, wireType 2 =*/346).bytes(message.futureproofData);
            if (message.statusPsaCampaignId != null && Object.hasOwnProperty.call(message, "statusPsaCampaignId"))
                writer.uint32(/* id 44, wireType 2 =*/354).string(message.statusPsaCampaignId);
            if (message.statusPsaCampaignDuration != null && Object.hasOwnProperty.call(message, "statusPsaCampaignDuration"))
                writer.uint32(/* id 45, wireType 0 =*/360).uint32(message.statusPsaCampaignDuration);
            if (message.statusPsaCampaignReadTimestamp != null && Object.hasOwnProperty.call(message, "statusPsaCampaignReadTimestamp"))
                writer.uint32(/* id 46, wireType 0 =*/368).uint64(message.statusPsaCampaignReadTimestamp);
            return writer;
        };

        /**
         * Encodes the specified WebMessageInfo message, length delimited. Does not implicitly {@link proto.WebMessageInfo.verify|verify} messages.
         * @function encodeDelimited
         * @memberof proto.WebMessageInfo
         * @static
         * @param {proto.IWebMessageInfo} message WebMessageInfo message or plain object to encode
         * @param {$protobuf.Writer} [writer] Writer to encode to
         * @returns {$protobuf.Writer} Writer
         */
        WebMessageInfo.encodeDelimited = function encodeDelimited(message, writer) {
            return this.encode(message, writer).ldelim();
        };

        /**
         * Decodes a WebMessageInfo message from the specified reader or buffer.
         * @function decode
         * @memberof proto.WebMessageInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @param {number} [length] Message length if known beforehand
         * @returns {proto.WebMessageInfo} WebMessageInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        WebMessageInfo.decode = function decode(reader, length) {
            if (!(reader instanceof $Reader))
                reader = $Reader.create(reader);
            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.proto.WebMessageInfo();
            while (reader.pos < end) {
                var tag = reader.uint32();
                switch (tag >>> 3) {
                case 1:
                    message.key = $root.proto.MessageKey.decode(reader, reader.uint32());
                    break;
                case 2:
                    message.message = $root.proto.Message.decode(reader, reader.uint32());
                    break;
                case 3:
                    message.messageTimestamp = reader.uint64();
                    break;
                case 4:
                    message.status = reader.int32();
                    break;
                case 5:
                    message.participant = reader.string();
                    break;
                case 6:
                    message.messageC2STimestamp = reader.uint64();
                    break;
                case 16:
                    message.ignore = reader.bool();
                    break;
                case 17:
                    message.starred = reader.bool();
                    break;
                case 18:
                    message.broadcast = reader.bool();
                    break;
                case 19:
                    message.pushName = reader.string();
                    break;
                case 20:
                    message.mediaCiphertextSha256 = reader.bytes();
                    break;
                case 21:
                    message.multicast = reader.bool();
                    break;
                case 22:
                    message.urlText = reader.bool();
                    break;
                case 23:
                    message.urlNumber = reader.bool();
                    break;
                case 24:
                    message.messageStubType = reader.int32();
                    break;
                case 25:
                    message.clearMedia = reader.bool();
                    break;
                case 26:
                    if (!(message.messageStubParameters && message.messageStubParameters.length))
                        message.messageStubParameters = [];
                    message.messageStubParameters.push(reader.string());
                    break;
                case 27:
                    message.duration = reader.uint32();
                    break;
                case 28:
                    if (!(message.labels && message.labels.length))
                        message.labels = [];
                    message.labels.push(reader.string());
                    break;
                case 29:
                    message.paymentInfo = $root.proto.PaymentInfo.decode(reader, reader.uint32());
                    break;
                case 30:
                    message.finalLiveLocation = $root.proto.LiveLocationMessage.decode(reader, reader.uint32());
                    break;
                case 31:
                    message.quotedPaymentInfo = $root.proto.PaymentInfo.decode(reader, reader.uint32());
                    break;
                case 32:
                    message.ephemeralStartTimestamp = reader.uint64();
                    break;
                case 33:
                    message.ephemeralDuration = reader.uint32();
                    break;
                case 34:
                    message.ephemeralOffToOn = reader.bool();
                    break;
                case 35:
                    message.ephemeralOutOfSync = reader.bool();
                    break;
                case 36:
                    message.bizPrivacyStatus = reader.int32();
                    break;
                case 37:
                    message.verifiedBizName = reader.string();
                    break;
                case 38:
                    message.mediaData = $root.proto.MediaData.decode(reader, reader.uint32());
                    break;
                case 39:
                    message.photoChange = $root.proto.PhotoChange.decode(reader, reader.uint32());
                    break;
                case 40:
                    if (!(message.userReceipt && message.userReceipt.length))
                        message.userReceipt = [];
                    message.userReceipt.push($root.proto.UserReceipt.decode(reader, reader.uint32()));
                    break;
                case 41:
                    if (!(message.reactions && message.reactions.length))
                        message.reactions = [];
                    message.reactions.push($root.proto.Reaction.decode(reader, reader.uint32()));
                    break;
                case 42:
                    message.quotedStickerData = $root.proto.MediaData.decode(reader, reader.uint32());
                    break;
                case 43:
                    message.futureproofData = reader.bytes();
                    break;
                case 44:
                    message.statusPsaCampaignId = reader.string();
                    break;
                case 45:
                    message.statusPsaCampaignDuration = reader.uint32();
                    break;
                case 46:
                    message.statusPsaCampaignReadTimestamp = reader.uint64();
                    break;
                default:
                    reader.skipType(tag & 7);
                    break;
                }
            }
            if (!message.hasOwnProperty("key"))
                throw $util.ProtocolError("missing required 'key'", { instance: message });
            return message;
        };

        /**
         * Decodes a WebMessageInfo message from the specified reader or buffer, length delimited.
         * @function decodeDelimited
         * @memberof proto.WebMessageInfo
         * @static
         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
         * @returns {proto.WebMessageInfo} WebMessageInfo
         * @throws {Error} If the payload is not a reader or valid buffer
         * @throws {$protobuf.util.ProtocolError} If required fields are missing
         */
        WebMessageInfo.decodeDelimited = function decodeDelimited(reader) {
            if (!(reader instanceof $Reader))
                reader = new $Reader(reader);
            return this.decode(reader, reader.uint32());
        };

        /**
         * Verifies a WebMessageInfo message.
         * @function verify
         * @memberof proto.WebMessageInfo
         * @static
         * @param {Object.<string,*>} message Plain object to verify
         * @returns {string|null} `null` if valid, otherwise the reason why it is not
         */
        WebMessageInfo.verify = function verify(message) {
            if (typeof message !== "object" || message === null)
                return "object expected";
            {
                var error = $root.proto.MessageKey.verify(message.key);
                if (error)
                    return "key." + error;
            }
            if (message.message != null && message.hasOwnProperty("message")) {
                var error = $root.proto.Message.verify(message.message);
                if (error)
                    return "message." + error;
            }
            if (message.messageTimestamp != null && message.hasOwnProperty("messageTimestamp"))
                if (!$util.isInteger(message.messageTimestamp) && !(message.messageTimestamp && $util.isInteger(message.messageTimestamp.low) && $util.isInteger(message.messageTimestamp.high)))
                    return "messageTimestamp: integer|Long expected";
            if (message.status != null && message.hasOwnProperty("status"))
                switch (message.status) {
                default:
                    return "status: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                    break;
                }
            if (message.participant != null && message.hasOwnProperty("participant"))
                if (!$util.isString(message.participant))
                    return "participant: string expected";
            if (message.messageC2STimestamp != null && message.hasOwnProperty("messageC2STimestamp"))
                if (!$util.isInteger(message.messageC2STimestamp) && !(message.messageC2STimestamp && $util.isInteger(message.messageC2STimestamp.low) && $util.isInteger(message.messageC2STimestamp.high)))
                    return "messageC2STimestamp: integer|Long expected";
            if (message.ignore != null && message.hasOwnProperty("ignore"))
                if (typeof message.ignore !== "boolean")
                    return "ignore: boolean expected";
            if (message.starred != null && message.hasOwnProperty("starred"))
                if (typeof message.starred !== "boolean")
                    return "starred: boolean expected";
            if (message.broadcast != null && message.hasOwnProperty("broadcast"))
                if (typeof message.broadcast !== "boolean")
                    return "broadcast: boolean expected";
            if (message.pushName != null && message.hasOwnProperty("pushName"))
                if (!$util.isString(message.pushName))
                    return "pushName: string expected";
            if (message.mediaCiphertextSha256 != null && message.hasOwnProperty("mediaCiphertextSha256"))
                if (!(message.mediaCiphertextSha256 && typeof message.mediaCiphertextSha256.length === "number" || $util.isString(message.mediaCiphertextSha256)))
                    return "mediaCiphertextSha256: buffer expected";
            if (message.multicast != null && message.hasOwnProperty("multicast"))
                if (typeof message.multicast !== "boolean")
                    return "multicast: boolean expected";
            if (message.urlText != null && message.hasOwnProperty("urlText"))
                if (typeof message.urlText !== "boolean")
                    return "urlText: boolean expected";
            if (message.urlNumber != null && message.hasOwnProperty("urlNumber"))
                if (typeof message.urlNumber !== "boolean")
                    return "urlNumber: boolean expected";
            if (message.messageStubType != null && message.hasOwnProperty("messageStubType"))
                switch (message.messageStubType) {
                default:
                    return "messageStubType: enum value expected";
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                case 8:
                case 9:
                case 10:
                case 11:
                case 12:
                case 13:
                case 14:
                case 15:
                case 16:
                case 17:
                case 18:
                case 19:
                case 20:
                case 21:
                case 22:
                case 23:
                case 24:
                case 25:
                case 26:
                case 27:
                case 28:
                case 29:
                case 30:
                case 31:
                case 32:
                case 33:
                case 34:
                case 35:
                case 36:
                case 37:
                case 38:
                case 39:
                case 40:
                case 41:
                case 42:
                case 43:
                case 44:
                case 45:
                case 46:
                case 47:
                case 48:
                case 49:
                case 50:
                case 51:
                case 52:
                case 53:
                case 54:
                case 55:
                case 56:
                case 57:
                case 58:
                case 59:
                case 60:
                case 61:
                case 62:
                case 63:
                case 64:
                case 65:
                case 66:
                case 67:
                case 68:
                case 69:
                case 70:
                case 71:
                case 72:
                case 73:
                case 74:
                case 75:
                case 76:
                case 77:
                case 78:
                case 79:
                case 80:
                case 81:
                case 82:
                case 83:
                case 84:
                case 85:
                case 86:
                case 87:
                case 88:
                case 89:
                case 90:
                case 91:
                case 92:
                case 93:
                case 94:
                case 95:
                case 96:
                case 97:
                case 98:
                case 99:
                case 100:
                case 101:
                case 102:
                case 103:
                case 104:
                case 105:
                case 106:
                case 107:
                case 108:
                case 109:
                case 110:
                case 111:
                case 112:
                case 113:
                case 114:
                case 115:
                case 116:
                case 117:
                case 118:
                case 119:
                case 120:
                case 121:
                case 122:
                case 123:
                case 124:
                case 125:
                case 126:
                case 127:
                case 128:
                case 129:
                case 130:
                case 131:
                    break;
                }
            if (message.clearMedia != null && message.hasOwnProperty("clearMedia"))
                if (typeof message.clearMedia !== "boolean")
                    return "clearMedia: boolean expected";
            if (message.messageStubParameters != null && message.hasOwnProperty("messageStubParameters")) {
                if (!Array.isArray(message.messageStubParameters))
                    return "messageStubParameters: array expected";
                for (var i = 0; i < message.messageStubParameters.length; ++i)
                    if (!$util.isString(message.messageStubParameters[i]))
                        return "messageStubParameters: string[] expected";
            }
            if (message.duration != null && message.hasOwnProperty("duration"))
                if (!$util.isInteger(message.duration))
                    return "duration: integer expected";
            if (message.labels != null && message.hasOwnProperty("labels")) {
                if (!Array.isArray(message.labels))
                    return "labels: array expected";
                for (var i = 0; i < message.labels.length; ++i)
                    if (!$util.isString(message.labels[i]))
                        return "labels: string[] expected";
            }
            if (message.paymentInfo != null && message.hasOwnProperty("paymentInfo")) {
                var error = $root.proto.PaymentInfo.verify(message.paymentInfo);
                if (error)
                    return "paymentInfo." + error;
            }
            if (message.finalLiveLocation != null && message.hasOwnProperty("finalLiveLocation")) {
                var error = $root.proto.LiveLocationMessage.verify(message.finalLiveLocation);
                if (error)
                    return "finalLiveLocation." + error;
            }
            if (message.quotedPaymentInfo != null && message.hasOwnProperty("quotedPaymentInfo")) {
                var error = $root.proto.PaymentInfo.verify(message.quotedPaymentInfo);
                if (error)
                    return "quotedPaymentInfo." + error;
            }
            if (message.ephemeralStartTimestamp != null && message.hasOwnProperty("ephemeralStartTimestamp"))
                if (!$util.isInteger(message.ephemeralStartTimestamp) && !(message.ephemeralStartTimestamp && $util.isInteger(message.ephemeralStartTimestamp.low) && $util.isInteger(message.ephemeralStartTimestamp.high)))
                    return "ephemeralStartTimestamp: integer|Long expected";
            if (message.ephemeralDuration != null && message.hasOwnProperty("ephemeralDuration"))
                if (!$util.isInteger(message.ephemeralDuration))
                    return "ephemeralDuration: integer expected";
            if (message.ephemeralOffToOn != null && message.hasOwnProperty("ephemeralOffToOn"))
                if (typeof message.ephemeralOffToOn !== "boolean")
                    return "ephemeralOffToOn: boolean expected";
            if (message.ephemeralOutOfSync != null && message.hasOwnProperty("ephemeralOutOfSync"))
                if (typeof message.ephemeralOutOfSync !== "boolean")
                    return "ephemeralOutOfSync: boolean expected";
            if (message.bizPrivacyStatus != null && message.hasOwnProperty("bizPrivacyStatus"))
                switch (message.bizPrivacyStatus) {
                default:
                    return "bizPrivacyStatus: enum value expected";
                case 0:
                case 2:
                case 1:
                case 3:
                    break;
                }
            if (message.verifiedBizName != null && message.hasOwnProperty("verifiedBizName"))
                if (!$util.isString(message.verifiedBizName))
                    return "verifiedBizName: string expected";
            if (message.mediaData != null && message.hasOwnProperty("mediaData")) {
                var error = $root.proto.MediaData.verify(message.mediaData);
                if (error)
                    return "mediaData." + error;
            }
            if (message.photoChange != null && message.hasOwnProperty("photoChange")) {
                var error = $root.proto.PhotoChange.verify(message.photoChange);
                if (error)
                    return "photoChange." + error;
            }
            if (message.userReceipt != null && message.hasOwnProperty("userReceipt")) {
                if (!Array.isArray(message.userReceipt))
                    return "userReceipt: array expected";
                for (var i = 0; i < message.userReceipt.length; ++i) {
                    var error = $root.proto.UserReceipt.verify(message.userReceipt[i]);
                    if (error)
                        return "userReceipt." + error;
                }
            }
            if (message.reactions != null && message.hasOwnProperty("reactions")) {
                if (!Array.isArray(message.reactions))
                    return "reactions: array expected";
                for (var i = 0; i < message.reactions.length; ++i) {
                    var error = $root.proto.Reaction.verify(message.reactions[i]);
                    if (error)
                        return "reactions." + error;
                }
            }
            if (message.quotedStickerData != null && message.hasOwnProperty("quotedStickerData")) {
                var error = $root.proto.MediaData.verify(message.quotedStickerData);
                if (error)
                    return "quotedStickerData." + error;
            }
            if (message.futureproofData != null && message.hasOwnProperty("futureproofData"))
                if (!(message.futureproofData && typeof message.futureproofData.length === "number" || $util.isString(message.futureproofData)))
                    return "futureproofData: buffer expected";
            if (message.statusPsaCampaignId != null && message.hasOwnProperty("statusPsaCampaignId"))
                if (!$util.isString(message.statusPsaCampaignId))
                    return "statusPsaCampaignId: string expected";
            if (message.statusPsaCampaignDuration != null && message.hasOwnProperty("statusPsaCampaignDuration"))
                if (!$util.isInteger(message.statusPsaCampaignDuration))
                    return "statusPsaCampaignDuration: integer expected";
            if (message.statusPsaCampaignReadTimestamp != null && message.hasOwnProperty("statusPsaCampaignReadTimestamp"))
                if (!$util.isInteger(message.statusPsaCampaignReadTimestamp) && !(message.statusPsaCampaignReadTimestamp && $util.isInteger(message.statusPsaCampaignReadTimestamp.low) && $util.isInteger(message.statusPsaCampaignReadTimestamp.high)))
                    return "statusPsaCampaignReadTimestamp: integer|Long expected";
            return null;
        };

        /**
         * Creates a WebMessageInfo message from a plain object. Also converts values to their respective internal types.
         * @function fromObject
         * @memberof proto.WebMessageInfo
         * @static
         * @param {Object.<string,*>} object Plain object
         * @returns {proto.WebMessageInfo} WebMessageInfo
         */
        WebMessageInfo.fromObject = function fromObject(object) {
            if (object instanceof $root.proto.WebMessageInfo)
                return object;
            var message = new $root.proto.WebMessageInfo();
            if (object.key != null) {
                if (typeof object.key !== "object")
                    throw TypeError(".proto.WebMessageInfo.key: object expected");
                message.key = $root.proto.MessageKey.fromObject(object.key);
            }
            if (object.message != null) {
                if (typeof object.message !== "object")
                    throw TypeError(".proto.WebMessageInfo.message: object expected");
                message.message = $root.proto.Message.fromObject(object.message);
            }
            if (object.messageTimestamp != null)
                if ($util.Long)
                    (message.messageTimestamp = $util.Long.fromValue(object.messageTimestamp)).unsigned = true;
                else if (typeof object.messageTimestamp === "string")
                    message.messageTimestamp = parseInt(object.messageTimestamp, 10);
                else if (typeof object.messageTimestamp === "number")
                    message.messageTimestamp = object.messageTimestamp;
                else if (typeof object.messageTimestamp === "object")
                    message.messageTimestamp = new $util.LongBits(object.messageTimestamp.low >>> 0, object.messageTimestamp.high >>> 0).toNumber(true);
            switch (object.status) {
            case "ERROR":
            case 0:
                message.status = 0;
                break;
            case "PENDING":
            case 1:
                message.status = 1;
                break;
            case "SERVER_ACK":
            case 2:
                message.status = 2;
                break;
            case "DELIVERY_ACK":
            case 3:
                message.status = 3;
                break;
            case "READ":
            case 4:
                message.status = 4;
                break;
            case "PLAYED":
            case 5:
                message.status = 5;
                break;
            }
            if (object.participant != null)
                message.participant = String(object.participant);
            if (object.messageC2STimestamp != null)
                if ($util.Long)
                    (message.messageC2STimestamp = $util.Long.fromValue(object.messageC2STimestamp)).unsigned = true;
                else if (typeof object.messageC2STimestamp === "string")
                    message.messageC2STimestamp = parseInt(object.messageC2STimestamp, 10);
                else if (typeof object.messageC2STimestamp === "number")
                    message.messageC2STimestamp = object.messageC2STimestamp;
                else if (typeof object.messageC2STimestamp === "object")
                    message.messageC2STimestamp = new $util.LongBits(object.messageC2STimestamp.low >>> 0, object.messageC2STimestamp.high >>> 0).toNumber(true);
            if (object.ignore != null)
                message.ignore = Boolean(object.ignore);
            if (object.starred != null)
                message.starred = Boolean(object.starred);
            if (object.broadcast != null)
                message.broadcast = Boolean(object.broadcast);
            if (object.pushName != null)
                message.pushName = String(object.pushName);
            if (object.mediaCiphertextSha256 != null)
                if (typeof object.mediaCiphertextSha256 === "string")
                    $util.base64.decode(object.mediaCiphertextSha256, message.mediaCiphertextSha256 = $util.newBuffer($util.base64.length(object.mediaCiphertextSha256)), 0);
                else if (object.mediaCiphertextSha256.length)
                    message.mediaCiphertextSha256 = object.mediaCiphertextSha256;
            if (object.multicast != null)
                message.multicast = Boolean(object.multicast);
            if (object.urlText != null)
                message.urlText = Boolean(object.urlText);
            if (object.urlNumber != null)
                message.urlNumber = Boolean(object.urlNumber);
            switch (object.messageStubType) {
            case "UNKNOWN":
            case 0:
                message.messageStubType = 0;
                break;
            case "REVOKE":
            case 1:
                message.messageStubType = 1;
                break;
            case "CIPHERTEXT":
            case 2:
                message.messageStubType = 2;
                break;
            case "FUTUREPROOF":
            case 3:
                message.messageStubType = 3;
                break;
            case "NON_VERIFIED_TRANSITION":
            case 4:
                message.messageStubType = 4;
                break;
            case "UNVERIFIED_TRANSITION":
            case 5:
                message.messageStubType = 5;
                break;
            case "VERIFIED_TRANSITION":
            case 6:
                message.messageStubType = 6;
                break;
            case "VERIFIED_LOW_UNKNOWN":
            case 7:
                message.messageStubType = 7;
                break;
            case "VERIFIED_HIGH":
            case 8:
                message.messageStubType = 8;
                break;
            case "VERIFIED_INITIAL_UNKNOWN":
            case 9:
                message.messageStubType = 9;
                break;
            case "VERIFIED_INITIAL_LOW":
            case 10:
                message.messageStubType = 10;
                break;
            case "VERIFIED_INITIAL_HIGH":
            case 11:
                message.messageStubType = 11;
                break;
            case "VERIFIED_TRANSITION_ANY_TO_NONE":
            case 12:
                message.messageStubType = 12;
                break;
            case "VERIFIED_TRANSITION_ANY_TO_HIGH":
            case 13:
                message.messageStubType = 13;
                break;
            case "VERIFIED_TRANSITION_HIGH_TO_LOW":
            case 14:
                message.messageStubType = 14;
                break;
            case "VERIFIED_TRANSITION_HIGH_TO_UNKNOWN":
            case 15:
                message.messageStubType = 15;
                break;
            case "VERIFIED_TRANSITION_UNKNOWN_TO_LOW":
            case 16:
                message.messageStubType = 16;
                break;
            case "VERIFIED_TRANSITION_LOW_TO_UNKNOWN":
            case 17:
                message.messageStubType = 17;
                break;
            case "VERIFIED_TRANSITION_NONE_TO_LOW":
            case 18:
                message.messageStubType = 18;
                break;
            case "VERIFIED_TRANSITION_NONE_TO_UNKNOWN":
            case 19:
                message.messageStubType = 19;
                break;
            case "GROUP_CREATE":
            case 20:
                message.messageStubType = 20;
                break;
            case "GROUP_CHANGE_SUBJECT":
            case 21:
                message.messageStubType = 21;
                break;
            case "GROUP_CHANGE_ICON":
            case 22:
                message.messageStubType = 22;
                break;
            case "GROUP_CHANGE_INVITE_LINK":
            case 23:
                message.messageStubType = 23;
                break;
            case "GROUP_CHANGE_DESCRIPTION":
            case 24:
                message.messageStubType = 24;
                break;
            case "GROUP_CHANGE_RESTRICT":
            case 25:
                message.messageStubType = 25;
                break;
            case "GROUP_CHANGE_ANNOUNCE":
            case 26:
                message.messageStubType = 26;
                break;
            case "GROUP_PARTICIPANT_ADD":
            case 27:
                message.messageStubType = 27;
                break;
            case "GROUP_PARTICIPANT_REMOVE":
            case 28:
                message.messageStubType = 28;
                break;
            case "GROUP_PARTICIPANT_PROMOTE":
            case 29:
                message.messageStubType = 29;
                break;
            case "GROUP_PARTICIPANT_DEMOTE":
            case 30:
                message.messageStubType = 30;
                break;
            case "GROUP_PARTICIPANT_INVITE":
            case 31:
                message.messageStubType = 31;
                break;
            case "GROUP_PARTICIPANT_LEAVE":
            case 32:
                message.messageStubType = 32;
                break;
            case "GROUP_PARTICIPANT_CHANGE_NUMBER":
            case 33:
                message.messageStubType = 33;
                break;
            case "BROADCAST_CREATE":
            case 34:
                message.messageStubType = 34;
                break;
            case "BROADCAST_ADD":
            case 35:
                message.messageStubType = 35;
                break;
            case "BROADCAST_REMOVE":
            case 36:
                message.messageStubType = 36;
                break;
            case "GENERIC_NOTIFICATION":
            case 37:
                message.messageStubType = 37;
                break;
            case "E2E_IDENTITY_CHANGED":
            case 38:
                message.messageStubType = 38;
                break;
            case "E2E_ENCRYPTED":
            case 39:
                message.messageStubType = 39;
                break;
            case "CALL_MISSED_VOICE":
            case 40:
                message.messageStubType = 40;
                break;
            case "CALL_MISSED_VIDEO":
            case 41:
                message.messageStubType = 41;
                break;
            case "INDIVIDUAL_CHANGE_NUMBER":
            case 42:
                message.messageStubType = 42;
                break;
            case "GROUP_DELETE":
            case 43:
                message.messageStubType = 43;
                break;
            case "GROUP_ANNOUNCE_MODE_MESSAGE_BOUNCE":
            case 44:
                message.messageStubType = 44;
                break;
            case "CALL_MISSED_GROUP_VOICE":
            case 45:
                message.messageStubType = 45;
                break;
            case "CALL_MISSED_GROUP_VIDEO":
            case 46:
                message.messageStubType = 46;
                break;
            case "PAYMENT_CIPHERTEXT":
            case 47:
                message.messageStubType = 47;
                break;
            case "PAYMENT_FUTUREPROOF":
            case 48:
                message.messageStubType = 48;
                break;
            case "PAYMENT_TRANSACTION_STATUS_UPDATE_FAILED":
            case 49:
                message.messageStubType = 49;
                break;
            case "PAYMENT_TRANSACTION_STATUS_UPDATE_REFUNDED":
            case 50:
                message.messageStubType = 50;
                break;
            case "PAYMENT_TRANSACTION_STATUS_UPDATE_REFUND_FAILED":
            case 51:
                message.messageStubType = 51;
                break;
            case "PAYMENT_TRANSACTION_STATUS_RECEIVER_PENDING_SETUP":
            case 52:
                message.messageStubType = 52;
                break;
            case "PAYMENT_TRANSACTION_STATUS_RECEIVER_SUCCESS_AFTER_HICCUP":
            case 53:
                message.messageStubType = 53;
                break;
            case "PAYMENT_ACTION_ACCOUNT_SETUP_REMINDER":
            case 54:
                message.messageStubType = 54;
                break;
            case "PAYMENT_ACTION_SEND_PAYMENT_REMINDER":
            case 55:
                message.messageStubType = 55;
                break;
            case "PAYMENT_ACTION_SEND_PAYMENT_INVITATION":
            case 56:
                message.messageStubType = 56;
                break;
            case "PAYMENT_ACTION_REQUEST_DECLINED":
            case 57:
                message.messageStubType = 57;
                break;
            case "PAYMENT_ACTION_REQUEST_EXPIRED":
            case 58:
                message.messageStubType = 58;
                break;
            case "PAYMENT_ACTION_REQUEST_CANCELLED":
            case 59:
                message.messageStubType = 59;
                break;
            case "BIZ_VERIFIED_TRANSITION_TOP_TO_BOTTOM":
            case 60:
                message.messageStubType = 60;
                break;
            case "BIZ_VERIFIED_TRANSITION_BOTTOM_TO_TOP":
            case 61:
                message.messageStubType = 61;
                break;
            case "BIZ_INTRO_TOP":
            case 62:
                message.messageStubType = 62;
                break;
            case "BIZ_INTRO_BOTTOM":
            case 63:
                message.messageStubType = 63;
                break;
            case "BIZ_NAME_CHANGE":
            case 64:
                message.messageStubType = 64;
                break;
            case "BIZ_MOVE_TO_CONSUMER_APP":
            case 65:
                message.messageStubType = 65;
                break;
            case "BIZ_TWO_TIER_MIGRATION_TOP":
            case 66:
                message.messageStubType = 66;
                break;
            case "BIZ_TWO_TIER_MIGRATION_BOTTOM":
            case 67:
                message.messageStubType = 67;
                break;
            case "OVERSIZED":
            case 68:
                message.messageStubType = 68;
                break;
            case "GROUP_CHANGE_NO_FREQUENTLY_FORWARDED":
            case 69:
                message.messageStubType = 69;
                break;
            case "GROUP_V4_ADD_INVITE_SENT":
            case 70:
                message.messageStubType = 70;
                break;
            case "GROUP_PARTICIPANT_ADD_REQUEST_JOIN":
            case 71:
                message.messageStubType = 71;
                break;
            case "CHANGE_EPHEMERAL_SETTING":
            case 72:
                message.messageStubType = 72;
                break;
            case "E2E_DEVICE_CHANGED":
            case 73:
                message.messageStubType = 73;
                break;
            case "VIEWED_ONCE":
            case 74:
                message.messageStubType = 74;
                break;
            case "E2E_ENCRYPTED_NOW":
            case 75:
                message.messageStubType = 75;
                break;
            case "BLUE_MSG_BSP_FB_TO_BSP_PREMISE":
            case 76:
                message.messageStubType = 76;
                break;
            case "BLUE_MSG_BSP_FB_TO_SELF_FB":
            case 77:
                message.messageStubType = 77;
                break;
            case "BLUE_MSG_BSP_FB_TO_SELF_PREMISE":
            case 78:
                message.messageStubType = 78;
                break;
            case "BLUE_MSG_BSP_FB_UNVERIFIED":
            case 79:
                message.messageStubType = 79;
                break;
            case "BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED":
            case 80:
                message.messageStubType = 80;
                break;
            case "BLUE_MSG_BSP_FB_VERIFIED":
            case 81:
                message.messageStubType = 81;
                break;
            case "BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED":
            case 82:
                message.messageStubType = 82;
                break;
            case "BLUE_MSG_BSP_PREMISE_TO_SELF_PREMISE":
            case 83:
                message.messageStubType = 83;
                break;
            case "BLUE_MSG_BSP_PREMISE_UNVERIFIED":
            case 84:
                message.messageStubType = 84;
                break;
            case "BLUE_MSG_BSP_PREMISE_UNVERIFIED_TO_SELF_PREMISE_VERIFIED":
            case 85:
                message.messageStubType = 85;
                break;
            case "BLUE_MSG_BSP_PREMISE_VERIFIED":
            case 86:
                message.messageStubType = 86;
                break;
            case "BLUE_MSG_BSP_PREMISE_VERIFIED_TO_SELF_PREMISE_UNVERIFIED":
            case 87:
                message.messageStubType = 87;
                break;
            case "BLUE_MSG_CONSUMER_TO_BSP_FB_UNVERIFIED":
            case 88:
                message.messageStubType = 88;
                break;
            case "BLUE_MSG_CONSUMER_TO_BSP_PREMISE_UNVERIFIED":
            case 89:
                message.messageStubType = 89;
                break;
            case "BLUE_MSG_CONSUMER_TO_SELF_FB_UNVERIFIED":
            case 90:
                message.messageStubType = 90;
                break;
            case "BLUE_MSG_CONSUMER_TO_SELF_PREMISE_UNVERIFIED":
            case 91:
                message.messageStubType = 91;
                break;
            case "BLUE_MSG_SELF_FB_TO_BSP_PREMISE":
            case 92:
                message.messageStubType = 92;
                break;
            case "BLUE_MSG_SELF_FB_TO_SELF_PREMISE":
            case 93:
                message.messageStubType = 93;
                break;
            case "BLUE_MSG_SELF_FB_UNVERIFIED":
            case 94:
                message.messageStubType = 94;
                break;
            case "BLUE_MSG_SELF_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED":
            case 95:
                message.messageStubType = 95;
                break;
            case "BLUE_MSG_SELF_FB_VERIFIED":
            case 96:
                message.messageStubType = 96;
                break;
            case "BLUE_MSG_SELF_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED":
            case 97:
                message.messageStubType = 97;
                break;
            case "BLUE_MSG_SELF_PREMISE_TO_BSP_PREMISE":
            case 98:
                message.messageStubType = 98;
                break;
            case "BLUE_MSG_SELF_PREMISE_UNVERIFIED":
            case 99:
                message.messageStubType = 99;
                break;
            case "BLUE_MSG_SELF_PREMISE_VERIFIED":
            case 100:
                message.messageStubType = 100;
                break;
            case "BLUE_MSG_TO_BSP_FB":
            case 101:
                message.messageStubType = 101;
                break;
            case "BLUE_MSG_TO_CONSUMER":
            case 102:
                message.messageStubType = 102;
                break;
            case "BLUE_MSG_TO_SELF_FB":
            case 103:
                message.messageStubType = 103;
                break;
            case "BLUE_MSG_UNVERIFIED_TO_BSP_FB_VERIFIED":
            case 104:
                message.messageStubType = 104;
                break;
            case "BLUE_MSG_UNVERIFIED_TO_BSP_PREMISE_VERIFIED":
            case 105:
                message.messageStubType = 105;
                break;
            case "BLUE_MSG_UNVERIFIED_TO_SELF_FB_VERIFIED":
            case 106:
                message.messageStubType = 106;
                break;
            case "BLUE_MSG_UNVERIFIED_TO_VERIFIED":
            case 107:
                message.messageStubType = 107;
                break;
            case "BLUE_MSG_VERIFIED_TO_BSP_FB_UNVERIFIED":
            case 108:
                message.messageStubType = 108;
                break;
            case "BLUE_MSG_VERIFIED_TO_BSP_PREMISE_UNVERIFIED":
            case 109:
                message.messageStubType = 109;
                break;
            case "BLUE_MSG_VERIFIED_TO_SELF_FB_UNVERIFIED":
            case 110:
                message.messageStubType = 110;
                break;
            case "BLUE_MSG_VERIFIED_TO_UNVERIFIED":
            case 111:
                message.messageStubType = 111;
                break;
            case "BLUE_MSG_BSP_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED":
            case 112:
                message.messageStubType = 112;
                break;
            case "BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_FB_VERIFIED":
            case 113:
                message.messageStubType = 113;
                break;
            case "BLUE_MSG_BSP_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED":
            case 114:
                message.messageStubType = 114;
                break;
            case "BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_FB_UNVERIFIED":
            case 115:
                message.messageStubType = 115;
                break;
            case "BLUE_MSG_SELF_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED":
            case 116:
                message.messageStubType = 116;
                break;
            case "BLUE_MSG_SELF_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED":
            case 117:
                message.messageStubType = 117;
                break;
            case "E2E_IDENTITY_UNAVAILABLE":
            case 118:
                message.messageStubType = 118;
                break;
            case "GROUP_CREATING":
            case 119:
                message.messageStubType = 119;
                break;
            case "GROUP_CREATE_FAILED":
            case 120:
                message.messageStubType = 120;
                break;
            case "GROUP_BOUNCED":
            case 121:
                message.messageStubType = 121;
                break;
            case "BLOCK_CONTACT":
            case 122:
                message.messageStubType = 122;
                break;
            case "EPHEMERAL_SETTING_NOT_APPLIED":
            case 123:
                message.messageStubType = 123;
                break;
            case "SYNC_FAILED":
            case 124:
                message.messageStubType = 124;
                break;
            case "SYNCING":
            case 125:
                message.messageStubType = 125;
                break;
            case "BIZ_PRIVACY_MODE_INIT_FB":
            case 126:
                message.messageStubType = 126;
                break;
            case "BIZ_PRIVACY_MODE_INIT_BSP":
            case 127:
                message.messageStubType = 127;
                break;
            case "BIZ_PRIVACY_MODE_TO_FB":
            case 128:
                message.messageStubType = 128;
                break;
            case "BIZ_PRIVACY_MODE_TO_BSP":
            case 129:
                message.messageStubType = 129;
                break;
            case "DISAPPEARING_MODE":
            case 130:
                message.messageStubType = 130;
                break;
            case "E2E_DEVICE_FETCH_FAILED":
            case 131:
                message.messageStubType = 131;
                break;
            }
            if (object.clearMedia != null)
                message.clearMedia = Boolean(object.clearMedia);
            if (object.messageStubParameters) {
                if (!Array.isArray(object.messageStubParameters))
                    throw TypeError(".proto.WebMessageInfo.messageStubParameters: array expected");
                message.messageStubParameters = [];
                for (var i = 0; i < object.messageStubParameters.length; ++i)
                    message.messageStubParameters[i] = String(object.messageStubParameters[i]);
            }
            if (object.duration != null)
                message.duration = object.duration >>> 0;
            if (object.labels) {
                if (!Array.isArray(object.labels))
                    throw TypeError(".proto.WebMessageInfo.labels: array expected");
                message.labels = [];
                for (var i = 0; i < object.labels.length; ++i)
                    message.labels[i] = String(object.labels[i]);
            }
            if (object.paymentInfo != null) {
                if (typeof object.paymentInfo !== "object")
                    throw TypeError(".proto.WebMessageInfo.paymentInfo: object expected");
                message.paymentInfo = $root.proto.PaymentInfo.fromObject(object.paymentInfo);
            }
            if (object.finalLiveLocation != null) {
                if (typeof object.finalLiveLocation !== "object")
                    throw TypeError(".proto.WebMessageInfo.finalLiveLocation: object expected");
                message.finalLiveLocation = $root.proto.LiveLocationMessage.fromObject(object.finalLiveLocation);
            }
            if (object.quotedPaymentInfo != null) {
                if (typeof object.quotedPaymentInfo !== "object")
                    throw TypeError(".proto.WebMessageInfo.quotedPaymentInfo: object expected");
                message.quotedPaymentInfo = $root.proto.PaymentInfo.fromObject(object.quotedPaymentInfo);
            }
            if (object.ephemeralStartTimestamp != null)
                if ($util.Long)
                    (message.ephemeralStartTimestamp = $util.Long.fromValue(object.ephemeralStartTimestamp)).unsigned = true;
                else if (typeof object.ephemeralStartTimestamp === "string")
                    message.ephemeralStartTimestamp = parseInt(object.ephemeralStartTimestamp, 10);
                else if (typeof object.ephemeralStartTimestamp === "number")
                    message.ephemeralStartTimestamp = object.ephemeralStartTimestamp;
                else if (typeof object.ephemeralStartTimestamp === "object")
                    message.ephemeralStartTimestamp = new $util.LongBits(object.ephemeralStartTimestamp.low >>> 0, object.ephemeralStartTimestamp.high >>> 0).toNumber(true);
            if (object.ephemeralDuration != null)
                message.ephemeralDuration = object.ephemeralDuration >>> 0;
            if (object.ephemeralOffToOn != null)
                message.ephemeralOffToOn = Boolean(object.ephemeralOffToOn);
            if (object.ephemeralOutOfSync != null)
                message.ephemeralOutOfSync = Boolean(object.ephemeralOutOfSync);
            switch (object.bizPrivacyStatus) {
            case "E2EE":
            case 0:
                message.bizPrivacyStatus = 0;
                break;
            case "FB":
            case 2:
                message.bizPrivacyStatus = 2;
                break;
            case "BSP":
            case 1:
                message.bizPrivacyStatus = 1;
                break;
            case "BSP_AND_FB":
            case 3:
                message.bizPrivacyStatus = 3;
                break;
            }
            if (object.verifiedBizName != null)
                message.verifiedBizName = String(object.verifiedBizName);
            if (object.mediaData != null) {
                if (typeof object.mediaData !== "object")
                    throw TypeError(".proto.WebMessageInfo.mediaData: object expected");
                message.mediaData = $root.proto.MediaData.fromObject(object.mediaData);
            }
            if (object.photoChange != null) {
                if (typeof object.photoChange !== "object")
                    throw TypeError(".proto.WebMessageInfo.photoChange: object expected");
                message.photoChange = $root.proto.PhotoChange.fromObject(object.photoChange);
            }
            if (object.userReceipt) {
                if (!Array.isArray(object.userReceipt))
                    throw TypeError(".proto.WebMessageInfo.userReceipt: array expected");
                message.userReceipt = [];
                for (var i = 0; i < object.userReceipt.length; ++i) {
                    if (typeof object.userReceipt[i] !== "object")
                        throw TypeError(".proto.WebMessageInfo.userReceipt: object expected");
                    message.userReceipt[i] = $root.proto.UserReceipt.fromObject(object.userReceipt[i]);
                }
            }
            if (object.reactions) {
                if (!Array.isArray(object.reactions))
                    throw TypeError(".proto.WebMessageInfo.reactions: array expected");
                message.reactions = [];
                for (var i = 0; i < object.reactions.length; ++i) {
                    if (typeof object.reactions[i] !== "object")
                        throw TypeError(".proto.WebMessageInfo.reactions: object expected");
                    message.reactions[i] = $root.proto.Reaction.fromObject(object.reactions[i]);
                }
            }
            if (object.quotedStickerData != null) {
                if (typeof object.quotedStickerData !== "object")
                    throw TypeError(".proto.WebMessageInfo.quotedStickerData: object expected");
                message.quotedStickerData = $root.proto.MediaData.fromObject(object.quotedStickerData);
            }
            if (object.futureproofData != null)
                if (typeof object.futureproofData === "string")
                    $util.base64.decode(object.futureproofData, message.futureproofData = $util.newBuffer($util.base64.length(object.futureproofData)), 0);
                else if (object.futureproofData.length)
                    message.futureproofData = object.futureproofData;
            if (object.statusPsaCampaignId != null)
                message.statusPsaCampaignId = String(object.statusPsaCampaignId);
            if (object.statusPsaCampaignDuration != null)
                message.statusPsaCampaignDuration = object.statusPsaCampaignDuration >>> 0;
            if (object.statusPsaCampaignReadTimestamp != null)
                if ($util.Long)
                    (message.statusPsaCampaignReadTimestamp = $util.Long.fromValue(object.statusPsaCampaignReadTimestamp)).unsigned = true;
                else if (typeof object.statusPsaCampaignReadTimestamp === "string")
                    message.statusPsaCampaignReadTimestamp = parseInt(object.statusPsaCampaignReadTimestamp, 10);
                else if (typeof object.statusPsaCampaignReadTimestamp === "number")
                    message.statusPsaCampaignReadTimestamp = object.statusPsaCampaignReadTimestamp;
                else if (typeof object.statusPsaCampaignReadTimestamp === "object")
                    message.statusPsaCampaignReadTimestamp = new $util.LongBits(object.statusPsaCampaignReadTimestamp.low >>> 0, object.statusPsaCampaignReadTimestamp.high >>> 0).toNumber(true);
            return message;
        };

        /**
         * Creates a plain object from a WebMessageInfo message. Also converts values to other types if specified.
         * @function toObject
         * @memberof proto.WebMessageInfo
         * @static
         * @param {proto.WebMessageInfo} message WebMessageInfo
         * @param {$protobuf.IConversionOptions} [options] Conversion options
         * @returns {Object.<string,*>} Plain object
         */
        WebMessageInfo.toObject = function toObject(message, options) {
            if (!options)
                options = {};
            var object = {};
            if (options.arrays || options.defaults) {
                object.messageStubParameters = [];
                object.labels = [];
                object.userReceipt = [];
                object.reactions = [];
            }
            if (options.defaults) {
                object.key = null;
                object.message = null;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.messageTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.messageTimestamp = options.longs === String ? "0" : 0;
                object.status = options.enums === String ? "ERROR" : 0;
                object.participant = "";
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.messageC2STimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.messageC2STimestamp = options.longs === String ? "0" : 0;
                object.ignore = false;
                object.starred = false;
                object.broadcast = false;
                object.pushName = "";
                if (options.bytes === String)
                    object.mediaCiphertextSha256 = "";
                else {
                    object.mediaCiphertextSha256 = [];
                    if (options.bytes !== Array)
                        object.mediaCiphertextSha256 = $util.newBuffer(object.mediaCiphertextSha256);
                }
                object.multicast = false;
                object.urlText = false;
                object.urlNumber = false;
                object.messageStubType = options.enums === String ? "UNKNOWN" : 0;
                object.clearMedia = false;
                object.duration = 0;
                object.paymentInfo = null;
                object.finalLiveLocation = null;
                object.quotedPaymentInfo = null;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.ephemeralStartTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.ephemeralStartTimestamp = options.longs === String ? "0" : 0;
                object.ephemeralDuration = 0;
                object.ephemeralOffToOn = false;
                object.ephemeralOutOfSync = false;
                object.bizPrivacyStatus = options.enums === String ? "E2EE" : 0;
                object.verifiedBizName = "";
                object.mediaData = null;
                object.photoChange = null;
                object.quotedStickerData = null;
                if (options.bytes === String)
                    object.futureproofData = "";
                else {
                    object.futureproofData = [];
                    if (options.bytes !== Array)
                        object.futureproofData = $util.newBuffer(object.futureproofData);
                }
                object.statusPsaCampaignId = "";
                object.statusPsaCampaignDuration = 0;
                if ($util.Long) {
                    var long = new $util.Long(0, 0, true);
                    object.statusPsaCampaignReadTimestamp = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
                } else
                    object.statusPsaCampaignReadTimestamp = options.longs === String ? "0" : 0;
            }
            if (message.key != null && message.hasOwnProperty("key"))
                object.key = $root.proto.MessageKey.toObject(message.key, options);
            if (message.message != null && message.hasOwnProperty("message"))
                object.message = $root.proto.Message.toObject(message.message, options);
            if (message.messageTimestamp != null && message.hasOwnProperty("messageTimestamp"))
                if (typeof message.messageTimestamp === "number")
                    object.messageTimestamp = options.longs === String ? String(message.messageTimestamp) : message.messageTimestamp;
                else
                    object.messageTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.messageTimestamp) : options.longs === Number ? new $util.LongBits(message.messageTimestamp.low >>> 0, message.messageTimestamp.high >>> 0).toNumber(true) : message.messageTimestamp;
            if (message.status != null && message.hasOwnProperty("status"))
                object.status = options.enums === String ? $root.proto.WebMessageInfo.WebMessageInfoStatus[message.status] : message.status;
            if (message.participant != null && message.hasOwnProperty("participant"))
                object.participant = message.participant;
            if (message.messageC2STimestamp != null && message.hasOwnProperty("messageC2STimestamp"))
                if (typeof message.messageC2STimestamp === "number")
                    object.messageC2STimestamp = options.longs === String ? String(message.messageC2STimestamp) : message.messageC2STimestamp;
                else
                    object.messageC2STimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.messageC2STimestamp) : options.longs === Number ? new $util.LongBits(message.messageC2STimestamp.low >>> 0, message.messageC2STimestamp.high >>> 0).toNumber(true) : message.messageC2STimestamp;
            if (message.ignore != null && message.hasOwnProperty("ignore"))
                object.ignore = message.ignore;
            if (message.starred != null && message.hasOwnProperty("starred"))
                object.starred = message.starred;
            if (message.broadcast != null && message.hasOwnProperty("broadcast"))
                object.broadcast = message.broadcast;
            if (message.pushName != null && message.hasOwnProperty("pushName"))
                object.pushName = message.pushName;
            if (message.mediaCiphertextSha256 != null && message.hasOwnProperty("mediaCiphertextSha256"))
                object.mediaCiphertextSha256 = options.bytes === String ? $util.base64.encode(message.mediaCiphertextSha256, 0, message.mediaCiphertextSha256.length) : options.bytes === Array ? Array.prototype.slice.call(message.mediaCiphertextSha256) : message.mediaCiphertextSha256;
            if (message.multicast != null && message.hasOwnProperty("multicast"))
                object.multicast = message.multicast;
            if (message.urlText != null && message.hasOwnProperty("urlText"))
                object.urlText = message.urlText;
            if (message.urlNumber != null && message.hasOwnProperty("urlNumber"))
                object.urlNumber = message.urlNumber;
            if (message.messageStubType != null && message.hasOwnProperty("messageStubType"))
                object.messageStubType = options.enums === String ? $root.proto.WebMessageInfo.WebMessageInfoStubType[message.messageStubType] : message.messageStubType;
            if (message.clearMedia != null && message.hasOwnProperty("clearMedia"))
                object.clearMedia = message.clearMedia;
            if (message.messageStubParameters && message.messageStubParameters.length) {
                object.messageStubParameters = [];
                for (var j = 0; j < message.messageStubParameters.length; ++j)
                    object.messageStubParameters[j] = message.messageStubParameters[j];
            }
            if (message.duration != null && message.hasOwnProperty("duration"))
                object.duration = message.duration;
            if (message.labels && message.labels.length) {
                object.labels = [];
                for (var j = 0; j < message.labels.length; ++j)
                    object.labels[j] = message.labels[j];
            }
            if (message.paymentInfo != null && message.hasOwnProperty("paymentInfo"))
                object.paymentInfo = $root.proto.PaymentInfo.toObject(message.paymentInfo, options);
            if (message.finalLiveLocation != null && message.hasOwnProperty("finalLiveLocation"))
                object.finalLiveLocation = $root.proto.LiveLocationMessage.toObject(message.finalLiveLocation, options);
            if (message.quotedPaymentInfo != null && message.hasOwnProperty("quotedPaymentInfo"))
                object.quotedPaymentInfo = $root.proto.PaymentInfo.toObject(message.quotedPaymentInfo, options);
            if (message.ephemeralStartTimestamp != null && message.hasOwnProperty("ephemeralStartTimestamp"))
                if (typeof message.ephemeralStartTimestamp === "number")
                    object.ephemeralStartTimestamp = options.longs === String ? String(message.ephemeralStartTimestamp) : message.ephemeralStartTimestamp;
                else
                    object.ephemeralStartTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.ephemeralStartTimestamp) : options.longs === Number ? new $util.LongBits(message.ephemeralStartTimestamp.low >>> 0, message.ephemeralStartTimestamp.high >>> 0).toNumber(true) : message.ephemeralStartTimestamp;
            if (message.ephemeralDuration != null && message.hasOwnProperty("ephemeralDuration"))
                object.ephemeralDuration = message.ephemeralDuration;
            if (message.ephemeralOffToOn != null && message.hasOwnProperty("ephemeralOffToOn"))
                object.ephemeralOffToOn = message.ephemeralOffToOn;
            if (message.ephemeralOutOfSync != null && message.hasOwnProperty("ephemeralOutOfSync"))
                object.ephemeralOutOfSync = message.ephemeralOutOfSync;
            if (message.bizPrivacyStatus != null && message.hasOwnProperty("bizPrivacyStatus"))
                object.bizPrivacyStatus = options.enums === String ? $root.proto.WebMessageInfo.WebMessageInfoBizPrivacyStatus[message.bizPrivacyStatus] : message.bizPrivacyStatus;
            if (message.verifiedBizName != null && message.hasOwnProperty("verifiedBizName"))
                object.verifiedBizName = message.verifiedBizName;
            if (message.mediaData != null && message.hasOwnProperty("mediaData"))
                object.mediaData = $root.proto.MediaData.toObject(message.mediaData, options);
            if (message.photoChange != null && message.hasOwnProperty("photoChange"))
                object.photoChange = $root.proto.PhotoChange.toObject(message.photoChange, options);
            if (message.userReceipt && message.userReceipt.length) {
                object.userReceipt = [];
                for (var j = 0; j < message.userReceipt.length; ++j)
                    object.userReceipt[j] = $root.proto.UserReceipt.toObject(message.userReceipt[j], options);
            }
            if (message.reactions && message.reactions.length) {
                object.reactions = [];
                for (var j = 0; j < message.reactions.length; ++j)
                    object.reactions[j] = $root.proto.Reaction.toObject(message.reactions[j], options);
            }
            if (message.quotedStickerData != null && message.hasOwnProperty("quotedStickerData"))
                object.quotedStickerData = $root.proto.MediaData.toObject(message.quotedStickerData, options);
            if (message.futureproofData != null && message.hasOwnProperty("futureproofData"))
                object.futureproofData = options.bytes === String ? $util.base64.encode(message.futureproofData, 0, message.futureproofData.length) : options.bytes === Array ? Array.prototype.slice.call(message.futureproofData) : message.futureproofData;
            if (message.statusPsaCampaignId != null && message.hasOwnProperty("statusPsaCampaignId"))
                object.statusPsaCampaignId = message.statusPsaCampaignId;
            if (message.statusPsaCampaignDuration != null && message.hasOwnProperty("statusPsaCampaignDuration"))
                object.statusPsaCampaignDuration = message.statusPsaCampaignDuration;
            if (message.statusPsaCampaignReadTimestamp != null && message.hasOwnProperty("statusPsaCampaignReadTimestamp"))
                if (typeof message.statusPsaCampaignReadTimestamp === "number")
                    object.statusPsaCampaignReadTimestamp = options.longs === String ? String(message.statusPsaCampaignReadTimestamp) : message.statusPsaCampaignReadTimestamp;
                else
                    object.statusPsaCampaignReadTimestamp = options.longs === String ? $util.Long.prototype.toString.call(message.statusPsaCampaignReadTimestamp) : options.longs === Number ? new $util.LongBits(message.statusPsaCampaignReadTimestamp.low >>> 0, message.statusPsaCampaignReadTimestamp.high >>> 0).toNumber(true) : message.statusPsaCampaignReadTimestamp;
            return object;
        };

        /**
         * Converts this WebMessageInfo to JSON.
         * @function toJSON
         * @memberof proto.WebMessageInfo
         * @instance
         * @returns {Object.<string,*>} JSON object
         */
        WebMessageInfo.prototype.toJSON = function toJSON() {
            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
        };

        /**
         * WebMessageInfoStatus enum.
         * @name proto.WebMessageInfo.WebMessageInfoStatus
         * @enum {number}
         * @property {number} ERROR=0 ERROR value
         * @property {number} PENDING=1 PENDING value
         * @property {number} SERVER_ACK=2 SERVER_ACK value
         * @property {number} DELIVERY_ACK=3 DELIVERY_ACK value
         * @property {number} READ=4 READ value
         * @property {number} PLAYED=5 PLAYED value
         */
        WebMessageInfo.WebMessageInfoStatus = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "ERROR"] = 0;
            values[valuesById[1] = "PENDING"] = 1;
            values[valuesById[2] = "SERVER_ACK"] = 2;
            values[valuesById[3] = "DELIVERY_ACK"] = 3;
            values[valuesById[4] = "READ"] = 4;
            values[valuesById[5] = "PLAYED"] = 5;
            return values;
        })();

        /**
         * WebMessageInfoStubType enum.
         * @name proto.WebMessageInfo.WebMessageInfoStubType
         * @enum {number}
         * @property {number} UNKNOWN=0 UNKNOWN value
         * @property {number} REVOKE=1 REVOKE value
         * @property {number} CIPHERTEXT=2 CIPHERTEXT value
         * @property {number} FUTUREPROOF=3 FUTUREPROOF value
         * @property {number} NON_VERIFIED_TRANSITION=4 NON_VERIFIED_TRANSITION value
         * @property {number} UNVERIFIED_TRANSITION=5 UNVERIFIED_TRANSITION value
         * @property {number} VERIFIED_TRANSITION=6 VERIFIED_TRANSITION value
         * @property {number} VERIFIED_LOW_UNKNOWN=7 VERIFIED_LOW_UNKNOWN value
         * @property {number} VERIFIED_HIGH=8 VERIFIED_HIGH value
         * @property {number} VERIFIED_INITIAL_UNKNOWN=9 VERIFIED_INITIAL_UNKNOWN value
         * @property {number} VERIFIED_INITIAL_LOW=10 VERIFIED_INITIAL_LOW value
         * @property {number} VERIFIED_INITIAL_HIGH=11 VERIFIED_INITIAL_HIGH value
         * @property {number} VERIFIED_TRANSITION_ANY_TO_NONE=12 VERIFIED_TRANSITION_ANY_TO_NONE value
         * @property {number} VERIFIED_TRANSITION_ANY_TO_HIGH=13 VERIFIED_TRANSITION_ANY_TO_HIGH value
         * @property {number} VERIFIED_TRANSITION_HIGH_TO_LOW=14 VERIFIED_TRANSITION_HIGH_TO_LOW value
         * @property {number} VERIFIED_TRANSITION_HIGH_TO_UNKNOWN=15 VERIFIED_TRANSITION_HIGH_TO_UNKNOWN value
         * @property {number} VERIFIED_TRANSITION_UNKNOWN_TO_LOW=16 VERIFIED_TRANSITION_UNKNOWN_TO_LOW value
         * @property {number} VERIFIED_TRANSITION_LOW_TO_UNKNOWN=17 VERIFIED_TRANSITION_LOW_TO_UNKNOWN value
         * @property {number} VERIFIED_TRANSITION_NONE_TO_LOW=18 VERIFIED_TRANSITION_NONE_TO_LOW value
         * @property {number} VERIFIED_TRANSITION_NONE_TO_UNKNOWN=19 VERIFIED_TRANSITION_NONE_TO_UNKNOWN value
         * @property {number} GROUP_CREATE=20 GROUP_CREATE value
         * @property {number} GROUP_CHANGE_SUBJECT=21 GROUP_CHANGE_SUBJECT value
         * @property {number} GROUP_CHANGE_ICON=22 GROUP_CHANGE_ICON value
         * @property {number} GROUP_CHANGE_INVITE_LINK=23 GROUP_CHANGE_INVITE_LINK value
         * @property {number} GROUP_CHANGE_DESCRIPTION=24 GROUP_CHANGE_DESCRIPTION value
         * @property {number} GROUP_CHANGE_RESTRICT=25 GROUP_CHANGE_RESTRICT value
         * @property {number} GROUP_CHANGE_ANNOUNCE=26 GROUP_CHANGE_ANNOUNCE value
         * @property {number} GROUP_PARTICIPANT_ADD=27 GROUP_PARTICIPANT_ADD value
         * @property {number} GROUP_PARTICIPANT_REMOVE=28 GROUP_PARTICIPANT_REMOVE value
         * @property {number} GROUP_PARTICIPANT_PROMOTE=29 GROUP_PARTICIPANT_PROMOTE value
         * @property {number} GROUP_PARTICIPANT_DEMOTE=30 GROUP_PARTICIPANT_DEMOTE value
         * @property {number} GROUP_PARTICIPANT_INVITE=31 GROUP_PARTICIPANT_INVITE value
         * @property {number} GROUP_PARTICIPANT_LEAVE=32 GROUP_PARTICIPANT_LEAVE value
         * @property {number} GROUP_PARTICIPANT_CHANGE_NUMBER=33 GROUP_PARTICIPANT_CHANGE_NUMBER value
         * @property {number} BROADCAST_CREATE=34 BROADCAST_CREATE value
         * @property {number} BROADCAST_ADD=35 BROADCAST_ADD value
         * @property {number} BROADCAST_REMOVE=36 BROADCAST_REMOVE value
         * @property {number} GENERIC_NOTIFICATION=37 GENERIC_NOTIFICATION value
         * @property {number} E2E_IDENTITY_CHANGED=38 E2E_IDENTITY_CHANGED value
         * @property {number} E2E_ENCRYPTED=39 E2E_ENCRYPTED value
         * @property {number} CALL_MISSED_VOICE=40 CALL_MISSED_VOICE value
         * @property {number} CALL_MISSED_VIDEO=41 CALL_MISSED_VIDEO value
         * @property {number} INDIVIDUAL_CHANGE_NUMBER=42 INDIVIDUAL_CHANGE_NUMBER value
         * @property {number} GROUP_DELETE=43 GROUP_DELETE value
         * @property {number} GROUP_ANNOUNCE_MODE_MESSAGE_BOUNCE=44 GROUP_ANNOUNCE_MODE_MESSAGE_BOUNCE value
         * @property {number} CALL_MISSED_GROUP_VOICE=45 CALL_MISSED_GROUP_VOICE value
         * @property {number} CALL_MISSED_GROUP_VIDEO=46 CALL_MISSED_GROUP_VIDEO value
         * @property {number} PAYMENT_CIPHERTEXT=47 PAYMENT_CIPHERTEXT value
         * @property {number} PAYMENT_FUTUREPROOF=48 PAYMENT_FUTUREPROOF value
         * @property {number} PAYMENT_TRANSACTION_STATUS_UPDATE_FAILED=49 PAYMENT_TRANSACTION_STATUS_UPDATE_FAILED value
         * @property {number} PAYMENT_TRANSACTION_STATUS_UPDATE_REFUNDED=50 PAYMENT_TRANSACTION_STATUS_UPDATE_REFUNDED value
         * @property {number} PAYMENT_TRANSACTION_STATUS_UPDATE_REFUND_FAILED=51 PAYMENT_TRANSACTION_STATUS_UPDATE_REFUND_FAILED value
         * @property {number} PAYMENT_TRANSACTION_STATUS_RECEIVER_PENDING_SETUP=52 PAYMENT_TRANSACTION_STATUS_RECEIVER_PENDING_SETUP value
         * @property {number} PAYMENT_TRANSACTION_STATUS_RECEIVER_SUCCESS_AFTER_HICCUP=53 PAYMENT_TRANSACTION_STATUS_RECEIVER_SUCCESS_AFTER_HICCUP value
         * @property {number} PAYMENT_ACTION_ACCOUNT_SETUP_REMINDER=54 PAYMENT_ACTION_ACCOUNT_SETUP_REMINDER value
         * @property {number} PAYMENT_ACTION_SEND_PAYMENT_REMINDER=55 PAYMENT_ACTION_SEND_PAYMENT_REMINDER value
         * @property {number} PAYMENT_ACTION_SEND_PAYMENT_INVITATION=56 PAYMENT_ACTION_SEND_PAYMENT_INVITATION value
         * @property {number} PAYMENT_ACTION_REQUEST_DECLINED=57 PAYMENT_ACTION_REQUEST_DECLINED value
         * @property {number} PAYMENT_ACTION_REQUEST_EXPIRED=58 PAYMENT_ACTION_REQUEST_EXPIRED value
         * @property {number} PAYMENT_ACTION_REQUEST_CANCELLED=59 PAYMENT_ACTION_REQUEST_CANCELLED value
         * @property {number} BIZ_VERIFIED_TRANSITION_TOP_TO_BOTTOM=60 BIZ_VERIFIED_TRANSITION_TOP_TO_BOTTOM value
         * @property {number} BIZ_VERIFIED_TRANSITION_BOTTOM_TO_TOP=61 BIZ_VERIFIED_TRANSITION_BOTTOM_TO_TOP value
         * @property {number} BIZ_INTRO_TOP=62 BIZ_INTRO_TOP value
         * @property {number} BIZ_INTRO_BOTTOM=63 BIZ_INTRO_BOTTOM value
         * @property {number} BIZ_NAME_CHANGE=64 BIZ_NAME_CHANGE value
         * @property {number} BIZ_MOVE_TO_CONSUMER_APP=65 BIZ_MOVE_TO_CONSUMER_APP value
         * @property {number} BIZ_TWO_TIER_MIGRATION_TOP=66 BIZ_TWO_TIER_MIGRATION_TOP value
         * @property {number} BIZ_TWO_TIER_MIGRATION_BOTTOM=67 BIZ_TWO_TIER_MIGRATION_BOTTOM value
         * @property {number} OVERSIZED=68 OVERSIZED value
         * @property {number} GROUP_CHANGE_NO_FREQUENTLY_FORWARDED=69 GROUP_CHANGE_NO_FREQUENTLY_FORWARDED value
         * @property {number} GROUP_V4_ADD_INVITE_SENT=70 GROUP_V4_ADD_INVITE_SENT value
         * @property {number} GROUP_PARTICIPANT_ADD_REQUEST_JOIN=71 GROUP_PARTICIPANT_ADD_REQUEST_JOIN value
         * @property {number} CHANGE_EPHEMERAL_SETTING=72 CHANGE_EPHEMERAL_SETTING value
         * @property {number} E2E_DEVICE_CHANGED=73 E2E_DEVICE_CHANGED value
         * @property {number} VIEWED_ONCE=74 VIEWED_ONCE value
         * @property {number} E2E_ENCRYPTED_NOW=75 E2E_ENCRYPTED_NOW value
         * @property {number} BLUE_MSG_BSP_FB_TO_BSP_PREMISE=76 BLUE_MSG_BSP_FB_TO_BSP_PREMISE value
         * @property {number} BLUE_MSG_BSP_FB_TO_SELF_FB=77 BLUE_MSG_BSP_FB_TO_SELF_FB value
         * @property {number} BLUE_MSG_BSP_FB_TO_SELF_PREMISE=78 BLUE_MSG_BSP_FB_TO_SELF_PREMISE value
         * @property {number} BLUE_MSG_BSP_FB_UNVERIFIED=79 BLUE_MSG_BSP_FB_UNVERIFIED value
         * @property {number} BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED=80 BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED value
         * @property {number} BLUE_MSG_BSP_FB_VERIFIED=81 BLUE_MSG_BSP_FB_VERIFIED value
         * @property {number} BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED=82 BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED value
         * @property {number} BLUE_MSG_BSP_PREMISE_TO_SELF_PREMISE=83 BLUE_MSG_BSP_PREMISE_TO_SELF_PREMISE value
         * @property {number} BLUE_MSG_BSP_PREMISE_UNVERIFIED=84 BLUE_MSG_BSP_PREMISE_UNVERIFIED value
         * @property {number} BLUE_MSG_BSP_PREMISE_UNVERIFIED_TO_SELF_PREMISE_VERIFIED=85 BLUE_MSG_BSP_PREMISE_UNVERIFIED_TO_SELF_PREMISE_VERIFIED value
         * @property {number} BLUE_MSG_BSP_PREMISE_VERIFIED=86 BLUE_MSG_BSP_PREMISE_VERIFIED value
         * @property {number} BLUE_MSG_BSP_PREMISE_VERIFIED_TO_SELF_PREMISE_UNVERIFIED=87 BLUE_MSG_BSP_PREMISE_VERIFIED_TO_SELF_PREMISE_UNVERIFIED value
         * @property {number} BLUE_MSG_CONSUMER_TO_BSP_FB_UNVERIFIED=88 BLUE_MSG_CONSUMER_TO_BSP_FB_UNVERIFIED value
         * @property {number} BLUE_MSG_CONSUMER_TO_BSP_PREMISE_UNVERIFIED=89 BLUE_MSG_CONSUMER_TO_BSP_PREMISE_UNVERIFIED value
         * @property {number} BLUE_MSG_CONSUMER_TO_SELF_FB_UNVERIFIED=90 BLUE_MSG_CONSUMER_TO_SELF_FB_UNVERIFIED value
         * @property {number} BLUE_MSG_CONSUMER_TO_SELF_PREMISE_UNVERIFIED=91 BLUE_MSG_CONSUMER_TO_SELF_PREMISE_UNVERIFIED value
         * @property {number} BLUE_MSG_SELF_FB_TO_BSP_PREMISE=92 BLUE_MSG_SELF_FB_TO_BSP_PREMISE value
         * @property {number} BLUE_MSG_SELF_FB_TO_SELF_PREMISE=93 BLUE_MSG_SELF_FB_TO_SELF_PREMISE value
         * @property {number} BLUE_MSG_SELF_FB_UNVERIFIED=94 BLUE_MSG_SELF_FB_UNVERIFIED value
         * @property {number} BLUE_MSG_SELF_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED=95 BLUE_MSG_SELF_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED value
         * @property {number} BLUE_MSG_SELF_FB_VERIFIED=96 BLUE_MSG_SELF_FB_VERIFIED value
         * @property {number} BLUE_MSG_SELF_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED=97 BLUE_MSG_SELF_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED value
         * @property {number} BLUE_MSG_SELF_PREMISE_TO_BSP_PREMISE=98 BLUE_MSG_SELF_PREMISE_TO_BSP_PREMISE value
         * @property {number} BLUE_MSG_SELF_PREMISE_UNVERIFIED=99 BLUE_MSG_SELF_PREMISE_UNVERIFIED value
         * @property {number} BLUE_MSG_SELF_PREMISE_VERIFIED=100 BLUE_MSG_SELF_PREMISE_VERIFIED value
         * @property {number} BLUE_MSG_TO_BSP_FB=101 BLUE_MSG_TO_BSP_FB value
         * @property {number} BLUE_MSG_TO_CONSUMER=102 BLUE_MSG_TO_CONSUMER value
         * @property {number} BLUE_MSG_TO_SELF_FB=103 BLUE_MSG_TO_SELF_FB value
         * @property {number} BLUE_MSG_UNVERIFIED_TO_BSP_FB_VERIFIED=104 BLUE_MSG_UNVERIFIED_TO_BSP_FB_VERIFIED value
         * @property {number} BLUE_MSG_UNVERIFIED_TO_BSP_PREMISE_VERIFIED=105 BLUE_MSG_UNVERIFIED_TO_BSP_PREMISE_VERIFIED value
         * @property {number} BLUE_MSG_UNVERIFIED_TO_SELF_FB_VERIFIED=106 BLUE_MSG_UNVERIFIED_TO_SELF_FB_VERIFIED value
         * @property {number} BLUE_MSG_UNVERIFIED_TO_VERIFIED=107 BLUE_MSG_UNVERIFIED_TO_VERIFIED value
         * @property {number} BLUE_MSG_VERIFIED_TO_BSP_FB_UNVERIFIED=108 BLUE_MSG_VERIFIED_TO_BSP_FB_UNVERIFIED value
         * @property {number} BLUE_MSG_VERIFIED_TO_BSP_PREMISE_UNVERIFIED=109 BLUE_MSG_VERIFIED_TO_BSP_PREMISE_UNVERIFIED value
         * @property {number} BLUE_MSG_VERIFIED_TO_SELF_FB_UNVERIFIED=110 BLUE_MSG_VERIFIED_TO_SELF_FB_UNVERIFIED value
         * @property {number} BLUE_MSG_VERIFIED_TO_UNVERIFIED=111 BLUE_MSG_VERIFIED_TO_UNVERIFIED value
         * @property {number} BLUE_MSG_BSP_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED=112 BLUE_MSG_BSP_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED value
         * @property {number} BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_FB_VERIFIED=113 BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_FB_VERIFIED value
         * @property {number} BLUE_MSG_BSP_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED=114 BLUE_MSG_BSP_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED value
         * @property {number} BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_FB_UNVERIFIED=115 BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_FB_UNVERIFIED value
         * @property {number} BLUE_MSG_SELF_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED=116 BLUE_MSG_SELF_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED value
         * @property {number} BLUE_MSG_SELF_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED=117 BLUE_MSG_SELF_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED value
         * @property {number} E2E_IDENTITY_UNAVAILABLE=118 E2E_IDENTITY_UNAVAILABLE value
         * @property {number} GROUP_CREATING=119 GROUP_CREATING value
         * @property {number} GROUP_CREATE_FAILED=120 GROUP_CREATE_FAILED value
         * @property {number} GROUP_BOUNCED=121 GROUP_BOUNCED value
         * @property {number} BLOCK_CONTACT=122 BLOCK_CONTACT value
         * @property {number} EPHEMERAL_SETTING_NOT_APPLIED=123 EPHEMERAL_SETTING_NOT_APPLIED value
         * @property {number} SYNC_FAILED=124 SYNC_FAILED value
         * @property {number} SYNCING=125 SYNCING value
         * @property {number} BIZ_PRIVACY_MODE_INIT_FB=126 BIZ_PRIVACY_MODE_INIT_FB value
         * @property {number} BIZ_PRIVACY_MODE_INIT_BSP=127 BIZ_PRIVACY_MODE_INIT_BSP value
         * @property {number} BIZ_PRIVACY_MODE_TO_FB=128 BIZ_PRIVACY_MODE_TO_FB value
         * @property {number} BIZ_PRIVACY_MODE_TO_BSP=129 BIZ_PRIVACY_MODE_TO_BSP value
         * @property {number} DISAPPEARING_MODE=130 DISAPPEARING_MODE value
         * @property {number} E2E_DEVICE_FETCH_FAILED=131 E2E_DEVICE_FETCH_FAILED value
         */
        WebMessageInfo.WebMessageInfoStubType = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "UNKNOWN"] = 0;
            values[valuesById[1] = "REVOKE"] = 1;
            values[valuesById[2] = "CIPHERTEXT"] = 2;
            values[valuesById[3] = "FUTUREPROOF"] = 3;
            values[valuesById[4] = "NON_VERIFIED_TRANSITION"] = 4;
            values[valuesById[5] = "UNVERIFIED_TRANSITION"] = 5;
            values[valuesById[6] = "VERIFIED_TRANSITION"] = 6;
            values[valuesById[7] = "VERIFIED_LOW_UNKNOWN"] = 7;
            values[valuesById[8] = "VERIFIED_HIGH"] = 8;
            values[valuesById[9] = "VERIFIED_INITIAL_UNKNOWN"] = 9;
            values[valuesById[10] = "VERIFIED_INITIAL_LOW"] = 10;
            values[valuesById[11] = "VERIFIED_INITIAL_HIGH"] = 11;
            values[valuesById[12] = "VERIFIED_TRANSITION_ANY_TO_NONE"] = 12;
            values[valuesById[13] = "VERIFIED_TRANSITION_ANY_TO_HIGH"] = 13;
            values[valuesById[14] = "VERIFIED_TRANSITION_HIGH_TO_LOW"] = 14;
            values[valuesById[15] = "VERIFIED_TRANSITION_HIGH_TO_UNKNOWN"] = 15;
            values[valuesById[16] = "VERIFIED_TRANSITION_UNKNOWN_TO_LOW"] = 16;
            values[valuesById[17] = "VERIFIED_TRANSITION_LOW_TO_UNKNOWN"] = 17;
            values[valuesById[18] = "VERIFIED_TRANSITION_NONE_TO_LOW"] = 18;
            values[valuesById[19] = "VERIFIED_TRANSITION_NONE_TO_UNKNOWN"] = 19;
            values[valuesById[20] = "GROUP_CREATE"] = 20;
            values[valuesById[21] = "GROUP_CHANGE_SUBJECT"] = 21;
            values[valuesById[22] = "GROUP_CHANGE_ICON"] = 22;
            values[valuesById[23] = "GROUP_CHANGE_INVITE_LINK"] = 23;
            values[valuesById[24] = "GROUP_CHANGE_DESCRIPTION"] = 24;
            values[valuesById[25] = "GROUP_CHANGE_RESTRICT"] = 25;
            values[valuesById[26] = "GROUP_CHANGE_ANNOUNCE"] = 26;
            values[valuesById[27] = "GROUP_PARTICIPANT_ADD"] = 27;
            values[valuesById[28] = "GROUP_PARTICIPANT_REMOVE"] = 28;
            values[valuesById[29] = "GROUP_PARTICIPANT_PROMOTE"] = 29;
            values[valuesById[30] = "GROUP_PARTICIPANT_DEMOTE"] = 30;
            values[valuesById[31] = "GROUP_PARTICIPANT_INVITE"] = 31;
            values[valuesById[32] = "GROUP_PARTICIPANT_LEAVE"] = 32;
            values[valuesById[33] = "GROUP_PARTICIPANT_CHANGE_NUMBER"] = 33;
            values[valuesById[34] = "BROADCAST_CREATE"] = 34;
            values[valuesById[35] = "BROADCAST_ADD"] = 35;
            values[valuesById[36] = "BROADCAST_REMOVE"] = 36;
            values[valuesById[37] = "GENERIC_NOTIFICATION"] = 37;
            values[valuesById[38] = "E2E_IDENTITY_CHANGED"] = 38;
            values[valuesById[39] = "E2E_ENCRYPTED"] = 39;
            values[valuesById[40] = "CALL_MISSED_VOICE"] = 40;
            values[valuesById[41] = "CALL_MISSED_VIDEO"] = 41;
            values[valuesById[42] = "INDIVIDUAL_CHANGE_NUMBER"] = 42;
            values[valuesById[43] = "GROUP_DELETE"] = 43;
            values[valuesById[44] = "GROUP_ANNOUNCE_MODE_MESSAGE_BOUNCE"] = 44;
            values[valuesById[45] = "CALL_MISSED_GROUP_VOICE"] = 45;
            values[valuesById[46] = "CALL_MISSED_GROUP_VIDEO"] = 46;
            values[valuesById[47] = "PAYMENT_CIPHERTEXT"] = 47;
            values[valuesById[48] = "PAYMENT_FUTUREPROOF"] = 48;
            values[valuesById[49] = "PAYMENT_TRANSACTION_STATUS_UPDATE_FAILED"] = 49;
            values[valuesById[50] = "PAYMENT_TRANSACTION_STATUS_UPDATE_REFUNDED"] = 50;
            values[valuesById[51] = "PAYMENT_TRANSACTION_STATUS_UPDATE_REFUND_FAILED"] = 51;
            values[valuesById[52] = "PAYMENT_TRANSACTION_STATUS_RECEIVER_PENDING_SETUP"] = 52;
            values[valuesById[53] = "PAYMENT_TRANSACTION_STATUS_RECEIVER_SUCCESS_AFTER_HICCUP"] = 53;
            values[valuesById[54] = "PAYMENT_ACTION_ACCOUNT_SETUP_REMINDER"] = 54;
            values[valuesById[55] = "PAYMENT_ACTION_SEND_PAYMENT_REMINDER"] = 55;
            values[valuesById[56] = "PAYMENT_ACTION_SEND_PAYMENT_INVITATION"] = 56;
            values[valuesById[57] = "PAYMENT_ACTION_REQUEST_DECLINED"] = 57;
            values[valuesById[58] = "PAYMENT_ACTION_REQUEST_EXPIRED"] = 58;
            values[valuesById[59] = "PAYMENT_ACTION_REQUEST_CANCELLED"] = 59;
            values[valuesById[60] = "BIZ_VERIFIED_TRANSITION_TOP_TO_BOTTOM"] = 60;
            values[valuesById[61] = "BIZ_VERIFIED_TRANSITION_BOTTOM_TO_TOP"] = 61;
            values[valuesById[62] = "BIZ_INTRO_TOP"] = 62;
            values[valuesById[63] = "BIZ_INTRO_BOTTOM"] = 63;
            values[valuesById[64] = "BIZ_NAME_CHANGE"] = 64;
            values[valuesById[65] = "BIZ_MOVE_TO_CONSUMER_APP"] = 65;
            values[valuesById[66] = "BIZ_TWO_TIER_MIGRATION_TOP"] = 66;
            values[valuesById[67] = "BIZ_TWO_TIER_MIGRATION_BOTTOM"] = 67;
            values[valuesById[68] = "OVERSIZED"] = 68;
            values[valuesById[69] = "GROUP_CHANGE_NO_FREQUENTLY_FORWARDED"] = 69;
            values[valuesById[70] = "GROUP_V4_ADD_INVITE_SENT"] = 70;
            values[valuesById[71] = "GROUP_PARTICIPANT_ADD_REQUEST_JOIN"] = 71;
            values[valuesById[72] = "CHANGE_EPHEMERAL_SETTING"] = 72;
            values[valuesById[73] = "E2E_DEVICE_CHANGED"] = 73;
            values[valuesById[74] = "VIEWED_ONCE"] = 74;
            values[valuesById[75] = "E2E_ENCRYPTED_NOW"] = 75;
            values[valuesById[76] = "BLUE_MSG_BSP_FB_TO_BSP_PREMISE"] = 76;
            values[valuesById[77] = "BLUE_MSG_BSP_FB_TO_SELF_FB"] = 77;
            values[valuesById[78] = "BLUE_MSG_BSP_FB_TO_SELF_PREMISE"] = 78;
            values[valuesById[79] = "BLUE_MSG_BSP_FB_UNVERIFIED"] = 79;
            values[valuesById[80] = "BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED"] = 80;
            values[valuesById[81] = "BLUE_MSG_BSP_FB_VERIFIED"] = 81;
            values[valuesById[82] = "BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED"] = 82;
            values[valuesById[83] = "BLUE_MSG_BSP_PREMISE_TO_SELF_PREMISE"] = 83;
            values[valuesById[84] = "BLUE_MSG_BSP_PREMISE_UNVERIFIED"] = 84;
            values[valuesById[85] = "BLUE_MSG_BSP_PREMISE_UNVERIFIED_TO_SELF_PREMISE_VERIFIED"] = 85;
            values[valuesById[86] = "BLUE_MSG_BSP_PREMISE_VERIFIED"] = 86;
            values[valuesById[87] = "BLUE_MSG_BSP_PREMISE_VERIFIED_TO_SELF_PREMISE_UNVERIFIED"] = 87;
            values[valuesById[88] = "BLUE_MSG_CONSUMER_TO_BSP_FB_UNVERIFIED"] = 88;
            values[valuesById[89] = "BLUE_MSG_CONSUMER_TO_BSP_PREMISE_UNVERIFIED"] = 89;
            values[valuesById[90] = "BLUE_MSG_CONSUMER_TO_SELF_FB_UNVERIFIED"] = 90;
            values[valuesById[91] = "BLUE_MSG_CONSUMER_TO_SELF_PREMISE_UNVERIFIED"] = 91;
            values[valuesById[92] = "BLUE_MSG_SELF_FB_TO_BSP_PREMISE"] = 92;
            values[valuesById[93] = "BLUE_MSG_SELF_FB_TO_SELF_PREMISE"] = 93;
            values[valuesById[94] = "BLUE_MSG_SELF_FB_UNVERIFIED"] = 94;
            values[valuesById[95] = "BLUE_MSG_SELF_FB_UNVERIFIED_TO_SELF_PREMISE_VERIFIED"] = 95;
            values[valuesById[96] = "BLUE_MSG_SELF_FB_VERIFIED"] = 96;
            values[valuesById[97] = "BLUE_MSG_SELF_FB_VERIFIED_TO_SELF_PREMISE_UNVERIFIED"] = 97;
            values[valuesById[98] = "BLUE_MSG_SELF_PREMISE_TO_BSP_PREMISE"] = 98;
            values[valuesById[99] = "BLUE_MSG_SELF_PREMISE_UNVERIFIED"] = 99;
            values[valuesById[100] = "BLUE_MSG_SELF_PREMISE_VERIFIED"] = 100;
            values[valuesById[101] = "BLUE_MSG_TO_BSP_FB"] = 101;
            values[valuesById[102] = "BLUE_MSG_TO_CONSUMER"] = 102;
            values[valuesById[103] = "BLUE_MSG_TO_SELF_FB"] = 103;
            values[valuesById[104] = "BLUE_MSG_UNVERIFIED_TO_BSP_FB_VERIFIED"] = 104;
            values[valuesById[105] = "BLUE_MSG_UNVERIFIED_TO_BSP_PREMISE_VERIFIED"] = 105;
            values[valuesById[106] = "BLUE_MSG_UNVERIFIED_TO_SELF_FB_VERIFIED"] = 106;
            values[valuesById[107] = "BLUE_MSG_UNVERIFIED_TO_VERIFIED"] = 107;
            values[valuesById[108] = "BLUE_MSG_VERIFIED_TO_BSP_FB_UNVERIFIED"] = 108;
            values[valuesById[109] = "BLUE_MSG_VERIFIED_TO_BSP_PREMISE_UNVERIFIED"] = 109;
            values[valuesById[110] = "BLUE_MSG_VERIFIED_TO_SELF_FB_UNVERIFIED"] = 110;
            values[valuesById[111] = "BLUE_MSG_VERIFIED_TO_UNVERIFIED"] = 111;
            values[valuesById[112] = "BLUE_MSG_BSP_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED"] = 112;
            values[valuesById[113] = "BLUE_MSG_BSP_FB_UNVERIFIED_TO_SELF_FB_VERIFIED"] = 113;
            values[valuesById[114] = "BLUE_MSG_BSP_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED"] = 114;
            values[valuesById[115] = "BLUE_MSG_BSP_FB_VERIFIED_TO_SELF_FB_UNVERIFIED"] = 115;
            values[valuesById[116] = "BLUE_MSG_SELF_FB_UNVERIFIED_TO_BSP_PREMISE_VERIFIED"] = 116;
            values[valuesById[117] = "BLUE_MSG_SELF_FB_VERIFIED_TO_BSP_PREMISE_UNVERIFIED"] = 117;
            values[valuesById[118] = "E2E_IDENTITY_UNAVAILABLE"] = 118;
            values[valuesById[119] = "GROUP_CREATING"] = 119;
            values[valuesById[120] = "GROUP_CREATE_FAILED"] = 120;
            values[valuesById[121] = "GROUP_BOUNCED"] = 121;
            values[valuesById[122] = "BLOCK_CONTACT"] = 122;
            values[valuesById[123] = "EPHEMERAL_SETTING_NOT_APPLIED"] = 123;
            values[valuesById[124] = "SYNC_FAILED"] = 124;
            values[valuesById[125] = "SYNCING"] = 125;
            values[valuesById[126] = "BIZ_PRIVACY_MODE_INIT_FB"] = 126;
            values[valuesById[127] = "BIZ_PRIVACY_MODE_INIT_BSP"] = 127;
            values[valuesById[128] = "BIZ_PRIVACY_MODE_TO_FB"] = 128;
            values[valuesById[129] = "BIZ_PRIVACY_MODE_TO_BSP"] = 129;
            values[valuesById[130] = "DISAPPEARING_MODE"] = 130;
            values[valuesById[131] = "E2E_DEVICE_FETCH_FAILED"] = 131;
            return values;
        })();

        /**
         * WebMessageInfoBizPrivacyStatus enum.
         * @name proto.WebMessageInfo.WebMessageInfoBizPrivacyStatus
         * @enum {number}
         * @property {number} E2EE=0 E2EE value
         * @property {number} FB=2 FB value
         * @property {number} BSP=1 BSP value
         * @property {number} BSP_AND_FB=3 BSP_AND_FB value
         */
        WebMessageInfo.WebMessageInfoBizPrivacyStatus = (function() {
            var valuesById = {}, values = Object.create(valuesById);
            values[valuesById[0] = "E2EE"] = 0;
            values[valuesById[2] = "FB"] = 2;
            values[valuesById[1] = "BSP"] = 1;
            values[valuesById[3] = "BSP_AND_FB"] = 3;
            return values;
        })();

        return WebMessageInfo;
    })();

    return proto;
})();

module.exports = $root;
